Skip to content

Commit abb1658

Browse files
authored
[Fix] 리뷰 작성 후 리뷰 리스트 화면에 돌아왔을때 방금 쓴 리뷰가 없는 문제를 해결해요 (#493)
* fix: review list refreshes after write * fix: refresh review list after write
1 parent 27261d2 commit abb1658

3 files changed

Lines changed: 45 additions & 15 deletions

File tree

app/src/main/java/com/eatssu/android/presentation/cafeteria/review/ReviewNav.kt

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
package com.eatssu.android.presentation.cafeteria.review
22

33
import androidx.compose.runtime.Composable
4+
import androidx.compose.runtime.LaunchedEffect
5+
import androidx.compose.runtime.collectAsState
6+
import androidx.compose.runtime.getValue
47
import androidx.navigation.NavHostController
58
import androidx.navigation.compose.NavHost
69
import androidx.navigation.compose.composable
@@ -17,6 +20,8 @@ object ReviewNav {
1720
const val Modify = "modify"
1821
}
1922

23+
private const val KEY_REVIEW_LIST_REFRESH_NONCE = "review_list_refresh_nonce"
24+
2025
@Composable
2126
fun ReviewNav(
2227
navHostController: NavHostController = rememberNavController(),
@@ -31,11 +36,16 @@ fun ReviewNav(
3136
startDestination = ReviewNav.List
3237
) {
3338
// 리뷰 보기
34-
composable(ReviewNav.List) {
39+
composable(ReviewNav.List) { backStackEntry ->
40+
val refreshNonce by backStackEntry.savedStateHandle
41+
.getStateFlow(KEY_REVIEW_LIST_REFRESH_NONCE, 0L)
42+
.collectAsState()
43+
3544
ReviewListScreen(
3645
menuName = menuName,
3746
menuType = menuType,
3847
id = id,
48+
refreshNonce = refreshNonce,
3949
onBack = { onExit() },
4050
onModifyClick = { review ->
4151
// 선택된 리뷰 데이터를 Modify 화면으로 전달
@@ -54,6 +64,12 @@ fun ReviewNav(
5464
}
5565
}
5666
)
67+
68+
LaunchedEffect(refreshNonce) {
69+
if (refreshNonce != 0L) {
70+
backStackEntry.savedStateHandle[KEY_REVIEW_LIST_REFRESH_NONCE] = 0L
71+
}
72+
}
5773
}
5874

5975
// 리뷰 작성
@@ -62,7 +78,12 @@ fun ReviewNav(
6278
menuType = menuType,
6379
menuName = menuName,
6480
id = id,
65-
onBack = { navHostController.popBackStack() },
81+
onBack = {
82+
navHostController.previousBackStackEntry
83+
?.savedStateHandle
84+
?.set(KEY_REVIEW_LIST_REFRESH_NONCE, System.currentTimeMillis())
85+
navHostController.popBackStack()
86+
},
6687
)
6788
}
6889

@@ -84,4 +105,4 @@ fun ReviewNav(
84105
)
85106
}
86107
}
87-
}
108+
}

