diff --git a/app/src/main/java/org/go/sopt/winey/presentation/main/feed/WineyFeedFragment.kt b/app/src/main/java/org/go/sopt/winey/presentation/main/feed/WineyFeedFragment.kt index 6fd7ae92..1c42d549 100644 --- a/app/src/main/java/org/go/sopt/winey/presentation/main/feed/WineyFeedFragment.kt +++ b/app/src/main/java/org/go/sopt/winey/presentation/main/feed/WineyFeedFragment.kt @@ -40,6 +40,7 @@ import org.go.sopt.winey.util.amplitude.type.EventType import org.go.sopt.winey.util.amplitude.type.EventType.TYPE_CLICK_FEED_ITEM import org.go.sopt.winey.util.amplitude.type.EventType.TYPE_CLICK_LIKE import org.go.sopt.winey.util.binding.BindingFragment +import org.go.sopt.winey.util.event.EventBus import org.go.sopt.winey.util.fragment.WineyDialogFragment import org.go.sopt.winey.util.fragment.WineyUploadDialogFragment import org.go.sopt.winey.util.fragment.snackBar @@ -107,6 +108,7 @@ class WineyFeedFragment : initPostLikeStateObserver() initDeleteFeedStateObserver() initLevelUpStateObserver() + collectEvent() } /** Adapter */ @@ -327,10 +329,6 @@ class WineyFeedFragment : is UiState.Success -> { val pagingData = state.data wineyFeedAdapter.submitData(pagingData) - - // 상세피드 들어갔다 나올 때, 성공 상태가 계속 관찰되어 - // 이미 삭제된 항목이 되살아나는 일이 없도록 UiState 초기화 - viewModel.initGetWineyFeedState() } is UiState.Failure -> { @@ -391,17 +389,8 @@ class WineyFeedFragment : val response = state.data ?: return@onEach deletePagingDataItem(response.feedId.toInt()) - wineySnackbar( - anchorView = binding.root, - message = stringOf(R.string.snackbar_feed_delete_success), - type = SnackbarType.WineyFeedResult(isSuccess = true) - ) - + // 목표 프로그레스바 갱신을 위해 유저 데이터 재조회 mainViewModel.getUser() - - // 상세피드 들어갔다 나올 때 성공 상태가 계속 관찰되어 - // 스낵바가 반복해서 뜨지 않도록 UiState 초기화 - viewModel.initDeleteFeedState() } is UiState.Failure -> { @@ -413,6 +402,28 @@ class WineyFeedFragment : }.launchIn(viewLifeCycleScope) } + private fun collectEvent() { + viewModel.eventFlow.flowWithLifecycle(viewLifeCycle) + .onEach { event -> + when (event) { + is EventBus.ShowSnackBar -> { + showFeedDeleteSuccessSnackBar() + } + + else -> {} + } + } + .launchIn(viewLifeCycleScope) + } + + private fun showFeedDeleteSuccessSnackBar() { + wineySnackbar( + anchorView = binding.root, + message = stringOf(R.string.snackbar_feed_delete_success), + type = SnackbarType.WineyFeedResult(isSuccess = true) + ) + } + private fun deletePagingDataItem(feedId: Int) { viewLifeCycleScope.launch { val newList = wineyFeedAdapter.deleteItem(feedId) diff --git a/app/src/main/java/org/go/sopt/winey/presentation/main/feed/WineyFeedViewModel.kt b/app/src/main/java/org/go/sopt/winey/presentation/main/feed/WineyFeedViewModel.kt index 6a0b206a..d23f7b2e 100644 --- a/app/src/main/java/org/go/sopt/winey/presentation/main/feed/WineyFeedViewModel.kt +++ b/app/src/main/java/org/go/sopt/winey/presentation/main/feed/WineyFeedViewModel.kt @@ -5,8 +5,11 @@ import androidx.lifecycle.viewModelScope import androidx.paging.PagingData import androidx.paging.cachedIn import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.SharedFlow import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asSharedFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.catch import kotlinx.coroutines.flow.collectLatest @@ -17,6 +20,7 @@ import org.go.sopt.winey.domain.entity.DetailFeed import org.go.sopt.winey.domain.entity.Like import org.go.sopt.winey.domain.entity.WineyFeed import org.go.sopt.winey.domain.repository.FeedRepository +import org.go.sopt.winey.util.event.EventBus import org.go.sopt.winey.util.view.UiState import retrofit2.HttpException import timber.log.Timber @@ -44,6 +48,9 @@ class WineyFeedViewModel @Inject constructor( val deleteWineyFeedState: StateFlow> = _deleteWineyFeedState.asStateFlow() + private val _eventFlow = MutableSharedFlow() + val eventFlow: SharedFlow = _eventFlow.asSharedFlow() + init { getWineyFeedList() } @@ -62,10 +69,6 @@ class WineyFeedViewModel @Inject constructor( } } - fun initGetWineyFeedState() { - _getWineyFeedListState.value = UiState.Empty - } - fun getDetailFeed(feedId: Int) { viewModelScope.launch { _getDetailFeedState.emit(UiState.Loading) @@ -102,13 +105,16 @@ class WineyFeedViewModel @Inject constructor( feedRepository.deleteFeed(feedId) .onSuccess { response -> _deleteWineyFeedState.emit(UiState.Success(response)) + sendEvent(EventBus.ShowSnackBar) } .onFailure { t -> handleFailureState(_deleteWineyFeedState, t) } } } - fun initDeleteFeedState() { - _deleteWineyFeedState.value = UiState.Empty + private fun sendEvent(event: EventBus) { + viewModelScope.launch { + _eventFlow.emit(event) + } } private fun handleFailureState(loadingState: MutableStateFlow>, t: Throwable) { @@ -127,6 +133,5 @@ class WineyFeedViewModel @Inject constructor( private const val CODE_WINEYFEED_INVALID_USER = 404 private const val CODE_WINEYFEED_INVALID_REQUEST = 400 private const val MSG_WINEYFEED_FAIL = "FAIL" - private const val ERROR_GET_WINEY_FEED_LIST = "error get winey feed list" } } diff --git a/app/src/main/java/org/go/sopt/winey/util/event/EventBus.kt b/app/src/main/java/org/go/sopt/winey/util/event/EventBus.kt new file mode 100644 index 00000000..8d411da3 --- /dev/null +++ b/app/src/main/java/org/go/sopt/winey/util/event/EventBus.kt @@ -0,0 +1,6 @@ +package org.go.sopt.winey.util.event + +sealed interface EventBus { + object Empty : EventBus + object ShowSnackBar : EventBus +}