From 08df6d68677ebde2d246a59a27b9f9d5269ca3e2 Mon Sep 17 00:00:00 2001 From: dongchyeon Date: Wed, 15 Jan 2025 18:48:23 +0900 Subject: [PATCH 01/11] =?UTF-8?q?[FEAT/#40]=20core:common=20=EB=AA=A8?= =?UTF-8?q?=EB=93=88=EC=97=90=20=EA=B3=B5=EC=9A=A9=20Routes=20=EA=B4=80?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/yapp/common/navigation/Routes.kt | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 core/common/src/main/java/com/yapp/common/navigation/Routes.kt diff --git a/core/common/src/main/java/com/yapp/common/navigation/Routes.kt b/core/common/src/main/java/com/yapp/common/navigation/Routes.kt new file mode 100644 index 0000000..b25684a --- /dev/null +++ b/core/common/src/main/java/com/yapp/common/navigation/Routes.kt @@ -0,0 +1,23 @@ +package com.yapp.common.navigation + +object Routes { + object Onboarding { + const val ROUTE = "onboarding_route" + const val EXPLAIN = "onboarding_explain" + const val ALARM_TIME_SELECTION = "onboarding_alarm_time_selection" + const val BIRTHDAY = "onboarding_birthday" + const val TIME_OF_BIRTH = "onboarding_time_of_birth" + const val NAME = "onboarding_name" + } + + object Home { + const val ROUTE = "home_route" + const val HOME = "home" + const val ALARM_ADD_EDIT = "alarm_add_edit" + } + + object MyPage { + const val ROUTE = "mypage_route" + const val MYPAGE = "mypage" + } +} From 60ead79636282e89ab8304f98f4bcf4c31396707 Mon Sep 17 00:00:00 2001 From: dongchyeon Date: Thu, 16 Jan 2025 21:47:10 +0900 Subject: [PATCH 02/11] [RENAME/#40] MainScreen -> OrbitNavHost --- .../navigator/{MainScreen.kt => OrbitNavHost.kt} | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) rename feature/navigator/src/main/java/com/yapp/navigator/{MainScreen.kt => OrbitNavHost.kt} (76%) diff --git a/feature/navigator/src/main/java/com/yapp/navigator/MainScreen.kt b/feature/navigator/src/main/java/com/yapp/navigator/OrbitNavHost.kt similarity index 76% rename from feature/navigator/src/main/java/com/yapp/navigator/MainScreen.kt rename to feature/navigator/src/main/java/com/yapp/navigator/OrbitNavHost.kt index ea6ceb7..eb6835d 100644 --- a/feature/navigator/src/main/java/com/yapp/navigator/MainScreen.kt +++ b/feature/navigator/src/main/java/com/yapp/navigator/OrbitNavHost.kt @@ -5,25 +5,24 @@ import androidx.compose.material3.Scaffold import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.navigation.compose.NavHost +import com.yapp.common.navigation.OrbitNavigator +import com.yapp.common.navigation.rememberOrbitNavigator import com.yapp.designsystem.theme.OrbitTheme import com.yapp.home.homeNavGraph import com.yapp.mypage.mypageNavGraph -import com.yapp.navigator.navigation.MainNavTab -import com.yapp.navigator.navigation.MainNavigator -import com.yapp.navigator.navigation.rememberMainNavigator import kotlinx.collections.immutable.toImmutableList @Composable -internal fun MainScreen( +internal fun OrbitNavHost( modifier: Modifier = Modifier, - navigator: MainNavigator = rememberMainNavigator(), + navigator: OrbitNavigator = rememberOrbitNavigator(), ) { Scaffold( modifier = modifier, bottomBar = { - MainBottomNavigationBar( + OrbitBottomNavigationBar( visible = false, - currentTab = navigator.currentTab, + currentTab = navigator.c, entries = MainNavTab.entries.toImmutableList(), onClickItem = navigator::navigate, ) From bc92de131075ba7a1ceb00e000c60120649ab883 Mon Sep 17 00:00:00 2001 From: dongchyeon Date: Thu, 16 Jan 2025 21:59:08 +0900 Subject: [PATCH 03/11] [RENAME/#40] MainBottomNavigationBar -> OrbitBottomNavigationBar --- .../yapp/navigator/MainBottomNavigationBar.kt | 43 ----------- .../main/java/com/yapp/navigator/NavItem.kt | 40 ---------- .../navigator/OrbitBottomNavigationBar.kt | 77 +++++++++++++++++++ 3 files changed, 77 insertions(+), 83 deletions(-) delete mode 100644 feature/navigator/src/main/java/com/yapp/navigator/MainBottomNavigationBar.kt delete mode 100644 feature/navigator/src/main/java/com/yapp/navigator/NavItem.kt create mode 100644 feature/navigator/src/main/java/com/yapp/navigator/OrbitBottomNavigationBar.kt diff --git a/feature/navigator/src/main/java/com/yapp/navigator/MainBottomNavigationBar.kt b/feature/navigator/src/main/java/com/yapp/navigator/MainBottomNavigationBar.kt deleted file mode 100644 index 55ce1cd..0000000 --- a/feature/navigator/src/main/java/com/yapp/navigator/MainBottomNavigationBar.kt +++ /dev/null @@ -1,43 +0,0 @@ -package com.yapp.navigator - -import androidx.compose.animation.AnimatedVisibility -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.height -import androidx.compose.material3.HorizontalDivider -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.unit.dp -import com.yapp.navigator.navigation.MainNavTab -import kotlinx.collections.immutable.ImmutableList - -@Composable -internal fun MainBottomNavigationBar( - visible: Boolean, - currentTab: MainNavTab?, - entries: ImmutableList, - onClickItem: (MainNavTab) -> Unit, -) { - AnimatedVisibility(visible = visible) { - Column { - HorizontalDivider(color = Color.Black, thickness = 1.dp) - Row( - modifier = Modifier - .height(56.dp) - .background(color = Color.White), - ) { - entries.forEach { tab -> - NavItem( - selected = tab == currentTab, - label = stringResource(id = tab.titleId), - iconId = tab.iconId, - onClick = { onClickItem(tab) }, - ) - } - } - } - } -} diff --git a/feature/navigator/src/main/java/com/yapp/navigator/NavItem.kt b/feature/navigator/src/main/java/com/yapp/navigator/NavItem.kt deleted file mode 100644 index cdbf713..0000000 --- a/feature/navigator/src/main/java/com/yapp/navigator/NavItem.kt +++ /dev/null @@ -1,40 +0,0 @@ -package com.yapp.navigator - -import androidx.annotation.DrawableRes -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.RowScope -import androidx.compose.foundation.layout.fillMaxHeight -import androidx.compose.material3.Icon -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.res.painterResource - -@Composable -fun RowScope.NavItem( - modifier: Modifier = Modifier, - selected: Boolean, - label: String, - @DrawableRes iconId: Int, - onClick: () -> Unit, -) { - Column( - modifier = modifier - .weight(1f) - .fillMaxHeight() - .clickable(onClick = onClick), - horizontalAlignment = Alignment.CenterHorizontally, - verticalArrangement = Arrangement.Center, - ) { - Icon( - painter = painterResource(id = iconId), - contentDescription = label, - tint = if (selected) Color.Blue else Color.Gray, - ) - Text(text = label, color = if (selected) Color.Blue else Color.Black) - } -} diff --git a/feature/navigator/src/main/java/com/yapp/navigator/OrbitBottomNavigationBar.kt b/feature/navigator/src/main/java/com/yapp/navigator/OrbitBottomNavigationBar.kt new file mode 100644 index 0000000..6cf04aa --- /dev/null +++ b/feature/navigator/src/main/java/com/yapp/navigator/OrbitBottomNavigationBar.kt @@ -0,0 +1,77 @@ +package com.yapp.navigator + +import androidx.annotation.DrawableRes +import androidx.compose.animation.AnimatedVisibility +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.RowScope +import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.height +import androidx.compose.material3.HorizontalDivider +import androidx.compose.material3.Icon +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.unit.dp +import com.yapp.common.navigation.TopLevelDestination +import kotlinx.collections.immutable.ImmutableList + +@Composable +internal fun OrbitBottomNavigationBar( + visible: Boolean, + currentTab: TopLevelDestination?, + entries: ImmutableList, + onClickItem: (TopLevelDestination) -> Unit, +) { + AnimatedVisibility(visible = visible) { + Column { + HorizontalDivider(color = Color.Black, thickness = 1.dp) + Row( + modifier = Modifier + .height(56.dp) + .background(color = Color.White), + ) { + entries.forEach { tab -> + NavItem( + selected = tab == currentTab, + label = stringResource(id = tab.titleId), + iconId = tab.iconId, + onClick = { onClickItem(tab) }, + ) + } + } + } + } +} + +@Composable +fun RowScope.NavItem( + modifier: Modifier = Modifier, + selected: Boolean, + label: String, + @DrawableRes iconId: Int, + onClick: () -> Unit, +) { + Column( + modifier = modifier + .weight(1f) + .fillMaxHeight() + .clickable(onClick = onClick), + horizontalAlignment = Alignment.CenterHorizontally, + verticalArrangement = Arrangement.Center, + ) { + Icon( + painter = painterResource(id = iconId), + contentDescription = label, + tint = if (selected) Color.Blue else Color.Gray, + ) + Text(text = label, color = if (selected) Color.Blue else Color.Black) + } +} From fb59e59787ea573d91f3d97495e5b9584444034c Mon Sep 17 00:00:00 2001 From: dongchyeon Date: Thu, 16 Jan 2025 21:59:46 +0900 Subject: [PATCH 04/11] [RENAME/#40] MainNavTab -> TopLevelDestination --- .../yapp/common/navigation/TopLevelDestination.kt | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) rename feature/navigator/src/main/java/com/yapp/navigator/navigation/MainNavTab.kt => core/common/src/main/java/com/yapp/common/navigation/TopLevelDestination.kt (67%) diff --git a/feature/navigator/src/main/java/com/yapp/navigator/navigation/MainNavTab.kt b/core/common/src/main/java/com/yapp/common/navigation/TopLevelDestination.kt similarity index 67% rename from feature/navigator/src/main/java/com/yapp/navigator/navigation/MainNavTab.kt rename to core/common/src/main/java/com/yapp/common/navigation/TopLevelDestination.kt index a9432be..d453ecf 100644 --- a/feature/navigator/src/main/java/com/yapp/navigator/navigation/MainNavTab.kt +++ b/core/common/src/main/java/com/yapp/common/navigation/TopLevelDestination.kt @@ -1,11 +1,9 @@ -package com.yapp.navigator.navigation +package com.yapp.common.navigation import androidx.annotation.DrawableRes import androidx.annotation.StringRes -import com.yapp.home.HomeRoute -import com.yapp.mypage.MypageRoute -enum class MainNavTab( +enum class TopLevelDestination( @DrawableRes val iconId: Int, @StringRes val titleId: Int, val route: String, @@ -13,17 +11,17 @@ enum class MainNavTab( HOME( iconId = core.designsystem.R.drawable.ic_launcher_foreground, titleId = core.designsystem.R.string.app_name, - route = HomeRoute.HOME, + route = Routes.Home.ROUTE, ), MYPAGE( iconId = core.designsystem.R.drawable.ic_launcher_foreground, titleId = core.designsystem.R.string.app_name, - route = MypageRoute.MYPAGE, + route = Routes.MyPage.MYPAGE, ), ; companion object { operator fun contains(route: String): Boolean = entries.any { it.route == route } - fun find(route: String): MainNavTab? = entries.find { it.route == route } + fun find(route: String): TopLevelDestination? = entries.find { it.route == route } } } From 7baf7a8c1aae42e11e1522e1a50fcbda16ba943b Mon Sep 17 00:00:00 2001 From: dongchyeon Date: Thu, 16 Jan 2025 22:00:06 +0900 Subject: [PATCH 05/11] [RENAME/#40] MainNavigator -> OrbitNavigator --- .../yapp/common/navigation/OrbitNavigator.kt | 31 +++++++++---------- 1 file changed, 15 insertions(+), 16 deletions(-) rename feature/navigator/src/main/java/com/yapp/navigator/navigation/MainNavigator.kt => core/common/src/main/java/com/yapp/common/navigation/OrbitNavigator.kt (56%) diff --git a/feature/navigator/src/main/java/com/yapp/navigator/navigation/MainNavigator.kt b/core/common/src/main/java/com/yapp/common/navigation/OrbitNavigator.kt similarity index 56% rename from feature/navigator/src/main/java/com/yapp/navigator/navigation/MainNavigator.kt rename to core/common/src/main/java/com/yapp/common/navigation/OrbitNavigator.kt index 6af2302..d6a39e0 100644 --- a/feature/navigator/src/main/java/com/yapp/navigator/navigation/MainNavigator.kt +++ b/core/common/src/main/java/com/yapp/common/navigation/OrbitNavigator.kt @@ -1,4 +1,4 @@ -package com.yapp.navigator.navigation +package com.yapp.common.navigation import androidx.compose.runtime.Composable import androidx.compose.runtime.remember @@ -7,25 +7,24 @@ import androidx.navigation.NavHostController import androidx.navigation.compose.currentBackStackEntryAsState import androidx.navigation.compose.rememberNavController import androidx.navigation.navOptions -import com.yapp.home.HomeRoute -import com.yapp.mypage.MypageRoute -internal class MainNavigator( - val navController: NavHostController, +class OrbitNavigator( + private val navController: NavHostController, ) { - val startDestination = HomeRoute.ALARM_ADD_EDIT + val startDestination = Routes.Onboarding.ROUTE + private val currentDestination: NavDestination? @Composable get() = navController .currentBackStackEntryAsState().value?.destination - val currentTab: MainNavTab? + val currentTab: TopLevelDestination? @Composable get() = currentDestination ?.route - ?.let(MainNavTab.Companion::find) + ?.let(TopLevelDestination.Companion::find) - fun navigate(tab: MainNavTab) { + fun navigateToTopLevelDestination(tab: TopLevelDestination) { val navOptions = navOptions { - popUpTo(HomeRoute.HOME) { + popUpTo(Routes.Home.ROUTE) { saveState = true } launchSingleTop = true @@ -33,21 +32,21 @@ internal class MainNavigator( } when (tab) { - MainNavTab.HOME -> navController.navigate(HomeRoute.HOME, navOptions) - MainNavTab.MYPAGE -> navController.navigate(MypageRoute.MYPAGE, navOptions) + TopLevelDestination.HOME -> navController.navigate(Routes.Home.ROUTE, navOptions) + TopLevelDestination.MYPAGE -> navController.navigate(Routes.MyPage.ROUTE, navOptions) } } @Composable fun shouldShowBottomBar(): Boolean { val currentRoute = currentDestination?.route ?: return false - return currentRoute in MainNavTab.entries.map { it.route } + return currentRoute in TopLevelDestination.entries.map { it.route } } } @Composable -internal fun rememberMainNavigator( +fun rememberOrbitNavigator( navController: NavHostController = rememberNavController(), -): MainNavigator = remember(navController) { - MainNavigator(navController) +): OrbitNavigator = remember(navController) { + OrbitNavigator(navController) } From 068b29e91cbf385596c1cea5266767bfc0751912 Mon Sep 17 00:00:00 2001 From: dongchyeon Date: Thu, 16 Jan 2025 22:01:17 +0900 Subject: [PATCH 06/11] =?UTF-8?q?[FEAT/#40]=20navigator=20=EB=AA=A8?= =?UTF-8?q?=EB=93=88=EC=9D=98=20navigation=20=EC=BB=B4=ED=8F=AC=EB=84=8C?= =?UTF-8?q?=ED=8A=B8=EB=A5=BC=20core:common=EC=9D=98=20navigation=20?= =?UTF-8?q?=ED=8C=A8=ED=82=A4=EC=A7=80=EB=A1=9C=20=EC=9D=B4=EC=A0=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/common/build.gradle.kts | 5 ++++ .../yapp/common/navigation/OrbitNavigator.kt | 3 ++- .../{ => destination}/TopLevelDestination.kt | 3 ++- feature/home/build.gradle.kts | 1 + .../main/java/com/yapp/home/HomeNavigation.kt | 23 ++++++++++--------- feature/navigator/build.gradle.kts | 1 + .../java/com/yapp/navigator/MainActivity.kt | 3 +-- .../navigator/OrbitBottomNavigationBar.kt | 2 +- .../java/com/yapp/navigator/OrbitNavHost.kt | 7 +++--- 9 files changed, 29 insertions(+), 19 deletions(-) rename core/common/src/main/java/com/yapp/common/navigation/{ => destination}/TopLevelDestination.kt (89%) diff --git a/core/common/build.gradle.kts b/core/common/build.gradle.kts index 3b0c0f4..1650b2d 100644 --- a/core/common/build.gradle.kts +++ b/core/common/build.gradle.kts @@ -8,3 +8,8 @@ plugins { android { setNamespace("core.common") } + +dependencies { + implementation(projects.core.designsystem) + implementation(libs.compose.navigation) +} diff --git a/core/common/src/main/java/com/yapp/common/navigation/OrbitNavigator.kt b/core/common/src/main/java/com/yapp/common/navigation/OrbitNavigator.kt index d6a39e0..e313a67 100644 --- a/core/common/src/main/java/com/yapp/common/navigation/OrbitNavigator.kt +++ b/core/common/src/main/java/com/yapp/common/navigation/OrbitNavigator.kt @@ -7,9 +7,10 @@ import androidx.navigation.NavHostController import androidx.navigation.compose.currentBackStackEntryAsState import androidx.navigation.compose.rememberNavController import androidx.navigation.navOptions +import com.yapp.common.navigation.destination.TopLevelDestination class OrbitNavigator( - private val navController: NavHostController, + val navController: NavHostController, ) { val startDestination = Routes.Onboarding.ROUTE diff --git a/core/common/src/main/java/com/yapp/common/navigation/TopLevelDestination.kt b/core/common/src/main/java/com/yapp/common/navigation/destination/TopLevelDestination.kt similarity index 89% rename from core/common/src/main/java/com/yapp/common/navigation/TopLevelDestination.kt rename to core/common/src/main/java/com/yapp/common/navigation/destination/TopLevelDestination.kt index d453ecf..3a9fcc5 100644 --- a/core/common/src/main/java/com/yapp/common/navigation/TopLevelDestination.kt +++ b/core/common/src/main/java/com/yapp/common/navigation/destination/TopLevelDestination.kt @@ -1,7 +1,8 @@ -package com.yapp.common.navigation +package com.yapp.common.navigation.destination import androidx.annotation.DrawableRes import androidx.annotation.StringRes +import com.yapp.common.navigation.Routes enum class TopLevelDestination( @DrawableRes val iconId: Int, diff --git a/feature/home/build.gradle.kts b/feature/home/build.gradle.kts index 6c75091..228a644 100644 --- a/feature/home/build.gradle.kts +++ b/feature/home/build.gradle.kts @@ -10,6 +10,7 @@ android { dependencies { implementation(projects.core.ui) + implementation(projects.core.common) implementation(libs.orbit.core) implementation(libs.orbit.compose) implementation(libs.orbit.viewmodel) diff --git a/feature/home/src/main/java/com/yapp/home/HomeNavigation.kt b/feature/home/src/main/java/com/yapp/home/HomeNavigation.kt index d1b9ffc..33b0f98 100644 --- a/feature/home/src/main/java/com/yapp/home/HomeNavigation.kt +++ b/feature/home/src/main/java/com/yapp/home/HomeNavigation.kt @@ -2,20 +2,21 @@ package com.yapp.home import androidx.navigation.NavGraphBuilder import androidx.navigation.compose.composable +import androidx.navigation.compose.navigation import com.yapp.alarm.AlarmAddEditRoute +import com.yapp.common.navigation.Routes fun NavGraphBuilder.homeNavGraph() { - composable(route = HomeRoute.HOME) { - HomeRoute() - } + navigation( + route = Routes.Home.ROUTE, + startDestination = Routes.Home.HOME, + ) { + composable(route = Routes.Home.HOME) { + HomeRoute() + } - composable(route = HomeRoute.ALARM_ADD_EDIT) { - AlarmAddEditRoute() + composable(route = Routes.Home.ALARM_ADD_EDIT) { + AlarmAddEditRoute() + } } } - -object HomeRoute { - const val HOME = "home" - - const val ALARM_ADD_EDIT = "alarm_add_edit" -} diff --git a/feature/navigator/build.gradle.kts b/feature/navigator/build.gradle.kts index 8c427e8..93e9103 100644 --- a/feature/navigator/build.gradle.kts +++ b/feature/navigator/build.gradle.kts @@ -9,6 +9,7 @@ android { } dependencies { + implementation(projects.core.common) implementation(projects.feature.home) implementation(projects.feature.mypage) implementation(projects.feature.onboarding) diff --git a/feature/navigator/src/main/java/com/yapp/navigator/MainActivity.kt b/feature/navigator/src/main/java/com/yapp/navigator/MainActivity.kt index a9c2429..ed7df7c 100644 --- a/feature/navigator/src/main/java/com/yapp/navigator/MainActivity.kt +++ b/feature/navigator/src/main/java/com/yapp/navigator/MainActivity.kt @@ -16,8 +16,7 @@ class MainActivity : ComponentActivity() { requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT setContent { OrbitTheme { - // OnboardingRoute(onFinishOnboarding = {}) - MainScreen() + OrbitNavHost() } } } diff --git a/feature/navigator/src/main/java/com/yapp/navigator/OrbitBottomNavigationBar.kt b/feature/navigator/src/main/java/com/yapp/navigator/OrbitBottomNavigationBar.kt index 6cf04aa..82d9ac5 100644 --- a/feature/navigator/src/main/java/com/yapp/navigator/OrbitBottomNavigationBar.kt +++ b/feature/navigator/src/main/java/com/yapp/navigator/OrbitBottomNavigationBar.kt @@ -20,7 +20,7 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp -import com.yapp.common.navigation.TopLevelDestination +import com.yapp.common.navigation.destination.TopLevelDestination import kotlinx.collections.immutable.ImmutableList @Composable diff --git a/feature/navigator/src/main/java/com/yapp/navigator/OrbitNavHost.kt b/feature/navigator/src/main/java/com/yapp/navigator/OrbitNavHost.kt index eb6835d..d4781a4 100644 --- a/feature/navigator/src/main/java/com/yapp/navigator/OrbitNavHost.kt +++ b/feature/navigator/src/main/java/com/yapp/navigator/OrbitNavHost.kt @@ -6,6 +6,7 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.navigation.compose.NavHost import com.yapp.common.navigation.OrbitNavigator +import com.yapp.common.navigation.destination.TopLevelDestination import com.yapp.common.navigation.rememberOrbitNavigator import com.yapp.designsystem.theme.OrbitTheme import com.yapp.home.homeNavGraph @@ -22,9 +23,9 @@ internal fun OrbitNavHost( bottomBar = { OrbitBottomNavigationBar( visible = false, - currentTab = navigator.c, - entries = MainNavTab.entries.toImmutableList(), - onClickItem = navigator::navigate, + currentTab = navigator.currentTab, + entries = TopLevelDestination.entries.toImmutableList(), + onClickItem = navigator::navigateToTopLevelDestination, ) }, containerColor = OrbitTheme.colors.gray_900, From 6e67b67017b2134c7e45cd7b76970b131901c020 Mon Sep 17 00:00:00 2001 From: dongchyeon Date: Thu, 16 Jan 2025 22:17:03 +0900 Subject: [PATCH 07/11] =?UTF-8?q?[FEAT/#40]=20Home=20=EB=9D=BC=EC=9A=B0?= =?UTF-8?q?=ED=8C=85=20=EA=B2=BD=EB=A1=9C=EB=A5=BC=20HomeDestination?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EA=B4=80=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/yapp/common/navigation/Routes.kt | 4 ++++ .../navigation/destination/HomeDestination.kt | 9 +++++++++ .../home/{HomeNavigation.kt => HomeNavGraph.kt} | 10 +++++----- .../navigation/RememberOnboardingAppState.kt | 13 ------------- .../java/com/kms/onboarding/navigation/Routes.kt | 13 ------------- 5 files changed, 18 insertions(+), 31 deletions(-) create mode 100644 core/common/src/main/java/com/yapp/common/navigation/destination/HomeDestination.kt rename feature/home/src/main/java/com/yapp/home/{HomeNavigation.kt => HomeNavGraph.kt} (54%) delete mode 100644 feature/onboarding/src/main/java/com/kms/onboarding/navigation/RememberOnboardingAppState.kt delete mode 100644 feature/onboarding/src/main/java/com/kms/onboarding/navigation/Routes.kt diff --git a/core/common/src/main/java/com/yapp/common/navigation/Routes.kt b/core/common/src/main/java/com/yapp/common/navigation/Routes.kt index b25684a..d39203f 100644 --- a/core/common/src/main/java/com/yapp/common/navigation/Routes.kt +++ b/core/common/src/main/java/com/yapp/common/navigation/Routes.kt @@ -8,6 +8,10 @@ object Routes { const val BIRTHDAY = "onboarding_birthday" const val TIME_OF_BIRTH = "onboarding_time_of_birth" const val NAME = "onboarding_name" + const val GENDER = "onboarding_gender" + const val ACCESS = "onboarding_access" + const val COMPLETE_FIRST = "onboarding_complete_first" + const val COMPLETE_SECOND = "onboarding_complete_second" } object Home { diff --git a/core/common/src/main/java/com/yapp/common/navigation/destination/HomeDestination.kt b/core/common/src/main/java/com/yapp/common/navigation/destination/HomeDestination.kt new file mode 100644 index 0000000..81a71ae --- /dev/null +++ b/core/common/src/main/java/com/yapp/common/navigation/destination/HomeDestination.kt @@ -0,0 +1,9 @@ +package com.yapp.common.navigation.destination + +import com.yapp.common.navigation.Routes + +sealed class HomeDestination(val route: String) { + data object Route : HomeDestination(Routes.Home.ROUTE) + data object Home : HomeDestination(Routes.Home.HOME) + data object AlarmAddEdit : HomeDestination(Routes.Home.ALARM_ADD_EDIT) +} diff --git a/feature/home/src/main/java/com/yapp/home/HomeNavigation.kt b/feature/home/src/main/java/com/yapp/home/HomeNavGraph.kt similarity index 54% rename from feature/home/src/main/java/com/yapp/home/HomeNavigation.kt rename to feature/home/src/main/java/com/yapp/home/HomeNavGraph.kt index 33b0f98..0868ea2 100644 --- a/feature/home/src/main/java/com/yapp/home/HomeNavigation.kt +++ b/feature/home/src/main/java/com/yapp/home/HomeNavGraph.kt @@ -4,18 +4,18 @@ import androidx.navigation.NavGraphBuilder import androidx.navigation.compose.composable import androidx.navigation.compose.navigation import com.yapp.alarm.AlarmAddEditRoute -import com.yapp.common.navigation.Routes +import com.yapp.common.navigation.destination.HomeDestination fun NavGraphBuilder.homeNavGraph() { navigation( - route = Routes.Home.ROUTE, - startDestination = Routes.Home.HOME, + route = HomeDestination.Route.route, + startDestination = HomeDestination.Home.route, ) { - composable(route = Routes.Home.HOME) { + composable(route = HomeDestination.Home.route) { HomeRoute() } - composable(route = Routes.Home.ALARM_ADD_EDIT) { + composable(route = HomeDestination.AlarmAddEdit.route) { AlarmAddEditRoute() } } diff --git a/feature/onboarding/src/main/java/com/kms/onboarding/navigation/RememberOnboardingAppState.kt b/feature/onboarding/src/main/java/com/kms/onboarding/navigation/RememberOnboardingAppState.kt deleted file mode 100644 index f5d547f..0000000 --- a/feature/onboarding/src/main/java/com/kms/onboarding/navigation/RememberOnboardingAppState.kt +++ /dev/null @@ -1,13 +0,0 @@ -package com.kms.onboarding.navigation - -import androidx.compose.runtime.Composable -import androidx.compose.runtime.remember -import androidx.navigation.NavHostController -import androidx.navigation.compose.rememberNavController - -@Composable -fun rememberOnboardingAppState( - navController: NavHostController = rememberNavController(), -): OnboardingAppState { - return remember { OnboardingAppState(navController) } -} diff --git a/feature/onboarding/src/main/java/com/kms/onboarding/navigation/Routes.kt b/feature/onboarding/src/main/java/com/kms/onboarding/navigation/Routes.kt deleted file mode 100644 index 2664e97..0000000 --- a/feature/onboarding/src/main/java/com/kms/onboarding/navigation/Routes.kt +++ /dev/null @@ -1,13 +0,0 @@ -package com.kms.onboarding.navigation - -object Routes { - const val EXPLAIN = "onboarding_explain" - const val ALARM_TIME_SELECTION = "onboarding_alarm_time_selection" - const val BIRTHDAY = "onboarding_birthday" - const val TIME_OF_BIRTH = "onboarding_time_of_birth" - const val NAME = "onboarding_name" - const val GENDER = "onboarding_gender" - const val ACCESS = "onboarding_access" - const val COMPLETE_FIRST = "onboarding_complete_first" - const val COMPLETE_SECOND = "onboarding_complete_second" -} From 4cc42c50cd2c0ddf52d6942c0fc374d7d83ac151 Mon Sep 17 00:00:00 2001 From: dongchyeon Date: Thu, 16 Jan 2025 22:49:07 +0900 Subject: [PATCH 08/11] =?UTF-8?q?[FEAT/#40]=20SharedViewModel=20=ED=99=95?= =?UTF-8?q?=EC=9E=A5=ED=95=A8=EC=88=98=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../extensions/SharedViewModelExtensions.kt | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 core/common/src/main/java/com/yapp/common/navigation/extensions/SharedViewModelExtensions.kt diff --git a/core/common/src/main/java/com/yapp/common/navigation/extensions/SharedViewModelExtensions.kt b/core/common/src/main/java/com/yapp/common/navigation/extensions/SharedViewModelExtensions.kt new file mode 100644 index 0000000..f09dc15 --- /dev/null +++ b/core/common/src/main/java/com/yapp/common/navigation/extensions/SharedViewModelExtensions.kt @@ -0,0 +1,17 @@ +package com.yapp.common.navigation.extensions + +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewmodel.compose.viewModel +import androidx.navigation.NavBackStackEntry +import androidx.navigation.NavController + +@Composable +inline fun NavBackStackEntry.sharedViewModel(navController: NavController): T { + val navGraphRoute = destination.parent?.route ?: return viewModel() + val parentEntry = remember(this) { + navController.getBackStackEntry(navGraphRoute) + } + return viewModel(parentEntry) +} From eba7e4ffc33fad4580590666475aeeca5240bc5f Mon Sep 17 00:00:00 2001 From: dongchyeon Date: Fri, 17 Jan 2025 00:36:09 +0900 Subject: [PATCH 09/11] =?UTF-8?q?[FEAT/#40]=20Onboarding=20=EA=B7=B8?= =?UTF-8?q?=EB=9E=98=ED=94=84=20NavGraph=20-=20Route=20=ED=98=95=ED=83=9C?= =?UTF-8?q?=EB=A1=9C=20=EA=B4=80=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/common/build.gradle.kts | 1 + .../yapp/common/navigation/OrbitNavigator.kt | 17 +- .../destination/MyPageDestination.kt | 8 + .../destination/OnboardingDestination.kt | 24 ++ .../main/java/com/yapp/home/HomeNavGraph.kt | 5 +- feature/onboarding/build.gradle.kts | 1 + .../com/kms/onboarding/OnBoardingScreen.kt | 45 ---- .../kms/onboarding/OnboardingAccessScreen.kt | 19 ++ .../OnboardingAlarmTimeSelectionScreen.kt | 16 ++ .../onboarding/OnboardingBirthdayScreen.kt | 17 ++ .../onboarding/OnboardingCompleteScreen1.kt | 15 ++ .../onboarding/OnboardingCompleteScreen2.kt | 16 ++ .../kms/onboarding/OnboardingExplainScreen.kt | 14 ++ .../kms/onboarding/OnboardingGenderScreen.kt | 21 ++ .../kms/onboarding/OnboardingNameScreen.kt | 20 ++ .../com/kms/onboarding/OnboardingNavGraph.kt | 213 ++++++++++++++++++ .../onboarding/OnboardingTimeOfBirthScreen.kt | 29 +++ .../com/kms/onboarding/OnboardingViewModel.kt | 2 +- .../navigation/OnboardingAppState.kt | 25 -- .../navigation/OnboardingDestination.kt | 21 -- .../navigation/OnboardingNavGraph.kt | 148 ------------ 21 files changed, 435 insertions(+), 242 deletions(-) create mode 100644 core/common/src/main/java/com/yapp/common/navigation/destination/MyPageDestination.kt create mode 100644 core/common/src/main/java/com/yapp/common/navigation/destination/OnboardingDestination.kt create mode 100644 feature/onboarding/src/main/java/com/kms/onboarding/OnboardingNavGraph.kt delete mode 100644 feature/onboarding/src/main/java/com/kms/onboarding/navigation/OnboardingAppState.kt delete mode 100644 feature/onboarding/src/main/java/com/kms/onboarding/navigation/OnboardingDestination.kt delete mode 100644 feature/onboarding/src/main/java/com/kms/onboarding/navigation/OnboardingNavGraph.kt diff --git a/core/common/build.gradle.kts b/core/common/build.gradle.kts index 1650b2d..d65e802 100644 --- a/core/common/build.gradle.kts +++ b/core/common/build.gradle.kts @@ -3,6 +3,7 @@ import com.yapp.convention.setNamespace plugins { id("orbit.android.library") id("orbit.android.hilt") + id("orbit.android.compose") } android { diff --git a/core/common/src/main/java/com/yapp/common/navigation/OrbitNavigator.kt b/core/common/src/main/java/com/yapp/common/navigation/OrbitNavigator.kt index e313a67..25ed69d 100644 --- a/core/common/src/main/java/com/yapp/common/navigation/OrbitNavigator.kt +++ b/core/common/src/main/java/com/yapp/common/navigation/OrbitNavigator.kt @@ -7,12 +7,13 @@ import androidx.navigation.NavHostController import androidx.navigation.compose.currentBackStackEntryAsState import androidx.navigation.compose.rememberNavController import androidx.navigation.navOptions +import com.yapp.common.navigation.destination.OnboardingDestination import com.yapp.common.navigation.destination.TopLevelDestination class OrbitNavigator( val navController: NavHostController, ) { - val startDestination = Routes.Onboarding.ROUTE + val startDestination = OnboardingDestination.Route.route private val currentDestination: NavDestination? @Composable get() = navController @@ -23,6 +24,20 @@ class OrbitNavigator( ?.route ?.let(TopLevelDestination.Companion::find) + fun navigateTo(route: String, popUpTo: String? = null, inclusive: Boolean = false) { + navController.navigate(route) { + popUpTo?.let { + popUpTo(it) { this.inclusive = inclusive } + } + launchSingleTop = true + restoreState = true + } + } + + fun navigateBack() { + navController.popBackStack() + } + fun navigateToTopLevelDestination(tab: TopLevelDestination) { val navOptions = navOptions { popUpTo(Routes.Home.ROUTE) { diff --git a/core/common/src/main/java/com/yapp/common/navigation/destination/MyPageDestination.kt b/core/common/src/main/java/com/yapp/common/navigation/destination/MyPageDestination.kt new file mode 100644 index 0000000..9ccb7d9 --- /dev/null +++ b/core/common/src/main/java/com/yapp/common/navigation/destination/MyPageDestination.kt @@ -0,0 +1,8 @@ +package com.yapp.common.navigation.destination + +import com.yapp.common.navigation.Routes + +sealed class MyPageDestination(val route: String) { + data object Route : MyPageDestination(Routes.MyPage.ROUTE) + data object MyPage : MyPageDestination(Routes.MyPage.MYPAGE) +} diff --git a/core/common/src/main/java/com/yapp/common/navigation/destination/OnboardingDestination.kt b/core/common/src/main/java/com/yapp/common/navigation/destination/OnboardingDestination.kt new file mode 100644 index 0000000..4ad4df5 --- /dev/null +++ b/core/common/src/main/java/com/yapp/common/navigation/destination/OnboardingDestination.kt @@ -0,0 +1,24 @@ +package com.yapp.common.navigation.destination + +import com.yapp.common.navigation.Routes + +sealed class OnboardingDestination(val route: String) { + data object Route : OnboardingDestination(Routes.Onboarding.ROUTE) + data object Explain : OnboardingDestination(Routes.Onboarding.EXPLAIN) + data object AlarmTimeSelection : OnboardingDestination(Routes.Onboarding.ALARM_TIME_SELECTION) + data object Birthday : OnboardingDestination(Routes.Onboarding.BIRTHDAY) + data object TimeOfBirth : OnboardingDestination(Routes.Onboarding.TIME_OF_BIRTH) + data object Name : OnboardingDestination(Routes.Onboarding.NAME) + data object Gender : OnboardingDestination(Routes.Onboarding.GENDER) + data object Access : OnboardingDestination(Routes.Onboarding.ACCESS) + data object Complete1 : OnboardingDestination(Routes.Onboarding.COMPLETE_FIRST) + data object Complete2 : OnboardingDestination(Routes.Onboarding.COMPLETE_SECOND) + + companion object { + private val routes = listOf(Explain, AlarmTimeSelection, Birthday, TimeOfBirth, Name, Gender, Access, Complete1, Complete2) + + fun nextRoute(currentStep: Int): String? { + return routes.getOrNull(currentStep)?.route + } + } +} diff --git a/feature/home/src/main/java/com/yapp/home/HomeNavGraph.kt b/feature/home/src/main/java/com/yapp/home/HomeNavGraph.kt index 0868ea2..e4e5bda 100644 --- a/feature/home/src/main/java/com/yapp/home/HomeNavGraph.kt +++ b/feature/home/src/main/java/com/yapp/home/HomeNavGraph.kt @@ -4,9 +4,12 @@ import androidx.navigation.NavGraphBuilder import androidx.navigation.compose.composable import androidx.navigation.compose.navigation import com.yapp.alarm.AlarmAddEditRoute +import com.yapp.common.navigation.OrbitNavigator import com.yapp.common.navigation.destination.HomeDestination -fun NavGraphBuilder.homeNavGraph() { +fun NavGraphBuilder.homeNavGraph( + navigator: OrbitNavigator, +) { navigation( route = HomeDestination.Route.route, startDestination = HomeDestination.Home.route, diff --git a/feature/onboarding/build.gradle.kts b/feature/onboarding/build.gradle.kts index 19c7620..8380aa6 100644 --- a/feature/onboarding/build.gradle.kts +++ b/feature/onboarding/build.gradle.kts @@ -10,6 +10,7 @@ android { dependencies { implementation(projects.core.ui) + implementation(projects.core.common) implementation(libs.orbit.core) implementation(libs.orbit.compose) implementation(libs.orbit.viewmodel) diff --git a/feature/onboarding/src/main/java/com/kms/onboarding/OnBoardingScreen.kt b/feature/onboarding/src/main/java/com/kms/onboarding/OnBoardingScreen.kt index dd011c4..eda59c5 100644 --- a/feature/onboarding/src/main/java/com/kms/onboarding/OnBoardingScreen.kt +++ b/feature/onboarding/src/main/java/com/kms/onboarding/OnBoardingScreen.kt @@ -8,56 +8,11 @@ import androidx.compose.foundation.layout.imePadding import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.layout.statusBarsPadding import androidx.compose.runtime.Composable -import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier -import androidx.hilt.navigation.compose.hiltViewModel -import androidx.lifecycle.compose.collectAsStateWithLifecycle -import androidx.navigation.compose.NavHost import com.kms.onboarding.component.OnBoardingTopAppBar import com.kms.onboarding.component.OnboardingBottomBar -import com.kms.onboarding.navigation.onboardingNavGraph -import com.kms.onboarding.navigation.rememberOnboardingAppState import com.yapp.designsystem.theme.OrbitTheme -@Composable -fun OnboardingRoute( - viewModel: OnboardingViewModel = hiltViewModel(), - onFinishOnboarding: () -> Unit, -) { - val appState = rememberOnboardingAppState() - val state by viewModel.container.stateFlow.collectAsStateWithLifecycle() - - LaunchedEffect(viewModel) { - viewModel.container.sideEffectFlow.collect { sideEffect -> - when (sideEffect) { - is OnboardingContract.SideEffect.Navigate -> appState.navigateTo( - route = sideEffect.route, - popUpTo = sideEffect.popUpTo, - inclusive = sideEffect.inclusive, - ) - - OnboardingContract.SideEffect.NavigateBack -> appState.navigateBack() - OnboardingContract.SideEffect.OnboardingCompleted -> onFinishOnboarding() - OnboardingContract.SideEffect.ResetField -> viewModel.processAction( - OnboardingContract.Action.Reset, - ) - } - } - } - - NavHost( - navController = appState.navController, - startDestination = appState.startDestination, - ) { - onboardingNavGraph( - stateProvider = { state }, - eventDispatcher = { viewModel.processAction(it) }, - onFinishOnboarding = onFinishOnboarding, - ) - } -} - @Composable fun OnboardingScreen( currentStep: Int, diff --git a/feature/onboarding/src/main/java/com/kms/onboarding/OnboardingAccessScreen.kt b/feature/onboarding/src/main/java/com/kms/onboarding/OnboardingAccessScreen.kt index aef3d16..d4a2194 100644 --- a/feature/onboarding/src/main/java/com/kms/onboarding/OnboardingAccessScreen.kt +++ b/feature/onboarding/src/main/java/com/kms/onboarding/OnboardingAccessScreen.kt @@ -8,6 +8,7 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.wrapContentSize 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.ui.Alignment @@ -16,10 +17,28 @@ import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.Preview +import androidx.lifecycle.compose.collectAsStateWithLifecycle +import com.yapp.common.navigation.OrbitNavigator import com.yapp.designsystem.theme.OrbitTheme import com.yapp.ui.utils.heightForScreenPercentage import feature.onboarding.R +@Composable +fun OnboardingAccessRoute( + navigator: OrbitNavigator, + viewModel: OnboardingViewModel, +) { + val state by viewModel.container.stateFlow.collectAsStateWithLifecycle() + + OnboardingAccessScreen( + state = state, + currentStep = 6, + totalSteps = 6, + onNextClick = { viewModel.processAction(OnboardingContract.Action.NextStep) }, + onBackClick = { viewModel.processAction(OnboardingContract.Action.PreviousStep) }, + ) +} + @Composable fun OnboardingAccessScreen( state: OnboardingContract.State, diff --git a/feature/onboarding/src/main/java/com/kms/onboarding/OnboardingAlarmTimeSelectionScreen.kt b/feature/onboarding/src/main/java/com/kms/onboarding/OnboardingAlarmTimeSelectionScreen.kt index 9a94fb3..3cf0586 100644 --- a/feature/onboarding/src/main/java/com/kms/onboarding/OnboardingAlarmTimeSelectionScreen.kt +++ b/feature/onboarding/src/main/java/com/kms/onboarding/OnboardingAlarmTimeSelectionScreen.kt @@ -16,11 +16,27 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp +import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.yapp.designsystem.theme.OrbitTheme import com.yapp.ui.component.timepicker.OrbitPicker import com.yapp.ui.utils.heightForScreenPercentage import feature.onboarding.R +@Composable +fun OnboardingAlarmTimeSelectionRoute( + viewModel: OnboardingViewModel, +) { + val state by viewModel.container.stateFlow.collectAsStateWithLifecycle() + + OnboardingAlarmTimeSelectionScreen( + state = state, + currentStep = 1, + totalSteps = 6, + onNextClick = { viewModel.processAction(OnboardingContract.Action.NextStep) }, + onBackClick = { viewModel.processAction(OnboardingContract.Action.PreviousStep) }, + ) +} + @Composable fun OnboardingAlarmTimeSelectionScreen( state: OnboardingContract.State, diff --git a/feature/onboarding/src/main/java/com/kms/onboarding/OnboardingBirthdayScreen.kt b/feature/onboarding/src/main/java/com/kms/onboarding/OnboardingBirthdayScreen.kt index 94d7994..98e4815 100644 --- a/feature/onboarding/src/main/java/com/kms/onboarding/OnboardingBirthdayScreen.kt +++ b/feature/onboarding/src/main/java/com/kms/onboarding/OnboardingBirthdayScreen.kt @@ -8,16 +8,33 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp +import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.yapp.designsystem.theme.OrbitTheme import com.yapp.ui.component.timepicker.OrbitYearMonthPicker import com.yapp.ui.utils.heightForScreenPercentage import feature.onboarding.R +@Composable +fun OnboardingBirthdayRoute( + viewModel: OnboardingViewModel, +) { + val state by viewModel.container.stateFlow.collectAsStateWithLifecycle() + + OnboardingBirthdayScreen( + state = state, + currentStep = 2, + totalSteps = 6, + onNextClick = { viewModel.processAction(OnboardingContract.Action.NextStep) }, + onBackClick = { viewModel.processAction(OnboardingContract.Action.PreviousStep) }, + ) +} + @Composable fun OnboardingBirthdayScreen( state: OnboardingContract.State, diff --git a/feature/onboarding/src/main/java/com/kms/onboarding/OnboardingCompleteScreen1.kt b/feature/onboarding/src/main/java/com/kms/onboarding/OnboardingCompleteScreen1.kt index b3c6b11..e583d20 100644 --- a/feature/onboarding/src/main/java/com/kms/onboarding/OnboardingCompleteScreen1.kt +++ b/feature/onboarding/src/main/java/com/kms/onboarding/OnboardingCompleteScreen1.kt @@ -7,17 +7,32 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.wrapContentSize import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.Preview +import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.yapp.designsystem.theme.OrbitTheme import com.yapp.ui.component.lottie.LottieAnimation import com.yapp.ui.utils.heightForScreenPercentage import com.yapp.ui.utils.paddingForScreenPercentage import feature.onboarding.R +@Composable +fun OnboardingCompleteRoute( + viewModel: OnboardingViewModel, +) { + val state by viewModel.container.stateFlow.collectAsStateWithLifecycle() + + OnboardingCompleteScreen1( + state = state, + onNextClick = { viewModel.processAction(OnboardingContract.Action.NextStep) }, + onBackClick = { viewModel.processAction(OnboardingContract.Action.PreviousStep) }, + ) +} + @Composable fun OnboardingCompleteScreen1( state: OnboardingContract.State, diff --git a/feature/onboarding/src/main/java/com/kms/onboarding/OnboardingCompleteScreen2.kt b/feature/onboarding/src/main/java/com/kms/onboarding/OnboardingCompleteScreen2.kt index 6dee20a..466d06e 100644 --- a/feature/onboarding/src/main/java/com/kms/onboarding/OnboardingCompleteScreen2.kt +++ b/feature/onboarding/src/main/java/com/kms/onboarding/OnboardingCompleteScreen2.kt @@ -13,6 +13,7 @@ import androidx.compose.foundation.layout.statusBarsPadding import androidx.compose.foundation.layout.wrapContentSize import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.layout.ContentScale @@ -20,6 +21,7 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp +import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.kms.onboarding.component.OnBoardingTopAppBar import com.yapp.designsystem.theme.OrbitTheme import com.yapp.ui.component.button.OrbitButton @@ -28,6 +30,20 @@ import com.yapp.ui.utils.heightForScreenPercentage import com.yapp.ui.utils.paddingForScreenPercentage import feature.onboarding.R +@Composable +fun OnboardingCompleteRoute2( + viewModel: OnboardingViewModel, + onFinishOnboarding: () -> Unit, +) { + val state by viewModel.container.stateFlow.collectAsStateWithLifecycle() + + OnboardingCompleteScreen2( + state = state, + onNextClick = { onFinishOnboarding() }, + onBackClick = { viewModel.processAction(OnboardingContract.Action.PreviousStep) }, + ) +} + @Composable fun OnboardingCompleteScreen2( state: OnboardingContract.State, diff --git a/feature/onboarding/src/main/java/com/kms/onboarding/OnboardingExplainScreen.kt b/feature/onboarding/src/main/java/com/kms/onboarding/OnboardingExplainScreen.kt index aeb3846..29bc195 100644 --- a/feature/onboarding/src/main/java/com/kms/onboarding/OnboardingExplainScreen.kt +++ b/feature/onboarding/src/main/java/com/kms/onboarding/OnboardingExplainScreen.kt @@ -7,17 +7,31 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp +import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.kms.onboarding.component.GifImage import com.yapp.designsystem.theme.OrbitTheme import com.yapp.ui.utils.heightForScreenPercentage import com.yapp.ui.utils.paddingForScreenPercentage import feature.onboarding.R +@Composable +fun OnboardingExplainRoute( + viewModel: OnboardingViewModel, +) { + val state by viewModel.container.stateFlow.collectAsStateWithLifecycle() + + OnboardingExplainScreen( + state = state, + onNextClick = { viewModel.processAction(OnboardingContract.Action.NextStep) }, + ) +} + @Composable fun OnboardingExplainScreen( state: OnboardingContract.State, diff --git a/feature/onboarding/src/main/java/com/kms/onboarding/OnboardingGenderScreen.kt b/feature/onboarding/src/main/java/com/kms/onboarding/OnboardingGenderScreen.kt index e9ef1a9..5b3bb18 100644 --- a/feature/onboarding/src/main/java/com/kms/onboarding/OnboardingGenderScreen.kt +++ b/feature/onboarding/src/main/java/com/kms/onboarding/OnboardingGenderScreen.kt @@ -9,11 +9,13 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.Preview +import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.kms.onboarding.component.OnboardingGenderToggle import com.kms.onboarding.component.UserInfoBottomSheet import com.yapp.designsystem.theme.OrbitTheme @@ -22,6 +24,25 @@ import com.yapp.ui.utils.paddingForScreenPercentage import com.yapp.ui.utils.widthForScreenPercentage import feature.onboarding.R +@Composable +fun OnboardingGenderRoute( + viewModel: OnboardingViewModel, +) { + val state by viewModel.container.stateFlow.collectAsStateWithLifecycle() + + OnboardingGenderScreen( + state = state, + currentStep = 5, + totalSteps = 6, + onNextClick = { viewModel.processAction(OnboardingContract.Action.NextStep) }, + onBackClick = { viewModel.processAction(OnboardingContract.Action.PreviousStep) }, + onGenderSelect = { gender -> + viewModel.processAction(OnboardingContract.Action.UpdateGender(gender)) + }, + toggleBottomSheet = { viewModel.processAction(OnboardingContract.Action.ToggleBottomSheet) }, + ) +} + @OptIn(ExperimentalMaterial3Api::class) @Composable fun OnboardingGenderScreen( diff --git a/feature/onboarding/src/main/java/com/kms/onboarding/OnboardingNameScreen.kt b/feature/onboarding/src/main/java/com/kms/onboarding/OnboardingNameScreen.kt index 290309e..cb83451 100644 --- a/feature/onboarding/src/main/java/com/kms/onboarding/OnboardingNameScreen.kt +++ b/feature/onboarding/src/main/java/com/kms/onboarding/OnboardingNameScreen.kt @@ -6,11 +6,13 @@ import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.Preview +import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.yapp.designsystem.theme.OrbitTheme import com.yapp.ui.component.textfield.OrbitTextField import com.yapp.ui.extensions.customClickable @@ -18,6 +20,24 @@ import com.yapp.ui.utils.heightForScreenPercentage import com.yapp.ui.utils.paddingForScreenPercentage import feature.onboarding.R +@Composable +fun OnboardingNameRoute( + viewModel: OnboardingViewModel, +) { + val state by viewModel.container.stateFlow.collectAsStateWithLifecycle() + + OnboardingNameScreen( + state = state, + currentStep = 4, + totalSteps = 6, + onNextClick = { viewModel.processAction(OnboardingContract.Action.NextStep) }, + onBackClick = { viewModel.processAction(OnboardingContract.Action.PreviousStep) }, + onTextChange = { value -> + viewModel.processAction(OnboardingContract.Action.UpdateField(value, OnboardingContract.FieldType.NAME)) + }, + ) +} + @Composable fun OnboardingNameScreen( state: OnboardingContract.State, diff --git a/feature/onboarding/src/main/java/com/kms/onboarding/OnboardingNavGraph.kt b/feature/onboarding/src/main/java/com/kms/onboarding/OnboardingNavGraph.kt new file mode 100644 index 0000000..42e5086 --- /dev/null +++ b/feature/onboarding/src/main/java/com/kms/onboarding/OnboardingNavGraph.kt @@ -0,0 +1,213 @@ +package com.kms.onboarding + +import androidx.compose.runtime.LaunchedEffect +import androidx.navigation.NavGraphBuilder +import androidx.navigation.compose.composable +import androidx.navigation.navigation +import com.yapp.common.navigation.OrbitNavigator +import com.yapp.common.navigation.destination.OnboardingDestination +import com.yapp.common.navigation.extensions.sharedViewModel + +fun NavGraphBuilder.onboardingNavGraph( + navigator: OrbitNavigator, + onFinishOnboarding: () -> Unit, +) { + navigation( + route = OnboardingDestination.Route.route, + startDestination = OnboardingDestination.Explain.route, + ) { + composable(OnboardingDestination.Explain.route) { + val viewModel = it.sharedViewModel(navigator.navController) + + LaunchedEffect(viewModel) { + viewModel.container.sideEffectFlow.collect { sideEffect -> + handleSideEffect( + sideEffect = sideEffect, + navigator = navigator, + viewModel = viewModel, + onFinishOnboarding = onFinishOnboarding, + ) + } + } + + OnboardingExplainRoute( + viewModel = viewModel, + ) + } + + composable(OnboardingDestination.AlarmTimeSelection.route) { + val viewModel = it.sharedViewModel(navigator.navController) + + LaunchedEffect(viewModel) { + viewModel.container.sideEffectFlow.collect { sideEffect -> + handleSideEffect( + sideEffect = sideEffect, + navigator = navigator, + viewModel = viewModel, + onFinishOnboarding = onFinishOnboarding, + ) + } + } + + OnboardingAlarmTimeSelectionRoute( + viewModel = viewModel, + ) + } + + composable(OnboardingDestination.Birthday.route) { + val viewModel = it.sharedViewModel(navigator.navController) + + LaunchedEffect(viewModel) { + viewModel.container.sideEffectFlow.collect { sideEffect -> + handleSideEffect( + sideEffect = sideEffect, + navigator = navigator, + viewModel = viewModel, + onFinishOnboarding = onFinishOnboarding, + ) + } + } + + OnboardingBirthdayRoute( + viewModel = viewModel, + ) + } + + composable(OnboardingDestination.TimeOfBirth.route) { + val viewModel = it.sharedViewModel(navigator.navController) + + LaunchedEffect(viewModel) { + viewModel.container.sideEffectFlow.collect { sideEffect -> + handleSideEffect( + sideEffect = sideEffect, + navigator = navigator, + viewModel = viewModel, + onFinishOnboarding = onFinishOnboarding, + ) + } + } + + OnboardingTimeOfBirthRoute( + viewModel = viewModel, + ) + } + + composable(OnboardingDestination.Name.route) { + val viewModel = it.sharedViewModel(navigator.navController) + + LaunchedEffect(viewModel) { + viewModel.container.sideEffectFlow.collect { sideEffect -> + handleSideEffect( + sideEffect = sideEffect, + navigator = navigator, + viewModel = viewModel, + onFinishOnboarding = onFinishOnboarding, + ) + } + } + + OnboardingNameRoute( + viewModel = viewModel, + ) + } + + composable(OnboardingDestination.Gender.route) { + val viewModel = it.sharedViewModel(navigator.navController) + + LaunchedEffect(viewModel) { + viewModel.container.sideEffectFlow.collect { sideEffect -> + handleSideEffect( + sideEffect = sideEffect, + navigator = navigator, + viewModel = viewModel, + onFinishOnboarding = onFinishOnboarding, + ) + } + } + + OnboardingGenderRoute( + viewModel = viewModel, + ) + } + + composable(OnboardingDestination.Access.route) { + val viewModel = it.sharedViewModel(navigator.navController) + + LaunchedEffect(viewModel) { + viewModel.container.sideEffectFlow.collect { sideEffect -> + handleSideEffect( + sideEffect = sideEffect, + navigator = navigator, + viewModel = viewModel, + onFinishOnboarding = onFinishOnboarding, + ) + } + } + + OnboardingAccessRoute( + navigator = navigator, + viewModel = viewModel, + ) + } + + composable(OnboardingDestination.Complete1.route) { + val viewModel = it.sharedViewModel(navigator.navController) + + LaunchedEffect(viewModel) { + viewModel.container.sideEffectFlow.collect { sideEffect -> + handleSideEffect( + sideEffect = sideEffect, + navigator = navigator, + viewModel = viewModel, + onFinishOnboarding = onFinishOnboarding, + ) + } + } + + OnboardingCompleteRoute( + viewModel = viewModel, + ) + } + + composable(OnboardingDestination.Complete2.route) { + val viewModel = it.sharedViewModel(navigator.navController) + + LaunchedEffect(viewModel) { + viewModel.container.sideEffectFlow.collect { sideEffect -> + handleSideEffect( + sideEffect = sideEffect, + navigator = navigator, + viewModel = viewModel, + onFinishOnboarding = onFinishOnboarding, + ) + } + } + + OnboardingCompleteRoute2( + viewModel = viewModel, + onFinishOnboarding = onFinishOnboarding, + ) + } + } +} + +private fun handleSideEffect( + sideEffect: OnboardingContract.SideEffect, + navigator: OrbitNavigator, + viewModel: OnboardingViewModel, + onFinishOnboarding: () -> Unit, +) { + when (sideEffect) { + is OnboardingContract.SideEffect.Navigate -> navigator.navigateTo( + route = sideEffect.route, + popUpTo = sideEffect.popUpTo, + inclusive = sideEffect.inclusive, + ) + + OnboardingContract.SideEffect.NavigateBack -> navigator.navigateBack() + OnboardingContract.SideEffect.OnboardingCompleted -> onFinishOnboarding() + OnboardingContract.SideEffect.ResetField -> viewModel.processAction( + OnboardingContract.Action.Reset, + ) + } +} diff --git a/feature/onboarding/src/main/java/com/kms/onboarding/OnboardingTimeOfBirthScreen.kt b/feature/onboarding/src/main/java/com/kms/onboarding/OnboardingTimeOfBirthScreen.kt index 6eb78d7..84578cc 100644 --- a/feature/onboarding/src/main/java/com/kms/onboarding/OnboardingTimeOfBirthScreen.kt +++ b/feature/onboarding/src/main/java/com/kms/onboarding/OnboardingTimeOfBirthScreen.kt @@ -20,11 +20,14 @@ import androidx.compose.ui.ExperimentalComposeUiApi import androidx.compose.ui.Modifier import androidx.compose.ui.input.pointer.pointerInteropFilter import androidx.compose.ui.platform.LocalFocusManager +import androidx.compose.ui.platform.LocalSoftwareKeyboardController +import androidx.compose.ui.platform.SoftwareKeyboardController import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp +import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.yapp.designsystem.theme.OrbitTheme import com.yapp.ui.component.textfield.OrbitTextField import com.yapp.ui.extensions.customClickable @@ -32,6 +35,32 @@ import com.yapp.ui.utils.heightForScreenPercentage import com.yapp.ui.utils.paddingForScreenPercentage import feature.onboarding.R +@Composable +fun OnboardingTimeOfBirthRoute( + viewModel: OnboardingViewModel, +) { + val state by viewModel.container.stateFlow.collectAsStateWithLifecycle() + + val keyboardController: SoftwareKeyboardController? = LocalSoftwareKeyboardController.current + + OnboardingTimeOfBirthScreen( + state = state, + currentStep = 3, + totalSteps = 6, + onNextClick = { + viewModel.processAction(OnboardingContract.Action.NextStep) + viewModel.processAction(OnboardingContract.Action.Reset) + keyboardController?.hide() + }, + onBackClick = { + viewModel.processAction(OnboardingContract.Action.PreviousStep) + }, + onTextChange = { value -> + viewModel.processAction(OnboardingContract.Action.UpdateField(value, OnboardingContract.FieldType.TIME)) + }, + ) +} + @OptIn(ExperimentalComposeUiApi::class) @Composable fun OnboardingTimeOfBirthScreen( diff --git a/feature/onboarding/src/main/java/com/kms/onboarding/OnboardingViewModel.kt b/feature/onboarding/src/main/java/com/kms/onboarding/OnboardingViewModel.kt index 4d9cb33..8a85fc4 100644 --- a/feature/onboarding/src/main/java/com/kms/onboarding/OnboardingViewModel.kt +++ b/feature/onboarding/src/main/java/com/kms/onboarding/OnboardingViewModel.kt @@ -2,7 +2,7 @@ package com.kms.onboarding import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.viewModelScope -import com.kms.onboarding.navigation.OnboardingDestination +import com.yapp.common.navigation.destination.OnboardingDestination import com.yapp.ui.base.BaseViewModel import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.delay diff --git a/feature/onboarding/src/main/java/com/kms/onboarding/navigation/OnboardingAppState.kt b/feature/onboarding/src/main/java/com/kms/onboarding/navigation/OnboardingAppState.kt deleted file mode 100644 index ab926ea..0000000 --- a/feature/onboarding/src/main/java/com/kms/onboarding/navigation/OnboardingAppState.kt +++ /dev/null @@ -1,25 +0,0 @@ -package com.kms.onboarding.navigation - -import androidx.compose.runtime.Stable -import androidx.navigation.NavHostController - -@Stable -class OnboardingAppState( - val navController: NavHostController, -) { - val startDestination: String = OnboardingDestination.Explain.route - - fun navigateTo(route: String, popUpTo: String? = null, inclusive: Boolean = false) { - navController.navigate(route) { - popUpTo?.let { - popUpTo(it) { this.inclusive = inclusive } - } - launchSingleTop = true - restoreState = true - } - } - - fun navigateBack() { - navController.popBackStack() - } -} diff --git a/feature/onboarding/src/main/java/com/kms/onboarding/navigation/OnboardingDestination.kt b/feature/onboarding/src/main/java/com/kms/onboarding/navigation/OnboardingDestination.kt deleted file mode 100644 index 99a99ae..0000000 --- a/feature/onboarding/src/main/java/com/kms/onboarding/navigation/OnboardingDestination.kt +++ /dev/null @@ -1,21 +0,0 @@ -package com.kms.onboarding.navigation - -sealed class OnboardingDestination(val route: String) { - data object Explain : OnboardingDestination(Routes.EXPLAIN) - data object AlarmTimeSelection : OnboardingDestination(Routes.ALARM_TIME_SELECTION) - data object Birthday : OnboardingDestination(Routes.BIRTHDAY) - data object TimeOfBirth : OnboardingDestination(Routes.TIME_OF_BIRTH) - data object Name : OnboardingDestination(Routes.NAME) - data object Gender : OnboardingDestination(Routes.GENDER) - data object Access : OnboardingDestination(Routes.ACCESS) - data object Complete1 : OnboardingDestination(Routes.COMPLETE_FIRST) - data object Complete2 : OnboardingDestination(Routes.COMPLETE_SECOND) - - companion object { - private val routes = listOf(Explain, AlarmTimeSelection, Birthday, TimeOfBirth, Name, Gender, Access, Complete1, Complete2) - - fun nextRoute(currentStep: Int): String? { - return routes.getOrNull(currentStep)?.route - } - } -} diff --git a/feature/onboarding/src/main/java/com/kms/onboarding/navigation/OnboardingNavGraph.kt b/feature/onboarding/src/main/java/com/kms/onboarding/navigation/OnboardingNavGraph.kt deleted file mode 100644 index d108f79..0000000 --- a/feature/onboarding/src/main/java/com/kms/onboarding/navigation/OnboardingNavGraph.kt +++ /dev/null @@ -1,148 +0,0 @@ -package com.kms.onboarding.navigation - -import androidx.compose.ui.platform.LocalSoftwareKeyboardController -import androidx.navigation.NavGraphBuilder -import androidx.navigation.compose.composable -import com.kms.onboarding.OnboardingAccessScreen -import com.kms.onboarding.OnboardingAlarmTimeSelectionScreen -import com.kms.onboarding.OnboardingBirthdayScreen -import com.kms.onboarding.OnboardingCompleteScreen1 -import com.kms.onboarding.OnboardingCompleteScreen2 -import com.kms.onboarding.OnboardingContract -import com.kms.onboarding.OnboardingExplainScreen -import com.kms.onboarding.OnboardingGenderScreen -import com.kms.onboarding.OnboardingNameScreen -import com.kms.onboarding.OnboardingTimeOfBirthScreen - -fun NavGraphBuilder.onboardingNavGraph( - stateProvider: () -> OnboardingContract.State, - eventDispatcher: (OnboardingContract.Action) -> Unit, - onFinishOnboarding: () -> Unit, -) { - composable(OnboardingDestination.Explain.route) { - OnboardingExplainScreen( - state = stateProvider(), - onNextClick = { - eventDispatcher(OnboardingContract.Action.NextStep) - }, - ) - } - - composable(OnboardingDestination.AlarmTimeSelection.route) { - OnboardingAlarmTimeSelectionScreen( - state = stateProvider(), - currentStep = 1, - totalSteps = 6, - onNextClick = { - eventDispatcher(OnboardingContract.Action.NextStep) - }, - onBackClick = { - eventDispatcher(OnboardingContract.Action.PreviousStep) - }, - ) - } - - composable(OnboardingDestination.Birthday.route) { - OnboardingBirthdayScreen( - state = stateProvider(), - currentStep = 2, - totalSteps = 6, - onNextClick = { - eventDispatcher(OnboardingContract.Action.NextStep) - }, - onBackClick = { - eventDispatcher(OnboardingContract.Action.PreviousStep) - }, - ) - } - - composable(OnboardingDestination.TimeOfBirth.route) { - val keyboardContract = LocalSoftwareKeyboardController.current - OnboardingTimeOfBirthScreen( - state = stateProvider(), - currentStep = 3, - totalSteps = 6, - onNextClick = { - eventDispatcher(OnboardingContract.Action.NextStep) - eventDispatcher(OnboardingContract.Action.Reset) - keyboardContract?.hide() - }, - onBackClick = { - eventDispatcher(OnboardingContract.Action.PreviousStep) - }, - onTextChange = { value -> - eventDispatcher(OnboardingContract.Action.UpdateField(value, OnboardingContract.FieldType.TIME)) - }, - ) - } - composable(OnboardingDestination.Name.route) { - OnboardingNameScreen( - state = stateProvider(), - currentStep = 4, - totalSteps = 6, - onNextClick = { - eventDispatcher(OnboardingContract.Action.NextStep) - }, - onBackClick = { - eventDispatcher(OnboardingContract.Action.PreviousStep) - }, - onTextChange = { value -> - eventDispatcher(OnboardingContract.Action.UpdateField(value, OnboardingContract.FieldType.NAME)) - }, - ) - } - composable(OnboardingDestination.Gender.route) { - OnboardingGenderScreen( - state = stateProvider(), - currentStep = 5, - totalSteps = 6, - onNextClick = { - eventDispatcher(OnboardingContract.Action.NextStep) - }, - onBackClick = { - eventDispatcher(OnboardingContract.Action.PreviousStep) - }, - onGenderSelect = { gender -> - eventDispatcher(OnboardingContract.Action.UpdateGender(gender)) - }, - toggleBottomSheet = { - eventDispatcher(OnboardingContract.Action.ToggleBottomSheet) - }, - ) - } - composable(OnboardingDestination.Access.route) { - OnboardingAccessScreen( - state = stateProvider(), - currentStep = 6, - totalSteps = 6, - onNextClick = { - eventDispatcher(OnboardingContract.Action.NextStep) - }, - onBackClick = { - eventDispatcher(OnboardingContract.Action.PreviousStep) - }, - ) - } - composable(OnboardingDestination.Complete1.route) { - OnboardingCompleteScreen1( - state = stateProvider(), - onNextClick = { - eventDispatcher(OnboardingContract.Action.NextStep) - }, - onBackClick = { - eventDispatcher(OnboardingContract.Action.PreviousStep) - }, - ) - } - composable(OnboardingDestination.Complete2.route) { - OnboardingCompleteScreen2( - state = stateProvider(), - onNextClick = { - onFinishOnboarding() - }, - onBackClick = { - eventDispatcher(OnboardingContract.Action.PreviousStep) - }, - ) - } -} From 484765a94a04780da3c4e09d232dc4f716f98d00 Mon Sep 17 00:00:00 2001 From: dongchyeon Date: Fri, 17 Jan 2025 00:37:36 +0900 Subject: [PATCH 10/11] =?UTF-8?q?[REFACTOR/#40]=20=EB=A7=88=EC=9D=B4?= =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=A7=80=20=EB=84=A4=EB=B9=84=EA=B2=8C?= =?UTF-8?q?=EC=9D=B4=EC=85=98=EC=9D=84=20=EB=8B=A8=EC=9D=BC=20Composable?= =?UTF-8?q?=EC=97=90=EC=84=9C=20Navigation=20=EA=B7=B8=EB=9E=98=ED=94=84?= =?UTF-8?q?=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- feature/mypage/build.gradle.kts | 4 ++++ .../java/com/yapp/mypage/MyPageNavGraph.kt | 20 +++++++++++++++++++ .../java/com/yapp/mypage/MyPageNavigation.kt | 14 ------------- .../java/com/yapp/navigator/OrbitNavHost.kt | 15 +++++++++++--- 4 files changed, 36 insertions(+), 17 deletions(-) create mode 100644 feature/mypage/src/main/java/com/yapp/mypage/MyPageNavGraph.kt delete mode 100644 feature/mypage/src/main/java/com/yapp/mypage/MyPageNavigation.kt diff --git a/feature/mypage/build.gradle.kts b/feature/mypage/build.gradle.kts index 13762d8..9288f55 100644 --- a/feature/mypage/build.gradle.kts +++ b/feature/mypage/build.gradle.kts @@ -7,3 +7,7 @@ plugins { android { setNamespace("feature.myapge") } + +dependencies { + implementation(projects.core.common) +} diff --git a/feature/mypage/src/main/java/com/yapp/mypage/MyPageNavGraph.kt b/feature/mypage/src/main/java/com/yapp/mypage/MyPageNavGraph.kt new file mode 100644 index 0000000..24eab0a --- /dev/null +++ b/feature/mypage/src/main/java/com/yapp/mypage/MyPageNavGraph.kt @@ -0,0 +1,20 @@ +package com.yapp.mypage + +import androidx.navigation.NavGraphBuilder +import androidx.navigation.compose.composable +import androidx.navigation.navigation +import com.yapp.common.navigation.OrbitNavigator +import com.yapp.common.navigation.destination.MyPageDestination + +fun NavGraphBuilder.myPageNavGraph( + navigator: OrbitNavigator, +) { + navigation( + route = MyPageDestination.Route.route, + startDestination = MyPageDestination.MyPage.route, + ) { + composable(route = MyPageDestination.MyPage.route) { + MypageRoute() + } + } +} diff --git a/feature/mypage/src/main/java/com/yapp/mypage/MyPageNavigation.kt b/feature/mypage/src/main/java/com/yapp/mypage/MyPageNavigation.kt deleted file mode 100644 index d381f4d..0000000 --- a/feature/mypage/src/main/java/com/yapp/mypage/MyPageNavigation.kt +++ /dev/null @@ -1,14 +0,0 @@ -package com.yapp.mypage - -import androidx.navigation.NavGraphBuilder -import androidx.navigation.compose.composable - -fun NavGraphBuilder.mypageNavGraph() { - composable(route = MypageRoute.MYPAGE) { - MypageRoute() - } -} - -object MypageRoute { - const val MYPAGE = "mypage" -} diff --git a/feature/navigator/src/main/java/com/yapp/navigator/OrbitNavHost.kt b/feature/navigator/src/main/java/com/yapp/navigator/OrbitNavHost.kt index d4781a4..1dcb616 100644 --- a/feature/navigator/src/main/java/com/yapp/navigator/OrbitNavHost.kt +++ b/feature/navigator/src/main/java/com/yapp/navigator/OrbitNavHost.kt @@ -5,12 +5,13 @@ import androidx.compose.material3.Scaffold import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.navigation.compose.NavHost +import com.kms.onboarding.onboardingNavGraph import com.yapp.common.navigation.OrbitNavigator import com.yapp.common.navigation.destination.TopLevelDestination import com.yapp.common.navigation.rememberOrbitNavigator import com.yapp.designsystem.theme.OrbitTheme import com.yapp.home.homeNavGraph -import com.yapp.mypage.mypageNavGraph +import com.yapp.mypage.myPageNavGraph import kotlinx.collections.immutable.toImmutableList @Composable @@ -35,8 +36,16 @@ internal fun OrbitNavHost( startDestination = navigator.startDestination, modifier = Modifier.padding(innerPadding), ) { - homeNavGraph() - mypageNavGraph() + onboardingNavGraph( + navigator = navigator, + onFinishOnboarding = { navigator.navigateToTopLevelDestination(TopLevelDestination.HOME) }, + ) + homeNavGraph( + navigator = navigator, + ) + myPageNavGraph( + navigator = navigator, + ) } } } From ba4c55d3c922a7c72f151a32b8f79c8f9d4d563e Mon Sep 17 00:00:00 2001 From: dongchyeon Date: Fri, 17 Jan 2025 21:02:52 +0900 Subject: [PATCH 11/11] =?UTF-8?q?[REFACTOR/#40]=20Onboarding=20=EB=84=A4?= =?UTF-8?q?=EB=B9=84=EA=B2=8C=EC=9D=B4=EC=85=98=20=EC=BB=B4=ED=8F=AC?= =?UTF-8?q?=EC=A0=80=EB=B8=94=20=EB=93=B1=EB=A1=9D=20=EB=B0=A9=EC=8B=9D?= =?UTF-8?q?=EC=9D=84=20`routes.forEach`=20=EA=B8=B0=EB=B0=98=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EB=A6=AC=ED=8C=A9=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../destination/OnboardingDestination.kt | 2 +- .../com/kms/onboarding/OnboardingNavGraph.kt | 203 ++++-------------- 2 files changed, 37 insertions(+), 168 deletions(-) diff --git a/core/common/src/main/java/com/yapp/common/navigation/destination/OnboardingDestination.kt b/core/common/src/main/java/com/yapp/common/navigation/destination/OnboardingDestination.kt index 4ad4df5..89c4afe 100644 --- a/core/common/src/main/java/com/yapp/common/navigation/destination/OnboardingDestination.kt +++ b/core/common/src/main/java/com/yapp/common/navigation/destination/OnboardingDestination.kt @@ -15,7 +15,7 @@ sealed class OnboardingDestination(val route: String) { data object Complete2 : OnboardingDestination(Routes.Onboarding.COMPLETE_SECOND) companion object { - private val routes = listOf(Explain, AlarmTimeSelection, Birthday, TimeOfBirth, Name, Gender, Access, Complete1, Complete2) + val routes = listOf(Explain, AlarmTimeSelection, Birthday, TimeOfBirth, Name, Gender, Access, Complete1, Complete2) fun nextRoute(currentStep: Int): String? { return routes.getOrNull(currentStep)?.route diff --git a/feature/onboarding/src/main/java/com/kms/onboarding/OnboardingNavGraph.kt b/feature/onboarding/src/main/java/com/kms/onboarding/OnboardingNavGraph.kt index 42e5086..f626ffd 100644 --- a/feature/onboarding/src/main/java/com/kms/onboarding/OnboardingNavGraph.kt +++ b/feature/onboarding/src/main/java/com/kms/onboarding/OnboardingNavGraph.kt @@ -16,177 +16,46 @@ fun NavGraphBuilder.onboardingNavGraph( route = OnboardingDestination.Route.route, startDestination = OnboardingDestination.Explain.route, ) { - composable(OnboardingDestination.Explain.route) { - val viewModel = it.sharedViewModel(navigator.navController) - - LaunchedEffect(viewModel) { - viewModel.container.sideEffectFlow.collect { sideEffect -> - handleSideEffect( - sideEffect = sideEffect, - navigator = navigator, - viewModel = viewModel, - onFinishOnboarding = onFinishOnboarding, - ) - } - } - - OnboardingExplainRoute( - viewModel = viewModel, - ) - } - - composable(OnboardingDestination.AlarmTimeSelection.route) { - val viewModel = it.sharedViewModel(navigator.navController) - - LaunchedEffect(viewModel) { - viewModel.container.sideEffectFlow.collect { sideEffect -> - handleSideEffect( - sideEffect = sideEffect, - navigator = navigator, - viewModel = viewModel, - onFinishOnboarding = onFinishOnboarding, - ) - } - } - - OnboardingAlarmTimeSelectionRoute( - viewModel = viewModel, - ) - } - - composable(OnboardingDestination.Birthday.route) { - val viewModel = it.sharedViewModel(navigator.navController) - - LaunchedEffect(viewModel) { - viewModel.container.sideEffectFlow.collect { sideEffect -> - handleSideEffect( - sideEffect = sideEffect, - navigator = navigator, - viewModel = viewModel, - onFinishOnboarding = onFinishOnboarding, - ) - } - } - - OnboardingBirthdayRoute( - viewModel = viewModel, - ) - } - - composable(OnboardingDestination.TimeOfBirth.route) { - val viewModel = it.sharedViewModel(navigator.navController) - - LaunchedEffect(viewModel) { - viewModel.container.sideEffectFlow.collect { sideEffect -> - handleSideEffect( - sideEffect = sideEffect, - navigator = navigator, - viewModel = viewModel, - onFinishOnboarding = onFinishOnboarding, - ) - } - } - - OnboardingTimeOfBirthRoute( - viewModel = viewModel, - ) - } - - composable(OnboardingDestination.Name.route) { - val viewModel = it.sharedViewModel(navigator.navController) - - LaunchedEffect(viewModel) { - viewModel.container.sideEffectFlow.collect { sideEffect -> - handleSideEffect( - sideEffect = sideEffect, - navigator = navigator, - viewModel = viewModel, - onFinishOnboarding = onFinishOnboarding, - ) - } - } - - OnboardingNameRoute( - viewModel = viewModel, - ) - } - - composable(OnboardingDestination.Gender.route) { - val viewModel = it.sharedViewModel(navigator.navController) - - LaunchedEffect(viewModel) { - viewModel.container.sideEffectFlow.collect { sideEffect -> - handleSideEffect( - sideEffect = sideEffect, - navigator = navigator, - viewModel = viewModel, - onFinishOnboarding = onFinishOnboarding, - ) - } - } - - OnboardingGenderRoute( - viewModel = viewModel, - ) - } - - composable(OnboardingDestination.Access.route) { - val viewModel = it.sharedViewModel(navigator.navController) - - LaunchedEffect(viewModel) { - viewModel.container.sideEffectFlow.collect { sideEffect -> - handleSideEffect( - sideEffect = sideEffect, - navigator = navigator, - viewModel = viewModel, - onFinishOnboarding = onFinishOnboarding, - ) - } - } - - OnboardingAccessRoute( - navigator = navigator, - viewModel = viewModel, - ) - } - - composable(OnboardingDestination.Complete1.route) { - val viewModel = it.sharedViewModel(navigator.navController) - - LaunchedEffect(viewModel) { - viewModel.container.sideEffectFlow.collect { sideEffect -> - handleSideEffect( - sideEffect = sideEffect, - navigator = navigator, - viewModel = viewModel, - onFinishOnboarding = onFinishOnboarding, - ) + OnboardingDestination.routes.forEach { destination -> + composable(destination.route) { backStackEntry -> + val viewModel = backStackEntry.sharedViewModel(navigator.navController) + + LaunchedEffect(viewModel) { + viewModel.container.sideEffectFlow.collect { sideEffect -> + handleSideEffect(sideEffect, navigator, viewModel, onFinishOnboarding) + } } - } - - OnboardingCompleteRoute( - viewModel = viewModel, - ) - } - - composable(OnboardingDestination.Complete2.route) { - val viewModel = it.sharedViewModel(navigator.navController) - LaunchedEffect(viewModel) { - viewModel.container.sideEffectFlow.collect { sideEffect -> - handleSideEffect( - sideEffect = sideEffect, - navigator = navigator, - viewModel = viewModel, - onFinishOnboarding = onFinishOnboarding, - ) + when (destination) { + OnboardingDestination.Route, OnboardingDestination.Explain -> { + OnboardingExplainRoute(viewModel) + } + OnboardingDestination.AlarmTimeSelection -> { + OnboardingAlarmTimeSelectionRoute(viewModel) + } + OnboardingDestination.Birthday -> { + OnboardingBirthdayRoute(viewModel) + } + OnboardingDestination.TimeOfBirth -> { + OnboardingTimeOfBirthRoute(viewModel) + } + OnboardingDestination.Name -> { + OnboardingNameRoute(viewModel) + } + OnboardingDestination.Gender -> { + OnboardingGenderRoute(viewModel) + } + OnboardingDestination.Access -> { + OnboardingAccessRoute(navigator, viewModel) + } + OnboardingDestination.Complete1 -> { + OnboardingCompleteRoute(viewModel) + } + OnboardingDestination.Complete2 -> { + OnboardingCompleteRoute2(viewModel, onFinishOnboarding) + } } } - - OnboardingCompleteRoute2( - viewModel = viewModel, - onFinishOnboarding = onFinishOnboarding, - ) } } }