diff --git a/app/src/main/java/com/flint/core/designsystem/component/image/SelectedContentItem.kt b/app/src/main/java/com/flint/core/designsystem/component/image/SelectedContentItem.kt index 899e6e74..fd929695 100644 --- a/app/src/main/java/com/flint/core/designsystem/component/image/SelectedContentItem.kt +++ b/app/src/main/java/com/flint/core/designsystem/component/image/SelectedContentItem.kt @@ -1,7 +1,7 @@ package com.flint.core.designsystem.component.image import androidx.compose.foundation.background -import androidx.compose.foundation.clickable +import com.flint.core.common.extension.noRippleClickable import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.size import androidx.compose.foundation.shape.CircleShape @@ -43,7 +43,7 @@ fun SelectedContentItem( Modifier .align(Alignment.TopEnd) .size(48.dp) - .clickable { onRemoveClick() }, + .noRippleClickable { onRemoveClick() }, ) } } diff --git a/app/src/main/java/com/flint/core/designsystem/component/listView/SavedContentsSection.kt b/app/src/main/java/com/flint/core/designsystem/component/listView/SavedContentsSection.kt index 0bc59898..ec5f97c4 100644 --- a/app/src/main/java/com/flint/core/designsystem/component/listView/SavedContentsSection.kt +++ b/app/src/main/java/com/flint/core/designsystem/component/listView/SavedContentsSection.kt @@ -27,6 +27,7 @@ import com.flint.core.designsystem.component.listItem.SavedContentItem import com.flint.core.designsystem.theme.FlintTheme import com.flint.domain.model.content.BookmarkedContentListModel import com.flint.domain.model.content.ContentModel +import com.flint.domain.type.OttType import kotlinx.collections.immutable.ImmutableList @Composable @@ -96,7 +97,6 @@ fun SavedContentsSection( SavedContentItem( contentModel = item, onItemClick = { contentId -> - onItemClick(contentId) }, ) diff --git a/app/src/main/java/com/flint/presentation/collectiondetail/CollectionDetailScreen.kt b/app/src/main/java/com/flint/presentation/collectiondetail/CollectionDetailScreen.kt index d6428046..92398b66 100644 --- a/app/src/main/java/com/flint/presentation/collectiondetail/CollectionDetailScreen.kt +++ b/app/src/main/java/com/flint/presentation/collectiondetail/CollectionDetailScreen.kt @@ -41,6 +41,8 @@ import com.flint.domain.model.collection.CollectionDetailModelNew import com.flint.domain.model.content.ContentModelNew import com.flint.domain.type.UserRoleType import com.flint.presentation.collectiondetail.component.CollectionCopyrightFooter +import com.flint.R +import com.flint.core.designsystem.component.modal.OneButtonModal import com.flint.presentation.collectiondetail.component.CollectionDetailDeleteModal import com.flint.presentation.collectiondetail.component.CollectionDetailDescription import com.flint.presentation.collectiondetail.component.CollectionDetailThumbnail @@ -74,6 +76,7 @@ fun CollectionDetailRoute( var showContentSaveToast: Boolean by remember { mutableStateOf(false) } var showContentCancelToast: Boolean by remember { mutableStateOf(false) } var showDeleteModal: Boolean by remember { mutableStateOf(false) } + var showBookmarkRestrictionModal: Boolean by remember { mutableStateOf(false) } var showEditSuccessToastState: Boolean by remember { mutableStateOf(showEditSuccessToast) } when (val uiState = uiState) { @@ -123,6 +126,17 @@ fun CollectionDetailRoute( else -> {} } + if (showBookmarkRestrictionModal) { + OneButtonModal( + title = "작품 저장을 취소할 수 없어요", + message = "취향 키워드 분석을 위해\n최소 5개의 작품을 저장해주세요", + buttonText = "확인", + onConfirm = { showBookmarkRestrictionModal = false }, + onDismiss = { showBookmarkRestrictionModal = false }, + icon = R.drawable.ic_gradient_bookmark, + ) + } + if (showDeleteModal) { CollectionDetailDeleteModal( onConfirm = { @@ -218,6 +232,10 @@ fun CollectionDetailRoute( } } + CollectionDetailSideEffect.ToggleContentBookmarkMinLimitExceeded -> { + showBookmarkRestrictionModal = true + } + CollectionDetailSideEffect.DeleteCollectionSuccess -> navigateUpWithDeleteSuccess() CollectionDetailSideEffect.DeleteCollectionFailure -> { diff --git a/app/src/main/java/com/flint/presentation/collectiondetail/CollectionDetailViewModel.kt b/app/src/main/java/com/flint/presentation/collectiondetail/CollectionDetailViewModel.kt index f7bed4f2..feb5fb66 100644 --- a/app/src/main/java/com/flint/presentation/collectiondetail/CollectionDetailViewModel.kt +++ b/app/src/main/java/com/flint/presentation/collectiondetail/CollectionDetailViewModel.kt @@ -11,6 +11,7 @@ import com.flint.data.local.PreferencesManager import com.flint.domain.model.bookmark.CollectionBookmarkUsersModel import com.flint.domain.model.collection.CollectionDetailModelNew import com.flint.domain.model.content.ContentModelNew +import com.flint.domain.model.bookmark.BookmarkException import com.flint.domain.repository.BookmarkRepository import com.flint.domain.repository.CollectionRepository import com.flint.presentation.collectiondetail.sideeffect.CollectionDetailSideEffect @@ -107,14 +108,47 @@ class CollectionDetailViewModel @Inject constructor( val newBookmarkState: Boolean = !targetContent.isBookmarked val initialBookmarkCount: Int = targetContent.bookmarkCount - val adjustedBookmarkCount: Int = - if (newBookmarkState) initialBookmarkCount + 1 - else (initialBookmarkCount - 1).coerceAtLeast(0) + // 북마크 취소 + if (!newBookmarkState) { + contentBookmarkDebounceJobs[contentId]?.cancel() + contentBookmarkDebounceJobs.remove(contentId) + val initialState = initialContentBookmarkStates.remove(contentId) + + if (initialState == false) { + updateContentBookmarkState( + contentId = contentId, + isBookmarked = false, + bookmarkCount = (initialBookmarkCount - 1).coerceAtLeast(0), + ) + return + } + + viewModelScope.launch { + bookmarkRepository.toggleContentBookmark(contentId) + .onSuccess { isBookmarked: Boolean -> + updateContentBookmarkState( + contentId = contentId, + isBookmarked = isBookmarked, + bookmarkCount = (initialBookmarkCount - 1).coerceAtLeast(0), + ) + _sideEffect.emit(CollectionDetailSideEffect.ToggleContentBookmarkSuccess(isBookmarked)) + } + .onFailure { throwable -> + if (throwable is BookmarkException.ContentMinLimitExceeded) { + _sideEffect.emit(CollectionDetailSideEffect.ToggleContentBookmarkMinLimitExceeded) + } + } + } + return + } + + // 북마크 추가 + val adjustedBookmarkCount: Int = initialBookmarkCount + 1 updateContentBookmarkState( contentId = contentId, isBookmarked = newBookmarkState, - bookmarkCount = adjustedBookmarkCount + bookmarkCount = adjustedBookmarkCount, ) contentBookmarkDebounceJobs[contentId]?.cancel() @@ -132,7 +166,7 @@ class CollectionDetailViewModel @Inject constructor( .onSuccess { isBookmarked: Boolean -> updateContentIsBookmarkedOnly( contentId = contentId, - isBookmarked = isBookmarked + isBookmarked = isBookmarked, ) _sideEffect.emit( CollectionDetailSideEffect.ToggleContentBookmarkSuccess(isBookmarked) @@ -143,14 +177,10 @@ class CollectionDetailViewModel @Inject constructor( (_uiState.value as? UiState.Success)?.data?.collectionDetail?.contents ?.find { it.id == contentId } ?: return@onFailure - val rollbackCount: Int = - if (initialState) fallbackContent.bookmarkCount + 1 - else (fallbackContent.bookmarkCount - 1).coerceAtLeast(0) - updateContentBookmarkState( contentId = contentId, isBookmarked = initialState, - bookmarkCount = rollbackCount + bookmarkCount = (fallbackContent.bookmarkCount - 1).coerceAtLeast(0), ) } } diff --git a/app/src/main/java/com/flint/presentation/collectiondetail/sideeffect/CollectionDetailSideEffect.kt b/app/src/main/java/com/flint/presentation/collectiondetail/sideeffect/CollectionDetailSideEffect.kt index 0bfedc1e..8b196305 100644 --- a/app/src/main/java/com/flint/presentation/collectiondetail/sideeffect/CollectionDetailSideEffect.kt +++ b/app/src/main/java/com/flint/presentation/collectiondetail/sideeffect/CollectionDetailSideEffect.kt @@ -7,6 +7,8 @@ sealed interface CollectionDetailSideEffect { class ToggleContentBookmarkSuccess(val isBookmarked: Boolean) : CollectionDetailSideEffect + object ToggleContentBookmarkMinLimitExceeded : CollectionDetailSideEffect + object DeleteCollectionSuccess : CollectionDetailSideEffect object DeleteCollectionFailure : CollectionDetailSideEffect diff --git a/app/src/main/java/com/flint/presentation/main/MainNavHost.kt b/app/src/main/java/com/flint/presentation/main/MainNavHost.kt index eb8099ea..413be350 100644 --- a/app/src/main/java/com/flint/presentation/main/MainNavHost.kt +++ b/app/src/main/java/com/flint/presentation/main/MainNavHost.kt @@ -22,6 +22,8 @@ import com.flint.presentation.explore.navigation.exploreNavGraph import com.flint.presentation.home.navigation.homeNavGraph import com.flint.presentation.login.navigation.loginNavGraph import com.flint.presentation.onboarding.navigation.onBoardingNavGraph +import com.flint.core.navigation.MainTabRoute +import com.flint.presentation.profile.navigation.KEY_PROFILE_UPDATED import com.flint.presentation.profile.navigation.myProfileNavGraph import com.flint.presentation.profile.navigation.profileNavGraph import com.flint.presentation.savedcontent.navigation.savedContentListNavGraph @@ -144,6 +146,15 @@ fun MainNavHost( editProfileNavGraph( navigateUp = navigator::navigateUp, + onProfileSaved = { + try { + navigator.navController + .getBackStackEntry(MainTabRoute.Profile) + .savedStateHandle[KEY_PROFILE_UPDATED] = true + } catch (_: IllegalArgumentException) { + // MainTabRoute.Profile이 백스택에 없는 경우 무시 + } + }, ) withdrawNavGraph( diff --git a/app/src/main/java/com/flint/presentation/onboarding/OnboardingContentScreen.kt b/app/src/main/java/com/flint/presentation/onboarding/OnboardingContentScreen.kt index 3b2f97d9..3bac8412 100644 --- a/app/src/main/java/com/flint/presentation/onboarding/OnboardingContentScreen.kt +++ b/app/src/main/java/com/flint/presentation/onboarding/OnboardingContentScreen.kt @@ -141,13 +141,24 @@ fun OnboardingContentScreen( // 타이틀 영역 - 스크롤됨 item(span = { GridItemSpan(3) }) { Column { + var useMultiLine by remember(nickname) { mutableStateOf(false) } Text( - text = "${nickname}님이 좋아하는 작품\n7개를 골라주세요", + text = if (useMultiLine) { + "${nickname}님이\n좋아하는 작품\n7개를 골라주세요" + } else { + "${nickname}님이 좋아하는 작품\n7개를 골라주세요" + }, color = FlintTheme.colors.white, style = FlintTheme.typography.display2M28, + onTextLayout = { result -> + // 2줄 포맷인데 실제 렌더링이 3줄 이상이면 자연 줄바꿈 발생한 것 + if (!useMultiLine && result.lineCount > 2) { + useMultiLine = true + } + }, ) - Spacer(modifier = Modifier.height(8.dp)) + Spacer(modifier = Modifier.height(24.dp)) } } @@ -193,6 +204,8 @@ fun OnboardingContentScreen( } } + Spacer(modifier = Modifier.height(8.dp)) + FlintSearchTextField( placeholder = "작품 이름", value = contentUiState.searchKeyword, @@ -277,7 +290,7 @@ fun OnboardingContentScreen( contentAlignment = Alignment.Center, ) { FlintSearchEmptyView( - title = "아직 준비 중인 작품이이요" + title = "아직 준비 중인 작품이에요" ) } } @@ -296,7 +309,7 @@ fun OnboardingContentScreen( contentAlignment = Alignment.Center, ) { FlintSearchEmptyView( - title = "작품을 찾을 수 없어요" + title = "아직 준비 중인 작품이에요" ) } } diff --git a/app/src/main/java/com/flint/presentation/profile/ProfileScreen.kt b/app/src/main/java/com/flint/presentation/profile/ProfileScreen.kt index 50e30391..2983cad6 100644 --- a/app/src/main/java/com/flint/presentation/profile/ProfileScreen.kt +++ b/app/src/main/java/com/flint/presentation/profile/ProfileScreen.kt @@ -48,6 +48,7 @@ import com.flint.core.navigation.model.CollectionListRouteType import com.flint.domain.model.collection.CollectionListModel import com.flint.domain.model.content.BookmarkedContentListModel import com.flint.domain.model.ott.OttListModel +import com.flint.domain.model.ott.OttModel import com.flint.domain.model.user.KeywordListModel import com.flint.domain.model.user.UserProfileResponseModel import com.flint.presentation.MainActivity @@ -66,6 +67,8 @@ fun ProfileRoute( navigateToSavedContentList: (userId: String?) -> Unit, navigateToCollectionDetail: (collectionId: String) -> Unit, navigateToSetting: () -> Unit = {}, + shouldRefreshProfile: Boolean = false, + onProfileRefreshed: () -> Unit = {}, viewModel: ProfileViewModel = hiltViewModel(), ) { val uiState by viewModel.uiState.collectAsStateWithLifecycle() @@ -76,6 +79,13 @@ fun ProfileRoute( var ottListModel by remember { mutableStateOf(OttListModel()) } val sheetState = rememberModalBottomSheetState() + LaunchedEffect(shouldRefreshProfile) { + if (shouldRefreshProfile) { + viewModel.reloadUserProfile() + onProfileRefreshed() + } + } + LaunchedEffect(Unit) { viewModel.sideEffect.collect { sideEffect -> when (sideEffect) { @@ -104,7 +114,11 @@ fun ProfileRoute( onCollectionItemClick = navigateToCollectionDetail, onSettingsClick = navigateToSetting, onContentItemClick = { contentId -> - viewModel.getOttListPerContent(contentId) + val ottList = (uiState.sectionData as? UiState.Success) + ?.data?.savedContents?.contents + ?.find { it.id == contentId }?.getOttSimpleList ?: emptyList() + ottListModel = OttListModel(otts = ottList.map { OttModel(name = it.name) }) + if (ottListModel.otts.isNotEmpty()) showOttListBottomSheet = true }, onContentMoreClick = { navigateToSavedContentList(uiState.userId) }, onCreatedCollectionMoreClick = { diff --git a/app/src/main/java/com/flint/presentation/profile/ProfileViewModel.kt b/app/src/main/java/com/flint/presentation/profile/ProfileViewModel.kt index ba6cc961..799f3be2 100644 --- a/app/src/main/java/com/flint/presentation/profile/ProfileViewModel.kt +++ b/app/src/main/java/com/flint/presentation/profile/ProfileViewModel.kt @@ -149,6 +149,17 @@ class ProfileViewModel @Inject constructor( } } + // 프로필 헤더만 재조회 (섹션 데이터는 유지) + fun reloadUserProfile() { + viewModelScope.launch { + userRepository.getUserProfile(userId = userId) + .onSuccess { profile -> + _uiState.update { it.copy(profile = profile) } + } + .onFailure { Timber.e(it) } + } + } + fun recalculateKeywords() = viewModelScope.launch { _uiState.update { it.copy(isRecalculating = true) } userRepository.recalculateKeywords() diff --git a/app/src/main/java/com/flint/presentation/profile/SavedContentScreen.kt b/app/src/main/java/com/flint/presentation/profile/SavedContentScreen.kt index 74f78722..d2f65bb5 100644 --- a/app/src/main/java/com/flint/presentation/profile/SavedContentScreen.kt +++ b/app/src/main/java/com/flint/presentation/profile/SavedContentScreen.kt @@ -12,9 +12,14 @@ import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.foundation.text.KeyboardActions import androidx.compose.foundation.text.KeyboardOptions +import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalSoftwareKeyboardController @@ -25,14 +30,18 @@ import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.flint.R import com.flint.core.common.util.UiState +import com.flint.core.designsystem.component.bottomsheet.OttListBottomSheet import com.flint.core.designsystem.component.indicator.FlintLoadingIndicator import com.flint.core.designsystem.component.modal.OneButtonModal +import com.flint.core.designsystem.component.toast.ShowToast import com.flint.core.designsystem.component.textfield.FlintSearchTextField import com.flint.core.designsystem.component.topappbar.FlintBackTopAppbar import com.flint.core.designsystem.component.view.FlintSearchEmptyView import com.flint.core.designsystem.theme.FlintTheme import com.flint.domain.model.content.BookmarkedContentItemModel import com.flint.domain.model.content.BookmarkedContentListModel +import com.flint.domain.model.ott.OttListModel +import com.flint.domain.model.ott.OttModel import com.flint.domain.type.OttType import com.flint.presentation.profile.component.CollectionCreateContentBookmark import com.flint.presentation.profile.uistate.SavedContentUiState @@ -46,6 +55,24 @@ fun SavedContentRoute( viewModel: SavedContentViewModel = hiltViewModel(), ) { val uiState by viewModel.uiState.collectAsStateWithLifecycle() + var showSaveToast by remember { mutableStateOf(false) } + var showCancelToast by remember { mutableStateOf(false) } + + LaunchedEffect(Unit) { + viewModel.sideEffect.collect { effect -> + when (effect) { + is SavedContentSideEffect.ToggleBookmarkSuccess -> { + if (effect.isBookmarked) { + showSaveToast = true + showCancelToast = false + } else { + showCancelToast = true + showSaveToast = false + } + } + } + } + } SavedContentScreen( uiState = uiState, @@ -56,8 +83,29 @@ fun SavedContentRoute( onDismissRestrictionModal = viewModel::dismissBookmarkRestrictionModal, modifier = Modifier.padding(paddingValues), ) + + if (showSaveToast) { + ShowToast( + text = "작품을 저장했어요", + imageVector = null, + paddingValues = paddingValues, + yOffset = 12.dp, + hide = { showSaveToast = false }, + ) + } + + if (showCancelToast) { + ShowToast( + text = "작품 저장이 취소되었어요", + imageVector = null, + paddingValues = paddingValues, + yOffset = 12.dp, + hide = { showCancelToast = false }, + ) + } } +@OptIn(ExperimentalMaterial3Api::class) @Composable fun SavedContentScreen( uiState: SavedContentUiState, @@ -69,6 +117,8 @@ fun SavedContentScreen( modifier: Modifier = Modifier, ) { val keyboardController = LocalSoftwareKeyboardController.current + var showOttBottomSheet by remember { mutableStateOf(false) } + var selectedOttList by remember { mutableStateOf>(emptyList()) } Column( modifier = modifier @@ -96,12 +146,12 @@ fun SavedContentScreen( onClearAction = onClearSearch, ) - // "총 n개"는 실제 데이터가 있는 Success 상태에서만 노출 - if (uiState.contents is UiState.Success) { + // "총 n개"는 검색 결과가 있을 때만 노출 + if (uiState.contents is UiState.Success && uiState.filteredContents.isNotEmpty()) { Spacer(modifier = Modifier.height(16.dp)) Text( - text = "총 ${uiState.totalCount}개", + text = "총 ${uiState.filteredContents.size}개", modifier = Modifier.padding(horizontal = 16.dp), color = FlintTheme.colors.gray100, style = FlintTheme.typography.body2R14, @@ -134,6 +184,10 @@ fun SavedContentScreen( SavedContentList( contents = uiState.filteredContents, onBookmarkClick = onBookmarkClick, + onMoreClick = { ottList -> + selectedOttList = ottList + showOttBottomSheet = true + }, ) } } @@ -151,6 +205,13 @@ fun SavedContentScreen( } } + if (showOttBottomSheet && selectedOttList.isNotEmpty()) { + OttListBottomSheet( + ottList = OttListModel(otts = selectedOttList.map { OttModel(name = it.name) }), + onDismiss = { showOttBottomSheet = false }, + ) + } + // 저장 취소 제한 안내 모달 (저장 작품이 5개일 때 북마크 토글 시 노출) if (uiState.showBookmarkRestrictionModal) { OneButtonModal( @@ -168,6 +229,7 @@ fun SavedContentScreen( private fun SavedContentList( contents: ImmutableList, onBookmarkClick: (contentId: String) -> Unit, + onMoreClick: (ottList: List) -> Unit, modifier: Modifier = Modifier, ) { if (contents.isEmpty()) { @@ -192,7 +254,7 @@ private fun SavedContentList( CollectionCreateContentBookmark( modifier = Modifier.animateItem(), onBookmarkClick = { onBookmarkClick(content.id) }, - onMoreClick = {}, + onMoreClick = { onMoreClick(content.getOttSimpleList) }, isBookmarked = content.isBookmarked, bookmarkCount = content.bookmarkCount, imageUrl = content.imageUrl, diff --git a/app/src/main/java/com/flint/presentation/profile/SavedContentSideEffect.kt b/app/src/main/java/com/flint/presentation/profile/SavedContentSideEffect.kt new file mode 100644 index 00000000..aa62a8aa --- /dev/null +++ b/app/src/main/java/com/flint/presentation/profile/SavedContentSideEffect.kt @@ -0,0 +1,5 @@ +package com.flint.presentation.profile + +sealed interface SavedContentSideEffect { + data class ToggleBookmarkSuccess(val isBookmarked: Boolean) : SavedContentSideEffect +} diff --git a/app/src/main/java/com/flint/presentation/profile/SavedContentViewModel.kt b/app/src/main/java/com/flint/presentation/profile/SavedContentViewModel.kt index 721730d5..6f3549fe 100644 --- a/app/src/main/java/com/flint/presentation/profile/SavedContentViewModel.kt +++ b/app/src/main/java/com/flint/presentation/profile/SavedContentViewModel.kt @@ -12,8 +12,11 @@ import com.flint.domain.repository.UserRepository import com.flint.presentation.profile.uistate.SavedContentUiState import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.collections.immutable.toPersistentList +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.update import kotlinx.coroutines.launch @@ -32,6 +35,9 @@ class SavedContentViewModel @Inject constructor( private val _uiState = MutableStateFlow(SavedContentUiState()) val uiState: StateFlow = _uiState.asStateFlow() + private val _sideEffect = MutableSharedFlow() + val sideEffect: SharedFlow = _sideEffect.asSharedFlow() + init { loadBookmarkedContents() } @@ -87,12 +93,14 @@ class SavedContentViewModel @Inject constructor( val currentList = (state.contents as? UiState.Success)?.data ?: return@update state val updated = currentList.copy( + totalCount = maxOf(0, currentList.totalCount + if (isBookmarked) 1 else -1), contents = currentList.contents .map { if (it.id == contentId) it.copy(isBookmarked = isBookmarked) else it } .toPersistentList() ) state.copy(contents = UiState.Success(updated)) } + _sideEffect.emit(SavedContentSideEffect.ToggleBookmarkSuccess(isBookmarked)) } .onFailure { throwable -> if (throwable is BookmarkException.ContentMinLimitExceeded) { diff --git a/app/src/main/java/com/flint/presentation/profile/navigation/ProfileNavigation.kt b/app/src/main/java/com/flint/presentation/profile/navigation/ProfileNavigation.kt index a3b4eee4..1612f1b4 100644 --- a/app/src/main/java/com/flint/presentation/profile/navigation/ProfileNavigation.kt +++ b/app/src/main/java/com/flint/presentation/profile/navigation/ProfileNavigation.kt @@ -1,6 +1,8 @@ package com.flint.presentation.profile.navigation import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.runtime.getValue +import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.navigation.NavController import androidx.navigation.NavGraphBuilder import androidx.navigation.NavOptions @@ -10,6 +12,8 @@ import com.flint.core.navigation.Route import com.flint.core.navigation.model.CollectionListRouteType import com.flint.presentation.profile.ProfileRoute +const val KEY_PROFILE_UPDATED = "key_profile_updated" + fun NavController.navigateToMyProfile( navOptions: NavOptions? = null ) { @@ -30,7 +34,11 @@ fun NavGraphBuilder.myProfileNavGraph( navigateToCollectionDetail: (collectionId: String) -> Unit, navigateToSetting: () -> Unit = {}, ) { - composable { + composable { entry -> + val shouldRefreshProfile by entry.savedStateHandle + .getStateFlow(KEY_PROFILE_UPDATED, false) + .collectAsStateWithLifecycle() + ProfileRoute( paddingValues = paddingValues, navigateUp = {}, @@ -38,6 +46,10 @@ fun NavGraphBuilder.myProfileNavGraph( navigateToSavedContentList = navigateToSavedContentList, navigateToCollectionDetail = navigateToCollectionDetail, navigateToSetting = navigateToSetting, + shouldRefreshProfile = shouldRefreshProfile, + onProfileRefreshed = { + entry.savedStateHandle[KEY_PROFILE_UPDATED] = false + }, ) } } diff --git a/app/src/main/java/com/flint/presentation/setting/editprofile/EditProfileScreen.kt b/app/src/main/java/com/flint/presentation/setting/editprofile/EditProfileScreen.kt index c1a31628..5a0ccd1e 100644 --- a/app/src/main/java/com/flint/presentation/setting/editprofile/EditProfileScreen.kt +++ b/app/src/main/java/com/flint/presentation/setting/editprofile/EditProfileScreen.kt @@ -54,6 +54,7 @@ import com.flint.core.designsystem.theme.FlintTheme @Composable fun EditProfileRoute( navigateUp: () -> Unit, + onProfileSaved: () -> Unit = {}, viewModel: EditProfileViewModel = hiltViewModel(), ) { val uiState by viewModel.uiState.collectAsStateWithLifecycle() @@ -63,7 +64,10 @@ fun EditProfileRoute( } LaunchedEffect(Unit) { - viewModel.navigateUp.collect { navigateUp() } + viewModel.navigateUp.collect { + onProfileSaved() + navigateUp() + } } EditProfileScreen( diff --git a/app/src/main/java/com/flint/presentation/setting/editprofile/navigation/EditProfileNavigation.kt b/app/src/main/java/com/flint/presentation/setting/editprofile/navigation/EditProfileNavigation.kt index 99ff0e84..a8cad6fb 100644 --- a/app/src/main/java/com/flint/presentation/setting/editprofile/navigation/EditProfileNavigation.kt +++ b/app/src/main/java/com/flint/presentation/setting/editprofile/navigation/EditProfileNavigation.kt @@ -13,10 +13,12 @@ fun NavController.navigateToEditProfile(navOptions: NavOptions? = null) { fun NavGraphBuilder.editProfileNavGraph( navigateUp: () -> Unit, + onProfileSaved: () -> Unit = {}, ) { composable { EditProfileRoute( navigateUp = navigateUp, + onProfileSaved = onProfileSaved, ) } }