From 2fa03a0a32041c4a02b5c844747a2012257440dc Mon Sep 17 00:00:00 2001 From: yunsehwan Date: Sat, 26 Jul 2025 17:06:02 +0900 Subject: [PATCH 01/11] =?UTF-8?q?FEAT:=20=ED=99=88,=20=EC=B6=94=EC=B2=9C?= =?UTF-8?q?=20=EB=A3=A8=ED=8B=B4,=20=EB=A7=88=EC=9D=B4=ED=8E=98=EC=9D=B4?= =?UTF-8?q?=EC=A7=80=20=EB=B0=94=ED=85=80=20=EB=84=A4=EC=9D=B4=EA=B2=8C?= =?UTF-8?q?=EC=9D=B4=EC=85=98=20=EC=B4=88=EC=95=88=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/threegap/bitnagil/MainNavHost.kt | 4 +- .../home/HomeBottomNavigationBar.kt | 138 ++++++++++++++++++ .../bitnagil/navigation/home/HomeNavHost.kt | 38 +++++ .../bitnagil/navigation/home/HomeNavigator.kt | 17 +++ .../navigation/home/HomeNavigatorRoot.kt | 25 ++++ .../bitnagil/navigation/home/Route.kt | 15 ++ app/src/main/res/drawable/ic_home_empty.xml | 13 ++ app/src/main/res/drawable/ic_home_fill.xml | 13 ++ app/src/main/res/drawable/ic_mypage_empty.xml | 9 ++ app/src/main/res/drawable/ic_mypage_fill.xml | 13 ++ .../main/res/drawable/ic_recommend_empty.xml | 17 +++ .../main/res/drawable/ic_recommend_fill.xml | 30 ++++ app/src/main/res/drawable/ic_report_empty.xml | 18 +++ app/src/main/res/drawable/ic_report_fill.xml | 13 ++ 14 files changed, 361 insertions(+), 2 deletions(-) create mode 100644 app/src/main/java/com/threegap/bitnagil/navigation/home/HomeBottomNavigationBar.kt create mode 100644 app/src/main/java/com/threegap/bitnagil/navigation/home/HomeNavHost.kt create mode 100644 app/src/main/java/com/threegap/bitnagil/navigation/home/HomeNavigator.kt create mode 100644 app/src/main/java/com/threegap/bitnagil/navigation/home/HomeNavigatorRoot.kt create mode 100644 app/src/main/java/com/threegap/bitnagil/navigation/home/Route.kt create mode 100644 app/src/main/res/drawable/ic_home_empty.xml create mode 100644 app/src/main/res/drawable/ic_home_fill.xml create mode 100644 app/src/main/res/drawable/ic_mypage_empty.xml create mode 100644 app/src/main/res/drawable/ic_mypage_fill.xml create mode 100644 app/src/main/res/drawable/ic_recommend_empty.xml create mode 100644 app/src/main/res/drawable/ic_recommend_fill.xml create mode 100644 app/src/main/res/drawable/ic_report_empty.xml create mode 100644 app/src/main/res/drawable/ic_report_fill.xml diff --git a/app/src/main/java/com/threegap/bitnagil/MainNavHost.kt b/app/src/main/java/com/threegap/bitnagil/MainNavHost.kt index 79ac64fd..56f3522b 100644 --- a/app/src/main/java/com/threegap/bitnagil/MainNavHost.kt +++ b/app/src/main/java/com/threegap/bitnagil/MainNavHost.kt @@ -5,7 +5,7 @@ import androidx.compose.ui.Modifier import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable import androidx.navigation.toRoute -import com.threegap.bitnagil.presentation.home.HomeScreenContainer +import com.threegap.bitnagil.navigation.home.HomeNavigatorRoot import com.threegap.bitnagil.presentation.intro.IntroScreenContainer import com.threegap.bitnagil.presentation.login.LoginScreenContainer import com.threegap.bitnagil.presentation.splash.SplashScreenContainer @@ -66,7 +66,7 @@ fun MainNavHost( } composable { - HomeScreenContainer() + HomeNavigatorRoot() } composable { diff --git a/app/src/main/java/com/threegap/bitnagil/navigation/home/HomeBottomNavigationBar.kt b/app/src/main/java/com/threegap/bitnagil/navigation/home/HomeBottomNavigationBar.kt new file mode 100644 index 00000000..c57abdd1 --- /dev/null +++ b/app/src/main/java/com/threegap/bitnagil/navigation/home/HomeBottomNavigationBar.kt @@ -0,0 +1,138 @@ +package com.threegap.bitnagil.navigation.home + +import androidx.compose.foundation.Image +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.foundation.interaction.collectIsPressedAsState +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +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.graphics.ColorFilter +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import androidx.navigation.NavController +import com.threegap.bitnagil.R +import com.threegap.bitnagil.designsystem.BitnagilTheme + +@Composable +fun HomeBottomNavigationBar( + navController: NavController, +) { + var currentSelectedRoute : HomeRoute by remember { mutableStateOf(HomeRoute.Home) } + + Row( + modifier = Modifier + .fillMaxWidth() + .background(color = BitnagilTheme.colors.white) + .padding(horizontal = 16.dp, vertical = 7.dp), + horizontalArrangement = Arrangement.spacedBy(12.dp) + ) { + HomeBottomNavigationItem( + modifier = Modifier.weight(1f), + selectIconResourceId = R.drawable.ic_home_fill, + unSelectIconResourceId = R.drawable.ic_home_empty, + title = "홈", + onClick = { + navController.navigate(HomeRoute.Home) { + currentSelectedRoute = HomeRoute.Home + popUpTo(navController.graph.startDestinationId) { inclusive = true } + } + }, + selected = currentSelectedRoute == HomeRoute.Home + ) + + HomeBottomNavigationItem( + modifier = Modifier.weight(1f), + selectIconResourceId = R.drawable.ic_recommend_fill, + unSelectIconResourceId = R.drawable.ic_recommend_empty, + title = "추천 루틴", + onClick = { + navController.navigate(HomeRoute.RecommendRoutine) { + currentSelectedRoute = HomeRoute.RecommendRoutine + popUpTo(navController.graph.startDestinationId) { inclusive = true } + } + }, + selected = currentSelectedRoute == HomeRoute.RecommendRoutine + ) + + HomeBottomNavigationItem( + modifier = Modifier.weight(1f), + selectIconResourceId = R.drawable.ic_mypage_fill, + unSelectIconResourceId = R.drawable.ic_mypage_empty, + title = "마이페이지", + onClick = { + navController.navigate(HomeRoute.MyPage) { + currentSelectedRoute = HomeRoute.MyPage + popUpTo(navController.graph.startDestinationId) { inclusive = true } + } + }, + selected = currentSelectedRoute == HomeRoute.MyPage + ) + } +} + +@Composable +private fun HomeBottomNavigationItem( + modifier: Modifier = Modifier, + selectIconResourceId: Int, + unSelectIconResourceId: Int, + title: String, + onClick: () -> Unit, + selected: Boolean, +) { + val interactionSource = remember { MutableInteractionSource() } + val isPressed by interactionSource.collectIsPressedAsState() + + val contentTintColor = when { + isPressed -> BitnagilTheme.colors.navy300 + selected -> BitnagilTheme.colors.navy500 + else -> BitnagilTheme.colors.navy100 + } + val iconResourceId = if (selected) selectIconResourceId else unSelectIconResourceId + + Column( + modifier = modifier.clickable( + onClick = onClick, + interactionSource = interactionSource, + indication = null, + ), + horizontalAlignment = Alignment.CenterHorizontally + ) { + Image( + painter = painterResource(id = iconResourceId), + contentDescription = title, + modifier = Modifier.padding(4.dp).size(24.dp), + colorFilter = ColorFilter.tint(color = contentTintColor) + ) + + Text( + text = title, + style = BitnagilTheme.typography.caption2Medium, + color = contentTintColor + ) + } +} + +@Composable +@Preview +private fun HomeBottomNavigationBarPreview() { + val navigator = rememberHomeNavigator() + + HomeBottomNavigationBar( + navController = navigator.navController, + + ) +} diff --git a/app/src/main/java/com/threegap/bitnagil/navigation/home/HomeNavHost.kt b/app/src/main/java/com/threegap/bitnagil/navigation/home/HomeNavHost.kt new file mode 100644 index 00000000..52e8921c --- /dev/null +++ b/app/src/main/java/com/threegap/bitnagil/navigation/home/HomeNavHost.kt @@ -0,0 +1,38 @@ +package com.threegap.bitnagil.navigation.home + +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.navigation.compose.NavHost +import androidx.navigation.compose.composable +import com.threegap.bitnagil.presentation.home.HomeScreenContainer +import com.threegap.bitnagil.presentation.mypage.MyPageScreenContainer +import com.threegap.bitnagil.presentation.recommendroutine.RecommendRoutineScreenContainer + +@Composable +fun HomeNavHost( + navigator: HomeNavigator, + modifier: Modifier = Modifier, +) { + NavHost( + navController = navigator.navController, + startDestination = navigator.startDestination, + modifier = modifier, + ) { + composable { + HomeScreenContainer() + } + + composable { + RecommendRoutineScreenContainer() + } + + composable { + MyPageScreenContainer( + navigateToSetting = {}, + navigateToOnBoarding = {}, + navigateToNotice = {}, + navigateToQnA = {} + ) + } + } +} diff --git a/app/src/main/java/com/threegap/bitnagil/navigation/home/HomeNavigator.kt b/app/src/main/java/com/threegap/bitnagil/navigation/home/HomeNavigator.kt new file mode 100644 index 00000000..ab39017c --- /dev/null +++ b/app/src/main/java/com/threegap/bitnagil/navigation/home/HomeNavigator.kt @@ -0,0 +1,17 @@ +package com.threegap.bitnagil.navigation.home + +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import androidx.navigation.NavHostController +import androidx.navigation.compose.rememberNavController + +class HomeNavigator( + val navController: NavHostController, +) { + val startDestination = HomeRoute.Home +} +@Composable +fun rememberHomeNavigator(navController: NavHostController = rememberNavController()): HomeNavigator = + remember(navController) { + HomeNavigator(navController) + } diff --git a/app/src/main/java/com/threegap/bitnagil/navigation/home/HomeNavigatorRoot.kt b/app/src/main/java/com/threegap/bitnagil/navigation/home/HomeNavigatorRoot.kt new file mode 100644 index 00000000..c8ce3c83 --- /dev/null +++ b/app/src/main/java/com/threegap/bitnagil/navigation/home/HomeNavigatorRoot.kt @@ -0,0 +1,25 @@ +package com.threegap.bitnagil.navigation.home + +import android.annotation.SuppressLint +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.material3.Scaffold +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier + +@Composable +@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter") +fun HomeNavigatorRoot() { + val homeNavigator = rememberHomeNavigator() + Scaffold( + modifier = Modifier.fillMaxSize(), + bottomBar = { + HomeBottomNavigationBar(navController = homeNavigator.navController) + }, + content = { _ -> + HomeNavHost( + modifier = Modifier.fillMaxSize(), + navigator = homeNavigator, + ) + } + ) +} diff --git a/app/src/main/java/com/threegap/bitnagil/navigation/home/Route.kt b/app/src/main/java/com/threegap/bitnagil/navigation/home/Route.kt new file mode 100644 index 00000000..6cd5b00a --- /dev/null +++ b/app/src/main/java/com/threegap/bitnagil/navigation/home/Route.kt @@ -0,0 +1,15 @@ +package com.threegap.bitnagil.navigation.home + +import kotlinx.serialization.Serializable + +@Serializable +sealed interface HomeRoute { + @Serializable + data object Home : HomeRoute + + @Serializable + data object RecommendRoutine : HomeRoute + + @Serializable + data object MyPage : HomeRoute +} diff --git a/app/src/main/res/drawable/ic_home_empty.xml b/app/src/main/res/drawable/ic_home_empty.xml new file mode 100644 index 00000000..e77d8e04 --- /dev/null +++ b/app/src/main/res/drawable/ic_home_empty.xml @@ -0,0 +1,13 @@ + + + diff --git a/app/src/main/res/drawable/ic_home_fill.xml b/app/src/main/res/drawable/ic_home_fill.xml new file mode 100644 index 00000000..aa23253e --- /dev/null +++ b/app/src/main/res/drawable/ic_home_fill.xml @@ -0,0 +1,13 @@ + + + + diff --git a/app/src/main/res/drawable/ic_mypage_empty.xml b/app/src/main/res/drawable/ic_mypage_empty.xml new file mode 100644 index 00000000..d44821c2 --- /dev/null +++ b/app/src/main/res/drawable/ic_mypage_empty.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/drawable/ic_mypage_fill.xml b/app/src/main/res/drawable/ic_mypage_fill.xml new file mode 100644 index 00000000..d338b47d --- /dev/null +++ b/app/src/main/res/drawable/ic_mypage_fill.xml @@ -0,0 +1,13 @@ + + + + diff --git a/app/src/main/res/drawable/ic_recommend_empty.xml b/app/src/main/res/drawable/ic_recommend_empty.xml new file mode 100644 index 00000000..4154f12b --- /dev/null +++ b/app/src/main/res/drawable/ic_recommend_empty.xml @@ -0,0 +1,17 @@ + + + + diff --git a/app/src/main/res/drawable/ic_recommend_fill.xml b/app/src/main/res/drawable/ic_recommend_fill.xml new file mode 100644 index 00000000..5d4b84c4 --- /dev/null +++ b/app/src/main/res/drawable/ic_recommend_fill.xml @@ -0,0 +1,30 @@ + + + + + + diff --git a/app/src/main/res/drawable/ic_report_empty.xml b/app/src/main/res/drawable/ic_report_empty.xml new file mode 100644 index 00000000..c62ec063 --- /dev/null +++ b/app/src/main/res/drawable/ic_report_empty.xml @@ -0,0 +1,18 @@ + + + + + diff --git a/app/src/main/res/drawable/ic_report_fill.xml b/app/src/main/res/drawable/ic_report_fill.xml new file mode 100644 index 00000000..afa27517 --- /dev/null +++ b/app/src/main/res/drawable/ic_report_fill.xml @@ -0,0 +1,13 @@ + + + + From c04f3498668421dd98ac0042452e3297472da7f1 Mon Sep 17 00:00:00 2001 From: yunsehwan Date: Sat, 26 Jul 2025 17:28:05 +0900 Subject: [PATCH 02/11] =?UTF-8?q?FEAT:=20=ED=99=88=20=ED=99=94=EB=A9=B4=20?= =?UTF-8?q?=EA=B4=80=EB=A0=A8=20=EB=84=A4=EB=B9=84=EA=B2=8C=EC=9D=B4?= =?UTF-8?q?=EC=85=98=20=EA=B5=AC=ED=98=84,=20=EC=98=A8=EB=B3=B4=EB=94=A9/?= =?UTF-8?q?=EB=A1=9C=EA=B7=B8=EC=9D=B8=20=ED=99=94=EB=A9=B4=EC=97=90?= =?UTF-8?q?=EC=84=9C=20=ED=99=88=20=ED=99=94=EB=A9=B4=EC=9C=BC=EB=A1=9C=20?= =?UTF-8?q?=EC=9D=B4=EB=8F=99=EC=8B=9C=20=EC=9D=B4=EC=A0=84=20=ED=99=94?= =?UTF-8?q?=EB=A9=B4=EB=93=A4=20=EC=A0=9C=EA=B1=B0=ED=95=98=EB=8F=84?= =?UTF-8?q?=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/threegap/bitnagil/MainNavHost.kt | 81 ++++++++++++++++++- .../main/java/com/threegap/bitnagil/Route.kt | 14 ++++ .../bitnagil/navigation/home/HomeNavHost.kt | 64 ++++++++++----- .../navigation/home/HomeNavigatorRoot.kt | 25 ------ .../bitnagil/presentation/home/HomeScreen.kt | 17 ++-- 5 files changed, 147 insertions(+), 54 deletions(-) delete mode 100644 app/src/main/java/com/threegap/bitnagil/navigation/home/HomeNavigatorRoot.kt diff --git a/app/src/main/java/com/threegap/bitnagil/MainNavHost.kt b/app/src/main/java/com/threegap/bitnagil/MainNavHost.kt index 56f3522b..2363bec1 100644 --- a/app/src/main/java/com/threegap/bitnagil/MainNavHost.kt +++ b/app/src/main/java/com/threegap/bitnagil/MainNavHost.kt @@ -5,12 +5,16 @@ import androidx.compose.ui.Modifier import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable import androidx.navigation.toRoute -import com.threegap.bitnagil.navigation.home.HomeNavigatorRoot +import com.threegap.bitnagil.navigation.home.HomeNavHost +import com.threegap.bitnagil.presentation.emotion.EmotionScreenContainer import com.threegap.bitnagil.presentation.intro.IntroScreenContainer import com.threegap.bitnagil.presentation.login.LoginScreenContainer +import com.threegap.bitnagil.presentation.onboarding.OnBoardingScreenContainer +import com.threegap.bitnagil.presentation.setting.SettingScreenContainer import com.threegap.bitnagil.presentation.splash.SplashScreenContainer import com.threegap.bitnagil.presentation.terms.TermsAgreementScreenContainer import com.threegap.bitnagil.presentation.webview.BitnagilWebViewScreen +import com.threegap.bitnagil.presentation.writeroutine.WriteRoutineScreenContainer @Composable fun MainNavHost( @@ -25,7 +29,13 @@ fun MainNavHost( composable { SplashScreenContainer( navigateToIntro = { navigator.navController.navigate(Route.Intro) }, - navigateToHome = { navigator.navController.navigate(Route.Home) }, + navigateToHome = { + navigator.navController.navigate(Route.Home) { + popUpTo(navigator.navController.graph.startDestinationId) { + inclusive = true + } + } + }, ) } @@ -37,7 +47,13 @@ fun MainNavHost( composable { LoginScreenContainer( - navigateToHome = { navigator.navController.navigate(Route.Home) }, + navigateToHome = { + navigator.navController.navigate(Route.Home) { + popUpTo(navigator.navController.graph.startDestinationId) { + inclusive = true + } + } + }, navigateToTermsAgreement = { navigator.navController.navigate(Route.TermsAgreement) }, ) } @@ -66,7 +82,29 @@ fun MainNavHost( } composable { - HomeNavigatorRoot() + HomeNavHost( + navigateToSetting = { + navigator.navController.navigate(Route.Setting) + }, + navigateToOnBoarding = { + navigator.navController.navigate(Route.OnBoarding) + }, + navigateToNotice = { + + }, + navigateToQnA = { + + }, + navigateToRegisterRoutine = { + navigator.navController.navigate(Route.WriteRoutine()) + }, + navigateToEditRoutine = { routineId -> + navigator.navController.navigate(Route.WriteRoutine(routineId = routineId)) + }, + navigateToEmotion = { + navigator.navController.navigate(Route.Emotion) + } + ) } composable { @@ -77,5 +115,40 @@ fun MainNavHost( onBackClick = { navigator.navController.popBackStack() }, ) } + + composable { + SettingScreenContainer() + } + + composable { + OnBoardingScreenContainer( + navigateToHome = { + navigator.navController.navigate(Route.Home) { + popUpTo(navigator.navController.graph.startDestinationId) { + inclusive = true + } + } + }, + navigateToBack = { + navigator.navController.popBackStack() + }, + ) + } + + composable { + WriteRoutineScreenContainer( + navigateToBack = { + navigator.navController.popBackStack() + }, + ) + } + + composable { + EmotionScreenContainer( + navigateToBack = { + navigator.navController.popBackStack() + }, + ) + } } } diff --git a/app/src/main/java/com/threegap/bitnagil/Route.kt b/app/src/main/java/com/threegap/bitnagil/Route.kt index 621f026e..a72076b5 100644 --- a/app/src/main/java/com/threegap/bitnagil/Route.kt +++ b/app/src/main/java/com/threegap/bitnagil/Route.kt @@ -24,4 +24,18 @@ sealed interface Route { val title: String, val url: String, ) : Route + + @Serializable + data object Setting : Route + + @Serializable + data object OnBoarding: Route + + @Serializable + data class WriteRoutine( + val routineId: String? = null, + ): Route + + @Serializable + data object Emotion: Route } diff --git a/app/src/main/java/com/threegap/bitnagil/navigation/home/HomeNavHost.kt b/app/src/main/java/com/threegap/bitnagil/navigation/home/HomeNavHost.kt index 52e8921c..49541e73 100644 --- a/app/src/main/java/com/threegap/bitnagil/navigation/home/HomeNavHost.kt +++ b/app/src/main/java/com/threegap/bitnagil/navigation/home/HomeNavHost.kt @@ -1,5 +1,8 @@ package com.threegap.bitnagil.navigation.home +import android.annotation.SuppressLint +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.material3.Scaffold import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.navigation.compose.NavHost @@ -8,31 +11,52 @@ import com.threegap.bitnagil.presentation.home.HomeScreenContainer import com.threegap.bitnagil.presentation.mypage.MyPageScreenContainer import com.threegap.bitnagil.presentation.recommendroutine.RecommendRoutineScreenContainer + @Composable +@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter") fun HomeNavHost( - navigator: HomeNavigator, modifier: Modifier = Modifier, + navigateToSetting: () -> Unit, + navigateToOnBoarding: () -> Unit, + navigateToNotice: () -> Unit, + navigateToQnA: () -> Unit, + navigateToRegisterRoutine: () -> Unit, + navigateToEditRoutine: (String) -> Unit, + navigateToEmotion: () -> Unit, ) { - NavHost( - navController = navigator.navController, - startDestination = navigator.startDestination, - modifier = modifier, - ) { - composable { - HomeScreenContainer() - } + val navigator = rememberHomeNavigator() + Scaffold( + modifier = Modifier.fillMaxSize(), + bottomBar = { + HomeBottomNavigationBar(navController = navigator.navController) + }, + content = { _ -> + NavHost( + navController = navigator.navController, + startDestination = navigator.startDestination, + modifier = modifier, + ) { + composable { + HomeScreenContainer( + navigateToRegisterRoutine = navigateToRegisterRoutine, + navigateToEditRoutine = navigateToEditRoutine, + navigateToEmotion = navigateToEmotion, + ) + } - composable { - RecommendRoutineScreenContainer() - } + composable { + RecommendRoutineScreenContainer() + } - composable { - MyPageScreenContainer( - navigateToSetting = {}, - navigateToOnBoarding = {}, - navigateToNotice = {}, - navigateToQnA = {} - ) + composable { + MyPageScreenContainer( + navigateToSetting = navigateToSetting, + navigateToOnBoarding = navigateToOnBoarding, + navigateToNotice = navigateToNotice, + navigateToQnA = navigateToQnA + ) + } + } } - } + ) } diff --git a/app/src/main/java/com/threegap/bitnagil/navigation/home/HomeNavigatorRoot.kt b/app/src/main/java/com/threegap/bitnagil/navigation/home/HomeNavigatorRoot.kt deleted file mode 100644 index c8ce3c83..00000000 --- a/app/src/main/java/com/threegap/bitnagil/navigation/home/HomeNavigatorRoot.kt +++ /dev/null @@ -1,25 +0,0 @@ -package com.threegap.bitnagil.navigation.home - -import android.annotation.SuppressLint -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.material3.Scaffold -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier - -@Composable -@SuppressLint("UnusedMaterial3ScaffoldPaddingParameter") -fun HomeNavigatorRoot() { - val homeNavigator = rememberHomeNavigator() - Scaffold( - modifier = Modifier.fillMaxSize(), - bottomBar = { - HomeBottomNavigationBar(navController = homeNavigator.navController) - }, - content = { _ -> - HomeNavHost( - modifier = Modifier.fillMaxSize(), - navigator = homeNavigator, - ) - } - ) -} diff --git a/presentation/src/main/java/com/threegap/bitnagil/presentation/home/HomeScreen.kt b/presentation/src/main/java/com/threegap/bitnagil/presentation/home/HomeScreen.kt index f0854cfe..6bd4437a 100644 --- a/presentation/src/main/java/com/threegap/bitnagil/presentation/home/HomeScreen.kt +++ b/presentation/src/main/java/com/threegap/bitnagil/presentation/home/HomeScreen.kt @@ -45,6 +45,9 @@ import java.time.LocalDate @Composable fun HomeScreenContainer( viewModel: HomeViewModel = hiltViewModel(), + navigateToRegisterRoutine: () -> Unit, + navigateToEditRoutine: (String) -> Unit, + navigateToEmotion: () -> Unit, ) { val uiState by viewModel.stateFlow.collectAsStateWithLifecycle() @@ -65,8 +68,7 @@ fun HomeScreenContainer( RoutineDetailsBottomSheet( routine = routine, onDismiss = { viewModel.sendIntent(HomeIntent.HideRoutineDetailsBottomSheet) }, - // TODO: 수정 화면으로 네비게이션 - onEdit = {}, + onEdit = navigateToEditRoutine, onDelete = { if (routine.repeatDay.isEmpty()) { viewModel.deleteRoutine(routine.routineId) @@ -117,6 +119,8 @@ fun HomeScreenContainer( onShowRoutineDetailsBottomSheet = { routine -> viewModel.sendIntent(HomeIntent.ShowRoutineDetailsBottomSheet(routine)) }, + onRegisterRoutineClick = navigateToRegisterRoutine, + onRegisterEmotionClick = navigateToEmotion ) } @@ -130,6 +134,8 @@ private fun HomeScreen( onSubRoutineCompletionToggle: (String, String, Boolean) -> Unit, onShowRoutineSortBottomSheet: () -> Unit, onShowRoutineDetailsBottomSheet: (RoutineUiModel) -> Unit, + onRegisterRoutineClick: () -> Unit, + onRegisterEmotionClick: () -> Unit, modifier: Modifier = Modifier, ) { val collapsibleHeaderState = rememberCollapsibleHeaderState() @@ -177,8 +183,7 @@ private fun HomeScreen( if (uiState.selectedDateRoutines.isEmpty()) { item { RoutineEmptyView( - // todo: 루린 등록 화면으로 네비게이션 - onRegisterRoutineClick = {}, + onRegisterRoutineClick = onRegisterRoutineClick, modifier = Modifier .fillMaxSize() .padding(top = 62.dp), @@ -242,7 +247,7 @@ private fun HomeScreen( CollapsibleHomeHeader( userName = "대현", collapsibleHeaderState = collapsibleHeaderState, - onEmotionRecordClick = {}, + onEmotionRecordClick = onRegisterEmotionClick, ) } } @@ -259,5 +264,7 @@ private fun HomeScreenPreview() { onSubRoutineCompletionToggle = { _, _, _ -> }, onShowRoutineSortBottomSheet = {}, onShowRoutineDetailsBottomSheet = {}, + onRegisterRoutineClick = {}, + onRegisterEmotionClick = {} ) } From db9cf2a7a2622e0c1d60d033d6341d6d8543c3a6 Mon Sep 17 00:00:00 2001 From: yunsehwan Date: Sat, 26 Jul 2025 17:43:34 +0900 Subject: [PATCH 03/11] =?UTF-8?q?FEAT:=20=EC=B6=94=EC=B2=9C=20=EB=A3=A8?= =?UTF-8?q?=ED=8B=B4=20=ED=99=94=EB=A9=B4=20=EA=B4=80=EB=A0=A8=20=EB=84=A4?= =?UTF-8?q?=EB=B9=84=EA=B2=8C=EC=9D=B4=EC=85=98=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/threegap/bitnagil/MainNavHost.kt | 6 +++--- app/src/main/java/com/threegap/bitnagil/Route.kt | 1 + .../threegap/bitnagil/navigation/home/HomeNavHost.kt | 11 ++++++++--- .../recommendroutine/RecommendRoutineScreen.kt | 12 ++++++++++-- .../recommendroutine/model/RecommendRoutine.kt | 1 + 5 files changed, 23 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/com/threegap/bitnagil/MainNavHost.kt b/app/src/main/java/com/threegap/bitnagil/MainNavHost.kt index 2363bec1..ac7d8e1a 100644 --- a/app/src/main/java/com/threegap/bitnagil/MainNavHost.kt +++ b/app/src/main/java/com/threegap/bitnagil/MainNavHost.kt @@ -95,11 +95,11 @@ fun MainNavHost( navigateToQnA = { }, - navigateToRegisterRoutine = { - navigator.navController.navigate(Route.WriteRoutine()) + navigateToRegisterRoutine = { routineId -> + navigator.navController.navigate(Route.WriteRoutine(routineId = routineId)) }, navigateToEditRoutine = { routineId -> - navigator.navController.navigate(Route.WriteRoutine(routineId = routineId)) + navigator.navController.navigate(Route.WriteRoutine(routineId = routineId, isRegister = false)) }, navigateToEmotion = { navigator.navController.navigate(Route.Emotion) diff --git a/app/src/main/java/com/threegap/bitnagil/Route.kt b/app/src/main/java/com/threegap/bitnagil/Route.kt index a72076b5..ac5a9abd 100644 --- a/app/src/main/java/com/threegap/bitnagil/Route.kt +++ b/app/src/main/java/com/threegap/bitnagil/Route.kt @@ -34,6 +34,7 @@ sealed interface Route { @Serializable data class WriteRoutine( val routineId: String? = null, + val isRegister: Boolean = true, ): Route @Serializable diff --git a/app/src/main/java/com/threegap/bitnagil/navigation/home/HomeNavHost.kt b/app/src/main/java/com/threegap/bitnagil/navigation/home/HomeNavHost.kt index 49541e73..7d596da5 100644 --- a/app/src/main/java/com/threegap/bitnagil/navigation/home/HomeNavHost.kt +++ b/app/src/main/java/com/threegap/bitnagil/navigation/home/HomeNavHost.kt @@ -20,7 +20,7 @@ fun HomeNavHost( navigateToOnBoarding: () -> Unit, navigateToNotice: () -> Unit, navigateToQnA: () -> Unit, - navigateToRegisterRoutine: () -> Unit, + navigateToRegisterRoutine: (String?) -> Unit, navigateToEditRoutine: (String) -> Unit, navigateToEmotion: () -> Unit, ) { @@ -38,14 +38,19 @@ fun HomeNavHost( ) { composable { HomeScreenContainer( - navigateToRegisterRoutine = navigateToRegisterRoutine, + navigateToRegisterRoutine = { + navigateToRegisterRoutine(null) + }, navigateToEditRoutine = navigateToEditRoutine, navigateToEmotion = navigateToEmotion, ) } composable { - RecommendRoutineScreenContainer() + RecommendRoutineScreenContainer( + navigateToEmotion = navigateToEmotion, + navigateToRegisterRoutine = navigateToRegisterRoutine + ) } composable { diff --git a/presentation/src/main/java/com/threegap/bitnagil/presentation/recommendroutine/RecommendRoutineScreen.kt b/presentation/src/main/java/com/threegap/bitnagil/presentation/recommendroutine/RecommendRoutineScreen.kt index a5e339b9..428a4996 100644 --- a/presentation/src/main/java/com/threegap/bitnagil/presentation/recommendroutine/RecommendRoutineScreen.kt +++ b/presentation/src/main/java/com/threegap/bitnagil/presentation/recommendroutine/RecommendRoutineScreen.kt @@ -42,6 +42,8 @@ import com.threegap.bitnagil.presentation.recommendroutine.type.RecommendRoutine @Composable fun RecommendRoutineScreenContainer( viewmodel: RecommendRoutineViewModel = hiltViewModel(), + navigateToEmotion: () -> Unit, + navigateToRegisterRoutine: (String?) -> Unit, ) { val uiState by viewmodel.container.stateFlow.collectAsStateWithLifecycle() @@ -59,6 +61,8 @@ fun RecommendRoutineScreenContainer( onHideDifficultyBottomSheet = { viewmodel.sendIntent(RecommendRoutineIntent.HideDifficultyBottomSheet) }, + onRecommendRoutineByEmotionClick = navigateToEmotion, + onRegisterRoutineClick = navigateToRegisterRoutine, ) } @@ -69,6 +73,8 @@ private fun RecommendRoutineScreen( onDifficultySelected: (RecommendRoutineDifficulty?) -> Unit, onShowDifficultyBottomSheet: () -> Unit, onHideDifficultyBottomSheet: () -> Unit, + onRecommendRoutineByEmotionClick: () -> Unit, + onRegisterRoutineClick: (String) -> Unit, ) { Column( modifier = Modifier @@ -165,7 +171,7 @@ private fun RecommendRoutineScreen( if (uiState.isDefaultCategory) { item { EmotionRecommendRoutineButton( - onClick = {}, + onClick = onRecommendRoutineByEmotionClick, ) } } @@ -176,7 +182,7 @@ private fun RecommendRoutineScreen( RecommendRoutineItem( routineName = routine.name, routineDescription = routine.description, - onAddRoutineClick = {}, + onAddRoutineClick = { onRegisterRoutineClick(routine.id) }, ) } } @@ -203,5 +209,7 @@ private fun RoutineRecommendScreenPreview() { onDifficultySelected = {}, onShowDifficultyBottomSheet = {}, onHideDifficultyBottomSheet = {}, + onRecommendRoutineByEmotionClick = {}, + onRegisterRoutineClick = {} ) } diff --git a/presentation/src/main/java/com/threegap/bitnagil/presentation/recommendroutine/model/RecommendRoutine.kt b/presentation/src/main/java/com/threegap/bitnagil/presentation/recommendroutine/model/RecommendRoutine.kt index 5140297b..cc416918 100644 --- a/presentation/src/main/java/com/threegap/bitnagil/presentation/recommendroutine/model/RecommendRoutine.kt +++ b/presentation/src/main/java/com/threegap/bitnagil/presentation/recommendroutine/model/RecommendRoutine.kt @@ -9,4 +9,5 @@ data class RecommendRoutine( val name: String, val description: String, val difficulty: RecommendRoutineDifficulty, + val id: String = "0", ) : Parcelable From 68604ecc3dc1a2a1e05f0d69f809ed85b23d9b06 Mon Sep 17 00:00:00 2001 From: yunsehwan Date: Sat, 26 Jul 2025 18:00:10 +0900 Subject: [PATCH 04/11] =?UTF-8?q?FEAT:=20=EC=84=A4=EC=A0=95=20=ED=99=94?= =?UTF-8?q?=EB=A9=B4=20=EA=B4=80=EB=A0=A8=20=EB=84=A4=EB=B9=84=EA=B2=8C?= =?UTF-8?q?=EC=9D=B4=EC=85=98=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/threegap/bitnagil/MainNavHost.kt | 26 +++++++++++++++++-- .../presentation/setting/SettingScreen.kt | 19 +++++++++++--- .../writeroutine/WriteRoutineScreen.kt | 5 +++- 3 files changed, 43 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/com/threegap/bitnagil/MainNavHost.kt b/app/src/main/java/com/threegap/bitnagil/MainNavHost.kt index ac7d8e1a..fec19cf2 100644 --- a/app/src/main/java/com/threegap/bitnagil/MainNavHost.kt +++ b/app/src/main/java/com/threegap/bitnagil/MainNavHost.kt @@ -76,7 +76,9 @@ fun MainNavHost( ), ) }, - navigateToOnBoarding = { }, + navigateToOnBoarding = { + navigator.navController.navigate(Route.OnBoarding) + }, navigateToBack = { navigator.navController.popBackStack() }, ) } @@ -117,7 +119,27 @@ fun MainNavHost( } composable { - SettingScreenContainer() + SettingScreenContainer( + navigateToBack = { + navigator.navController.popBackStack() + }, + navigateToTermsOfService = { + navigator.navController.navigate( + Route.WebView( + title = "약관 동의", + url = "https://complex-wombat-99f.notion.site/2025-7-20-236f4587491d8071833adfaf8115bce2", + ), + ) + }, + navigateToPrivacyPolicy = { + navigator.navController.navigate( + Route.WebView( + title = "약관 동의", + url = "https://complex-wombat-99f.notion.site/2025-07-20-236f4587491d80308016eb810692d18b", + ), + ) + }, + ) } composable { diff --git a/presentation/src/main/java/com/threegap/bitnagil/presentation/setting/SettingScreen.kt b/presentation/src/main/java/com/threegap/bitnagil/presentation/setting/SettingScreen.kt index c20ceb5a..20ded019 100644 --- a/presentation/src/main/java/com/threegap/bitnagil/presentation/setting/SettingScreen.kt +++ b/presentation/src/main/java/com/threegap/bitnagil/presentation/setting/SettingScreen.kt @@ -34,6 +34,9 @@ import com.threegap.bitnagil.presentation.setting.model.mvi.SettingState @Composable fun SettingScreenContainer( viewModel: SettingViewModel = hiltViewModel(), + navigateToBack: () -> Unit, + navigateToTermsOfService: () -> Unit, + navigateToPrivacyPolicy: () -> Unit, ) { val state by viewModel.stateFlow.collectAsState() @@ -42,6 +45,9 @@ fun SettingScreenContainer( toggleServiceAlarm = viewModel::toggleServiceAlarm, togglePushAlarm = viewModel::togglePushAlarm, onClickUpdate = {}, + onClickBack = navigateToBack, + onClickTermsOfService = navigateToTermsOfService, + onClickPrivacyPolicy = navigateToPrivacyPolicy, ) } @@ -51,6 +57,9 @@ private fun SettingScreen( toggleServiceAlarm: () -> Unit, togglePushAlarm: () -> Unit, onClickUpdate: () -> Unit, + onClickBack: () -> Unit, + onClickTermsOfService: () -> Unit, + onClickPrivacyPolicy: () -> Unit, ) { Column( modifier = Modifier @@ -68,8 +77,7 @@ private fun SettingScreen( .size(36.dp) .background(BitnagilTheme.colors.black) .align(Alignment.CenterStart) - .clickable { - }, + .clickable(onClick = onClickBack), ) Text( @@ -159,9 +167,9 @@ private fun SettingScreen( } } - SettingRowButton(text = "서비스 이용약관", onClick = {}) + SettingRowButton(text = "서비스 이용약관", onClick = onClickTermsOfService) - SettingRowButton(text = "개인정보 처리방침", onClick = {}) + SettingRowButton(text = "개인정보 처리방침", onClick = onClickPrivacyPolicy) Spacer(modifier = Modifier.height(6.dp)) @@ -191,5 +199,8 @@ fun SettingScreenPreview() { toggleServiceAlarm = {}, togglePushAlarm = {}, onClickUpdate = {}, + onClickBack = {}, + onClickPrivacyPolicy = {}, + onClickTermsOfService = {}, ) } diff --git a/presentation/src/main/java/com/threegap/bitnagil/presentation/writeroutine/WriteRoutineScreen.kt b/presentation/src/main/java/com/threegap/bitnagil/presentation/writeroutine/WriteRoutineScreen.kt index 0109bf55..d7244244 100644 --- a/presentation/src/main/java/com/threegap/bitnagil/presentation/writeroutine/WriteRoutineScreen.kt +++ b/presentation/src/main/java/com/threegap/bitnagil/presentation/writeroutine/WriteRoutineScreen.kt @@ -79,6 +79,7 @@ fun WriteRoutineScreenContainer( showTimePickerBottomSheet = viewModel::showTimePickerBottomSheet, onClickRegister = viewModel::registerRoutine, removeSubRoutine = viewModel::removeSubRoutine, + onClickBack = navigateToBack ) } @@ -94,6 +95,7 @@ private fun WriteRoutineScreen( showTimePickerBottomSheet: () -> Unit, onClickRegister: () -> Unit, removeSubRoutine: (Int) -> Unit, + onClickBack: () -> Unit, ) { val scrollState = rememberScrollState() @@ -110,7 +112,7 @@ private fun WriteRoutineScreen( .padding(start = 4.dp) .align(alignment = Alignment.CenterStart) .size(36.dp) - .clickable { }, + .clickable(onClick = onClickBack), contentAlignment = Alignment.Center, ) { Image( @@ -415,6 +417,7 @@ fun WriteRoutineScreenPreview() { showTimePickerBottomSheet = {}, onClickRegister = {}, removeSubRoutine = {}, + onClickBack = {}, ) } } From a27868a56bd16baffa43456b448ec735b02abefb Mon Sep 17 00:00:00 2001 From: yunsehwan Date: Sun, 27 Jul 2025 15:54:22 +0900 Subject: [PATCH 05/11] =?UTF-8?q?FIX:=20=ED=99=88=20=EB=B0=94=ED=85=80=20?= =?UTF-8?q?=EB=84=A4=EB=B9=84=EA=B2=8C=EC=9D=B4=EC=85=98=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EC=88=98=EC=A0=95=20=EB=B0=8F=20=EB=92=A4=EB=A1=9C?= =?UTF-8?q?=EA=B0=80=EA=B8=B0=202=EB=B2=88=20=EC=97=B0=EC=86=8D=20?= =?UTF-8?q?=ED=81=B4=EB=A6=AD=EC=8B=9C=20=EC=95=B1=20=EC=A2=85=EB=A3=8C?= =?UTF-8?q?=EB=90=98=EB=8F=84=EB=A1=9D=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../home/HomeBottomNavigationBar.kt | 26 +++++++--------- .../bitnagil/navigation/home/HomeNavHost.kt | 31 ++++++++++++++++--- .../bitnagil/navigation/home/HomeNavigator.kt | 2 +- .../bitnagil/navigation/home/Route.kt | 8 ++--- 4 files changed, 43 insertions(+), 24 deletions(-) diff --git a/app/src/main/java/com/threegap/bitnagil/navigation/home/HomeBottomNavigationBar.kt b/app/src/main/java/com/threegap/bitnagil/navigation/home/HomeBottomNavigationBar.kt index c57abdd1..6db48f67 100644 --- a/app/src/main/java/com/threegap/bitnagil/navigation/home/HomeBottomNavigationBar.kt +++ b/app/src/main/java/com/threegap/bitnagil/navigation/home/HomeBottomNavigationBar.kt @@ -14,9 +14,7 @@ import androidx.compose.foundation.layout.size import androidx.compose.material3.Text import androidx.compose.runtime.Composable 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.graphics.ColorFilter @@ -24,6 +22,7 @@ import androidx.compose.ui.res.painterResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.navigation.NavController +import androidx.navigation.compose.currentBackStackEntryAsState import com.threegap.bitnagil.R import com.threegap.bitnagil.designsystem.BitnagilTheme @@ -31,7 +30,7 @@ import com.threegap.bitnagil.designsystem.BitnagilTheme fun HomeBottomNavigationBar( navController: NavController, ) { - var currentSelectedRoute : HomeRoute by remember { mutableStateOf(HomeRoute.Home) } + val navBackStackEntry by navController.currentBackStackEntryAsState() Row( modifier = Modifier @@ -46,12 +45,11 @@ fun HomeBottomNavigationBar( unSelectIconResourceId = R.drawable.ic_home_empty, title = "홈", onClick = { - navController.navigate(HomeRoute.Home) { - currentSelectedRoute = HomeRoute.Home - popUpTo(navController.graph.startDestinationId) { inclusive = true } + navController.navigate(HomeRoute.Home.route) { + popUpTo(0) { inclusive = true } } }, - selected = currentSelectedRoute == HomeRoute.Home + selected = navBackStackEntry?.destination?.route == HomeRoute.Home.route ) HomeBottomNavigationItem( @@ -60,12 +58,11 @@ fun HomeBottomNavigationBar( unSelectIconResourceId = R.drawable.ic_recommend_empty, title = "추천 루틴", onClick = { - navController.navigate(HomeRoute.RecommendRoutine) { - currentSelectedRoute = HomeRoute.RecommendRoutine - popUpTo(navController.graph.startDestinationId) { inclusive = true } + navController.navigate(HomeRoute.RecommendRoutine.route) { + popUpTo(0) { inclusive = true } } }, - selected = currentSelectedRoute == HomeRoute.RecommendRoutine + selected = navBackStackEntry?.destination?.route == HomeRoute.RecommendRoutine.route ) HomeBottomNavigationItem( @@ -74,12 +71,11 @@ fun HomeBottomNavigationBar( unSelectIconResourceId = R.drawable.ic_mypage_empty, title = "마이페이지", onClick = { - navController.navigate(HomeRoute.MyPage) { - currentSelectedRoute = HomeRoute.MyPage - popUpTo(navController.graph.startDestinationId) { inclusive = true } + navController.navigate(HomeRoute.MyPage.route) { + popUpTo(0) { inclusive = true } } }, - selected = currentSelectedRoute == HomeRoute.MyPage + selected = navBackStackEntry?.destination?.route == HomeRoute.MyPage.route ) } } diff --git a/app/src/main/java/com/threegap/bitnagil/navigation/home/HomeNavHost.kt b/app/src/main/java/com/threegap/bitnagil/navigation/home/HomeNavHost.kt index 7d596da5..05e3ed10 100644 --- a/app/src/main/java/com/threegap/bitnagil/navigation/home/HomeNavHost.kt +++ b/app/src/main/java/com/threegap/bitnagil/navigation/home/HomeNavHost.kt @@ -1,17 +1,23 @@ package com.threegap.bitnagil.navigation.home import android.annotation.SuppressLint +import android.app.Activity +import androidx.activity.compose.BackHandler import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.material3.Scaffold import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableLongStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable import com.threegap.bitnagil.presentation.home.HomeScreenContainer import com.threegap.bitnagil.presentation.mypage.MyPageScreenContainer import com.threegap.bitnagil.presentation.recommendroutine.RecommendRoutineScreenContainer - @Composable @SuppressLint("UnusedMaterial3ScaffoldPaddingParameter") fun HomeNavHost( @@ -25,6 +31,9 @@ fun HomeNavHost( navigateToEmotion: () -> Unit, ) { val navigator = rememberHomeNavigator() + + DoubleBackButtonPressedHandler() + Scaffold( modifier = Modifier.fillMaxSize(), bottomBar = { @@ -36,7 +45,7 @@ fun HomeNavHost( startDestination = navigator.startDestination, modifier = modifier, ) { - composable { + composable(HomeRoute.Home.route) { HomeScreenContainer( navigateToRegisterRoutine = { navigateToRegisterRoutine(null) @@ -46,14 +55,14 @@ fun HomeNavHost( ) } - composable { + composable(HomeRoute.RecommendRoutine.route) { RecommendRoutineScreenContainer( navigateToEmotion = navigateToEmotion, navigateToRegisterRoutine = navigateToRegisterRoutine ) } - composable { + composable(HomeRoute.MyPage.route) { MyPageScreenContainer( navigateToSetting = navigateToSetting, navigateToOnBoarding = navigateToOnBoarding, @@ -65,3 +74,17 @@ fun HomeNavHost( } ) } + +@Composable +fun DoubleBackButtonPressedHandler() { + val context = LocalContext.current + var backPressedTimeMillis by remember { mutableLongStateOf(0L) } + BackHandler { + if (System.currentTimeMillis() - backPressedTimeMillis < 2000) { + backPressedTimeMillis = 0 + (context as? Activity)?.finish() + } else { + backPressedTimeMillis = System.currentTimeMillis() + } + } +} diff --git a/app/src/main/java/com/threegap/bitnagil/navigation/home/HomeNavigator.kt b/app/src/main/java/com/threegap/bitnagil/navigation/home/HomeNavigator.kt index ab39017c..c5403ec7 100644 --- a/app/src/main/java/com/threegap/bitnagil/navigation/home/HomeNavigator.kt +++ b/app/src/main/java/com/threegap/bitnagil/navigation/home/HomeNavigator.kt @@ -8,7 +8,7 @@ import androidx.navigation.compose.rememberNavController class HomeNavigator( val navController: NavHostController, ) { - val startDestination = HomeRoute.Home + val startDestination = HomeRoute.Home.route } @Composable fun rememberHomeNavigator(navController: NavHostController = rememberNavController()): HomeNavigator = diff --git a/app/src/main/java/com/threegap/bitnagil/navigation/home/Route.kt b/app/src/main/java/com/threegap/bitnagil/navigation/home/Route.kt index 6cd5b00a..32aa4b84 100644 --- a/app/src/main/java/com/threegap/bitnagil/navigation/home/Route.kt +++ b/app/src/main/java/com/threegap/bitnagil/navigation/home/Route.kt @@ -3,13 +3,13 @@ package com.threegap.bitnagil.navigation.home import kotlinx.serialization.Serializable @Serializable -sealed interface HomeRoute { +sealed class HomeRoute(val route: String) { @Serializable - data object Home : HomeRoute + data object Home : HomeRoute("home/home") @Serializable - data object RecommendRoutine : HomeRoute + data object RecommendRoutine : HomeRoute("home/recommend_routine") @Serializable - data object MyPage : HomeRoute + data object MyPage : HomeRoute("home/my_page") } From 28cca43d9509f72adc5822ac62cabe8a40ddbb86 Mon Sep 17 00:00:00 2001 From: yunsehwan Date: Sun, 27 Jul 2025 16:35:40 +0900 Subject: [PATCH 06/11] =?UTF-8?q?FEATURE:=20=EC=84=A4=EC=A0=95=20=ED=99=94?= =?UTF-8?q?=EB=A9=B4=EC=97=90=EC=84=9C=20=EB=A1=9C=EA=B7=B8=EC=95=84?= =?UTF-8?q?=EC=9B=83/=ED=9A=8C=EC=9B=90=ED=83=88=ED=87=B4=20=EC=84=B1?= =?UTF-8?q?=EA=B3=B5=EC=8B=9C=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20=ED=99=94?= =?UTF-8?q?=EB=A9=B4=20=EC=9D=B4=EB=8F=99=20=EB=A1=9C=EC=A7=81=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20=EB=B0=8F=20=EB=A1=9C=EA=B7=B8=EC=95=84=EC=9B=83/?= =?UTF-8?q?=ED=9A=8C=EC=9B=90=ED=83=88=ED=87=B4=20API=20=EC=97=B0=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/threegap/bitnagil/MainNavHost.kt | 7 +++ .../auth/datasource/AuthRemoteDataSource.kt | 4 ++ .../AuthRemoteDataSourceImpl.kt | 13 +++++ .../auth/repositoryimpl/AuthRepositoryImpl.kt | 4 ++ .../bitnagil/data/auth/service/AuthService.kt | 6 +++ .../domain/auth/repository/AuthRepository.kt | 4 ++ .../domain/auth/usecase/LogoutUseCase.kt | 10 ++++ .../domain/auth/usecase/WithdrawalUseCase.kt | 10 ++++ .../presentation/setting/SettingScreen.kt | 20 +++++++- .../presentation/setting/SettingViewModel.kt | 48 ++++++++++++++++++- .../setting/model/mvi/SettingIntent.kt | 6 +++ .../setting/model/mvi/SettingSideEffect.kt | 4 +- .../setting/model/mvi/SettingState.kt | 2 + 13 files changed, 134 insertions(+), 4 deletions(-) create mode 100644 domain/src/main/java/com/threegap/bitnagil/domain/auth/usecase/LogoutUseCase.kt create mode 100644 domain/src/main/java/com/threegap/bitnagil/domain/auth/usecase/WithdrawalUseCase.kt diff --git a/app/src/main/java/com/threegap/bitnagil/MainNavHost.kt b/app/src/main/java/com/threegap/bitnagil/MainNavHost.kt index fec19cf2..16de0346 100644 --- a/app/src/main/java/com/threegap/bitnagil/MainNavHost.kt +++ b/app/src/main/java/com/threegap/bitnagil/MainNavHost.kt @@ -139,6 +139,13 @@ fun MainNavHost( ), ) }, + navigateToLogin = { + navigator.navController.navigate(Route.Login) { + popUpTo(0) { + inclusive = true + } + } + } ) } diff --git a/data/src/main/java/com/threegap/bitnagil/data/auth/datasource/AuthRemoteDataSource.kt b/data/src/main/java/com/threegap/bitnagil/data/auth/datasource/AuthRemoteDataSource.kt index 68470af8..dd4dce44 100644 --- a/data/src/main/java/com/threegap/bitnagil/data/auth/datasource/AuthRemoteDataSource.kt +++ b/data/src/main/java/com/threegap/bitnagil/data/auth/datasource/AuthRemoteDataSource.kt @@ -8,4 +8,8 @@ interface AuthRemoteDataSource { suspend fun login(socialAccessToken: String, loginRequestDto: LoginRequestDto): Result suspend fun submitAgreement(termsAgreementRequestDto: TermsAgreementRequestDto): Result + + suspend fun logout(): Result + + suspend fun withdrawal(): Result } diff --git a/data/src/main/java/com/threegap/bitnagil/data/auth/datasourceimpl/AuthRemoteDataSourceImpl.kt b/data/src/main/java/com/threegap/bitnagil/data/auth/datasourceimpl/AuthRemoteDataSourceImpl.kt index af1fbd5d..b98bdf51 100644 --- a/data/src/main/java/com/threegap/bitnagil/data/auth/datasourceimpl/AuthRemoteDataSourceImpl.kt +++ b/data/src/main/java/com/threegap/bitnagil/data/auth/datasourceimpl/AuthRemoteDataSourceImpl.kt @@ -6,6 +6,7 @@ import com.threegap.bitnagil.data.auth.model.request.TermsAgreementRequestDto import com.threegap.bitnagil.data.auth.model.response.LoginResponseDto import com.threegap.bitnagil.data.auth.service.AuthService import com.threegap.bitnagil.data.common.safeApiCall +import com.threegap.bitnagil.data.common.safeUnitApiCall import javax.inject.Inject class AuthRemoteDataSourceImpl @Inject constructor( @@ -20,4 +21,16 @@ class AuthRemoteDataSourceImpl @Inject constructor( safeApiCall { authService.submitAgreement(termsAgreementRequestDto) } + + override suspend fun logout(): Result = + safeUnitApiCall { + authService.postLogout() + } + + + override suspend fun withdrawal(): Result = + safeUnitApiCall { + authService.postWithdrawal() + } + } diff --git a/data/src/main/java/com/threegap/bitnagil/data/auth/repositoryimpl/AuthRepositoryImpl.kt b/data/src/main/java/com/threegap/bitnagil/data/auth/repositoryimpl/AuthRepositoryImpl.kt index bcdb5110..62b9e948 100644 --- a/data/src/main/java/com/threegap/bitnagil/data/auth/repositoryimpl/AuthRepositoryImpl.kt +++ b/data/src/main/java/com/threegap/bitnagil/data/auth/repositoryimpl/AuthRepositoryImpl.kt @@ -27,4 +27,8 @@ class AuthRepositoryImpl @Inject constructor( authRemoteDataSource.submitAgreement( termsAgreement.toDto(), ) + + override suspend fun logout(): Result = authRemoteDataSource.logout() + + override suspend fun withdrawal(): Result = authRemoteDataSource.withdrawal() } diff --git a/data/src/main/java/com/threegap/bitnagil/data/auth/service/AuthService.kt b/data/src/main/java/com/threegap/bitnagil/data/auth/service/AuthService.kt index 291dac0f..2548f1c8 100644 --- a/data/src/main/java/com/threegap/bitnagil/data/auth/service/AuthService.kt +++ b/data/src/main/java/com/threegap/bitnagil/data/auth/service/AuthService.kt @@ -21,4 +21,10 @@ interface AuthService { suspend fun submitAgreement( @Body termsAgreementRequestDto: TermsAgreementRequestDto, ): BaseResponse + + @POST("/api/v1/auth/withdrawal") + suspend fun postWithdrawal(): BaseResponse + + @POST("/api/v1/auth/logout") + suspend fun postLogout(): BaseResponse } diff --git a/domain/src/main/java/com/threegap/bitnagil/domain/auth/repository/AuthRepository.kt b/domain/src/main/java/com/threegap/bitnagil/domain/auth/repository/AuthRepository.kt index 8448e86d..f872955f 100644 --- a/domain/src/main/java/com/threegap/bitnagil/domain/auth/repository/AuthRepository.kt +++ b/domain/src/main/java/com/threegap/bitnagil/domain/auth/repository/AuthRepository.kt @@ -11,4 +11,8 @@ interface AuthRepository { suspend fun updateAuthToken(accessToken: String, refreshToken: String): Result suspend fun submitAgreement(termsAgreement: TermsAgreement): Result + + suspend fun logout(): Result + + suspend fun withdrawal(): Result } diff --git a/domain/src/main/java/com/threegap/bitnagil/domain/auth/usecase/LogoutUseCase.kt b/domain/src/main/java/com/threegap/bitnagil/domain/auth/usecase/LogoutUseCase.kt new file mode 100644 index 00000000..f8893314 --- /dev/null +++ b/domain/src/main/java/com/threegap/bitnagil/domain/auth/usecase/LogoutUseCase.kt @@ -0,0 +1,10 @@ +package com.threegap.bitnagil.domain.auth.usecase + +import com.threegap.bitnagil.domain.auth.repository.AuthRepository +import javax.inject.Inject + +class LogoutUseCase @Inject constructor( + private val authRepository: AuthRepository, +) { + suspend operator fun invoke(): Result = authRepository.logout() +} diff --git a/domain/src/main/java/com/threegap/bitnagil/domain/auth/usecase/WithdrawalUseCase.kt b/domain/src/main/java/com/threegap/bitnagil/domain/auth/usecase/WithdrawalUseCase.kt new file mode 100644 index 00000000..7e96ca67 --- /dev/null +++ b/domain/src/main/java/com/threegap/bitnagil/domain/auth/usecase/WithdrawalUseCase.kt @@ -0,0 +1,10 @@ +package com.threegap.bitnagil.domain.auth.usecase + +import com.threegap.bitnagil.domain.auth.repository.AuthRepository +import javax.inject.Inject + +class WithdrawalUseCase @Inject constructor( + private val authRepository: AuthRepository, +) { + suspend operator fun invoke(): Result = authRepository.withdrawal() +} diff --git a/presentation/src/main/java/com/threegap/bitnagil/presentation/setting/SettingScreen.kt b/presentation/src/main/java/com/threegap/bitnagil/presentation/setting/SettingScreen.kt index 20ded019..14076953 100644 --- a/presentation/src/main/java/com/threegap/bitnagil/presentation/setting/SettingScreen.kt +++ b/presentation/src/main/java/com/threegap/bitnagil/presentation/setting/SettingScreen.kt @@ -26,9 +26,11 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel import com.threegap.bitnagil.designsystem.BitnagilTheme +import com.threegap.bitnagil.presentation.common.flow.collectAsEffect import com.threegap.bitnagil.presentation.setting.component.atom.settingtitle.SettingTitle import com.threegap.bitnagil.presentation.setting.component.atom.toggleswitch.ToggleSwitch import com.threegap.bitnagil.presentation.setting.component.block.settingrowbutton.SettingRowButton +import com.threegap.bitnagil.presentation.setting.model.mvi.SettingSideEffect import com.threegap.bitnagil.presentation.setting.model.mvi.SettingState @Composable @@ -37,9 +39,16 @@ fun SettingScreenContainer( navigateToBack: () -> Unit, navigateToTermsOfService: () -> Unit, navigateToPrivacyPolicy: () -> Unit, + navigateToLogin: () -> Unit, ) { val state by viewModel.stateFlow.collectAsState() + viewModel.sideEffectFlow.collectAsEffect { sideEffect -> + when (sideEffect) { + SettingSideEffect.NavigateToLogin -> navigateToLogin() + } + } + SettingScreen( state = state, toggleServiceAlarm = viewModel::toggleServiceAlarm, @@ -48,6 +57,8 @@ fun SettingScreenContainer( onClickBack = navigateToBack, onClickTermsOfService = navigateToTermsOfService, onClickPrivacyPolicy = navigateToPrivacyPolicy, + onClickLogout = viewModel::logout, + onClickWithdrawal = viewModel::withdrawal ) } @@ -60,6 +71,8 @@ private fun SettingScreen( onClickBack: () -> Unit, onClickTermsOfService: () -> Unit, onClickPrivacyPolicy: () -> Unit, + onClickLogout: () -> Unit, + onClickWithdrawal: () -> Unit, ) { Column( modifier = Modifier @@ -179,9 +192,9 @@ private fun SettingScreen( SettingTitle("계정") - SettingRowButton(text = "로그아웃", onClick = {}) + SettingRowButton(text = "로그아웃", onClick = onClickLogout) - SettingRowButton(text = "탈퇴하기", onClick = {}) + SettingRowButton(text = "탈퇴하기", onClick = onClickWithdrawal) } } } @@ -195,6 +208,7 @@ fun SettingScreenPreview() { usePushAlarm = false, version = "1.0.1", latestVersion = "1.0.0", + loading = false ), toggleServiceAlarm = {}, togglePushAlarm = {}, @@ -202,5 +216,7 @@ fun SettingScreenPreview() { onClickBack = {}, onClickPrivacyPolicy = {}, onClickTermsOfService = {}, + onClickLogout = {}, + onClickWithdrawal = {} ) } diff --git a/presentation/src/main/java/com/threegap/bitnagil/presentation/setting/SettingViewModel.kt b/presentation/src/main/java/com/threegap/bitnagil/presentation/setting/SettingViewModel.kt index 6146b59f..8f1131db 100644 --- a/presentation/src/main/java/com/threegap/bitnagil/presentation/setting/SettingViewModel.kt +++ b/presentation/src/main/java/com/threegap/bitnagil/presentation/setting/SettingViewModel.kt @@ -2,6 +2,8 @@ package com.threegap.bitnagil.presentation.setting import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.viewModelScope +import com.threegap.bitnagil.domain.auth.usecase.LogoutUseCase +import com.threegap.bitnagil.domain.auth.usecase.WithdrawalUseCase import com.threegap.bitnagil.presentation.common.mviviewmodel.MviViewModel import com.threegap.bitnagil.presentation.setting.model.mvi.SettingIntent import com.threegap.bitnagil.presentation.setting.model.mvi.SettingSideEffect @@ -16,6 +18,8 @@ import javax.inject.Inject @HiltViewModel class SettingViewModel @Inject constructor( savedStateHandle: SavedStateHandle, + private val logoutUseCase: LogoutUseCase, + private val withdrawalUseCase: WithdrawalUseCase, ) : MviViewModel( initState = SettingState.Init, savedStateHandle = savedStateHandle, @@ -26,7 +30,7 @@ class SettingViewModel @Inject constructor( override suspend fun SimpleSyntax.reduceState( intent: SettingIntent, state: SettingState, - ): SettingState { + ): SettingState? { when (intent) { is SettingIntent.LoadSettingSuccess -> { return state.copy( @@ -46,6 +50,26 @@ class SettingViewModel @Inject constructor( useServiceAlarm = !state.useServiceAlarm, ) } + SettingIntent.LogoutSuccess -> { + sendSideEffect(SettingSideEffect.NavigateToLogin) + return null + } + SettingIntent.LogoutLoading -> { + return state.copy(loading = true) + } + SettingIntent.LogoutFailure -> { + return state.copy(loading = true) + } + SettingIntent.WithdrawalSuccess -> { + sendSideEffect(SettingSideEffect.NavigateToLogin) + return null + } + SettingIntent.WithdrawalLoading -> { + return state.copy(loading = true) + } + SettingIntent.WithdrawalFailure -> { + return state.copy(loading = true) + } } } @@ -64,4 +88,26 @@ class SettingViewModel @Inject constructor( delay(1000L) } } + + fun logout() { + viewModelScope.launch { + sendIntent(SettingIntent.LogoutLoading) + logoutUseCase().onSuccess { + sendIntent(SettingIntent.LogoutSuccess) + }.onFailure { + sendIntent(SettingIntent.LogoutFailure) + } + } + } + + fun withdrawal() { + viewModelScope.launch { + sendIntent(SettingIntent.WithdrawalLoading) + withdrawalUseCase().onSuccess { + sendIntent(SettingIntent.WithdrawalSuccess) + }.onFailure { + sendIntent(SettingIntent.WithdrawalFailure) + } + } + } } diff --git a/presentation/src/main/java/com/threegap/bitnagil/presentation/setting/model/mvi/SettingIntent.kt b/presentation/src/main/java/com/threegap/bitnagil/presentation/setting/model/mvi/SettingIntent.kt index b15206d2..a25490d5 100644 --- a/presentation/src/main/java/com/threegap/bitnagil/presentation/setting/model/mvi/SettingIntent.kt +++ b/presentation/src/main/java/com/threegap/bitnagil/presentation/setting/model/mvi/SettingIntent.kt @@ -12,4 +12,10 @@ sealed class SettingIntent : MviIntent { data object ToggleServiceAlarm : SettingIntent() data object TogglePushAlarm : SettingIntent() + data object LogoutLoading: SettingIntent() + data object LogoutSuccess: SettingIntent() + data object LogoutFailure: SettingIntent() + data object WithdrawalLoading: SettingIntent() + data object WithdrawalSuccess: SettingIntent() + data object WithdrawalFailure: SettingIntent() } diff --git a/presentation/src/main/java/com/threegap/bitnagil/presentation/setting/model/mvi/SettingSideEffect.kt b/presentation/src/main/java/com/threegap/bitnagil/presentation/setting/model/mvi/SettingSideEffect.kt index 00f22c19..cb457668 100644 --- a/presentation/src/main/java/com/threegap/bitnagil/presentation/setting/model/mvi/SettingSideEffect.kt +++ b/presentation/src/main/java/com/threegap/bitnagil/presentation/setting/model/mvi/SettingSideEffect.kt @@ -2,4 +2,6 @@ package com.threegap.bitnagil.presentation.setting.model.mvi import com.threegap.bitnagil.presentation.common.mviviewmodel.MviSideEffect -sealed class SettingSideEffect : MviSideEffect +sealed class SettingSideEffect : MviSideEffect { + data object NavigateToLogin : SettingSideEffect() +} diff --git a/presentation/src/main/java/com/threegap/bitnagil/presentation/setting/model/mvi/SettingState.kt b/presentation/src/main/java/com/threegap/bitnagil/presentation/setting/model/mvi/SettingState.kt index c1c8ebbd..e2382526 100644 --- a/presentation/src/main/java/com/threegap/bitnagil/presentation/setting/model/mvi/SettingState.kt +++ b/presentation/src/main/java/com/threegap/bitnagil/presentation/setting/model/mvi/SettingState.kt @@ -9,6 +9,7 @@ data class SettingState( val usePushAlarm: Boolean, val version: String, val latestVersion: String, + val loading: Boolean, ) : MviState { companion object { val Init = SettingState( @@ -16,6 +17,7 @@ data class SettingState( usePushAlarm = false, version = "", latestVersion = "", + loading = false, ) } } From 457fa4b3a1cee3080f093894200819e4137188fe Mon Sep 17 00:00:00 2001 From: yunsehwan Date: Sun, 27 Jul 2025 16:47:15 +0900 Subject: [PATCH 07/11] =?UTF-8?q?CHORE:=20ktlint=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/threegap/bitnagil/MainNavHost.kt | 6 ++---- app/src/main/java/com/threegap/bitnagil/Route.kt | 6 +++--- .../navigation/home/HomeBottomNavigationBar.kt | 14 +++++++------- .../bitnagil/navigation/home/HomeNavHost.kt | 6 +++--- .../bitnagil/navigation/home/HomeNavigator.kt | 1 + .../navigation/home/{Route.kt => HomeRoute.kt} | 0 .../datasourceimpl/AuthRemoteDataSourceImpl.kt | 2 -- .../bitnagil/presentation/home/HomeScreen.kt | 4 ++-- .../recommendroutine/RecommendRoutineScreen.kt | 2 +- .../bitnagil/presentation/setting/SettingScreen.kt | 6 +++--- .../setting/model/mvi/SettingIntent.kt | 12 ++++++------ .../writeroutine/WriteRoutineScreen.kt | 2 +- 12 files changed, 29 insertions(+), 32 deletions(-) rename app/src/main/java/com/threegap/bitnagil/navigation/home/{Route.kt => HomeRoute.kt} (100%) diff --git a/app/src/main/java/com/threegap/bitnagil/MainNavHost.kt b/app/src/main/java/com/threegap/bitnagil/MainNavHost.kt index 16de0346..92b1aa5d 100644 --- a/app/src/main/java/com/threegap/bitnagil/MainNavHost.kt +++ b/app/src/main/java/com/threegap/bitnagil/MainNavHost.kt @@ -92,10 +92,8 @@ fun MainNavHost( navigator.navController.navigate(Route.OnBoarding) }, navigateToNotice = { - }, navigateToQnA = { - }, navigateToRegisterRoutine = { routineId -> navigator.navController.navigate(Route.WriteRoutine(routineId = routineId)) @@ -105,7 +103,7 @@ fun MainNavHost( }, navigateToEmotion = { navigator.navController.navigate(Route.Emotion) - } + }, ) } @@ -145,7 +143,7 @@ fun MainNavHost( inclusive = true } } - } + }, ) } diff --git a/app/src/main/java/com/threegap/bitnagil/Route.kt b/app/src/main/java/com/threegap/bitnagil/Route.kt index ac5a9abd..c94979a3 100644 --- a/app/src/main/java/com/threegap/bitnagil/Route.kt +++ b/app/src/main/java/com/threegap/bitnagil/Route.kt @@ -29,14 +29,14 @@ sealed interface Route { data object Setting : Route @Serializable - data object OnBoarding: Route + data object OnBoarding : Route @Serializable data class WriteRoutine( val routineId: String? = null, val isRegister: Boolean = true, - ): Route + ) : Route @Serializable - data object Emotion: Route + data object Emotion : Route } diff --git a/app/src/main/java/com/threegap/bitnagil/navigation/home/HomeBottomNavigationBar.kt b/app/src/main/java/com/threegap/bitnagil/navigation/home/HomeBottomNavigationBar.kt index 6db48f67..10137be1 100644 --- a/app/src/main/java/com/threegap/bitnagil/navigation/home/HomeBottomNavigationBar.kt +++ b/app/src/main/java/com/threegap/bitnagil/navigation/home/HomeBottomNavigationBar.kt @@ -37,7 +37,7 @@ fun HomeBottomNavigationBar( .fillMaxWidth() .background(color = BitnagilTheme.colors.white) .padding(horizontal = 16.dp, vertical = 7.dp), - horizontalArrangement = Arrangement.spacedBy(12.dp) + horizontalArrangement = Arrangement.spacedBy(12.dp), ) { HomeBottomNavigationItem( modifier = Modifier.weight(1f), @@ -49,7 +49,7 @@ fun HomeBottomNavigationBar( popUpTo(0) { inclusive = true } } }, - selected = navBackStackEntry?.destination?.route == HomeRoute.Home.route + selected = navBackStackEntry?.destination?.route == HomeRoute.Home.route, ) HomeBottomNavigationItem( @@ -62,7 +62,7 @@ fun HomeBottomNavigationBar( popUpTo(0) { inclusive = true } } }, - selected = navBackStackEntry?.destination?.route == HomeRoute.RecommendRoutine.route + selected = navBackStackEntry?.destination?.route == HomeRoute.RecommendRoutine.route, ) HomeBottomNavigationItem( @@ -75,7 +75,7 @@ fun HomeBottomNavigationBar( popUpTo(0) { inclusive = true } } }, - selected = navBackStackEntry?.destination?.route == HomeRoute.MyPage.route + selected = navBackStackEntry?.destination?.route == HomeRoute.MyPage.route, ) } } @@ -105,19 +105,19 @@ private fun HomeBottomNavigationItem( interactionSource = interactionSource, indication = null, ), - horizontalAlignment = Alignment.CenterHorizontally + horizontalAlignment = Alignment.CenterHorizontally, ) { Image( painter = painterResource(id = iconResourceId), contentDescription = title, modifier = Modifier.padding(4.dp).size(24.dp), - colorFilter = ColorFilter.tint(color = contentTintColor) + colorFilter = ColorFilter.tint(color = contentTintColor), ) Text( text = title, style = BitnagilTheme.typography.caption2Medium, - color = contentTintColor + color = contentTintColor, ) } } diff --git a/app/src/main/java/com/threegap/bitnagil/navigation/home/HomeNavHost.kt b/app/src/main/java/com/threegap/bitnagil/navigation/home/HomeNavHost.kt index 05e3ed10..d9d7d227 100644 --- a/app/src/main/java/com/threegap/bitnagil/navigation/home/HomeNavHost.kt +++ b/app/src/main/java/com/threegap/bitnagil/navigation/home/HomeNavHost.kt @@ -58,7 +58,7 @@ fun HomeNavHost( composable(HomeRoute.RecommendRoutine.route) { RecommendRoutineScreenContainer( navigateToEmotion = navigateToEmotion, - navigateToRegisterRoutine = navigateToRegisterRoutine + navigateToRegisterRoutine = navigateToRegisterRoutine, ) } @@ -67,11 +67,11 @@ fun HomeNavHost( navigateToSetting = navigateToSetting, navigateToOnBoarding = navigateToOnBoarding, navigateToNotice = navigateToNotice, - navigateToQnA = navigateToQnA + navigateToQnA = navigateToQnA, ) } } - } + }, ) } diff --git a/app/src/main/java/com/threegap/bitnagil/navigation/home/HomeNavigator.kt b/app/src/main/java/com/threegap/bitnagil/navigation/home/HomeNavigator.kt index c5403ec7..0d6260fe 100644 --- a/app/src/main/java/com/threegap/bitnagil/navigation/home/HomeNavigator.kt +++ b/app/src/main/java/com/threegap/bitnagil/navigation/home/HomeNavigator.kt @@ -10,6 +10,7 @@ class HomeNavigator( ) { val startDestination = HomeRoute.Home.route } + @Composable fun rememberHomeNavigator(navController: NavHostController = rememberNavController()): HomeNavigator = remember(navController) { diff --git a/app/src/main/java/com/threegap/bitnagil/navigation/home/Route.kt b/app/src/main/java/com/threegap/bitnagil/navigation/home/HomeRoute.kt similarity index 100% rename from app/src/main/java/com/threegap/bitnagil/navigation/home/Route.kt rename to app/src/main/java/com/threegap/bitnagil/navigation/home/HomeRoute.kt diff --git a/data/src/main/java/com/threegap/bitnagil/data/auth/datasourceimpl/AuthRemoteDataSourceImpl.kt b/data/src/main/java/com/threegap/bitnagil/data/auth/datasourceimpl/AuthRemoteDataSourceImpl.kt index b98bdf51..d792438b 100644 --- a/data/src/main/java/com/threegap/bitnagil/data/auth/datasourceimpl/AuthRemoteDataSourceImpl.kt +++ b/data/src/main/java/com/threegap/bitnagil/data/auth/datasourceimpl/AuthRemoteDataSourceImpl.kt @@ -27,10 +27,8 @@ class AuthRemoteDataSourceImpl @Inject constructor( authService.postLogout() } - override suspend fun withdrawal(): Result = safeUnitApiCall { authService.postWithdrawal() } - } diff --git a/presentation/src/main/java/com/threegap/bitnagil/presentation/home/HomeScreen.kt b/presentation/src/main/java/com/threegap/bitnagil/presentation/home/HomeScreen.kt index 6bd4437a..79bf539f 100644 --- a/presentation/src/main/java/com/threegap/bitnagil/presentation/home/HomeScreen.kt +++ b/presentation/src/main/java/com/threegap/bitnagil/presentation/home/HomeScreen.kt @@ -120,7 +120,7 @@ fun HomeScreenContainer( viewModel.sendIntent(HomeIntent.ShowRoutineDetailsBottomSheet(routine)) }, onRegisterRoutineClick = navigateToRegisterRoutine, - onRegisterEmotionClick = navigateToEmotion + onRegisterEmotionClick = navigateToEmotion, ) } @@ -265,6 +265,6 @@ private fun HomeScreenPreview() { onShowRoutineSortBottomSheet = {}, onShowRoutineDetailsBottomSheet = {}, onRegisterRoutineClick = {}, - onRegisterEmotionClick = {} + onRegisterEmotionClick = {}, ) } diff --git a/presentation/src/main/java/com/threegap/bitnagil/presentation/recommendroutine/RecommendRoutineScreen.kt b/presentation/src/main/java/com/threegap/bitnagil/presentation/recommendroutine/RecommendRoutineScreen.kt index 428a4996..ba98326a 100644 --- a/presentation/src/main/java/com/threegap/bitnagil/presentation/recommendroutine/RecommendRoutineScreen.kt +++ b/presentation/src/main/java/com/threegap/bitnagil/presentation/recommendroutine/RecommendRoutineScreen.kt @@ -210,6 +210,6 @@ private fun RoutineRecommendScreenPreview() { onShowDifficultyBottomSheet = {}, onHideDifficultyBottomSheet = {}, onRecommendRoutineByEmotionClick = {}, - onRegisterRoutineClick = {} + onRegisterRoutineClick = {}, ) } diff --git a/presentation/src/main/java/com/threegap/bitnagil/presentation/setting/SettingScreen.kt b/presentation/src/main/java/com/threegap/bitnagil/presentation/setting/SettingScreen.kt index 14076953..970315a5 100644 --- a/presentation/src/main/java/com/threegap/bitnagil/presentation/setting/SettingScreen.kt +++ b/presentation/src/main/java/com/threegap/bitnagil/presentation/setting/SettingScreen.kt @@ -58,7 +58,7 @@ fun SettingScreenContainer( onClickTermsOfService = navigateToTermsOfService, onClickPrivacyPolicy = navigateToPrivacyPolicy, onClickLogout = viewModel::logout, - onClickWithdrawal = viewModel::withdrawal + onClickWithdrawal = viewModel::withdrawal, ) } @@ -208,7 +208,7 @@ fun SettingScreenPreview() { usePushAlarm = false, version = "1.0.1", latestVersion = "1.0.0", - loading = false + loading = false, ), toggleServiceAlarm = {}, togglePushAlarm = {}, @@ -217,6 +217,6 @@ fun SettingScreenPreview() { onClickPrivacyPolicy = {}, onClickTermsOfService = {}, onClickLogout = {}, - onClickWithdrawal = {} + onClickWithdrawal = {}, ) } diff --git a/presentation/src/main/java/com/threegap/bitnagil/presentation/setting/model/mvi/SettingIntent.kt b/presentation/src/main/java/com/threegap/bitnagil/presentation/setting/model/mvi/SettingIntent.kt index a25490d5..066691f3 100644 --- a/presentation/src/main/java/com/threegap/bitnagil/presentation/setting/model/mvi/SettingIntent.kt +++ b/presentation/src/main/java/com/threegap/bitnagil/presentation/setting/model/mvi/SettingIntent.kt @@ -12,10 +12,10 @@ sealed class SettingIntent : MviIntent { data object ToggleServiceAlarm : SettingIntent() data object TogglePushAlarm : SettingIntent() - data object LogoutLoading: SettingIntent() - data object LogoutSuccess: SettingIntent() - data object LogoutFailure: SettingIntent() - data object WithdrawalLoading: SettingIntent() - data object WithdrawalSuccess: SettingIntent() - data object WithdrawalFailure: SettingIntent() + data object LogoutLoading : SettingIntent() + data object LogoutSuccess : SettingIntent() + data object LogoutFailure : SettingIntent() + data object WithdrawalLoading : SettingIntent() + data object WithdrawalSuccess : SettingIntent() + data object WithdrawalFailure : SettingIntent() } diff --git a/presentation/src/main/java/com/threegap/bitnagil/presentation/writeroutine/WriteRoutineScreen.kt b/presentation/src/main/java/com/threegap/bitnagil/presentation/writeroutine/WriteRoutineScreen.kt index d7244244..074c1909 100644 --- a/presentation/src/main/java/com/threegap/bitnagil/presentation/writeroutine/WriteRoutineScreen.kt +++ b/presentation/src/main/java/com/threegap/bitnagil/presentation/writeroutine/WriteRoutineScreen.kt @@ -79,7 +79,7 @@ fun WriteRoutineScreenContainer( showTimePickerBottomSheet = viewModel::showTimePickerBottomSheet, onClickRegister = viewModel::registerRoutine, removeSubRoutine = viewModel::removeSubRoutine, - onClickBack = navigateToBack + onClickBack = navigateToBack, ) } From 58aa6f3b3d770693f923203895a4ec5fa909880a Mon Sep 17 00:00:00 2001 From: yunsehwan Date: Sun, 27 Jul 2025 19:52:38 +0900 Subject: [PATCH 08/11] =?UTF-8?q?FIX:=20=EB=A1=9C=EA=B7=B8=EC=95=84?= =?UTF-8?q?=EC=9B=83/=ED=9A=8C=EC=9B=90=ED=83=88=ED=87=B4=20=EC=8B=A4?= =?UTF-8?q?=ED=8C=A8=EC=8B=9C=20=EB=A1=9C=EB=94=A9=20=EC=83=81=ED=83=9C?= =?UTF-8?q?=EB=A5=BC=20false=EB=A1=9C=20=EC=88=98=EC=A0=95,=20=EB=A1=9C?= =?UTF-8?q?=EA=B7=B8=EC=95=84=EC=9B=83/=ED=9A=8C=EC=9B=90=ED=83=88?= =?UTF-8?q?=ED=87=B4=20=EC=84=B1=EA=B3=B5=EC=8B=9C=20=EB=82=B4=EB=B6=80=20?= =?UTF-8?q?=ED=86=A0=ED=81=B0=20=EB=8D=B0=EC=9D=B4=ED=84=B0=EB=A5=BC=20?= =?UTF-8?q?=EC=B4=88=EA=B8=B0=ED=99=94=ED=95=98=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../data/auth/datasource/AuthLocalDataSource.kt | 2 ++ .../auth/datasourceimpl/AuthLocalDataSourceImpl.kt | 5 +++++ .../data/auth/repositoryimpl/AuthRepositoryImpl.kt | 12 ++++++++++-- .../presentation/setting/SettingViewModel.kt | 4 ++-- 4 files changed, 19 insertions(+), 4 deletions(-) diff --git a/data/src/main/java/com/threegap/bitnagil/data/auth/datasource/AuthLocalDataSource.kt b/data/src/main/java/com/threegap/bitnagil/data/auth/datasource/AuthLocalDataSource.kt index 67dd07c2..4bf7bce4 100644 --- a/data/src/main/java/com/threegap/bitnagil/data/auth/datasource/AuthLocalDataSource.kt +++ b/data/src/main/java/com/threegap/bitnagil/data/auth/datasource/AuthLocalDataSource.kt @@ -4,4 +4,6 @@ interface AuthLocalDataSource { suspend fun hasToken(): Boolean suspend fun updateAuthToken(accessToken: String, refreshToken: String): Result + + suspend fun clearAuthToken(): Result } diff --git a/data/src/main/java/com/threegap/bitnagil/data/auth/datasourceimpl/AuthLocalDataSourceImpl.kt b/data/src/main/java/com/threegap/bitnagil/data/auth/datasourceimpl/AuthLocalDataSourceImpl.kt index b0ae1640..1c702874 100644 --- a/data/src/main/java/com/threegap/bitnagil/data/auth/datasourceimpl/AuthLocalDataSourceImpl.kt +++ b/data/src/main/java/com/threegap/bitnagil/data/auth/datasourceimpl/AuthLocalDataSourceImpl.kt @@ -17,4 +17,9 @@ class AuthLocalDataSourceImpl @Inject constructor( refreshToken = refreshToken, ) } + + override suspend fun clearAuthToken(): Result = + kotlin.runCatching { + authTokenDataStore.clearAuthToken() + } } diff --git a/data/src/main/java/com/threegap/bitnagil/data/auth/repositoryimpl/AuthRepositoryImpl.kt b/data/src/main/java/com/threegap/bitnagil/data/auth/repositoryimpl/AuthRepositoryImpl.kt index 62b9e948..065cc652 100644 --- a/data/src/main/java/com/threegap/bitnagil/data/auth/repositoryimpl/AuthRepositoryImpl.kt +++ b/data/src/main/java/com/threegap/bitnagil/data/auth/repositoryimpl/AuthRepositoryImpl.kt @@ -28,7 +28,15 @@ class AuthRepositoryImpl @Inject constructor( termsAgreement.toDto(), ) - override suspend fun logout(): Result = authRemoteDataSource.logout() + override suspend fun logout(): Result { + return authRemoteDataSource.logout().also { + if (it.isSuccess) authLocalDataSource.clearAuthToken() + } + } - override suspend fun withdrawal(): Result = authRemoteDataSource.withdrawal() + override suspend fun withdrawal(): Result { + return authRemoteDataSource.withdrawal().also { + if (it.isSuccess) authLocalDataSource.clearAuthToken() + } + } } diff --git a/presentation/src/main/java/com/threegap/bitnagil/presentation/setting/SettingViewModel.kt b/presentation/src/main/java/com/threegap/bitnagil/presentation/setting/SettingViewModel.kt index 8f1131db..58352281 100644 --- a/presentation/src/main/java/com/threegap/bitnagil/presentation/setting/SettingViewModel.kt +++ b/presentation/src/main/java/com/threegap/bitnagil/presentation/setting/SettingViewModel.kt @@ -58,7 +58,7 @@ class SettingViewModel @Inject constructor( return state.copy(loading = true) } SettingIntent.LogoutFailure -> { - return state.copy(loading = true) + return state.copy(loading = false) } SettingIntent.WithdrawalSuccess -> { sendSideEffect(SettingSideEffect.NavigateToLogin) @@ -68,7 +68,7 @@ class SettingViewModel @Inject constructor( return state.copy(loading = true) } SettingIntent.WithdrawalFailure -> { - return state.copy(loading = true) + return state.copy(loading = false) } } } From 8cd39323794a0988b8fa4eebdef34025ead80330 Mon Sep 17 00:00:00 2001 From: yunsehwan Date: Sun, 27 Jul 2025 19:57:10 +0900 Subject: [PATCH 09/11] =?UTF-8?q?CHORE:=20runCatching=20=EC=82=AC=EC=9A=A9?= =?UTF-8?q?=20=EC=9D=BC=EA=B4=80=EC=84=B1=20=ED=86=B5=EC=9D=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../data/auth/datasourceimpl/AuthLocalDataSourceImpl.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/src/main/java/com/threegap/bitnagil/data/auth/datasourceimpl/AuthLocalDataSourceImpl.kt b/data/src/main/java/com/threegap/bitnagil/data/auth/datasourceimpl/AuthLocalDataSourceImpl.kt index 1c702874..cd1fc995 100644 --- a/data/src/main/java/com/threegap/bitnagil/data/auth/datasourceimpl/AuthLocalDataSourceImpl.kt +++ b/data/src/main/java/com/threegap/bitnagil/data/auth/datasourceimpl/AuthLocalDataSourceImpl.kt @@ -19,7 +19,7 @@ class AuthLocalDataSourceImpl @Inject constructor( } override suspend fun clearAuthToken(): Result = - kotlin.runCatching { + runCatching { authTokenDataStore.clearAuthToken() } } From d0a1c2b2ef8b9f401be092050c4ad97d7d904ae9 Mon Sep 17 00:00:00 2001 From: yunsehwan Date: Sun, 27 Jul 2025 22:20:20 +0900 Subject: [PATCH 10/11] =?UTF-8?q?FIX:=20=EB=A1=9C=EA=B7=B8=EC=95=84?= =?UTF-8?q?=EC=9B=83/=ED=9A=8C=EC=9B=90=ED=83=88=ED=87=B4=EC=8B=9C=20?= =?UTF-8?q?=EB=A1=9C=EA=B7=B8=EC=9D=B8=20=ED=99=94=EB=A9=B4=EC=9D=B4=20?= =?UTF-8?q?=EC=95=84=EB=8B=8C,=20=EC=9D=B8=ED=8A=B8=EB=A1=9C=20=ED=99=94?= =?UTF-8?q?=EB=A9=B4=EC=9C=BC=EB=A1=9C=20=EC=9D=B4=EB=8F=99=ED=95=98?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/java/com/threegap/bitnagil/MainNavHost.kt | 4 ++-- .../threegap/bitnagil/presentation/setting/SettingScreen.kt | 4 ++-- .../bitnagil/presentation/setting/SettingViewModel.kt | 4 ++-- .../presentation/setting/model/mvi/SettingSideEffect.kt | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/com/threegap/bitnagil/MainNavHost.kt b/app/src/main/java/com/threegap/bitnagil/MainNavHost.kt index 92b1aa5d..e06ad28c 100644 --- a/app/src/main/java/com/threegap/bitnagil/MainNavHost.kt +++ b/app/src/main/java/com/threegap/bitnagil/MainNavHost.kt @@ -137,8 +137,8 @@ fun MainNavHost( ), ) }, - navigateToLogin = { - navigator.navController.navigate(Route.Login) { + navigateToIntro = { + navigator.navController.navigate(Route.Intro) { popUpTo(0) { inclusive = true } diff --git a/presentation/src/main/java/com/threegap/bitnagil/presentation/setting/SettingScreen.kt b/presentation/src/main/java/com/threegap/bitnagil/presentation/setting/SettingScreen.kt index 970315a5..23ae4f8e 100644 --- a/presentation/src/main/java/com/threegap/bitnagil/presentation/setting/SettingScreen.kt +++ b/presentation/src/main/java/com/threegap/bitnagil/presentation/setting/SettingScreen.kt @@ -39,13 +39,13 @@ fun SettingScreenContainer( navigateToBack: () -> Unit, navigateToTermsOfService: () -> Unit, navigateToPrivacyPolicy: () -> Unit, - navigateToLogin: () -> Unit, + navigateToIntro: () -> Unit, ) { val state by viewModel.stateFlow.collectAsState() viewModel.sideEffectFlow.collectAsEffect { sideEffect -> when (sideEffect) { - SettingSideEffect.NavigateToLogin -> navigateToLogin() + SettingSideEffect.NavigateToIntro -> navigateToIntro() } } diff --git a/presentation/src/main/java/com/threegap/bitnagil/presentation/setting/SettingViewModel.kt b/presentation/src/main/java/com/threegap/bitnagil/presentation/setting/SettingViewModel.kt index 58352281..baa49ba5 100644 --- a/presentation/src/main/java/com/threegap/bitnagil/presentation/setting/SettingViewModel.kt +++ b/presentation/src/main/java/com/threegap/bitnagil/presentation/setting/SettingViewModel.kt @@ -51,7 +51,7 @@ class SettingViewModel @Inject constructor( ) } SettingIntent.LogoutSuccess -> { - sendSideEffect(SettingSideEffect.NavigateToLogin) + sendSideEffect(SettingSideEffect.NavigateToIntro) return null } SettingIntent.LogoutLoading -> { @@ -61,7 +61,7 @@ class SettingViewModel @Inject constructor( return state.copy(loading = false) } SettingIntent.WithdrawalSuccess -> { - sendSideEffect(SettingSideEffect.NavigateToLogin) + sendSideEffect(SettingSideEffect.NavigateToIntro) return null } SettingIntent.WithdrawalLoading -> { diff --git a/presentation/src/main/java/com/threegap/bitnagil/presentation/setting/model/mvi/SettingSideEffect.kt b/presentation/src/main/java/com/threegap/bitnagil/presentation/setting/model/mvi/SettingSideEffect.kt index cb457668..45dacc0b 100644 --- a/presentation/src/main/java/com/threegap/bitnagil/presentation/setting/model/mvi/SettingSideEffect.kt +++ b/presentation/src/main/java/com/threegap/bitnagil/presentation/setting/model/mvi/SettingSideEffect.kt @@ -3,5 +3,5 @@ package com.threegap.bitnagil.presentation.setting.model.mvi import com.threegap.bitnagil.presentation.common.mviviewmodel.MviSideEffect sealed class SettingSideEffect : MviSideEffect { - data object NavigateToLogin : SettingSideEffect() + data object NavigateToIntro : SettingSideEffect() } From f12ae2645b4541d3941c45d5c6e0bfb036436e2f Mon Sep 17 00:00:00 2001 From: yunsehwan Date: Sun, 27 Jul 2025 22:31:51 +0900 Subject: [PATCH 11/11] =?UTF-8?q?FIX:=20BottomNavigation=EB=82=B4=20?= =?UTF-8?q?=EA=B0=81=20=EC=86=8D=EC=84=B1=EA=B0=92(=EC=9D=B4=EB=A6=84,=20?= =?UTF-8?q?=EC=95=84=EC=9D=B4=EC=BD=98,=20=EC=9D=B4=EB=8F=99=20=EA=B2=BD?= =?UTF-8?q?=EB=A1=9C)=EB=A5=BC=20enum=20class=EB=A1=9C=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../home/HomeBottomNavigationBar.kt | 53 +++++-------------- .../bitnagil/navigation/home/HomeRoute.kt | 35 ++++++++---- 2 files changed, 40 insertions(+), 48 deletions(-) diff --git a/app/src/main/java/com/threegap/bitnagil/navigation/home/HomeBottomNavigationBar.kt b/app/src/main/java/com/threegap/bitnagil/navigation/home/HomeBottomNavigationBar.kt index 10137be1..23935ee2 100644 --- a/app/src/main/java/com/threegap/bitnagil/navigation/home/HomeBottomNavigationBar.kt +++ b/app/src/main/java/com/threegap/bitnagil/navigation/home/HomeBottomNavigationBar.kt @@ -23,7 +23,6 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.navigation.NavController import androidx.navigation.compose.currentBackStackEntryAsState -import com.threegap.bitnagil.R import com.threegap.bitnagil.designsystem.BitnagilTheme @Composable @@ -39,44 +38,20 @@ fun HomeBottomNavigationBar( .padding(horizontal = 16.dp, vertical = 7.dp), horizontalArrangement = Arrangement.spacedBy(12.dp), ) { - HomeBottomNavigationItem( - modifier = Modifier.weight(1f), - selectIconResourceId = R.drawable.ic_home_fill, - unSelectIconResourceId = R.drawable.ic_home_empty, - title = "홈", - onClick = { - navController.navigate(HomeRoute.Home.route) { - popUpTo(0) { inclusive = true } - } - }, - selected = navBackStackEntry?.destination?.route == HomeRoute.Home.route, - ) - - HomeBottomNavigationItem( - modifier = Modifier.weight(1f), - selectIconResourceId = R.drawable.ic_recommend_fill, - unSelectIconResourceId = R.drawable.ic_recommend_empty, - title = "추천 루틴", - onClick = { - navController.navigate(HomeRoute.RecommendRoutine.route) { - popUpTo(0) { inclusive = true } - } - }, - selected = navBackStackEntry?.destination?.route == HomeRoute.RecommendRoutine.route, - ) - - HomeBottomNavigationItem( - modifier = Modifier.weight(1f), - selectIconResourceId = R.drawable.ic_mypage_fill, - unSelectIconResourceId = R.drawable.ic_mypage_empty, - title = "마이페이지", - onClick = { - navController.navigate(HomeRoute.MyPage.route) { - popUpTo(0) { inclusive = true } - } - }, - selected = navBackStackEntry?.destination?.route == HomeRoute.MyPage.route, - ) + HomeRoute.entries.map { homeRoute -> + HomeBottomNavigationItem( + modifier = Modifier.weight(1f), + selectIconResourceId = homeRoute.selectIconResourceId, + unSelectIconResourceId = homeRoute.unSelectIconResourceId, + title = homeRoute.title, + onClick = { + navController.navigate(homeRoute.route) { + popUpTo(0) { inclusive = true } + } + }, + selected = navBackStackEntry?.destination?.route == homeRoute.route, + ) + } } } diff --git a/app/src/main/java/com/threegap/bitnagil/navigation/home/HomeRoute.kt b/app/src/main/java/com/threegap/bitnagil/navigation/home/HomeRoute.kt index 32aa4b84..4ac10ce3 100644 --- a/app/src/main/java/com/threegap/bitnagil/navigation/home/HomeRoute.kt +++ b/app/src/main/java/com/threegap/bitnagil/navigation/home/HomeRoute.kt @@ -1,15 +1,32 @@ package com.threegap.bitnagil.navigation.home -import kotlinx.serialization.Serializable +import com.threegap.bitnagil.R -@Serializable -sealed class HomeRoute(val route: String) { - @Serializable - data object Home : HomeRoute("home/home") +enum class HomeRoute( + val route: String, + val title: String, + val selectIconResourceId: Int, + val unSelectIconResourceId: Int, +) { + Home( + route = "home/home", + title = "홈", + selectIconResourceId = R.drawable.ic_home_fill, + unSelectIconResourceId = R.drawable.ic_home_empty, + ), - @Serializable - data object RecommendRoutine : HomeRoute("home/recommend_routine") + RecommendRoutine( + route = "home/recommend_routine", + title = "추천 루틴", + selectIconResourceId = R.drawable.ic_recommend_fill, + unSelectIconResourceId = R.drawable.ic_recommend_empty, + ), - @Serializable - data object MyPage : HomeRoute("home/my_page") + MyPage( + route = "home/my_page", + title = "마이페이지", + selectIconResourceId = R.drawable.ic_mypage_fill, + unSelectIconResourceId = R.drawable.ic_mypage_empty, + ), + ; }