diff --git a/presentation/src/main/java/daily/dayo/presentation/screen/account/AccountScreen.kt b/presentation/src/main/java/daily/dayo/presentation/screen/account/AccountScreen.kt index 67f3f21b..da8ebb45 100644 --- a/presentation/src/main/java/daily/dayo/presentation/screen/account/AccountScreen.kt +++ b/presentation/src/main/java/daily/dayo/presentation/screen/account/AccountScreen.kt @@ -3,8 +3,8 @@ package daily.dayo.presentation.screen.account import android.annotation.SuppressLint import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.padding -import androidx.compose.material.ExperimentalMaterialApi import androidx.compose.material.Scaffold +import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.SnackbarHost import androidx.compose.material3.SnackbarHostState import androidx.compose.runtime.Composable @@ -18,7 +18,7 @@ import androidx.navigation.compose.NavHost import daily.dayo.presentation.view.dialog.getBottomSheetDialogState @SuppressLint("UnusedMaterialScaffoldPaddingParameter") -@OptIn(ExperimentalMaterialApi::class) +@OptIn(ExperimentalMaterial3Api::class) @Composable internal fun AccountScreen( navigator: AccountNavigator = rememberAccountNavigator() diff --git a/presentation/src/main/java/daily/dayo/presentation/screen/account/SetProfileSetupView.kt b/presentation/src/main/java/daily/dayo/presentation/screen/account/SetProfileSetupView.kt index f65e921b..c4e92d34 100644 --- a/presentation/src/main/java/daily/dayo/presentation/screen/account/SetProfileSetupView.kt +++ b/presentation/src/main/java/daily/dayo/presentation/screen/account/SetProfileSetupView.kt @@ -11,8 +11,8 @@ import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.wrapContentHeight import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.ExperimentalMaterialApi -import androidx.compose.material.ModalBottomSheetState +import androidx.compose.material3.BottomSheetScaffoldState +import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.runtime.Composable import androidx.compose.runtime.MutableState import androidx.compose.runtime.mutableStateOf @@ -34,12 +34,12 @@ import daily.dayo.presentation.view.dialog.getBottomSheetDialogState import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch -@OptIn(ExperimentalMaterialApi::class) +@OptIn(ExperimentalMaterial3Api::class) @Preview @Composable fun SetProfileSetupView( context: Context = LocalContext.current, - bottomSheetState: ModalBottomSheetState = getBottomSheetDialogState(), + bottomSheetState: BottomSheetScaffoldState = getBottomSheetDialogState(), coroutineScope: CoroutineScope = rememberCoroutineScope(), isNextButtonEnabled: MutableState = remember { mutableStateOf(false) }, isNextButtonClickable: MutableState = remember { mutableStateOf(false) }, @@ -63,7 +63,7 @@ fun SetProfileSetupView( interactionSource = interactionSource, indication = null, onClick = { - coroutineScope.launch { bottomSheetState.show() } + coroutineScope.launch { bottomSheetState.bottomSheetState.expand() } } ) } diff --git a/presentation/src/main/java/daily/dayo/presentation/screen/account/SignInNavigation.kt b/presentation/src/main/java/daily/dayo/presentation/screen/account/SignInNavigation.kt index 63778932..500a08d4 100644 --- a/presentation/src/main/java/daily/dayo/presentation/screen/account/SignInNavigation.kt +++ b/presentation/src/main/java/daily/dayo/presentation/screen/account/SignInNavigation.kt @@ -1,7 +1,7 @@ package daily.dayo.presentation.screen.account -import androidx.compose.material.ExperimentalMaterialApi -import androidx.compose.material.ModalBottomSheetState +import androidx.compose.material3.BottomSheetScaffoldState +import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.SnackbarHostState import androidx.compose.runtime.Composable import androidx.compose.runtime.remember @@ -36,6 +36,7 @@ fun NavController.navigateProfileSetting() { this.navigate(SignInRoute.profileSetting) } +@OptIn(ExperimentalMaterial3Api::class) fun NavGraphBuilder.signInNavGraph( coroutineScope: CoroutineScope, snackBarHostState: SnackbarHostState, @@ -47,7 +48,7 @@ fun NavGraphBuilder.signInNavGraph( navigateToSignUpEmail: () -> Unit, navigateToRules: (RuleType) -> Unit, navigateToProfileSetting: () -> Unit, - bottomSheetState: ModalBottomSheetState, + bottomSheetState: BottomSheetScaffoldState, bottomSheetContent: (@Composable () -> Unit) -> Unit, ) { composable(route = SignInRoute.route) { diff --git a/presentation/src/main/java/daily/dayo/presentation/screen/account/SignUpEmailScreen.kt b/presentation/src/main/java/daily/dayo/presentation/screen/account/SignUpEmailScreen.kt index 65e5b6c1..4746159c 100644 --- a/presentation/src/main/java/daily/dayo/presentation/screen/account/SignUpEmailScreen.kt +++ b/presentation/src/main/java/daily/dayo/presentation/screen/account/SignUpEmailScreen.kt @@ -16,9 +16,9 @@ import androidx.compose.foundation.layout.imePadding import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.wrapContentHeight import androidx.compose.foundation.layout.wrapContentSize -import androidx.compose.material.ExperimentalMaterialApi -import androidx.compose.material.ModalBottomSheetState import androidx.compose.material.Text +import androidx.compose.material3.BottomSheetScaffoldState +import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Scaffold import androidx.compose.material3.SnackbarHostState import androidx.compose.runtime.Composable @@ -59,8 +59,8 @@ import daily.dayo.presentation.view.TopNavigation import daily.dayo.presentation.view.dialog.ProfileImageBottomSheetDialog import daily.dayo.presentation.view.dialog.getBottomSheetDialogState import daily.dayo.presentation.viewmodel.AccountViewModel -import daily.dayo.presentation.viewmodel.AccountViewModel.Companion.SIGN_UP_EMAIL_CERTIFICATE_AUTH_CODE_FAIL import daily.dayo.presentation.viewmodel.AccountViewModel.Companion.EMAIL_CERTIFICATE_AUTH_CODE_INITIAL +import daily.dayo.presentation.viewmodel.AccountViewModel.Companion.SIGN_UP_EMAIL_CERTIFICATE_AUTH_CODE_FAIL import daily.dayo.presentation.viewmodel.ProfileSettingViewModel import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers @@ -76,7 +76,7 @@ const val PASSWORD_PERMIT_FORMAT = "^[a-z0-9]{8,16}$" const val IMAGE_TEMP_FILE_NAME_FORMAT = "yyyy-MM-d-HH-mm-ss-SSS" const val IMAGE_TEMP_FILE_EXTENSION = ".jpg" -@OptIn(ExperimentalMaterialApi::class) +@OptIn(ExperimentalMaterial3Api::class) @Composable internal fun SignUpEmailRoute( coroutineScope: CoroutineScope = rememberCoroutineScope(), @@ -229,19 +229,19 @@ internal fun SignUpEmailRoute( onClickProfileSelect = { coroutineScope.launch { showProfileGallery = true - bottomSheetState.hide() + bottomSheetState.bottomSheetState.hide() } }, onClickProfileCapture = { coroutineScope.launch { showProfileCapture = true - bottomSheetState.hide() + bottomSheetState.bottomSheetState.hide() } }, onClickProfileReset = { profileImgState.value = null coroutineScope.launch { - bottomSheetState.hide() + bottomSheetState.bottomSheetState.hide() } }, ) @@ -272,13 +272,13 @@ fun SignUpEmailTitleLayout( } } -@OptIn(ExperimentalMaterialApi::class) +@OptIn(ExperimentalMaterial3Api::class) @Composable @Preview fun SignUpEmailScreen( context: Context = LocalContext.current, coroutineScope: CoroutineScope = rememberCoroutineScope(), - bottomSheetState: ModalBottomSheetState = getBottomSheetDialogState(), + bottomSheetState: BottomSheetScaffoldState = getBottomSheetDialogState(), hideKeyboard: () -> Unit = {}, onBackClick: () -> Unit = {}, requestIsEmailDuplicate: (email: String) -> Unit = {}, diff --git a/presentation/src/main/java/daily/dayo/presentation/screen/feed/FeedNavigation.kt b/presentation/src/main/java/daily/dayo/presentation/screen/feed/FeedNavigation.kt index c7d64ea3..2e8ac3a8 100644 --- a/presentation/src/main/java/daily/dayo/presentation/screen/feed/FeedNavigation.kt +++ b/presentation/src/main/java/daily/dayo/presentation/screen/feed/FeedNavigation.kt @@ -1,13 +1,13 @@ package daily.dayo.presentation.screen.feed -import androidx.compose.material.ExperimentalMaterialApi -import androidx.compose.material.ModalBottomSheetState +import androidx.compose.material3.BottomSheetScaffoldState +import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.SnackbarHostState import androidx.compose.runtime.Composable import androidx.navigation.NavGraphBuilder import androidx.navigation.compose.composable -@OptIn(ExperimentalMaterialApi::class) +@OptIn(ExperimentalMaterial3Api::class) fun NavGraphBuilder.feedNavGraph( snackBarHostState: SnackbarHostState, onEmptyViewClick: () -> Unit, @@ -15,7 +15,7 @@ fun NavGraphBuilder.feedNavGraph( onProfileClick: (String) -> Unit, onPostLikeUsersClick: (Long) -> Unit, onPostHashtagClick: (String) -> Unit, - bottomSheetState: ModalBottomSheetState, + bottomSheetState: BottomSheetScaffoldState, bottomSheetContent: (@Composable () -> Unit) -> Unit, ) { composable(FeedRoute.route) { diff --git a/presentation/src/main/java/daily/dayo/presentation/screen/feed/FeedScreen.kt b/presentation/src/main/java/daily/dayo/presentation/screen/feed/FeedScreen.kt index 8c8d72a9..ccd7d6c3 100644 --- a/presentation/src/main/java/daily/dayo/presentation/screen/feed/FeedScreen.kt +++ b/presentation/src/main/java/daily/dayo/presentation/screen/feed/FeedScreen.kt @@ -11,10 +11,11 @@ import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.material.ExperimentalMaterialApi -import androidx.compose.material.ModalBottomSheetState import androidx.compose.material.pullrefresh.PullRefreshIndicator import androidx.compose.material.pullrefresh.pullRefresh import androidx.compose.material.pullrefresh.rememberPullRefreshState +import androidx.compose.material3.BottomSheetScaffoldState +import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Scaffold import androidx.compose.material3.SnackbarHostState import androidx.compose.material3.Text @@ -47,7 +48,7 @@ import daily.dayo.presentation.view.FilledButton import daily.dayo.presentation.view.TopNavigation import daily.dayo.presentation.viewmodel.FeedViewModel -@OptIn(ExperimentalMaterialApi::class) +@OptIn(ExperimentalMaterialApi::class, ExperimentalMaterial3Api::class) @Composable fun FeedScreen( snackBarHostState: SnackbarHostState, @@ -56,7 +57,7 @@ fun FeedScreen( onProfileClick: (String) -> Unit, onPostLikeUsersClick: (Long) -> Unit, onPostHashtagClick: (String) -> Unit, - bottomSheetState: ModalBottomSheetState, + bottomSheetState: BottomSheetScaffoldState, bottomSheetContent: (@Composable () -> Unit) -> Unit, feedViewModel: FeedViewModel = hiltViewModel() ) { diff --git a/presentation/src/main/java/daily/dayo/presentation/screen/home/HomeNavigation.kt b/presentation/src/main/java/daily/dayo/presentation/screen/home/HomeNavigation.kt index c3dbd892..d1db9dc3 100644 --- a/presentation/src/main/java/daily/dayo/presentation/screen/home/HomeNavigation.kt +++ b/presentation/src/main/java/daily/dayo/presentation/screen/home/HomeNavigation.kt @@ -2,6 +2,8 @@ package daily.dayo.presentation.screen.home import androidx.compose.material.ExperimentalMaterialApi import androidx.compose.material.ModalBottomSheetState +import androidx.compose.material3.BottomSheetScaffoldState +import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.runtime.Composable import androidx.navigation.NavController import androidx.navigation.NavGraphBuilder @@ -12,13 +14,13 @@ fun NavController.navigateHome() { this.navigate(HomeRoute.route) } -@OptIn(ExperimentalMaterialApi::class) +@OptIn(ExperimentalMaterial3Api::class) fun NavGraphBuilder.homeNavGraph( onPostClick: (Long) -> Unit, onProfileClick: (String) -> Unit, onSearchClick: () -> Unit, coroutineScope: CoroutineScope, - bottomSheetState: ModalBottomSheetState, + bottomSheetState: BottomSheetScaffoldState, bottomSheetContent: (@Composable () -> Unit) -> Unit ) { composable(HomeRoute.route) { diff --git a/presentation/src/main/java/daily/dayo/presentation/screen/home/HomeScreen.kt b/presentation/src/main/java/daily/dayo/presentation/screen/home/HomeScreen.kt index 05f952f6..159e0dab 100644 --- a/presentation/src/main/java/daily/dayo/presentation/screen/home/HomeScreen.kt +++ b/presentation/src/main/java/daily/dayo/presentation/screen/home/HomeScreen.kt @@ -7,8 +7,8 @@ import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size -import androidx.compose.material.ExperimentalMaterialApi -import androidx.compose.material.ModalBottomSheetState +import androidx.compose.material3.BottomSheetScaffoldState +import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Scaffold import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue @@ -45,31 +45,31 @@ import kotlinx.coroutines.launch const val HOME_DAYOPICK_PAGE_TAB_ID = 0 const val HOME_NEW_PAGE_TAB_ID = 1 -@OptIn(ExperimentalMaterialApi::class) +@OptIn(ExperimentalMaterial3Api::class) @Composable fun HomeScreen( onPostClick: (Long) -> Unit, onProfileClick: (String) -> Unit, onSearchClick: () -> Unit, coroutineScope: CoroutineScope, - bottomSheetState: ModalBottomSheetState, + bottomSheetState: BottomSheetScaffoldState, bottomSheetContent: (@Composable () -> Unit) -> Unit, homeViewModel: HomeViewModel = hiltViewModel() ) { var homeTabState by rememberSaveable { mutableIntStateOf(HOME_DAYOPICK_PAGE_TAB_ID) } var selectedCategory by rememberSaveable { mutableStateOf(Pair(CategoryMenu.All.name, 0)) } // name, index val onCategoryClick: () -> Unit = { - coroutineScope.launch { bottomSheetState.show() } + coroutineScope.launch { bottomSheetState.bottomSheetState.expand() } } val onCategorySelect: (CategoryMenu, Int) -> Unit = { categoryMenu, index -> selectedCategory = Pair(categoryMenu.name, index) homeViewModel.setCategory(categoryMenu.category) - coroutineScope.launch { bottomSheetState.hide() } + coroutineScope.launch { bottomSheetState.bottomSheetState.hide() } } - BackHandler(enabled = bottomSheetState.isVisible) { - coroutineScope.launch { bottomSheetState.hide() } + BackHandler(enabled = bottomSheetState.bottomSheetState.isVisible) { + coroutineScope.launch { bottomSheetState.bottomSheetState.hide() } } Scaffold( @@ -149,13 +149,13 @@ fun HomeScreen( } } -@OptIn(ExperimentalMaterialApi::class) +@OptIn(ExperimentalMaterial3Api::class) @Composable private fun CategoryBottomSheetDialog( onCategorySelected: (CategoryMenu, Int) -> Unit, selectedCategory: Pair, coroutineScope: CoroutineScope, - bottomSheetState: ModalBottomSheetState + bottomSheetState: BottomSheetScaffoldState ) { val categoryMenus = listOf( CategoryMenu.All, @@ -184,11 +184,11 @@ private fun CategoryBottomSheetDialog( normalColor = Gray2_767B83, checkedColor = Primary_23C882, checkedButtonIndex = selectedCategory.second, - closeButtonAction = { coroutineScope.launch { bottomSheetState.hide() } } + closeButtonAction = { coroutineScope.launch { bottomSheetState.bottomSheetState.hide() } } ) } -@OptIn(ExperimentalMaterialApi::class) +@OptIn(ExperimentalMaterial3Api::class) @Composable @Preview(showBackground = true) private fun PreviewHomeScreen() { diff --git a/presentation/src/main/java/daily/dayo/presentation/screen/main/MainScreen.kt b/presentation/src/main/java/daily/dayo/presentation/screen/main/MainScreen.kt index cf1a1c85..b1e71c39 100644 --- a/presentation/src/main/java/daily/dayo/presentation/screen/main/MainScreen.kt +++ b/presentation/src/main/java/daily/dayo/presentation/screen/main/MainScreen.kt @@ -1,20 +1,24 @@ package daily.dayo.presentation.screen.main -import android.annotation.SuppressLint import androidx.annotation.DrawableRes import androidx.annotation.StringRes import androidx.compose.animation.ExperimentalSharedTransitionApi import androidx.compose.animation.SharedTransitionLayout import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.material.BottomNavigation import androidx.compose.material.BottomNavigationItem +import androidx.compose.material.Divider import androidx.compose.material.Icon -import androidx.compose.material.Scaffold import androidx.compose.material.Text -import androidx.compose.material3.SnackbarHost +import androidx.compose.material3.BottomSheetScaffold +import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.SnackbarHostState import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue @@ -55,13 +59,13 @@ import daily.dayo.presentation.screen.write.writeNavGraph import daily.dayo.presentation.theme.Dark import daily.dayo.presentation.theme.DayoTheme import daily.dayo.presentation.theme.Gray2_767B83 +import daily.dayo.presentation.theme.Gray7_F6F6F7 import daily.dayo.presentation.theme.White_FFFFFF import daily.dayo.presentation.view.dialog.getBottomSheetDialogState import daily.dayo.presentation.viewmodel.NoticeViewModel import daily.dayo.presentation.viewmodel.ProfileViewModel -@OptIn(ExperimentalSharedTransitionApi::class) -@SuppressLint("UnusedMaterialScaffoldPaddingParameter") +@OptIn(ExperimentalSharedTransitionApi::class, ExperimentalMaterial3Api::class) @Composable internal fun MainScreen( onAdRequest: (onRewardSuccess: () -> Unit) -> Unit, @@ -73,184 +77,186 @@ internal fun MainScreen( val noticeViewModel = hiltViewModel() val snackBarHostState = remember { SnackbarHostState() } - val bottomSheetState = getBottomSheetDialogState() var bottomSheetContent by remember { mutableStateOf<(@Composable () -> Unit)?>(null) } + val bottomSheetState = getBottomSheetDialogState() + SharedTransitionLayout { - Scaffold( - snackbarHost = { SnackbarHost(hostState = snackBarHostState) } + BottomSheetScaffold( + scaffoldState = bottomSheetState, + sheetDragHandle = null, + sheetContent = { + Box(modifier = Modifier.navigationBarsPadding()) { + bottomSheetContent?.invoke() + } + }, + sheetPeekHeight = 0.dp ) { - Scaffold( - bottomBar = { bottomSheetContent?.invoke() } - ) { - Scaffold( - content = { innerPadding -> - Box(Modifier.padding(innerPadding)) { - NavHost( - navController = navigator.navController, - startDestination = Screen.Home.route - ) { - homeNavGraph( - onPostClick = { navigator.navigatePost(it) }, - onProfileClick = { memberId -> - navigator.navigateProfile( - currentMemberId, - memberId - ) - }, - onSearchClick = { navigator.navigateSearch() }, - coroutineScope = coroutineScope, - bottomSheetState = bottomSheetState, - bottomSheetContent = { content -> - bottomSheetContent = content - }, - ) - feedNavGraph( - snackBarHostState = snackBarHostState, - onEmptyViewClick = { navigator.navigateHome() }, - onPostClick = { navigator.navigatePost(it) }, - onProfileClick = { memberId -> - navigator.navigateProfile( - currentMemberId, - memberId - ) - }, - onPostLikeUsersClick = { navigator.navigatePostLikeUsers(it) }, - onPostHashtagClick = { navigator.navigateSearchPostHashtag(it) }, - bottomSheetState = bottomSheetState, - bottomSheetContent = { content -> bottomSheetContent = content } - ) - postNavGraph( - snackBarHostState = snackBarHostState, - onProfileClick = { memberId -> - navigator.navigateProfile( - currentMemberId, - memberId - ) - }, - onPostLikeUsersClick = { navigator.navigatePostLikeUsers(it) }, - onPostHashtagClick = { navigator.navigateSearchPostHashtag(it) }, - onBackClick = { navigator.popBackStack() } - ) - searchNavGraph( - onBackClick = { navigator.popBackStack() }, - onSearch = { navigator.navigateSearchResult(it) }, - onPostClick = { navigator.navigatePost(it) }, - onProfileClick = { memberId -> - navigator.navigateProfile( - currentMemberId, - memberId - ) - }, - navController = navigator.navController, - ) - writeNavGraph( - snackBarHostState = snackBarHostState, - navController = navigator.navController, - onBackClick = { navigator.navigateUp() }, - onTagClick = { navigator.navigateWriteTag() }, - onWriteFolderClick = { navigator.navigateWriteFolder() }, - onWriteFolderNewClick = { navigator.navigateWriteFolderNew() }, - onAdRequest = onAdRequest, - bottomSheetState = bottomSheetState, - bottomSheetContent = { content -> - bottomSheetContent = content - } - ) - myPageNavGraph( - navController = navigator.navController, - onBackClick = { navigator.popBackStack() }, - onSettingsClick = { navigator.navigateSettings() }, - onFollowButtonClick = { memberId, tabNum -> - navigator.navigateFollowMenu( - memberId, - tabNum - ) - }, - onProfileClick = { memberId -> - navigator.navigateProfile( - currentMemberId, - memberId - ) - }, - onProfileEditClick = { navigator.navigateProfileEdit() }, - onBookmarkClick = { navigator.navigateBookmark() }, - onFolderClick = { folderId -> navigator.navigateFolder(folderId) }, - onFolderCreateClick = { navigator.navigateFolderCreate() }, - onFolderEditClick = { folderId -> - navigator.navigateFolderEdit( - folderId - ) - }, - onPostClick = { postId -> navigator.navigatePost(postId) }, - onPostMoveClick = { folderId -> - navigator.navigateFolderPostMove( - folderId - ) - }, - onAdRequest = onAdRequest, - navigateBackToFolder = { folderId -> - navigator.navigateBackToFolder( - folderId - ) - } - ) - profileNavGraph( - snackBarHostState = snackBarHostState, - onFollowMenuClick = { memberId, tabNum -> - navigator.navigateFollowMenu( - memberId, - tabNum - ) - }, - onFolderClick = { folderId -> navigator.navigateFolder(folderId) }, - onPostClick = { postId -> navigator.navigatePost(postId) }, - onBackClick = { navigator.popBackStack() } - ) - notificationNavGraph( - onPostClick = { navigator.navigatePost(it) }, - onProfileClick = { memberId -> - navigator.navigateProfile( - currentMemberId, - memberId - ) - }, - onNoticeClick = { noticeId -> - navigator.navigateNoticeDetail( - noticeId - ) - }, - ) - settingsNavGraph( - coroutineScope = coroutineScope, - snackBarHostState = snackBarHostState, - onProfileEditClick = { navigator.navigateProfileEdit() }, - onBlockUsersClick = { navigator.navigateBlockedUsers() }, - onPasswordChangeClick = { navigator.navigateChangePassword() }, - onSettingNotificationClick = { navigator.navigateSettingsNotification() }, - onNoticesClick = { navigator.navigateNotices() }, - onInformationClick = { navigator.navigateInformation() }, - onRulesClick = { ruleType -> navigator.navigateRules(ruleType) }, - onBackClick = { navigator.popBackStack() } - ) - noticeNavGraph( - noticeViewModel = noticeViewModel, - onBackClick = { navigator.popBackStack() }, - onNoticeDetailClick = { noticeId -> - navigator.navigateNoticeDetail( - noticeId - ) - }, - sharedTransitionScope = this@SharedTransitionLayout, - ) - } + Column(modifier = Modifier.navigationBarsPadding()) { + NavHost( + modifier = Modifier.weight(1f), + navController = navigator.navController, + startDestination = Screen.Home.route, + ) { + homeNavGraph( + onPostClick = { navigator.navigatePost(it) }, + onProfileClick = { memberId -> + navigator.navigateProfile( + currentMemberId, + memberId + ) + }, + onSearchClick = { navigator.navigateSearch() }, + coroutineScope = coroutineScope, + bottomSheetState = bottomSheetState, + bottomSheetContent = { content -> + bottomSheetContent = content + }, + ) + feedNavGraph( + snackBarHostState = snackBarHostState, + onEmptyViewClick = { navigator.navigateHome() }, + onPostClick = { navigator.navigatePost(it) }, + onProfileClick = { memberId -> + navigator.navigateProfile( + currentMemberId, + memberId + ) + }, + onPostLikeUsersClick = { navigator.navigatePostLikeUsers(it) }, + onPostHashtagClick = { navigator.navigateSearchPostHashtag(it) }, + bottomSheetState = bottomSheetState, + bottomSheetContent = { content -> bottomSheetContent = content } + ) + postNavGraph( + snackBarHostState = snackBarHostState, + onProfileClick = { memberId -> + navigator.navigateProfile( + currentMemberId, + memberId + ) + }, + onPostLikeUsersClick = { navigator.navigatePostLikeUsers(it) }, + onPostHashtagClick = { navigator.navigateSearchPostHashtag(it) }, + onBackClick = { navigator.popBackStack() } + ) + searchNavGraph( + onBackClick = { navigator.popBackStack() }, + onSearch = { navigator.navigateSearchResult(it) }, + onPostClick = { navigator.navigatePost(it) }, + onProfileClick = { memberId -> + navigator.navigateProfile( + currentMemberId, + memberId + ) + }, + navController = navigator.navController, + ) + writeNavGraph( + snackBarHostState = snackBarHostState, + navController = navigator.navController, + onBackClick = { navigator.navigateUp() }, + onTagClick = { navigator.navigateWriteTag() }, + onWriteFolderClick = { navigator.navigateWriteFolder() }, + onWriteFolderNewClick = { navigator.navigateWriteFolderNew() }, + onAdRequest = onAdRequest, + bottomSheetState = bottomSheetState, + bottomSheetContent = { content -> + bottomSheetContent = content } - }, - bottomBar = { - MainBottomNavigation( - visible = navigator.shouldShowBottomBar(), - navController = navigator.navController - ) - } + ) + myPageNavGraph( + navController = navigator.navController, + onBackClick = { navigator.popBackStack() }, + onSettingsClick = { navigator.navigateSettings() }, + onFollowButtonClick = { memberId, tabNum -> + navigator.navigateFollowMenu( + memberId, + tabNum + ) + }, + onProfileClick = { memberId -> + navigator.navigateProfile( + currentMemberId, + memberId + ) + }, + onProfileEditClick = { navigator.navigateProfileEdit() }, + onBookmarkClick = { navigator.navigateBookmark() }, + onFolderClick = { folderId -> navigator.navigateFolder(folderId) }, + onFolderCreateClick = { navigator.navigateFolderCreate() }, + onFolderEditClick = { folderId -> + navigator.navigateFolderEdit( + folderId + ) + }, + onPostClick = { postId -> navigator.navigatePost(postId) }, + onPostMoveClick = { folderId -> + navigator.navigateFolderPostMove( + folderId + ) + }, + onAdRequest = onAdRequest, + navigateBackToFolder = { folderId -> + navigator.navigateBackToFolder( + folderId + ) + } + ) + profileNavGraph( + snackBarHostState = snackBarHostState, + onFollowMenuClick = { memberId, tabNum -> + navigator.navigateFollowMenu( + memberId, + tabNum + ) + }, + onFolderClick = { folderId -> navigator.navigateFolder(folderId) }, + onPostClick = { postId -> navigator.navigatePost(postId) }, + onBackClick = { navigator.popBackStack() } + ) + notificationNavGraph( + onPostClick = { navigator.navigatePost(it) }, + onProfileClick = { memberId -> + navigator.navigateProfile( + currentMemberId, + memberId + ) + }, + onNoticeClick = { noticeId -> + navigator.navigateNoticeDetail( + noticeId + ) + }, + ) + settingsNavGraph( + coroutineScope = coroutineScope, + snackBarHostState = snackBarHostState, + onProfileEditClick = { navigator.navigateProfileEdit() }, + onBlockUsersClick = { navigator.navigateBlockedUsers() }, + onPasswordChangeClick = { navigator.navigateChangePassword() }, + onSettingNotificationClick = { navigator.navigateSettingsNotification() }, + onNoticesClick = { navigator.navigateNotices() }, + onInformationClick = { navigator.navigateInformation() }, + onRulesClick = { ruleType -> navigator.navigateRules(ruleType) }, + onBackClick = { navigator.popBackStack() } + ) + noticeNavGraph( + noticeViewModel = noticeViewModel, + onBackClick = { navigator.popBackStack() }, + onNoticeDetailClick = { noticeId -> + navigator.navigateNoticeDetail( + noticeId + ) + }, + sharedTransitionScope = this@SharedTransitionLayout, + ) + } + + // bottom navigation + MainBottomNavigation( + visible = navigator.shouldShowBottomBar(), + navController = navigator.navController, + modifier = Modifier.fillMaxWidth() ) } } @@ -260,7 +266,8 @@ internal fun MainScreen( @Composable fun MainBottomNavigation( visible: Boolean, - navController: NavController + navController: NavController, + modifier: Modifier ) { val navBackStackEntry by navController.currentBackStackEntryAsState() val currentDestination = navBackStackEntry?.destination @@ -273,44 +280,52 @@ fun MainBottomNavigation( ) if (visible) { - BottomNavigation( - backgroundColor = White_FFFFFF, - contentColor = Gray2_767B83 - ) { - items.forEach { screen -> - val selected = currentDestination?.hierarchy?.any { it.route == screen.route } == true - BottomNavigationItem( - icon = { - Column( - horizontalAlignment = Alignment.CenterHorizontally - ) { - Icon( - imageVector = ImageVector.vectorResource(id = if (selected) screen.selectedIcon else screen.defaultIcon), - contentDescription = stringResource(id = screen.resourceId), - modifier = Modifier.size(if (screen.route != Screen.Write.route) 24.dp else 36.dp) - ) + Column { + Divider(color = Gray7_F6F6F7, thickness = 1.dp) + + BottomNavigation( + backgroundColor = White_FFFFFF, + contentColor = Gray2_767B83, + elevation = 0.dp, + modifier = modifier + ) { + items.forEach { screen -> + val selected = currentDestination?.hierarchy?.any { it.route == screen.route } == true + BottomNavigationItem( + icon = { + Column( + horizontalAlignment = Alignment.CenterHorizontally + ) { + Icon( + imageVector = ImageVector.vectorResource(id = if (selected) screen.selectedIcon else screen.defaultIcon), + contentDescription = stringResource(id = screen.resourceId), + modifier = Modifier.size(if (screen.route != Screen.Write.route) 24.dp else 36.dp) + ) - if (screen.route != Screen.Write.route) { - Text(text = stringResource(screen.resourceId), style = DayoTheme.typography.caption5) + Spacer(Modifier.height(2.dp)) + + if (screen.route != Screen.Write.route) { + Text(text = stringResource(screen.resourceId), style = DayoTheme.typography.caption5) + } } - } - }, - modifier = Modifier.padding(top = 12.dp, bottom = 16.dp), - selected = selected, - selectedContentColor = Dark, - onClick = { - navController.navigate(screen.route) { - if (screen.route != Screen.Write.route) { - popUpTo(navController.graph.findStartDestination().id) { - saveState = true + }, + modifier = Modifier.padding(vertical = 8.dp), + selected = selected, + selectedContentColor = Dark, + onClick = { + navController.navigate(screen.route) { + if (screen.route != Screen.Write.route) { + popUpTo(navController.graph.findStartDestination().id) { + saveState = true + } } + launchSingleTop = + if (screen.route == Screen.Write.route) false else true + restoreState = true } - launchSingleTop = - if (screen.route == Screen.Write.route) false else true - restoreState = true } - } - ) + ) + } } } } @@ -335,6 +350,7 @@ sealed class Screen(val route: String, @StringRes val resourceId: Int, @Drawable private fun PreviewMainBottomNavigation() { MainBottomNavigation( visible = true, - navController = rememberNavController() + navController = rememberNavController(), + modifier = Modifier ) } diff --git a/presentation/src/main/java/daily/dayo/presentation/screen/mypage/MyPageEditScreen.kt b/presentation/src/main/java/daily/dayo/presentation/screen/mypage/MyPageEditScreen.kt index c76f3227..5cdd68a4 100644 --- a/presentation/src/main/java/daily/dayo/presentation/screen/mypage/MyPageEditScreen.kt +++ b/presentation/src/main/java/daily/dayo/presentation/screen/mypage/MyPageEditScreen.kt @@ -11,7 +11,6 @@ import androidx.activity.compose.ManagedActivityResultLauncher import androidx.activity.compose.rememberLauncherForActivityResult import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.launch -import androidx.appcompat.content.res.AppCompatResources import androidx.compose.foundation.background import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.Column @@ -26,12 +25,12 @@ import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.verticalScroll import androidx.compose.material.ExperimentalMaterialApi -import androidx.compose.material.ModalBottomSheetState import androidx.compose.material.Text +import androidx.compose.material3.BottomSheetScaffoldState import androidx.compose.material3.Divider +import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon import androidx.compose.material3.IconButton -import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Scaffold import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect @@ -72,7 +71,6 @@ import daily.dayo.presentation.theme.Gray1_50545B import daily.dayo.presentation.theme.Gray2_767B83 import daily.dayo.presentation.theme.Gray4_C5CAD2 import daily.dayo.presentation.theme.Gray6_F0F1F3 -import daily.dayo.presentation.theme.White_FFFFFF import daily.dayo.presentation.view.BadgeRoundImageView import daily.dayo.presentation.view.DayoTextField import daily.dayo.presentation.view.TopNavigation @@ -85,7 +83,7 @@ import java.io.File import java.io.FileOutputStream import java.util.regex.Pattern -@OptIn(ExperimentalMaterialApi::class) +@OptIn(ExperimentalMaterial3Api::class) @Composable internal fun MyPageEditScreen( onBackClick: () -> Unit, @@ -166,19 +164,19 @@ internal fun MyPageEditScreen( onClickProfileSelect = { coroutineScope.launch { showProfileGallery = true - bottomSheetState.hide() + bottomSheetState.bottomSheetState.hide() } }, onClickProfileCapture = { coroutineScope.launch { showProfileCapture = true - bottomSheetState.hide() + bottomSheetState.bottomSheetState.hide() } }, onClickProfileReset = { modifiedProfileImage.value = "" coroutineScope.launch { - bottomSheetState.hide() + bottomSheetState.bottomSheetState.hide() } }, onBackClick = onBackClick, @@ -197,13 +195,13 @@ internal fun MyPageEditScreen( ) } -@OptIn(ExperimentalMaterialApi::class) +@OptIn(ExperimentalMaterialApi::class, ExperimentalMaterial3Api::class) @Composable private fun MyPageEditScreen( profileInfo: MutableState, modifiedProfileImage: String, nickNameErrorMessage: String, - bottomSheetState: ModalBottomSheetState, + bottomSheetState: BottomSheetScaffoldState, onClickProfileSelect: () -> Unit, onClickProfileCapture: () -> Unit, onClickProfileReset: () -> Unit, @@ -253,7 +251,7 @@ private fun MyPageEditScreen( interactionSource = remember { MutableInteractionSource() }, indication = null, onClick = { - coroutineScope.launch { bottomSheetState.show() } + coroutineScope.launch { bottomSheetState.bottomSheetState.expand() } } ) ) @@ -342,10 +340,10 @@ private fun MyPageEditTopNavigation( ) } -@OptIn(ExperimentalMaterialApi::class) +@OptIn(ExperimentalMaterial3Api::class) @Composable private fun ProfileImageBottomSheetDialog( - bottomSheetState: ModalBottomSheetState, + bottomSheetState: BottomSheetScaffoldState, onClickProfileSelect: () -> Unit, onClickProfileCapture: () -> Unit, onClickProfileReset: () -> Unit, @@ -474,7 +472,7 @@ fun bitmapToUri(context: Context, bitmap: Bitmap): Uri? { } } -@OptIn(ExperimentalMaterialApi::class) +@OptIn(ExperimentalMaterial3Api::class) @Preview @Composable internal fun PreviewMyPageEditScreen() { diff --git a/presentation/src/main/java/daily/dayo/presentation/screen/write/WriteNavigation.kt b/presentation/src/main/java/daily/dayo/presentation/screen/write/WriteNavigation.kt index a68ca9ee..f2679470 100644 --- a/presentation/src/main/java/daily/dayo/presentation/screen/write/WriteNavigation.kt +++ b/presentation/src/main/java/daily/dayo/presentation/screen/write/WriteNavigation.kt @@ -1,6 +1,7 @@ package daily.dayo.presentation.screen.write -import androidx.compose.material.ModalBottomSheetState +import androidx.compose.material3.BottomSheetScaffoldState +import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.SnackbarHostState import androidx.compose.runtime.Composable import androidx.compose.runtime.remember @@ -26,6 +27,7 @@ fun NavController.navigateWriteFolderNew() { navigate(WriteRoute.folderNew) } +@OptIn(ExperimentalMaterial3Api::class) fun NavGraphBuilder.writeNavGraph( snackBarHostState: SnackbarHostState, navController: NavController, @@ -34,7 +36,7 @@ fun NavGraphBuilder.writeNavGraph( onWriteFolderClick: () -> Unit, onWriteFolderNewClick: () -> Unit, onAdRequest: (onRewardSuccess: () -> Unit) -> Unit, - bottomSheetState: ModalBottomSheetState, + bottomSheetState: BottomSheetScaffoldState, bottomSheetContent: (@Composable () -> Unit) -> Unit, ) { navigation( diff --git a/presentation/src/main/java/daily/dayo/presentation/screen/write/WriteScreen.kt b/presentation/src/main/java/daily/dayo/presentation/screen/write/WriteScreen.kt index 3e9e7cd5..03de02db 100644 --- a/presentation/src/main/java/daily/dayo/presentation/screen/write/WriteScreen.kt +++ b/presentation/src/main/java/daily/dayo/presentation/screen/write/WriteScreen.kt @@ -10,7 +10,6 @@ import androidx.activity.result.contract.ActivityResultContracts import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.clickable -import androidx.compose.foundation.indication import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box @@ -30,10 +29,10 @@ import androidx.compose.foundation.lazy.LazyRow import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.text.BasicTextField -import androidx.compose.material.ExperimentalMaterialApi -import androidx.compose.material.ModalBottomSheetState import androidx.compose.material.Surface +import androidx.compose.material3.BottomSheetScaffoldState import androidx.compose.material3.Divider +import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.SnackbarHostState import androidx.compose.material3.Text import androidx.compose.runtime.Composable @@ -100,7 +99,7 @@ const val WRITE_POST_DETAIL_MAX_LENGTH = 200 const val WRITE_POST_IMAGE_SIZE = 220 const val WRITE_POST_TOP_Z_INDEX = 1f -@OptIn(ExperimentalMaterialApi::class) +@OptIn(ExperimentalMaterial3Api::class) @Composable internal fun WriteRoute( snackBarHostState: SnackbarHostState, @@ -108,7 +107,7 @@ internal fun WriteRoute( onTagClick: () -> Unit, onWriteFolderClick: () -> Unit, writeViewModel: WriteViewModel = hiltViewModel(), - bottomSheetState: ModalBottomSheetState, + bottomSheetState: BottomSheetScaffoldState, bottomSheetContent: (@Composable () -> Unit) -> Unit, ) { val context = LocalContext.current @@ -126,7 +125,7 @@ internal fun WriteRoute( val selectedCategory by writeViewModel.writeCategory.collectAsState() // name, index val onClickCategory: (CategoryMenu, Int) -> Unit = { categoryMenu, index -> writeViewModel.setPostCategory(Pair(categoryMenu.category, index)) - coroutineScope.launch { bottomSheetState.hide() } + coroutineScope.launch { bottomSheetState.bottomSheetState.hide() } } val categoryMenus = listOf( CategoryMenu.Scheduler, @@ -142,9 +141,9 @@ internal fun WriteRoute( onBackClick() } - BackHandler(enabled = bottomSheetState.isVisible) { + BackHandler(enabled = bottomSheetState.bottomSheetState.isVisible) { coroutineScope.launch { - bottomSheetState.hide() + bottomSheetState.bottomSheetState.hide() } } @@ -196,7 +195,7 @@ internal fun WriteRoute( }, processedImages = processedImages, navigateToCategory = { - coroutineScope.launch { bottomSheetState.show() } + coroutineScope.launch { bottomSheetState.bottomSheetState.expand() } }, categoryMenus = categoryMenus, category = selectedCategory, @@ -219,14 +218,14 @@ internal fun WriteRoute( } } -@OptIn(ExperimentalMaterialApi::class) +@OptIn(ExperimentalMaterial3Api::class) @Composable private fun CategoryBottomSheetDialog( categoryMenus: List, onCategorySelected: (CategoryMenu, Int) -> Unit, selectedCategory: Pair, coroutineScope: CoroutineScope, - bottomSheetState: ModalBottomSheetState + bottomSheetState: BottomSheetScaffoldState ) { BottomSheetDialog( @@ -246,7 +245,7 @@ private fun CategoryBottomSheetDialog( normalColor = Gray2_767B83, checkedColor = Primary_23C882, checkedButtonIndex = selectedCategory.second, - closeButtonAction = { coroutineScope.launch { bottomSheetState.hide() } } + closeButtonAction = { coroutineScope.launch { bottomSheetState.bottomSheetState.hide() } } ) } diff --git a/presentation/src/main/java/daily/dayo/presentation/view/FeedPostView.kt b/presentation/src/main/java/daily/dayo/presentation/view/FeedPostView.kt index 20aeb6c0..527e61ec 100644 --- a/presentation/src/main/java/daily/dayo/presentation/view/FeedPostView.kt +++ b/presentation/src/main/java/daily/dayo/presentation/view/FeedPostView.kt @@ -24,8 +24,8 @@ import androidx.compose.foundation.pager.HorizontalPager import androidx.compose.foundation.pager.rememberPagerState import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.ExperimentalMaterialApi -import androidx.compose.material.ModalBottomSheetState +import androidx.compose.material3.BottomSheetScaffoldState +import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.SnackbarHostState @@ -80,7 +80,7 @@ import daily.dayo.presentation.viewmodel.ReportViewModel import kotlinx.coroutines.launch import java.text.DecimalFormat -@OptIn(ExperimentalMaterialApi::class) +@OptIn(ExperimentalMaterial3Api::class) @Composable fun FeedPostView( post: Post, @@ -92,7 +92,7 @@ fun FeedPostView( onClickBookmark: () -> Unit, onPostLikeUsersClick: (Long) -> Unit, onPostHashtagClick: (String) -> Unit, - bottomSheetState: ModalBottomSheetState, + bottomSheetState: BottomSheetScaffoldState, bottomSheetContent: (@Composable () -> Unit) -> Unit, reportViewModel: ReportViewModel = hiltViewModel() ) { @@ -103,14 +103,14 @@ fun FeedPostView( val context = LocalContext.current val onClickComment: (Long) -> Unit = { postId -> - coroutineScope.launch { bottomSheetState.show() } + coroutineScope.launch { bottomSheetState.bottomSheetState.expand() } bottomSheetContent { CommentBottomSheetDialog( postId = postId, sheetState = bottomSheetState, snackBarHostState = snackBarHostState, onClickProfile = onClickProfile, - onClickClose = { coroutineScope.launch { bottomSheetState.hide() } }, + onClickClose = { coroutineScope.launch { bottomSheetState.bottomSheetState.hide() } }, ) } } @@ -302,7 +302,8 @@ fun FeedPostView( val dec = DecimalFormat("#,###") Row(modifier = Modifier.weight(1f)) { Text(text = stringResource(id = R.string.post_like_count_message_1), style = DayoTheme.typography.caption1.copy(Gray2_767B83)) - Text(text = " ${dec.format(post.heartCount)} ", + Text( + text = " ${dec.format(post.heartCount)} ", style = DayoTheme.typography.caption1, modifier = if (post.heartCount != 0) Modifier.clickableSingle { post.postId?.let { onPostLikeUsersClick(it) } } else Modifier, color = if (post.heartCount != 0) Primary_23C882 else Gray4_C5CAD2) diff --git a/presentation/src/main/java/daily/dayo/presentation/view/dialog/BottomSheetDialog.kt b/presentation/src/main/java/daily/dayo/presentation/view/dialog/BottomSheetDialog.kt index 0bd45a55..041ed2c1 100644 --- a/presentation/src/main/java/daily/dayo/presentation/view/dialog/BottomSheetDialog.kt +++ b/presentation/src/main/java/daily/dayo/presentation/view/dialog/BottomSheetDialog.kt @@ -19,18 +19,17 @@ import androidx.compose.foundation.layout.wrapContentSize import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.Button import androidx.compose.material.Divider -import androidx.compose.material.ExperimentalMaterialApi -import androidx.compose.material.ModalBottomSheetLayout -import androidx.compose.material.ModalBottomSheetState -import androidx.compose.material.ModalBottomSheetValue import androidx.compose.material.Text import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Image import androidx.compose.material.icons.filled.ImageSearch -import androidx.compose.material.rememberModalBottomSheetState +import androidx.compose.material3.BottomSheetScaffoldState import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon +import androidx.compose.material3.SheetValue import androidx.compose.material3.Surface +import androidx.compose.material3.rememberBottomSheetScaffoldState +import androidx.compose.material3.rememberStandardBottomSheetState import androidx.compose.runtime.Composable import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope @@ -56,10 +55,10 @@ import kotlinx.coroutines.launch // 3. 가운데 정렬과 좌측 정렬 설정 // 4. 좌측 정렬하는 경우 좌측과 우측에 아이콘 존재 가능. -@OptIn(ExperimentalMaterialApi::class, ExperimentalMaterial3Api::class) +@OptIn(ExperimentalMaterial3Api::class) @Composable fun BottomSheetDialog( - sheetState: ModalBottomSheetState, + sheetState: BottomSheetScaffoldState, buttons: List Unit>>, leftIconButtons: List? = null, leftIconCheckedButtons: List? = null, @@ -72,144 +71,143 @@ fun BottomSheetDialog( checkedButtonIndex: Int = -1, closeButtonAction: (() -> Unit)? = null ) { - ModalBottomSheetLayout( - sheetState = sheetState, - sheetShape = RoundedCornerShape(12.dp, 12.dp, 0.dp, 0.dp), - sheetContent = { - Surface( - modifier = Modifier - .fillMaxWidth() - .wrapContentHeight() - ) { - Column( + Surface( + modifier = Modifier + .fillMaxWidth() + .wrapContentHeight(), + shape = RoundedCornerShape(12.dp, 12.dp, 0.dp, 0.dp), + color = White_FFFFFF + ) { + Column( + modifier = Modifier + .fillMaxWidth() + .wrapContentHeight() + ) { + Spacer(modifier = Modifier.height(2.dp)) + if (title.isNotEmpty()) { + Box( modifier = Modifier .fillMaxWidth() .wrapContentHeight() + .background(DayoTheme.colorScheme.background) ) { - Spacer(modifier = Modifier.height(2.dp)) - if (title.isNotEmpty()) { - Box( + Text( + text = title, + modifier = Modifier + .fillMaxWidth() + .wrapContentHeight() + .padding(12.dp), + textAlign = TextAlign.Center, + color = Dark, + style = DayoTheme.typography.b1 + ) + androidx.compose.material3.IconButton( + onClick = titleButtonAction, + modifier = Modifier + .align(Alignment.CenterEnd) + .wrapContentSize() + ) { + Icon( + imageVector = ImageVector.vectorResource(id = R.drawable.ic_x_sign), modifier = Modifier - .fillMaxWidth() - .wrapContentHeight() - .background(DayoTheme.colorScheme.background) - ) { - Text( - text = title, - modifier = Modifier - .fillMaxWidth() - .wrapContentHeight() - .padding(12.dp), - textAlign = TextAlign.Center, - color = Dark, - style = DayoTheme.typography.b1 - ) - androidx.compose.material3.IconButton( - onClick = titleButtonAction, - modifier = Modifier - .align(Alignment.CenterEnd) - .wrapContentSize() - ) { - Icon( - imageVector = ImageVector.vectorResource(id = R.drawable.ic_x_sign), - modifier = Modifier - .padding(12.dp) - .wrapContentSize() - .align(Alignment.CenterEnd) - .clickable(onClick = closeButtonAction ?: { }), - contentDescription = "x sign", - ) - } - } + .padding(12.dp) + .wrapContentSize() + .align(Alignment.CenterEnd) + .clickable(onClick = closeButtonAction ?: { }), + contentDescription = "x sign", + ) } + } + } - buttons.forEachIndexed { index, button -> - val interactionSource = remember { MutableInteractionSource() } - val isPressed = interactionSource.collectIsPressedAsState().value + buttons.forEachIndexed { index, button -> + val interactionSource = remember { MutableInteractionSource() } + val isPressed = interactionSource.collectIsPressedAsState().value - Row( - modifier = Modifier - .fillMaxWidth() - .wrapContentHeight() - .background( - if (isPressed) Gray6_F0F1F3 else White_FFFFFF, - RoundedCornerShape(12.dp, 12.dp, 0.dp, 0.dp) - ) - .padding(if (leftIconButtons == null) 16.dp else 12.dp) - .clickable( - onClick = button.second, - interactionSource = interactionSource, - indication = null - ), - horizontalArrangement = if (leftIconButtons == null) Arrangement.Center else Arrangement.SpaceBetween, - ) { - if (leftIconButtons != null && leftIconCheckedButtons != null) { - Icon( - imageVector = if (checkedButtonIndex == index) leftIconCheckedButtons[index] else leftIconButtons[index], - contentDescription = "", - modifier = Modifier.align(Alignment.CenterVertically), - tint = Color.Unspecified - ) - } - Text( - text = button.first, - modifier = Modifier.offset( - if (leftIconButtons == null) 0.dp else 8.dp, - 0.dp - ), - color = if ((isFirstButtonColored && index == 0) || (checkedButtonIndex == index)) checkedColor else normalColor, - fontSize = 16.sp, - style = DayoTheme.typography.b4 - ) - if (leftIconButtons != null) { - Spacer(modifier = Modifier.weight(1f)) - if (checkedButtonIndex == index) { - Icon( - imageVector = rightIcon, - contentDescription = "", - modifier = Modifier.align(Alignment.CenterVertically), - tint = Color.Unspecified - ) - } - } - } - if (index < buttons.size - 1 && title.isEmpty()) { - Divider( - modifier = Modifier - .fillMaxWidth() - .wrapContentHeight() - .padding(0.dp), - color = Gray6_F0F1F3 + Row( + modifier = Modifier + .fillMaxWidth() + .wrapContentHeight() + .background( + if (isPressed) Gray6_F0F1F3 else White_FFFFFF, + RoundedCornerShape(12.dp, 12.dp, 0.dp, 0.dp) + ) + .padding(if (leftIconButtons == null) 16.dp else 12.dp) + .clickable( + onClick = button.second, + interactionSource = interactionSource, + indication = null + ), + horizontalArrangement = if (leftIconButtons == null) Arrangement.Center else Arrangement.SpaceBetween, + ) { + if (leftIconButtons != null && leftIconCheckedButtons != null) { + Icon( + imageVector = if (checkedButtonIndex == index) leftIconCheckedButtons[index] else leftIconButtons[index], + contentDescription = "", + modifier = Modifier.align(Alignment.CenterVertically), + tint = Color.Unspecified + ) + } + Text( + text = button.first, + modifier = Modifier.offset( + if (leftIconButtons == null) 0.dp else 8.dp, + 0.dp + ), + color = if ((isFirstButtonColored && index == 0) || (checkedButtonIndex == index)) checkedColor else normalColor, + fontSize = 16.sp, + style = DayoTheme.typography.b4 + ) + if (leftIconButtons != null) { + Spacer(modifier = Modifier.weight(1f)) + if (checkedButtonIndex == index) { + Icon( + imageVector = rightIcon, + contentDescription = "", + modifier = Modifier.align(Alignment.CenterVertically), + tint = Color.Unspecified ) } } } + if (index < buttons.size - 1 && title.isEmpty()) { + Divider( + modifier = Modifier + .fillMaxWidth() + .wrapContentHeight() + .padding(0.dp), + color = Gray6_F0F1F3 + ) + } } } - ) { } + } } -@OptIn(ExperimentalMaterialApi::class) +@OptIn(ExperimentalMaterial3Api::class) @Composable fun getBottomSheetDialogState( disableFullExpanded: Boolean = false, - skipHalfExpanded: Boolean = true -): ModalBottomSheetState { - val bottomSheetState = rememberModalBottomSheetState( - initialValue = ModalBottomSheetValue.Hidden, + skipHiddenState: Boolean = false +): BottomSheetScaffoldState { + val bottomSheetState = rememberStandardBottomSheetState( + initialValue = SheetValue.Hidden, confirmValueChange = { - if (disableFullExpanded) - it != ModalBottomSheetValue.Expanded - else + if (disableFullExpanded) { + it != SheetValue.Expanded + } else { true + } }, - skipHalfExpanded = skipHalfExpanded + skipHiddenState = skipHiddenState ) - return bottomSheetState + return rememberBottomSheetScaffoldState( + bottomSheetState = bottomSheetState + ) } -@OptIn(ExperimentalMaterialApi::class) +@OptIn(ExperimentalMaterial3Api::class) @Preview @Composable fun PreviewMyBottomSheetDialog() { @@ -231,25 +229,25 @@ fun PreviewMyBottomSheetDialog() { // 구현 본문 내용 // BottomSheetDialog를 보여주는 경우 클릭하는 Button - Button(onClick = { coroutineScope.launch { bottomSheetState1.show() } }) { + Button(onClick = { coroutineScope.launch { bottomSheetState1.bottomSheetState.expand() } }) { Text(text = "Bottom Sheet Dialog / buton 1 / non-primary") } - Button(onClick = { coroutineScope.launch { bottomSheetState2.show() } }) { + Button(onClick = { coroutineScope.launch { bottomSheetState2.bottomSheetState.expand() } }) { Text(text = "Bottom Sheet Dialog / buton 1 / primary") } - Button(onClick = { coroutineScope.launch { bottomSheetState3.show() } }) { + Button(onClick = { coroutineScope.launch { bottomSheetState3.bottomSheetState.expand() } }) { Text(text = "Bottom Sheet Dialog / buton 2 / non-primary") } - Button(onClick = { coroutineScope.launch { bottomSheetState4.show() } }) { + Button(onClick = { coroutineScope.launch { bottomSheetState4.bottomSheetState.expand() } }) { Text(text = "Bottom Sheet Dialog / buton 2 / primary") } - Button(onClick = { coroutineScope.launch { bottomSheetState5.show() } }) { + Button(onClick = { coroutineScope.launch { bottomSheetState5.bottomSheetState.expand() } }) { Text(text = "Bottom Sheet Dialog / buton 3 / non-primary") } - Button(onClick = { coroutineScope.launch { bottomSheetState6.show() } }) { + Button(onClick = { coroutineScope.launch { bottomSheetState6.bottomSheetState.expand() } }) { Text(text = "Bottom Sheet Dialog / buton 3 / primary") } - Button(onClick = { coroutineScope.launch { bottomSheetState7.show() } }) { + Button(onClick = { coroutineScope.launch { bottomSheetState7.bottomSheetState.expand() } }) { Text(text = "Bottom Sheet Dialog / Category") } } diff --git a/presentation/src/main/java/daily/dayo/presentation/view/dialog/CommentBottomSheetDialog.kt b/presentation/src/main/java/daily/dayo/presentation/view/dialog/CommentBottomSheetDialog.kt index ab8ec7f1..91b30945 100644 --- a/presentation/src/main/java/daily/dayo/presentation/view/dialog/CommentBottomSheetDialog.kt +++ b/presentation/src/main/java/daily/dayo/presentation/view/dialog/CommentBottomSheetDialog.kt @@ -10,11 +10,12 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.wrapContentHeight import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.ModalBottomSheetLayout -import androidx.compose.material.ModalBottomSheetState -import androidx.compose.material.ModalBottomSheetValue import androidx.compose.material.Text +import androidx.compose.material3.BottomSheetScaffoldState +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.SheetValue import androidx.compose.material3.SnackbarHostState +import androidx.compose.material3.Surface import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.SideEffect @@ -48,6 +49,7 @@ import daily.dayo.presentation.common.Event import daily.dayo.presentation.common.Status import daily.dayo.presentation.theme.Dark import daily.dayo.presentation.theme.DayoTheme +import daily.dayo.presentation.theme.White_FFFFFF import daily.dayo.presentation.view.CommentListView import daily.dayo.presentation.view.CommentMentionSearchView import daily.dayo.presentation.view.CommentReplyDescriptionView @@ -59,10 +61,11 @@ import daily.dayo.presentation.viewmodel.ReportViewModel import daily.dayo.presentation.viewmodel.SearchViewModel import kotlinx.coroutines.launch +@OptIn(ExperimentalMaterial3Api::class) @Composable fun CommentBottomSheetDialog( postId: Long, - sheetState: ModalBottomSheetState, + sheetState: BottomSheetScaffoldState, snackBarHostState: SnackbarHostState, onClickProfile: (String) -> Unit, onClickClose: () -> Unit, @@ -176,65 +179,64 @@ fun CommentBottomSheetDialog( postViewModel.requestPostComment(postId) } - BackHandler(enabled = sheetState.isVisible) { + BackHandler(enabled = sheetState.bottomSheetState.isVisible) { coroutineScope.launch { clearComment() - sheetState.hide() + sheetState.bottomSheetState.hide() } } - LaunchedEffect(sheetState.currentValue) { - if (sheetState.currentValue == ModalBottomSheetValue.Hidden) { + LaunchedEffect(sheetState.bottomSheetState.currentValue) { + if (sheetState.bottomSheetState.currentValue == SheetValue.Hidden) { keyboardController?.hide() } } - ModalBottomSheetLayout( - sheetState = sheetState, - sheetShape = RoundedCornerShape(12.dp, 12.dp, 0.dp, 0.dp), + Surface( modifier = modifier, - sheetContent = { - Box( + shape = RoundedCornerShape(12.dp, 12.dp, 0.dp, 0.dp), + color = White_FFFFFF + ) { + Box( + modifier = Modifier + .fillMaxWidth() + .wrapContentHeight() + ) { + Column( modifier = Modifier .fillMaxWidth() - .wrapContentHeight() + .padding(top = 12.dp, bottom = 65.dp) + .wrapContentHeight(), ) { - Column( - modifier = Modifier - .fillMaxWidth() - .padding(top = 12.dp, bottom = 65.dp) - .wrapContentHeight(), - ) { - CommentBottomSheetDialogTitle(clearComment, onClickClose) - CommentBottomSheetDialogContent( - currentMemberId = currentMemberId, - postComments = when (postComments.value?.status) { - Status.SUCCESS -> postComments.value?.data ?: DEFAULT_COMMENTS - else -> DEFAULT_COMMENTS - }, - onClickCommentProfile = onClickCommentProfile, - onClickReply = onClickReply, - onClickDelete = onClickDelete, - onClickReport = onClickReport - ) - } + CommentBottomSheetDialogTitle(clearComment, onClickClose) + CommentBottomSheetDialogContent( + currentMemberId = currentMemberId, + postComments = when (postComments.value?.status) { + Status.SUCCESS -> postComments.value?.data ?: DEFAULT_COMMENTS + else -> DEFAULT_COMMENTS + }, + onClickCommentProfile = onClickCommentProfile, + onClickReply = onClickReply, + onClickDelete = onClickDelete, + onClickReport = onClickReport + ) + } - Column(modifier = Modifier.align(Alignment.BottomCenter)) { - if (showMentionSearchView.value) CommentMentionSearchView(userResults, onClickFollowUser) - if (replyCommentState.value != null) CommentReplyDescriptionView(replyCommentState, onClickCancelReply) - CommentTextField( - enabled = commentEnabled, - commentText = commentText, - replyCommentState = replyCommentState, - userSearchKeyword = userSearchKeyword, - showMentionSearchView = showMentionSearchView, - focusRequester = commentFocusRequester, - onClickPostComment = onClickPostComment - ) - } + Column(modifier = Modifier.align(Alignment.BottomCenter)) { + if (showMentionSearchView.value) CommentMentionSearchView(userResults, onClickFollowUser) + if (replyCommentState.value != null) CommentReplyDescriptionView(replyCommentState, onClickCancelReply) + CommentTextField( + enabled = commentEnabled, + commentText = commentText, + replyCommentState = replyCommentState, + userSearchKeyword = userSearchKeyword, + showMentionSearchView = showMentionSearchView, + focusRequester = commentFocusRequester, + onClickPostComment = onClickPostComment + ) } } - ) { + reportCommentId?.let { commentId -> if (showReportDialog) { CommentReportDialog( diff --git a/presentation/src/main/java/daily/dayo/presentation/view/dialog/ProfileImageBottomSheetDialog.kt b/presentation/src/main/java/daily/dayo/presentation/view/dialog/ProfileImageBottomSheetDialog.kt index c5781208..37877d63 100644 --- a/presentation/src/main/java/daily/dayo/presentation/view/dialog/ProfileImageBottomSheetDialog.kt +++ b/presentation/src/main/java/daily/dayo/presentation/view/dialog/ProfileImageBottomSheetDialog.kt @@ -1,15 +1,15 @@ package daily.dayo.presentation.view.dialog -import androidx.compose.material.ExperimentalMaterialApi -import androidx.compose.material.ModalBottomSheetState +import androidx.compose.material3.BottomSheetScaffoldState +import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.runtime.Composable import androidx.compose.ui.res.stringResource import daily.dayo.presentation.R -@OptIn(ExperimentalMaterialApi::class) +@OptIn(ExperimentalMaterial3Api::class) @Composable fun ProfileImageBottomSheetDialog( - bottomSheetState: ModalBottomSheetState, + bottomSheetState: BottomSheetScaffoldState, onClickProfileSelect: () -> Unit, onClickProfileCapture: () -> Unit, onClickProfileReset: () -> Unit,