app/src/main/java/com/eatssu/android/presentation/cafeteria/review/list/ReviewListScreen.kt

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ fun ReviewListScreen(
7777
menuType: MenuType,
7878
menuName: String,
7979
id: Long,
80+
refreshNonce: Long = 0L,
8081
onBack: () -> Unit = {},
8182
onWriteButtonClick: () -> Unit,
8283
onModifyClick: (Review) -> Unit,
@@ -94,6 +95,13 @@ fun ReviewListScreen(
9495
val reviewPagingItems = viewModel.reviewPagingData.collectAsLazyPagingItems()
9596
val uiEvent by viewModel.uiEvent.collectAsStateWithLifecycle(initialValue = null)
9697

98+
LaunchedEffect(refreshNonce) {
99+
if (refreshNonce == 0L) return@LaunchedEffect
100+
// 리뷰 작성 화면에서 돌아온 경우, 리스트/정보를 강제로 갱신한다.
101+
viewModel.getReview(menuType, id)
102+
reviewPagingItems.refresh()
103+
}
104+
97105
LaunchedEffect(uiEvent) {
98106
when (val event = uiEvent) {
99107
is UiEvent.ShowToast -> context.showToast(event)
@@ -730,4 +738,4 @@ fun ReviewListErrorPreview() {
730738
reviewPagingItems = rememberPreviewPagingItems(pagingData),
731739
)
732740
}
733-
}
741+
}

app/src/main/java/com/eatssu/android/presentation/cafeteria/review/list/ReviewListViewModel.kt

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,13 @@ import com.eatssu.common.enums.MenuType
1717
import com.eatssu.common.enums.ToastType
1818
import dagger.hilt.android.lifecycle.HiltViewModel
1919
import kotlinx.coroutines.ExperimentalCoroutinesApi
20+
import kotlinx.coroutines.channels.BufferOverflow
2021
import kotlinx.coroutines.flow.Flow
2122
import kotlinx.coroutines.flow.MutableSharedFlow
2223
import kotlinx.coroutines.flow.MutableStateFlow
2324
import kotlinx.coroutines.flow.StateFlow
2425
import kotlinx.coroutines.flow.asSharedFlow
2526
import kotlinx.coroutines.flow.asStateFlow
26-
import kotlinx.coroutines.flow.filterNotNull
2727
import kotlinx.coroutines.flow.flatMapLatest
2828
import kotlinx.coroutines.launch
2929
import javax.inject.Inject
@@ -41,21 +41,24 @@ class ReviewListViewModel @Inject constructor(
4141
private val _uiEvent: MutableSharedFlow<UiEvent> = MutableSharedFlow()
4242
val uiEvent = _uiEvent.asSharedFlow()
4343

44-
private val _loadParams = MutableStateFlow<Pair<MenuType, Long>?>(null)
44+
private val _loadParams = MutableSharedFlow<Pair<MenuType, Long>>(
45+
replay = 1,
46+
extraBufferCapacity = 1,
47+
onBufferOverflow = BufferOverflow.DROP_OLDEST,
48+
)
4549

4650
@OptIn(ExperimentalCoroutinesApi::class)
4751
val reviewPagingData: Flow<PagingData<Review>> = _loadParams
48-
.filterNotNull()
4952
.flatMapLatest { (menuType, itemId) ->
5053
getReviewListPagedUseCase(menuType, itemId)
5154
}
5255
.cachedIn(viewModelScope)
5356

5457
fun getReview(menuType: MenuType, itemId: Long) {
55-
// 파라미터 업데이트 시 페이징 흐름 트리거
56-
// StateFlow는 동일한 값으로 설정되어도 업데이트되지 않으므로 별도의 체크 불필요
57-
_loadParams.value = menuType to itemId
58-
58+
// 동일 파라미터로 다시 진입(작성/수정 후 popBackStack)해도
59+
// 항상 페이징 소스를 새로 만들 수 있도록 SharedFlow로 트리거한다.
60+
_loadParams.tryEmit(menuType to itemId)
61+
5962
viewModelScope.launch {
6063
loadReviewInfo(menuType, itemId)
6164
}
@@ -94,10 +97,8 @@ class ReviewListViewModel @Inject constructor(
9497
_uiEvent.emit(ReviewListEvent.ReviewDeleted)
9598

9699
// 정보 갱신
97-
val currentParams = _loadParams.value
98-
if (currentParams != null) {
99-
loadReviewInfo(currentParams.first, currentParams.second)
100-
}
100+
val currentParams = _loadParams.replayCache.lastOrNull()
101+
if (currentParams != null) loadReviewInfo(currentParams.first, currentParams.second)
101102
}
102103
}
103104
}

0 commit comments

Comments
 (0)