-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[#13] FestivalScreen / MoreScreen 구현 #14
Changes from all commits
29b626f
2840c21
93adf39
2d99764
8d136da
5713844
726dbc9
7ea3029
547f05e
7d57b1c
263f525
7eae70e
1e0f5fd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
package kr.ksw.visitkorea.data.paging.source | ||
|
||
import androidx.paging.PagingSource | ||
import androidx.paging.PagingState | ||
import kr.ksw.visitkorea.data.mapper.toItems | ||
import kr.ksw.visitkorea.data.remote.api.SearchFestivalApi | ||
import kr.ksw.visitkorea.data.remote.dto.SearchFestivalDTO | ||
|
||
class SearchFestivalPagingSource( | ||
private val searchFestivalApi: SearchFestivalApi, | ||
private val eventStartDate: String, | ||
private val eventEndDate: String, | ||
private val areaCode: String?, | ||
private val sigunguCode: String? | ||
) : PagingSource<Int, SearchFestivalDTO>() { | ||
|
||
override fun getRefreshKey(state: PagingState<Int, SearchFestivalDTO>): Int? { | ||
return state.anchorPosition?.let { anchor -> | ||
val anchorPage = state.closestPageToPosition(anchor) | ||
anchorPage?.prevKey?.plus(1) ?: anchorPage?.nextKey?.minus(1) | ||
} | ||
} | ||
|
||
override suspend fun load(params: LoadParams<Int>): LoadResult<Int, SearchFestivalDTO> { | ||
val page = params.key ?: 1 | ||
val loadSize = params.loadSize | ||
val response = searchFestivalApi.searchFestival( | ||
numOfRows = loadSize, | ||
pageNo = page, | ||
eventStartDate = eventStartDate, | ||
eventEndDate = eventEndDate, | ||
areaCode = areaCode, | ||
sigunguCode = sigunguCode | ||
) | ||
val data = response.toItems() | ||
return LoadResult.Page( | ||
data = data, | ||
prevKey = if(page == 1) null else page - 1, | ||
nextKey = if(data.size == loadSize) | ||
page + 1 | ||
else null | ||
) | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package kr.ksw.visitkorea.data.remote.api | ||
|
||
import kr.ksw.visitkorea.data.remote.dto.SearchFestivalDTO | ||
import kr.ksw.visitkorea.data.remote.model.ApiResponse | ||
import retrofit2.http.GET | ||
import retrofit2.http.Query | ||
|
||
interface SearchFestivalApi { | ||
@GET("searchFestival1") | ||
suspend fun searchFestival( | ||
@Query("arrange") arrange: String = "S", | ||
@Query("numOfRows") numOfRows: Int, | ||
@Query("pageNo") pageNo: Int, | ||
@Query("eventStartDate") eventStartDate: String, | ||
@Query("eventEndDate") eventEndDate: String, | ||
@Query("areaCode") areaCode: String? = null, | ||
@Query("sigunguCode") sigunguCode: String? = null | ||
): ApiResponse<SearchFestivalDTO> | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 프로퍼티명과 파싱할 값의 이름이 동일하다면 굳이 query annotation 을 쓰지 않아도 됩니다. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 몰랐었던 부분인데 감사합니다! |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package kr.ksw.visitkorea.data.remote.dto | ||
|
||
import com.google.gson.annotations.SerializedName | ||
|
||
data class SearchFestivalDTO( | ||
@SerializedName("addr1") | ||
val address: String, | ||
@SerializedName("areacode") | ||
val areaCode: String, | ||
@SerializedName("sigungucode") | ||
val sigunguCode: String, | ||
@SerializedName("contentid") | ||
val contentId: String, | ||
@SerializedName("contenttypeid") | ||
val contentTypeId: String, | ||
@SerializedName("eventstartdate") | ||
val eventStartDate: String, | ||
@SerializedName("eventenddate") | ||
val eventEndDate: String, | ||
@SerializedName("firstimage") | ||
val firstImage: String, | ||
@SerializedName("firstimage2") | ||
val firstImage2: String, | ||
@SerializedName("mapx") | ||
val mapX: String, | ||
@SerializedName("mapy") | ||
val mapY: String, | ||
val cat3: String, | ||
val tel: String, | ||
val title: String | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
package kr.ksw.visitkorea.data.repository | ||
|
||
import kr.ksw.visitkorea.data.remote.dto.SearchFestivalDTO | ||
|
||
interface SearchFestivalRepository { | ||
suspend operator fun invoke( | ||
numOfRows: Int, | ||
pageNo: Int, | ||
eventStartDate: String, | ||
eventEndDate: String, | ||
areaCode: String? = null, | ||
sigunguCode: String? = null | ||
): Result<List<SearchFestivalDTO>> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Trailing comma 추가하는게 좋을 거 같아요 |
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package kr.ksw.visitkorea.data.repository | ||
|
||
import kr.ksw.visitkorea.data.mapper.toItems | ||
import kr.ksw.visitkorea.data.remote.api.SearchFestivalApi | ||
import kr.ksw.visitkorea.data.remote.dto.SearchFestivalDTO | ||
import javax.inject.Inject | ||
|
||
class SearchFestivalRepositoryImpl @Inject constructor( | ||
private val searchFestivalApi: SearchFestivalApi | ||
): SearchFestivalRepository { | ||
override suspend fun invoke( | ||
numOfRows: Int, | ||
pageNo: Int, | ||
eventStartDate: String, | ||
eventEndDate: String, | ||
areaCode: String?, | ||
sigunguCode: String? | ||
): Result<List<SearchFestivalDTO>> = runCatching { | ||
searchFestivalApi.searchFestival( | ||
numOfRows = numOfRows, | ||
pageNo = pageNo, | ||
eventStartDate = eventStartDate, | ||
eventEndDate = eventEndDate, | ||
areaCode = areaCode, | ||
sigunguCode = sigunguCode | ||
).toItems() | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package kr.ksw.visitkorea.domain.di | ||
|
||
import dagger.Binds | ||
import dagger.Module | ||
import dagger.hilt.InstallIn | ||
import dagger.hilt.android.components.ActivityRetainedComponent | ||
import kr.ksw.visitkorea.domain.usecase.festival.GetFestivalListUseCase | ||
import kr.ksw.visitkorea.domain.usecase.festival.GetFestivalListUseCaseImpl | ||
|
||
@Module | ||
@InstallIn(ActivityRetainedComponent::class) | ||
abstract class FestivalModule { | ||
@Binds | ||
abstract fun bindGetFestivalListUseCase(getFestivalListUseCase: GetFestivalListUseCaseImpl): GetFestivalListUseCase | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package kr.ksw.visitkorea.domain.di | ||
|
||
import dagger.Binds | ||
import dagger.Module | ||
import dagger.hilt.InstallIn | ||
import dagger.hilt.android.components.ActivityRetainedComponent | ||
import kr.ksw.visitkorea.domain.usecase.more.GetMoreListUseCase | ||
import kr.ksw.visitkorea.domain.usecase.more.GetMoreListUseCaseImpl | ||
|
||
@Module | ||
@InstallIn(ActivityRetainedComponent::class) | ||
abstract class MoreModule { | ||
@Binds | ||
abstract fun bindGetMoreListUseCase( | ||
getMoreListUseCase: GetMoreListUseCaseImpl | ||
): GetMoreListUseCase | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package kr.ksw.visitkorea.domain.usecase.festival | ||
|
||
import androidx.paging.PagingData | ||
import kotlinx.coroutines.flow.Flow | ||
import kr.ksw.visitkorea.data.remote.dto.SearchFestivalDTO | ||
|
||
interface GetFestivalListUseCase { | ||
suspend operator fun invoke( | ||
forceFetch: Boolean, | ||
eventStartDate: String, | ||
eventEndDate: String, | ||
areaCode: String?, | ||
sigunguCode: String? | ||
) : Result<Flow<PagingData<SearchFestivalDTO>>> | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
package kr.ksw.visitkorea.domain.usecase.festival | ||
|
||
import androidx.paging.Pager | ||
import androidx.paging.PagingConfig | ||
import androidx.paging.PagingData | ||
import androidx.paging.PagingSource | ||
import kotlinx.coroutines.flow.Flow | ||
import kr.ksw.visitkorea.data.paging.source.SearchFestivalPagingSource | ||
import kr.ksw.visitkorea.data.remote.api.SearchFestivalApi | ||
import kr.ksw.visitkorea.data.remote.dto.SearchFestivalDTO | ||
import javax.inject.Inject | ||
|
||
class GetFestivalListUseCaseImpl @Inject constructor( | ||
private val searchFestivalApi: SearchFestivalApi | ||
) : GetFestivalListUseCase { | ||
private var pagingSource: PagingSource<Int, SearchFestivalDTO>? = null | ||
|
||
override suspend fun invoke( | ||
forceFetch: Boolean, | ||
eventStartDate: String, | ||
eventEndDate: String, | ||
areaCode: String?, | ||
sigunguCode: String? | ||
): Result<Flow<PagingData<SearchFestivalDTO>>> = runCatching { | ||
if(forceFetch && | ||
pagingSource != null && | ||
pagingSource?.invalid != true) { | ||
pagingSource?.invalidate() | ||
} | ||
Pager( | ||
config = PagingConfig( | ||
pageSize = 20, | ||
initialLoadSize = 20 | ||
), | ||
pagingSourceFactory = { | ||
SearchFestivalPagingSource( | ||
searchFestivalApi, | ||
eventStartDate, | ||
eventEndDate, | ||
areaCode, | ||
sigunguCode | ||
).also { | ||
pagingSource = it | ||
} | ||
} | ||
).flow | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package kr.ksw.visitkorea.domain.usecase.model | ||
|
||
data class Festival( | ||
val address: String = "", | ||
val firstImage: String = "", | ||
val title: String = "", | ||
val contentId: String = "", | ||
val eventStartDate: String = "", | ||
val eventEndDate: String = "" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Trailing comma - 를 추가해 주는 게 좋을 것 같아요. |
||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
try-catch 를 시용했는데, LocationBasedList 가 혹시 Retrofit 의 API 인가요 아니면 다른 레이어인가요? 제가 봤을때는 예외처리가 이미 완료된 데이터가 사용되는게 더 나을 거 같거든요. 같이 이야기해 보시죠.