diff --git a/app/src/main/java/com/myongsik/myongsikandroid/base/FlowResponse.kt b/app/src/main/java/com/myongsik/myongsikandroid/base/FlowResponse.kt index 98014261..6e93d872 100644 --- a/app/src/main/java/com/myongsik/myongsikandroid/base/FlowResponse.kt +++ b/app/src/main/java/com/myongsik/myongsikandroid/base/FlowResponse.kt @@ -7,12 +7,14 @@ import retrofit2.HttpException import retrofit2.Response import java.net.SocketException -fun safeApiCall(call: suspend () -> Response): Flow> = flow { +fun autoHandleApiResponse(transform: ((T) -> R)? = null, block: suspend () -> Response): Flow> = flow { try { - val response = call() + val response = block() val body = response.body() if (response.isSuccessful && body != null) { - emit(BaseResult.Success(body)) + transform?.invoke(body)?.let { + emit(BaseResult.Success(it)) + } ?: emit(BaseResult.Error(response.code())) } else { emit(BaseResult.Error(response.code())) } @@ -23,4 +25,4 @@ fun safeApiCall(call: suspend () -> Response): Flow> = flow else -> emit(BaseResult.Error(ErrorConstant.EVENT_UNKNOWN_HOST_EXCEPTION)) } } -} \ No newline at end of file +} diff --git a/app/src/main/java/com/myongsik/myongsikandroid/data/datasource/food/FoodDataSource.kt b/app/src/main/java/com/myongsik/myongsikandroid/data/datasource/food/FoodDataSource.kt index 57500f87..41c6983c 100644 --- a/app/src/main/java/com/myongsik/myongsikandroid/data/datasource/food/FoodDataSource.kt +++ b/app/src/main/java/com/myongsik/myongsikandroid/data/datasource/food/FoodDataSource.kt @@ -1,12 +1,14 @@ package com.myongsik.myongsikandroid.data.datasource.food +import com.myongsik.myongsikandroid.base.BaseResult import com.myongsik.myongsikandroid.domain.model.food.RequestReviewDataEntity import com.myongsik.myongsikandroid.domain.model.food.ResponseReviewDataEntity import com.myongsik.myongsikandroid.domain.model.food.ResponseWeekFoodEntity +import kotlinx.coroutines.flow.Flow interface FoodDataSource { - suspend fun weekGetFoodArea(s: String): ResponseWeekFoodEntity? + suspend fun weekGetFoodArea(s: String): Flow> suspend fun postReview(requestReviewDataEntity: RequestReviewDataEntity): ResponseReviewDataEntity? diff --git a/app/src/main/java/com/myongsik/myongsikandroid/data/datasource/food/FoodDataSourceImpl.kt b/app/src/main/java/com/myongsik/myongsikandroid/data/datasource/food/FoodDataSourceImpl.kt index 236e76c1..e6b763e7 100644 --- a/app/src/main/java/com/myongsik/myongsikandroid/data/datasource/food/FoodDataSourceImpl.kt +++ b/app/src/main/java/com/myongsik/myongsikandroid/data/datasource/food/FoodDataSourceImpl.kt @@ -1,6 +1,6 @@ package com.myongsik.myongsikandroid.data.datasource.food -import android.util.Log +import com.myongsik.myongsikandroid.base.autoHandleApiResponse import com.myongsik.myongsikandroid.data.api.HomeFoodApi import com.myongsik.myongsikandroid.data.model.food.toWeekFoodEntity import com.myongsik.myongsikandroid.data.model.review.toRequestReviewData @@ -8,19 +8,15 @@ import com.myongsik.myongsikandroid.data.model.review.toResponseReviewEntity import com.myongsik.myongsikandroid.domain.model.food.RequestReviewDataEntity import com.myongsik.myongsikandroid.domain.model.food.ResponseReviewDataEntity import com.myongsik.myongsikandroid.domain.model.food.ResponseWeekFoodEntity +import kotlinx.coroutines.flow.map import javax.inject.Inject class FoodDataSourceImpl @Inject constructor( private val homeFoodApi : HomeFoodApi ) : FoodDataSource { - override suspend fun weekGetFoodArea(s: String): ResponseWeekFoodEntity? { - val response = homeFoodApi.weekGetFoodArea(s) - return if(response.isSuccessful) { - response.body()?.toWeekFoodEntity() - } else { - null - } + override suspend fun weekGetFoodArea(s: String) = autoHandleApiResponse({ it.toWeekFoodEntity() }) { + homeFoodApi.weekGetFoodArea(s) } override suspend fun postReview(requestReviewDataEntity: RequestReviewDataEntity): ResponseReviewDataEntity? { diff --git a/app/src/main/java/com/myongsik/myongsikandroid/data/repository/food/FoodRepository.kt b/app/src/main/java/com/myongsik/myongsikandroid/data/repository/food/FoodRepository.kt index 099479fc..d44dff2a 100644 --- a/app/src/main/java/com/myongsik/myongsikandroid/data/repository/food/FoodRepository.kt +++ b/app/src/main/java/com/myongsik/myongsikandroid/data/repository/food/FoodRepository.kt @@ -1,13 +1,9 @@ package com.myongsik.myongsikandroid.data.repository.food import androidx.datastore.preferences.core.Preferences -import com.myongsik.myongsikandroid.base.ApiResponse import com.myongsik.myongsikandroid.data.model.food.DayFoodResponse import com.myongsik.myongsikandroid.data.model.food.RankRestaurantResponse import com.myongsik.myongsikandroid.data.model.food.ResponseOneRestaurant -import com.myongsik.myongsikandroid.data.model.food.WeekFoodResponse -import com.myongsik.myongsikandroid.data.model.review.RequestReviewData -import com.myongsik.myongsikandroid.data.model.review.ResponseReviewData import kotlinx.coroutines.flow.Flow import retrofit2.Response diff --git a/app/src/main/java/com/myongsik/myongsikandroid/data/repository/food/FoodRepositoryImpl.kt b/app/src/main/java/com/myongsik/myongsikandroid/data/repository/food/FoodRepositoryImpl.kt index 450b8d5d..aa9541b7 100644 --- a/app/src/main/java/com/myongsik/myongsikandroid/data/repository/food/FoodRepositoryImpl.kt +++ b/app/src/main/java/com/myongsik/myongsikandroid/data/repository/food/FoodRepositoryImpl.kt @@ -5,15 +5,10 @@ import androidx.datastore.core.DataStore import androidx.datastore.preferences.core.Preferences import androidx.datastore.preferences.core.edit import androidx.datastore.preferences.core.emptyPreferences -import com.myongsik.myongsikandroid.base.ApiResponse -import com.myongsik.myongsikandroid.base.safeApiCall import com.myongsik.myongsikandroid.data.api.HomeFoodApi import com.myongsik.myongsikandroid.data.model.food.DayFoodResponse import com.myongsik.myongsikandroid.data.model.food.RankRestaurantResponse import com.myongsik.myongsikandroid.data.model.food.ResponseOneRestaurant -import com.myongsik.myongsikandroid.data.model.food.WeekFoodResponse -import com.myongsik.myongsikandroid.data.model.review.RequestReviewData -import com.myongsik.myongsikandroid.data.model.review.ResponseReviewData import com.myongsik.myongsikandroid.util.DataStoreKey import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.catch diff --git a/app/src/main/java/com/myongsik/myongsikandroid/data/repository/food/FoodV2RepositoryImpl.kt b/app/src/main/java/com/myongsik/myongsikandroid/data/repository/food/FoodV2RepositoryImpl.kt index 0a95b311..978f3de4 100644 --- a/app/src/main/java/com/myongsik/myongsikandroid/data/repository/food/FoodV2RepositoryImpl.kt +++ b/app/src/main/java/com/myongsik/myongsikandroid/data/repository/food/FoodV2RepositoryImpl.kt @@ -1,18 +1,20 @@ package com.myongsik.myongsikandroid.data.repository.food import android.util.Log +import com.myongsik.myongsikandroid.base.BaseResult import com.myongsik.myongsikandroid.data.datasource.food.FoodDataSource import com.myongsik.myongsikandroid.domain.model.food.RequestReviewDataEntity import com.myongsik.myongsikandroid.domain.model.food.ResponseReviewDataEntity import com.myongsik.myongsikandroid.domain.model.food.ResponseWeekFoodEntity import com.myongsik.myongsikandroid.domain.repository.food.FoodV2Repository +import kotlinx.coroutines.flow.Flow import javax.inject.Inject class FoodV2RepositoryImpl @Inject constructor( private val foodDataSource: FoodDataSource ) : FoodV2Repository { - override suspend fun weekGetFoodArea(s: String): ResponseWeekFoodEntity? { + override suspend fun weekGetFoodArea(s: String): Flow> { return foodDataSource.weekGetFoodArea(s) } diff --git a/app/src/main/java/com/myongsik/myongsikandroid/domain/repository/food/FoodV2Repository.kt b/app/src/main/java/com/myongsik/myongsikandroid/domain/repository/food/FoodV2Repository.kt index 088ec248..307a010f 100644 --- a/app/src/main/java/com/myongsik/myongsikandroid/domain/repository/food/FoodV2Repository.kt +++ b/app/src/main/java/com/myongsik/myongsikandroid/domain/repository/food/FoodV2Repository.kt @@ -1,12 +1,14 @@ package com.myongsik.myongsikandroid.domain.repository.food +import com.myongsik.myongsikandroid.base.BaseResult import com.myongsik.myongsikandroid.domain.model.food.RequestReviewDataEntity import com.myongsik.myongsikandroid.domain.model.food.ResponseReviewDataEntity import com.myongsik.myongsikandroid.domain.model.food.ResponseWeekFoodEntity +import kotlinx.coroutines.flow.Flow interface FoodV2Repository { - suspend fun weekGetFoodArea(s: String): ResponseWeekFoodEntity? + suspend fun weekGetFoodArea(s: String): Flow> suspend fun postReview(requestReviewDataEntity: RequestReviewDataEntity): ResponseReviewDataEntity? } \ No newline at end of file diff --git a/app/src/main/java/com/myongsik/myongsikandroid/domain/usecase/food/GetWeekFoodDataUseCase.kt b/app/src/main/java/com/myongsik/myongsikandroid/domain/usecase/food/GetWeekFoodDataUseCase.kt index 11221e82..0cb0a625 100644 --- a/app/src/main/java/com/myongsik/myongsikandroid/domain/usecase/food/GetWeekFoodDataUseCase.kt +++ b/app/src/main/java/com/myongsik/myongsikandroid/domain/usecase/food/GetWeekFoodDataUseCase.kt @@ -6,6 +6,5 @@ import javax.inject.Inject class GetWeekFoodDataUseCase @Inject constructor( private val foodV2Repository: FoodV2Repository ){ - suspend operator fun invoke(s : String) = foodV2Repository.weekGetFoodArea(s) } \ No newline at end of file diff --git a/app/src/main/java/com/myongsik/myongsikandroid/presentation/view/food/HomeFragment.kt b/app/src/main/java/com/myongsik/myongsikandroid/presentation/view/food/HomeFragment.kt index 537699f9..48146256 100644 --- a/app/src/main/java/com/myongsik/myongsikandroid/presentation/view/food/HomeFragment.kt +++ b/app/src/main/java/com/myongsik/myongsikandroid/presentation/view/food/HomeFragment.kt @@ -27,15 +27,15 @@ import com.google.android.gms.ads.interstitial.InterstitialAd import com.google.android.gms.ads.interstitial.InterstitialAdLoadCallback import com.google.android.material.bottomsheet.BottomSheetBehavior import com.google.android.material.bottomsheet.BottomSheetDialog -import com.myongsik.myongsikandroid.base.BaseFragment import com.myongsik.myongsikandroid.BuildConfig import com.myongsik.myongsikandroid.R -import com.myongsik.myongsikandroid.base.ApiResponse +import com.myongsik.myongsikandroid.base.BaseFragment import com.myongsik.myongsikandroid.data.model.review.RequestReviewData import com.myongsik.myongsikandroid.databinding.DialogBottomUpdateSheetBinding import com.myongsik.myongsikandroid.databinding.FragmentHomeBinding import com.myongsik.myongsikandroid.presentation.adapter.food.MyPagerAdapter import com.myongsik.myongsikandroid.presentation.viewmodel.food.HomeViewModel +import com.myongsik.myongsikandroid.presentation.viewmodel.food.WeekFoodState import com.myongsik.myongsikandroid.util.* import dagger.hilt.android.AndroidEntryPoint import kotlinx.coroutines.delay @@ -76,12 +76,6 @@ class HomeFragment : BaseFragment() { initInterstitialAd() setInterstitialAd() } - - initData() - initViewPager() - initViews() - chekNetwork() - checkWeekend() } override fun initListener() { @@ -113,27 +107,47 @@ class HomeFragment : BaseFragment() { private fun initObserve() { viewLifecycleOwner.lifecycleScope.launch{ viewLifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) { - homeViewModel.weekGetFoodArea.collectLatest { - val list = mutableListOf>() + homeViewModel.weekGetFoodArea.collect { + when(it) { + is WeekFoodState.UnInitialized -> { + initData() + initViewPager() + initViews() + chekNetwork() + checkWeekend() + } - it?.let{ - settingDate(LocalDate.parse(it.localDateTime.substring(0, 10))) + is WeekFoodState.Loading -> { - it.data.forEach { foodResult -> - list.add(foodResult.meals) } - val chunkedList = if (list.size == 15) { - list.chunked(3).chunked(5).first() - } else { - list.chunked(2).chunked(5).first() + is WeekFoodState.SuccessWeekFoodGetData -> { + val list = mutableListOf>() + + it.let{ + settingDate(LocalDate.parse(it.getWeekFoodData.localDateTime.substring(0, 10))) + + it.getWeekFoodData.data.forEach { foodResult -> + list.add(foodResult.meals) + } + + val chunkedList = if (list.size == 15) { + list.chunked(3).chunked(5).first() + } else { + list.chunked(2).chunked(5).first() + } + + with(binding) { + viewPager2.adapter = MyPagerAdapter(chunkedList) + viewPager2.orientation = ViewPager2.ORIENTATION_HORIZONTAL + setCurrentPage(initDate) + indicator.setViewPager(viewPager2) + } + } } - with(binding) { - viewPager2.adapter = MyPagerAdapter(chunkedList) - viewPager2.orientation = ViewPager2.ORIENTATION_HORIZONTAL - setCurrentPage(initDate) - indicator.setViewPager(viewPager2) + is WeekFoodState.Error -> { + } } } diff --git a/app/src/main/java/com/myongsik/myongsikandroid/presentation/viewmodel/food/HomeViewModel.kt b/app/src/main/java/com/myongsik/myongsikandroid/presentation/viewmodel/food/HomeViewModel.kt index 4aa48abd..fabc84b4 100644 --- a/app/src/main/java/com/myongsik/myongsikandroid/presentation/viewmodel/food/HomeViewModel.kt +++ b/app/src/main/java/com/myongsik/myongsikandroid/presentation/viewmodel/food/HomeViewModel.kt @@ -1,12 +1,13 @@ package com.myongsik.myongsikandroid.presentation.viewmodel.food -import android.util.Log import androidx.datastore.preferences.core.Preferences import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData -import com.myongsik.myongsikandroid.base.ApiResponse +import com.myongsik.myongsikandroid.base.BaseResult import com.myongsik.myongsikandroid.base.BaseViewModel -import com.myongsik.myongsikandroid.data.model.food.* +import com.myongsik.myongsikandroid.data.model.food.RankRestaurantResponse +import com.myongsik.myongsikandroid.data.model.food.ResponseMealData +import com.myongsik.myongsikandroid.data.model.food.ResponseOneRestaurant import com.myongsik.myongsikandroid.data.model.review.RequestReviewData import com.myongsik.myongsikandroid.data.model.review.ResponseReviewData import com.myongsik.myongsikandroid.data.model.review.toRequestReviewEntity @@ -18,7 +19,10 @@ import com.myongsik.myongsikandroid.util.Constant import com.myongsik.myongsikandroid.util.MyongsikApplication import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.flow.* +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.first import kotlinx.coroutines.withContext import javax.inject.Inject @@ -29,8 +33,8 @@ class HomeViewModel @Inject constructor( private val postReviewDataUseCase: PostReviewDataUseCase ) : BaseViewModel() { - private val _weekGetFoodArea = MutableStateFlow(null) - val weekGetFoodArea: StateFlow = _weekGetFoodArea.asStateFlow() + private val _weekGetFoodArea = MutableStateFlow(WeekFoodState.UnInitialized) + val weekGetFoodArea: StateFlow = _weekGetFoodArea.asStateFlow() private val _postReviewData = MutableStateFlow(null) val postReviewData: StateFlow = _postReviewData.asStateFlow() @@ -40,16 +44,22 @@ class HomeViewModel @Inject constructor( get() = _postMealData fun weekGetFoodAreaFun(s: String) = launch { - getWeekFoodDataUseCase(s)?.let{ - _weekGetFoodArea.value = it.toWeekFoodResponse() + _weekGetFoodArea.emit(WeekFoodState.Loading) + getWeekFoodDataUseCase(s).collect { + when (it) { + is BaseResult.Success -> { + _weekGetFoodArea.emit(WeekFoodState.SuccessWeekFoodGetData(it.data)) + } + is BaseResult.Error -> { + _weekGetFoodArea.emit(WeekFoodState.Error(it.errorCode)) + } + } } } fun postReview(requestReviewData: RequestReviewData) = launch { postReviewDataUseCase(requestReviewData.toRequestReviewEntity())?.let{ - Log.d("DebugTag", "postReviewDataUseCase result: $it") _postReviewData.value = it.toResponseReviewData() - Log.d("DebugTag", "Value emitted to _postReviewData") } } diff --git a/app/src/main/java/com/myongsik/myongsikandroid/presentation/viewmodel/food/WeekFoodState.kt b/app/src/main/java/com/myongsik/myongsikandroid/presentation/viewmodel/food/WeekFoodState.kt new file mode 100644 index 00000000..7f2442ae --- /dev/null +++ b/app/src/main/java/com/myongsik/myongsikandroid/presentation/viewmodel/food/WeekFoodState.kt @@ -0,0 +1,14 @@ +package com.myongsik.myongsikandroid.presentation.viewmodel.food + +import com.myongsik.myongsikandroid.domain.model.food.ResponseWeekFoodEntity + +sealed class WeekFoodState { + + object UnInitialized : WeekFoodState() + + object Loading : WeekFoodState() + + data class SuccessWeekFoodGetData(val getWeekFoodData: ResponseWeekFoodEntity) : WeekFoodState() + + data class Error(val errorCode: Int) : WeekFoodState() +}