Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package com.eatssu.android.presentation.cafeteria.review

import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.navigation.NavHostController
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
Expand All @@ -17,6 +20,8 @@ object ReviewNav {
const val Modify = "modify"
}

private const val KEY_REVIEW_LIST_REFRESH_NONCE = "review_list_refresh_nonce"

@Composable
fun ReviewNav(
navHostController: NavHostController = rememberNavController(),
Expand All @@ -31,11 +36,16 @@ fun ReviewNav(
startDestination = ReviewNav.List
) {
// 리뷰 보기
composable(ReviewNav.List) {
composable(ReviewNav.List) { backStackEntry ->
val refreshNonce by backStackEntry.savedStateHandle
.getStateFlow(KEY_REVIEW_LIST_REFRESH_NONCE, 0L)
.collectAsState()

ReviewListScreen(
menuName = menuName,
menuType = menuType,
id = id,
refreshNonce = refreshNonce,
onBack = { onExit() },
onModifyClick = { review ->
// 선택된 리뷰 데이터를 Modify 화면으로 전달
Expand All @@ -54,6 +64,12 @@ fun ReviewNav(
}
}
)

LaunchedEffect(refreshNonce) {
if (refreshNonce != 0L) {
backStackEntry.savedStateHandle[KEY_REVIEW_LIST_REFRESH_NONCE] = 0L
}
}
}

// 리뷰 작성
Expand All @@ -62,7 +78,12 @@ fun ReviewNav(
menuType = menuType,
menuName = menuName,
id = id,
onBack = { navHostController.popBackStack() },
onBack = {
navHostController.previousBackStackEntry
?.savedStateHandle
?.set(KEY_REVIEW_LIST_REFRESH_NONCE, System.currentTimeMillis())
navHostController.popBackStack()
},
)
}

Expand All @@ -84,4 +105,4 @@ fun ReviewNav(
)
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ fun ReviewListScreen(
menuType: MenuType,
menuName: String,
id: Long,
refreshNonce: Long = 0L,
onBack: () -> Unit = {},
onWriteButtonClick: () -> Unit,
onModifyClick: (Review) -> Unit,
Expand All @@ -94,6 +95,13 @@ fun ReviewListScreen(
val reviewPagingItems = viewModel.reviewPagingData.collectAsLazyPagingItems()
val uiEvent by viewModel.uiEvent.collectAsStateWithLifecycle(initialValue = null)

LaunchedEffect(refreshNonce) {
if (refreshNonce == 0L) return@LaunchedEffect
// 리뷰 작성 화면에서 돌아온 경우, 리스트/정보를 강제로 갱신한다.
viewModel.getReview(menuType, id)
reviewPagingItems.refresh()
}

LaunchedEffect(uiEvent) {
when (val event = uiEvent) {
is UiEvent.ShowToast -> context.showToast(event)
Expand Down Expand Up @@ -730,4 +738,4 @@ fun ReviewListErrorPreview() {
reviewPagingItems = rememberPreviewPagingItems(pagingData),
)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@ import com.eatssu.common.enums.MenuType
import com.eatssu.common.enums.ToastType
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.channels.BufferOverflow
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.launch
import javax.inject.Inject
Expand All @@ -41,21 +41,24 @@ class ReviewListViewModel @Inject constructor(
private val _uiEvent: MutableSharedFlow<UiEvent> = MutableSharedFlow()
val uiEvent = _uiEvent.asSharedFlow()

private val _loadParams = MutableStateFlow<Pair<MenuType, Long>?>(null)
private val _loadParams = MutableSharedFlow<Pair<MenuType, Long>>(
replay = 1,
extraBufferCapacity = 1,
onBufferOverflow = BufferOverflow.DROP_OLDEST,
)

@OptIn(ExperimentalCoroutinesApi::class)
val reviewPagingData: Flow<PagingData<Review>> = _loadParams
.filterNotNull()
.flatMapLatest { (menuType, itemId) ->
getReviewListPagedUseCase(menuType, itemId)
}
.cachedIn(viewModelScope)

fun getReview(menuType: MenuType, itemId: Long) {
// 파라미터 업데이트 시 페이징 흐름 트리거
// StateFlow는 동일한 값으로 설정되어도 업데이트되지 않으므로 별도의 체크 불필요
_loadParams.value = menuType to itemId
// 동일 파라미터로 다시 진입(작성/수정 후 popBackStack)해도
// 항상 페이징 소스를 새로 만들 수 있도록 SharedFlow로 트리거한다.
_loadParams.tryEmit(menuType to itemId)

viewModelScope.launch {
loadReviewInfo(menuType, itemId)
}
Expand Down Expand Up @@ -94,10 +97,8 @@ class ReviewListViewModel @Inject constructor(
_uiEvent.emit(ReviewListEvent.ReviewDeleted)

// 정보 갱신
val currentParams = _loadParams.value
if (currentParams != null) {
loadReviewInfo(currentParams.first, currentParams.second)
}
val currentParams = _loadParams.replayCache.lastOrNull()
if (currentParams != null) loadReviewInfo(currentParams.first, currentParams.second)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

가독성과 향후 유지보수성을 위해 if 문에 중괄호 {}를 사용하는 것을 권장합니다. 이렇게 하면 나중에 if 블록에 코드를 추가할 때 발생할 수 있는 실수를 방지할 수 있습니다.

            if (currentParams != null) {
                loadReviewInfo(currentParams.first, currentParams.second)
            }

}
}
}
Expand Down