From 9d55152ff5416a8afe4bdbf1857f32ef0f1bb0fd Mon Sep 17 00:00:00 2001 From: dongchyeon Date: Mon, 2 Jun 2025 15:11:32 +0900 Subject: [PATCH 01/10] =?UTF-8?q?[REMOVE/#212]=20=EC=82=AC=EC=9A=A9?= =?UTF-8?q?=ED=95=98=EC=A7=80=20=EC=95=8A=EB=8A=94=20TopDestination,=20?= =?UTF-8?q?=EB=84=A4=EB=B9=84=EA=B2=8C=EC=9D=B4=EC=85=98=20=EB=B0=94=20?= =?UTF-8?q?=EC=A0=9C=EA=B1=B0?= 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 | 35 --------- .../destination/TopLevelDestination.kt | 28 ------- .../navigator/OrbitBottomNavigationBar.kt | 78 ------------------- .../java/com/yapp/navigator/OrbitNavHost.kt | 12 +-- .../java/com/yapp/splash/SplashViewModel.kt | 4 +- 6 files changed, 4 insertions(+), 154 deletions(-) delete mode 100644 core/common/src/main/java/com/yapp/common/navigation/destination/TopLevelDestination.kt delete mode 100644 feature/navigator/src/main/java/com/yapp/navigator/OrbitBottomNavigationBar.kt diff --git a/core/common/build.gradle.kts b/core/common/build.gradle.kts index c856674a..172673ac 100644 --- a/core/common/build.gradle.kts +++ b/core/common/build.gradle.kts @@ -14,4 +14,5 @@ dependencies { implementation(projects.core.designsystem) implementation(libs.compose.navigation) implementation(libs.hilt.navigation.compose) + implementation(libs.kotlinx.serialization.json) } 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 e465ab6f..295d3ce2 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 @@ -2,29 +2,15 @@ package com.yapp.common.navigation import androidx.compose.runtime.Composable import androidx.compose.runtime.remember -import androidx.navigation.NavDestination import androidx.navigation.NavHostController -import androidx.navigation.compose.currentBackStackEntryAsState import androidx.navigation.compose.rememberNavController -import androidx.navigation.navOptions -import com.yapp.common.navigation.destination.HomeDestination import com.yapp.common.navigation.destination.SplashDestination -import com.yapp.common.navigation.destination.TopLevelDestination class OrbitNavigator( val navController: NavHostController, ) { val startDestination = SplashDestination.Route.route - private val currentDestination: NavDestination? - @Composable get() = navController - .currentBackStackEntryAsState().value?.destination - - val currentTab: TopLevelDestination? - @Composable get() = currentDestination - ?.route - ?.let(TopLevelDestination.Companion::find) - fun navigateTo(route: String, popUpTo: String? = null, inclusive: Boolean = false) { navController.navigate(route) { popUpTo?.let { @@ -38,27 +24,6 @@ class OrbitNavigator( fun navigateBack() { navController.popBackStack() } - - fun navigateToTopLevelDestination(tab: TopLevelDestination) { - val navOptions = navOptions { - popUpTo(Routes.Home.ROUTE) { - saveState = true - } - launchSingleTop = true - restoreState = true - } - - when (tab) { - TopLevelDestination.HOME -> navController.navigate(Routes.Home.ROUTE, navOptions) - TopLevelDestination.MYPAGE -> navController.navigate(Routes.MyPage.ROUTE, navOptions) - } - } - - @Composable - fun shouldHaveNavigationBarsPadding(): Boolean { - val currentRoute = currentDestination?.route ?: return false - return currentRoute !in HomeDestination.Home.route - } } @Composable diff --git a/core/common/src/main/java/com/yapp/common/navigation/destination/TopLevelDestination.kt b/core/common/src/main/java/com/yapp/common/navigation/destination/TopLevelDestination.kt deleted file mode 100644 index 3a9fcc52..00000000 --- a/core/common/src/main/java/com/yapp/common/navigation/destination/TopLevelDestination.kt +++ /dev/null @@ -1,28 +0,0 @@ -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, - @StringRes val titleId: Int, - val route: String, -) { - HOME( - iconId = core.designsystem.R.drawable.ic_launcher_foreground, - titleId = core.designsystem.R.string.app_name, - route = Routes.Home.ROUTE, - ), - MYPAGE( - iconId = core.designsystem.R.drawable.ic_launcher_foreground, - titleId = core.designsystem.R.string.app_name, - route = Routes.MyPage.MYPAGE, - ), - ; - - companion object { - operator fun contains(route: String): Boolean = entries.any { it.route == route } - fun find(route: String): TopLevelDestination? = entries.find { it.route == route } - } -} diff --git a/feature/navigator/src/main/java/com/yapp/navigator/OrbitBottomNavigationBar.kt b/feature/navigator/src/main/java/com/yapp/navigator/OrbitBottomNavigationBar.kt deleted file mode 100644 index 60d481ba..00000000 --- a/feature/navigator/src/main/java/com/yapp/navigator/OrbitBottomNavigationBar.kt +++ /dev/null @@ -1,78 +0,0 @@ -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.destination.TopLevelDestination -import kotlinx.collections.immutable.ImmutableList - -@Composable -internal fun OrbitBottomNavigationBar( - modifier: Modifier = Modifier, - 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) - } -} 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 6fe6b82a..40be6215 100644 --- a/feature/navigator/src/main/java/com/yapp/navigator/OrbitNavHost.kt +++ b/feature/navigator/src/main/java/com/yapp/navigator/OrbitNavHost.kt @@ -19,7 +19,6 @@ import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable import com.yapp.common.navigation.OrbitNavigator import com.yapp.common.navigation.destination.SplashDestination -import com.yapp.common.navigation.destination.TopLevelDestination import com.yapp.common.navigation.rememberOrbitNavigator import com.yapp.designsystem.theme.OrbitTheme import com.yapp.fortune.fortuneNavGraph @@ -31,7 +30,6 @@ import com.yapp.splash.SplashRoute import com.yapp.ui.component.snackbar.CustomSnackBarVisuals import com.yapp.ui.component.snackbar.OrbitSnackBar import com.yapp.webview.webViewNavGraph -import kotlinx.collections.immutable.toImmutableList @SuppressLint("UnusedMaterial3ScaffoldPaddingParameter") @Composable @@ -43,14 +41,6 @@ internal fun OrbitNavHost( Scaffold( modifier = modifier, - bottomBar = { - OrbitBottomNavigationBar( - visible = false, - currentTab = navigator.currentTab, - entries = TopLevelDestination.entries.toImmutableList(), - onClickItem = navigator::navigateToTopLevelDestination, - ) - }, snackbarHost = { OrbitSnackBarHost(snackBarHostState = snackBarHostState) }, @@ -66,7 +56,7 @@ internal fun OrbitNavHost( } onboardingNavGraph( navigator = navigator, - onFinishOnboarding = { navigator.navigateToTopLevelDestination(TopLevelDestination.HOME) }, + onFinishOnboarding = { }, ) homeNavGraph( navigator = navigator, diff --git a/feature/splash/src/main/java/com/yapp/splash/SplashViewModel.kt b/feature/splash/src/main/java/com/yapp/splash/SplashViewModel.kt index 93649d48..201acd55 100644 --- a/feature/splash/src/main/java/com/yapp/splash/SplashViewModel.kt +++ b/feature/splash/src/main/java/com/yapp/splash/SplashViewModel.kt @@ -1,8 +1,8 @@ package com.yapp.splash import androidx.lifecycle.viewModelScope +import com.yapp.common.navigation.destination.HomeDestination import com.yapp.common.navigation.destination.OnboardingDestination -import com.yapp.common.navigation.destination.TopLevelDestination import com.yapp.datastore.UserPreferences import com.yapp.ui.base.BaseViewModel import dagger.hilt.android.lifecycle.HiltViewModel @@ -41,7 +41,7 @@ class SplashViewModel @Inject constructor( Pair(userId, onboardingCompleted) }.collect { (userId, onboardingCompleted) -> val destination = if (userId != null && onboardingCompleted) { - TopLevelDestination.HOME.route + HomeDestination.Home.route } else { OnboardingDestination.Route.route } From a964be04f0998df6fe023be12840b07c5999c9cf Mon Sep 17 00:00:00 2001 From: dongchyeon Date: Tue, 3 Jun 2025 19:58:54 +0900 Subject: [PATCH 02/10] =?UTF-8?q?[REFACTOR/#212]=20KClass=20=EA=B8=B0?= =?UTF-8?q?=EB=B0=98=20=EB=84=A4=EB=B9=84=EA=B2=8C=EC=9D=B4=EC=85=98?= =?UTF-8?q?=EC=9D=84=20=EC=9C=84=ED=95=B4=20=EB=9D=BC=EC=9A=B0=ED=8A=B8?= =?UTF-8?q?=EB=A5=BC=20@Serializable=20=EA=B8=B0=EB=B0=98=EC=9C=BC?= =?UTF-8?q?=EB=A1=9C=20=EA=B4=80=EB=A6=AC=ED=95=98=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/yapp/common/navigation/JsonNavType.kt | 18 ------ .../java/com/yapp/common/navigation/Routes.kt | 62 ------------------- .../AlarmInteractionDestination.kt | 9 --- .../destination/FortuneDestination.kt | 13 ---- .../navigation/destination/HomeDestination.kt | 9 --- .../destination/MissionDestination.kt | 8 --- .../destination/MyPageDestination.kt | 8 --- .../destination/OnboardingDestination.kt | 24 ------- .../destination/SettingDestination.kt | 14 ----- .../destination/SplashDestination.kt | 7 --- .../destination/WebViewDestination.kt | 8 --- .../navigation/route/AlarmInteractionRoute.kt | 18 ++++++ .../common/navigation/route/FortuneRoute.kt | 14 +++++ .../yapp/common/navigation/route/HomeRoute.kt | 14 +++++ .../common/navigation/route/MissionRoute.kt | 6 ++ .../navigation/route/OnboardingRoute.kt | 55 ++++++++++++++++ .../common/navigation/route/SettingRoute.kt | 18 ++++++ .../common/navigation/route/SplashRoute.kt | 6 ++ .../common/navigation/route/WebViewRoute.kt | 6 ++ .../java/com/yapp/webview/WebViewNavGraph.kt | 27 -------- 20 files changed, 137 insertions(+), 207 deletions(-) delete mode 100644 core/common/src/main/java/com/yapp/common/navigation/JsonNavType.kt delete mode 100644 core/common/src/main/java/com/yapp/common/navigation/Routes.kt delete mode 100644 core/common/src/main/java/com/yapp/common/navigation/destination/AlarmInteractionDestination.kt delete mode 100644 core/common/src/main/java/com/yapp/common/navigation/destination/FortuneDestination.kt delete mode 100644 core/common/src/main/java/com/yapp/common/navigation/destination/HomeDestination.kt delete mode 100644 core/common/src/main/java/com/yapp/common/navigation/destination/MissionDestination.kt delete mode 100644 core/common/src/main/java/com/yapp/common/navigation/destination/MyPageDestination.kt delete mode 100644 core/common/src/main/java/com/yapp/common/navigation/destination/OnboardingDestination.kt delete mode 100644 core/common/src/main/java/com/yapp/common/navigation/destination/SettingDestination.kt delete mode 100644 core/common/src/main/java/com/yapp/common/navigation/destination/SplashDestination.kt delete mode 100644 core/common/src/main/java/com/yapp/common/navigation/destination/WebViewDestination.kt create mode 100644 core/common/src/main/java/com/yapp/common/navigation/route/AlarmInteractionRoute.kt create mode 100644 core/common/src/main/java/com/yapp/common/navigation/route/FortuneRoute.kt create mode 100644 core/common/src/main/java/com/yapp/common/navigation/route/HomeRoute.kt create mode 100644 core/common/src/main/java/com/yapp/common/navigation/route/MissionRoute.kt create mode 100644 core/common/src/main/java/com/yapp/common/navigation/route/OnboardingRoute.kt create mode 100644 core/common/src/main/java/com/yapp/common/navigation/route/SettingRoute.kt create mode 100644 core/common/src/main/java/com/yapp/common/navigation/route/SplashRoute.kt create mode 100644 core/common/src/main/java/com/yapp/common/navigation/route/WebViewRoute.kt delete mode 100644 feature/webview/src/main/java/com/yapp/webview/WebViewNavGraph.kt diff --git a/core/common/src/main/java/com/yapp/common/navigation/JsonNavType.kt b/core/common/src/main/java/com/yapp/common/navigation/JsonNavType.kt deleted file mode 100644 index 4cc9ac3f..00000000 --- a/core/common/src/main/java/com/yapp/common/navigation/JsonNavType.kt +++ /dev/null @@ -1,18 +0,0 @@ -package com.yapp.common.navigation - -import android.os.Bundle -import androidx.navigation.NavType - -abstract class JsonNavType : NavType(isNullableAllowed = false) { - abstract fun fromJsonParse(value: String): T - abstract fun T.getJsonParse(): String - - override fun get(bundle: Bundle, key: String): T? = - bundle.getString(key)?.let { parseValue(it) } - - override fun parseValue(value: String): T = fromJsonParse(value) - - override fun put(bundle: Bundle, key: String, value: T) { - bundle.putString(key, value.getJsonParse()) - } -} 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 deleted file mode 100644 index d8fcb620..00000000 --- a/core/common/src/main/java/com/yapp/common/navigation/Routes.kt +++ /dev/null @@ -1,62 +0,0 @@ -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" - 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 { - const val ROUTE = "home_route" - const val HOME = "home" - const val ALARM_ADD_EDIT = "alarm_add_edit" - } - - object AlarmInteraction { - const val ROUTE = "alarm_interaction_route" - const val ALARM_ACTION = "alarm_action" - const val ALARM_SNOOZE_TIMER = "alarm_snooze_timer" - } - - object MyPage { - const val ROUTE = "mypage_route" - const val MYPAGE = "mypage" - } - - object Mission { - const val ROUTE = "mission_route" - const val MISSION = "mission_main" - const val PROGRESS = "mission_progress" - } - - object Fortune { - const val ROUTE = "fortune_route" - const val FORTUNE = "fortune_main" - const val REWARD = "fortune_reward" - } - - object Setting { - const val ROUTE = "setting_route" - const val SETTING = "setting_main" - const val EDIT_PROFILE = "setting_edit_profile" - const val EDIT_BIRTHDAY = "setting_edit_birthday" - } - - object Splash { - const val ROUTE = "splash_route" - const val SPLASH = "splash" - } - - object WebView { - const val ROUTE = "webview_route" - const val WEBVIEW = "webview" - } -} diff --git a/core/common/src/main/java/com/yapp/common/navigation/destination/AlarmInteractionDestination.kt b/core/common/src/main/java/com/yapp/common/navigation/destination/AlarmInteractionDestination.kt deleted file mode 100644 index 47b8d731..00000000 --- a/core/common/src/main/java/com/yapp/common/navigation/destination/AlarmInteractionDestination.kt +++ /dev/null @@ -1,9 +0,0 @@ -package com.yapp.common.navigation.destination - -import com.yapp.common.navigation.Routes - -sealed class AlarmInteractionDestination(val route: String) { - data object Route : AlarmInteractionDestination(Routes.AlarmInteraction.ROUTE) - data object AlarmAction : HomeDestination(Routes.AlarmInteraction.ALARM_ACTION) - data object AlarmSnoozeTimer : HomeDestination(Routes.AlarmInteraction.ALARM_SNOOZE_TIMER) -} diff --git a/core/common/src/main/java/com/yapp/common/navigation/destination/FortuneDestination.kt b/core/common/src/main/java/com/yapp/common/navigation/destination/FortuneDestination.kt deleted file mode 100644 index 808c3f62..00000000 --- a/core/common/src/main/java/com/yapp/common/navigation/destination/FortuneDestination.kt +++ /dev/null @@ -1,13 +0,0 @@ -package com.yapp.common.navigation.destination - -import com.yapp.common.navigation.Routes - -sealed class FortuneDestination(val route: String) { - data object Route : FortuneDestination(Routes.Fortune.ROUTE) - data object Fortune : FortuneDestination(Routes.Fortune.FORTUNE) - data object Reward : FortuneDestination(Routes.Fortune.REWARD) - - companion object { - val routes = listOf(Fortune, Reward) - } -} 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 deleted file mode 100644 index 81a71aed..00000000 --- a/core/common/src/main/java/com/yapp/common/navigation/destination/HomeDestination.kt +++ /dev/null @@ -1,9 +0,0 @@ -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/core/common/src/main/java/com/yapp/common/navigation/destination/MissionDestination.kt b/core/common/src/main/java/com/yapp/common/navigation/destination/MissionDestination.kt deleted file mode 100644 index 3366da3d..00000000 --- a/core/common/src/main/java/com/yapp/common/navigation/destination/MissionDestination.kt +++ /dev/null @@ -1,8 +0,0 @@ -package com.yapp.common.navigation.destination - -import com.yapp.common.navigation.Routes - -sealed class MissionDestination(val route: String) { - data object Route : MissionDestination(Routes.Mission.ROUTE) - data object Mission : MissionDestination(Routes.Mission.MISSION) -} 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 deleted file mode 100644 index 9ccb7d9c..00000000 --- a/core/common/src/main/java/com/yapp/common/navigation/destination/MyPageDestination.kt +++ /dev/null @@ -1,8 +0,0 @@ -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 deleted file mode 100644 index 89c4afe8..00000000 --- a/core/common/src/main/java/com/yapp/common/navigation/destination/OnboardingDestination.kt +++ /dev/null @@ -1,24 +0,0 @@ -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 { - 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/core/common/src/main/java/com/yapp/common/navigation/destination/SettingDestination.kt b/core/common/src/main/java/com/yapp/common/navigation/destination/SettingDestination.kt deleted file mode 100644 index 0b1f8e8f..00000000 --- a/core/common/src/main/java/com/yapp/common/navigation/destination/SettingDestination.kt +++ /dev/null @@ -1,14 +0,0 @@ -package com.yapp.common.navigation.destination - -import com.yapp.common.navigation.Routes - -sealed class SettingDestination(val route: String) { - data object Route : SettingDestination(Routes.Setting.ROUTE) - data object Setting : SettingDestination(Routes.Setting.SETTING) - data object EditProfile : SettingDestination(Routes.Setting.EDIT_PROFILE) - data object EditBirthday : SettingDestination(Routes.Setting.EDIT_BIRTHDAY) - - companion object { - val routes = listOf(Setting, EditProfile, EditBirthday) - } -} diff --git a/core/common/src/main/java/com/yapp/common/navigation/destination/SplashDestination.kt b/core/common/src/main/java/com/yapp/common/navigation/destination/SplashDestination.kt deleted file mode 100644 index 9ea3934f..00000000 --- a/core/common/src/main/java/com/yapp/common/navigation/destination/SplashDestination.kt +++ /dev/null @@ -1,7 +0,0 @@ -package com.yapp.common.navigation.destination - -import com.yapp.common.navigation.Routes - -sealed class SplashDestination(val route: String) { - data object Route : SplashDestination(Routes.Splash.ROUTE) -} diff --git a/core/common/src/main/java/com/yapp/common/navigation/destination/WebViewDestination.kt b/core/common/src/main/java/com/yapp/common/navigation/destination/WebViewDestination.kt deleted file mode 100644 index 9533099b..00000000 --- a/core/common/src/main/java/com/yapp/common/navigation/destination/WebViewDestination.kt +++ /dev/null @@ -1,8 +0,0 @@ -package com.yapp.common.navigation.destination - -import com.yapp.common.navigation.Routes - -sealed class WebViewDestination(val route: String) { - object Route : WebViewDestination(Routes.WebView.ROUTE) - object WebView : WebViewDestination(Routes.WebView.WEBVIEW) -} diff --git a/core/common/src/main/java/com/yapp/common/navigation/route/AlarmInteractionRoute.kt b/core/common/src/main/java/com/yapp/common/navigation/route/AlarmInteractionRoute.kt new file mode 100644 index 00000000..21310ba9 --- /dev/null +++ b/core/common/src/main/java/com/yapp/common/navigation/route/AlarmInteractionRoute.kt @@ -0,0 +1,18 @@ +package com.yapp.common.navigation.route + +import com.yapp.domain.model.Alarm +import kotlinx.serialization.Serializable + +@Serializable +data object AlarmInteractionBaseRoute + +sealed interface AlarmInteractionDestination { + @Serializable + data object Route : AlarmInteractionDestination + + @Serializable + data class AlarmAction(val alarm: Alarm) : AlarmInteractionDestination + + @Serializable + data class AlarmSnoozeTimer(val alarm: Alarm) : AlarmInteractionDestination +} diff --git a/core/common/src/main/java/com/yapp/common/navigation/route/FortuneRoute.kt b/core/common/src/main/java/com/yapp/common/navigation/route/FortuneRoute.kt new file mode 100644 index 00000000..c581c8ed --- /dev/null +++ b/core/common/src/main/java/com/yapp/common/navigation/route/FortuneRoute.kt @@ -0,0 +1,14 @@ +package com.yapp.common.navigation.route + +import kotlinx.serialization.Serializable + +@Serializable +data object FortuneBaseRoute + +sealed interface FortuneDestination { + @Serializable + data object Fortune : FortuneDestination + + @Serializable + data object Reward : FortuneDestination +} diff --git a/core/common/src/main/java/com/yapp/common/navigation/route/HomeRoute.kt b/core/common/src/main/java/com/yapp/common/navigation/route/HomeRoute.kt new file mode 100644 index 00000000..04b8b4da --- /dev/null +++ b/core/common/src/main/java/com/yapp/common/navigation/route/HomeRoute.kt @@ -0,0 +1,14 @@ +package com.yapp.common.navigation.route + +import kotlinx.serialization.Serializable + +@Serializable +data object HomeBaseRoute + +sealed interface HomeDestination { + @Serializable + data object Route : HomeDestination + + @Serializable + data class AlarmAddEdit(val alarmId: Long? = null) : HomeDestination +} diff --git a/core/common/src/main/java/com/yapp/common/navigation/route/MissionRoute.kt b/core/common/src/main/java/com/yapp/common/navigation/route/MissionRoute.kt new file mode 100644 index 00000000..d5a04949 --- /dev/null +++ b/core/common/src/main/java/com/yapp/common/navigation/route/MissionRoute.kt @@ -0,0 +1,6 @@ +package com.yapp.common.navigation.route + +import kotlinx.serialization.Serializable + +@Serializable +data object MissionRoute diff --git a/core/common/src/main/java/com/yapp/common/navigation/route/OnboardingRoute.kt b/core/common/src/main/java/com/yapp/common/navigation/route/OnboardingRoute.kt new file mode 100644 index 00000000..52f0bb5b --- /dev/null +++ b/core/common/src/main/java/com/yapp/common/navigation/route/OnboardingRoute.kt @@ -0,0 +1,55 @@ +package com.yapp.common.navigation.route + +import kotlinx.serialization.Serializable +import kotlin.reflect.KClass + +@Serializable +data object OnboardingBaseRoute + +sealed interface OnboardingDestination { + @Serializable + data object Explain : OnboardingDestination + + @Serializable + data object AlarmTimeSelection : OnboardingDestination + + @Serializable + data object Birthday : OnboardingDestination + + @Serializable + data object TimeOfBirth : OnboardingDestination + + @Serializable + data object Name : OnboardingDestination + + @Serializable + data object Gender : OnboardingDestination + + @Serializable + data object Access : OnboardingDestination + + @Serializable + data object Complete1 : OnboardingDestination + + @Serializable + data object Complete2 : OnboardingDestination + + companion object { + val routes: List> = listOf( + Explain::class, + AlarmTimeSelection::class, + Birthday::class, + TimeOfBirth::class, + Name::class, + Gender::class, + Access::class, + Complete1::class, + Complete2::class, + ) + + fun nextRoute(currentStep: Int): KClass? { + val nextRoute = routes.getOrNull(currentStep) + return nextRoute + } + } +} diff --git a/core/common/src/main/java/com/yapp/common/navigation/route/SettingRoute.kt b/core/common/src/main/java/com/yapp/common/navigation/route/SettingRoute.kt new file mode 100644 index 00000000..9246eed0 --- /dev/null +++ b/core/common/src/main/java/com/yapp/common/navigation/route/SettingRoute.kt @@ -0,0 +1,18 @@ +package com.yapp.common.navigation.route + +import kotlinx.serialization.Serializable + +@Serializable +data object SettingBaseRoute + +@Serializable +sealed interface SettingDestination { + @Serializable + data object Setting : SettingDestination + + @Serializable + data object EditProfile : SettingDestination + + @Serializable + data object EditBirthday : SettingDestination +} diff --git a/core/common/src/main/java/com/yapp/common/navigation/route/SplashRoute.kt b/core/common/src/main/java/com/yapp/common/navigation/route/SplashRoute.kt new file mode 100644 index 00000000..81724c65 --- /dev/null +++ b/core/common/src/main/java/com/yapp/common/navigation/route/SplashRoute.kt @@ -0,0 +1,6 @@ +package com.yapp.common.navigation.route + +import kotlinx.serialization.Serializable + +@Serializable +data object SplashRoute diff --git a/core/common/src/main/java/com/yapp/common/navigation/route/WebViewRoute.kt b/core/common/src/main/java/com/yapp/common/navigation/route/WebViewRoute.kt new file mode 100644 index 00000000..9ced251c --- /dev/null +++ b/core/common/src/main/java/com/yapp/common/navigation/route/WebViewRoute.kt @@ -0,0 +1,6 @@ +package com.yapp.common.navigation.route + +import kotlinx.serialization.Serializable + +@Serializable +data class WebViewRoute(val url: String) diff --git a/feature/webview/src/main/java/com/yapp/webview/WebViewNavGraph.kt b/feature/webview/src/main/java/com/yapp/webview/WebViewNavGraph.kt deleted file mode 100644 index 039cbcd8..00000000 --- a/feature/webview/src/main/java/com/yapp/webview/WebViewNavGraph.kt +++ /dev/null @@ -1,27 +0,0 @@ -package com.yapp.webview - -import androidx.navigation.NavGraphBuilder -import androidx.navigation.NavType -import androidx.navigation.compose.composable -import androidx.navigation.navArgument -import androidx.navigation.navigation -import com.yapp.common.navigation.OrbitNavigator -import com.yapp.common.navigation.destination.WebViewDestination - -fun NavGraphBuilder.webViewNavGraph(navigator: OrbitNavigator) { - navigation( - route = WebViewDestination.Route.route, - startDestination = WebViewDestination.WebView.route, - ) { - composable( - route = "${WebViewDestination.WebView.route}/{url}", - arguments = listOf(navArgument("url") { type = NavType.StringType }), - ) { backStackEntry -> - val url = backStackEntry.arguments?.getString("url") ?: "" - WebViewRoute( - url = url, - navController = navigator.navController, - ) - } - } -} From 5fa74fdafae63e37e4a2603c26898d8d00219fe8 Mon Sep 17 00:00:00 2001 From: dongchyeon Date: Tue, 3 Jun 2025 20:06:43 +0900 Subject: [PATCH 03/10] =?UTF-8?q?[REFACTOR/#212]=20KClass=20=EA=B8=B0?= =?UTF-8?q?=EB=B0=98=20=EB=9D=BC=EC=9A=B0=ED=8C=85=20=EC=A0=81=EC=9A=A9?= 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 | 82 ++++++-- domain/build.gradle.kts | 1 + .../main/java/com/yapp/domain/model/Alarm.kt | 2 + .../interaction/AlarmInteractionNavGraph.kt | 73 +++++--- .../java/com/yapp/fortune/FortuneNavGraph.kt | 105 ++++++----- .../main/java/com/yapp/home/HomeNavGraph.kt | 22 +-- .../java/com/yapp/mission/MissionNavGraph.kt | 60 +++--- .../java/com/yapp/navigator/OrbitNavHost.kt | 21 +-- .../com/yapp/onboarding/OnboardingNavGraph.kt | 152 ++++++++++----- .../java/com/yapp/setting/SettingNavGraph.kt | 177 +++++++++--------- .../java/com/yapp/splash/SettingNavGraph.kt | 14 ++ .../java/com/yapp/webview/WebViewNavGraph.kt | 19 ++ 13 files changed, 440 insertions(+), 289 deletions(-) create mode 100644 feature/splash/src/main/java/com/yapp/splash/SettingNavGraph.kt create mode 100644 feature/webview/src/main/java/com/yapp/webview/WebViewNavGraph.kt diff --git a/core/common/build.gradle.kts b/core/common/build.gradle.kts index 172673ac..a01d2fa2 100644 --- a/core/common/build.gradle.kts +++ b/core/common/build.gradle.kts @@ -12,6 +12,7 @@ android { dependencies { implementation(projects.core.designsystem) + implementation(projects.domain) implementation(libs.compose.navigation) implementation(libs.hilt.navigation.compose) implementation(libs.kotlinx.serialization.json) 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 295d3ce2..92e20cb5 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 @@ -3,22 +3,82 @@ package com.yapp.common.navigation import androidx.compose.runtime.Composable import androidx.compose.runtime.remember import androidx.navigation.NavHostController +import androidx.navigation.NavOptions import androidx.navigation.compose.rememberNavController -import com.yapp.common.navigation.destination.SplashDestination +import com.yapp.common.navigation.extensions.toRoute +import com.yapp.common.navigation.route.AlarmInteractionDestination +import com.yapp.common.navigation.route.FortuneBaseRoute +import com.yapp.common.navigation.route.FortuneDestination +import com.yapp.common.navigation.route.HomeBaseRoute +import com.yapp.common.navigation.route.HomeDestination +import com.yapp.common.navigation.route.OnboardingBaseRoute +import com.yapp.common.navigation.route.OnboardingDestination +import com.yapp.common.navigation.route.SettingBaseRoute +import com.yapp.common.navigation.route.SettingDestination +import com.yapp.common.navigation.route.SplashRoute +import com.yapp.common.navigation.route.WebViewRoute +import com.yapp.domain.model.Alarm class OrbitNavigator( val navController: NavHostController, ) { - val startDestination = SplashDestination.Route.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 - } + val startDestination = SplashRoute + + fun navigateToOnboarding(navOptions: NavOptions? = null) { + navController.navigate(OnboardingBaseRoute, navOptions) + } + + fun navigateToOnboardingNextStep(navOptions: NavOptions? = null) { + val currentRoute = navController.currentBackStackEntry?.destination?.route ?: return + + val currentIndex = OnboardingDestination.routes.indexOfFirst { it.toRoute() == currentRoute } + val nextRouteClass = OnboardingDestination.nextRoute(currentIndex + 1) ?: return + + navController.navigate(nextRouteClass, navOptions) + } + + fun navigateToAddAlarm(navOptions: NavOptions? = null) { + navController.navigate(HomeDestination.AlarmAddEdit(-1), navOptions) + } + + fun navigateToEditAlarm(alarmId: Long, navOptions: NavOptions? = null) { + navController.navigate(HomeDestination.AlarmAddEdit(alarmId), navOptions) + } + + fun navigateToHome(navOptions: NavOptions? = null) { + navController.navigate(HomeBaseRoute, navOptions) + } + + fun navigateToAlarmAction(alarm: Alarm, navOptions: NavOptions? = null) { + navController.navigate(AlarmInteractionDestination.AlarmAction(alarm), navOptions) + } + + fun navigateToAlarmSnoozeTimer(alarm: Alarm, navOptions: NavOptions? = null) { + navController.navigate(AlarmInteractionDestination.AlarmSnoozeTimer(alarm), navOptions) + } + + fun navigateToFortune(navOptions: NavOptions? = null) { + navController.navigate(FortuneBaseRoute, navOptions) + } + + fun navigateToFortuneReward(navOptions: NavOptions? = null) { + navController.navigate(FortuneDestination.Reward, navOptions) + } + + fun navigateToSetting(navOptions: NavOptions? = null) { + navController.navigate(SettingBaseRoute, navOptions) + } + + fun navigateToEditProfile(navOptions: NavOptions? = null) { + navController.navigate(SettingDestination.EditProfile, navOptions) + } + + fun navigateToEditBirthDay(navOptions: NavOptions? = null) { + navController.navigate(SettingDestination.EditBirthday, navOptions) + } + + fun navigateToWebView(url: String, navOptions: NavOptions? = null) { + navController.navigate(WebViewRoute(url), navOptions) } fun navigateBack() { diff --git a/domain/build.gradle.kts b/domain/build.gradle.kts index de2c4bb0..a9c80e75 100644 --- a/domain/build.gradle.kts +++ b/domain/build.gradle.kts @@ -11,4 +11,5 @@ android { dependencies { implementation(libs.gson) + implementation(libs.kotlinx.serialization.json) } diff --git a/domain/src/main/java/com/yapp/domain/model/Alarm.kt b/domain/src/main/java/com/yapp/domain/model/Alarm.kt index c3cf50ba..9e05ffca 100644 --- a/domain/src/main/java/com/yapp/domain/model/Alarm.kt +++ b/domain/src/main/java/com/yapp/domain/model/Alarm.kt @@ -5,8 +5,10 @@ import android.os.Parcelable import com.google.gson.Gson import com.google.gson.reflect.TypeToken import kotlinx.parcelize.Parcelize +import kotlinx.serialization.Serializable @Parcelize +@Serializable data class Alarm( val id: Long = 0, diff --git a/feature/alarm-interaction/src/main/java/com/yapp/alarm/interaction/AlarmInteractionNavGraph.kt b/feature/alarm-interaction/src/main/java/com/yapp/alarm/interaction/AlarmInteractionNavGraph.kt index d87492e6..312ce293 100644 --- a/feature/alarm-interaction/src/main/java/com/yapp/alarm/interaction/AlarmInteractionNavGraph.kt +++ b/feature/alarm-interaction/src/main/java/com/yapp/alarm/interaction/AlarmInteractionNavGraph.kt @@ -1,56 +1,75 @@ package com.yapp.alarm.interaction +import android.os.Bundle +import androidx.compose.runtime.LaunchedEffect import androidx.navigation.NavGraphBuilder +import androidx.navigation.NavType import androidx.navigation.compose.composable -import androidx.navigation.navArgument +import androidx.navigation.navOptions import androidx.navigation.navigation import com.google.gson.Gson import com.yapp.alarm.interaction.action.AlarmActionRoute import com.yapp.alarm.interaction.snooze.AlarmSnoozeTimerRoute -import com.yapp.common.navigation.JsonNavType import com.yapp.common.navigation.OrbitNavigator -import com.yapp.common.navigation.destination.AlarmInteractionDestination +import com.yapp.common.navigation.route.AlarmInteractionBaseRoute +import com.yapp.common.navigation.route.AlarmInteractionDestination import com.yapp.domain.model.Alarm +import kotlin.reflect.typeOf -class AlarmArgType : JsonNavType() { - override fun fromJsonParse(value: String): Alarm { - return Gson().fromJson(value, Alarm::class.java) +val AlarmArgType = object : NavType(isNullableAllowed = false) { + override fun get(bundle: Bundle, key: String): Alarm? { + return bundle.getString(key)?.let { Alarm.fromJson(it) } } - override fun Alarm.getJsonParse(): String { - return Gson().toJson(this) + override fun parseValue(value: String): Alarm { + return Alarm.fromJson(value) + } + + override fun put(bundle: Bundle, key: String, value: Alarm) { + bundle.putString(key, Gson().toJson(value)) } } fun NavGraphBuilder.alarmInteractionNavGraph( navigator: OrbitNavigator, + alarm: Alarm?, ) { - navigation( - route = AlarmInteractionDestination.Route.route, - startDestination = "${AlarmInteractionDestination.AlarmAction.route}/{alarm}", + navigation( + startDestination = AlarmInteractionDestination.Route, ) { - composable( - route = "${AlarmInteractionDestination.AlarmAction.route}/{alarm}", - arguments = listOf( - navArgument("alarm") { - type = AlarmArgType() - defaultValue = Alarm() - }, - ), + composable { + LaunchedEffect(Unit) { + alarm?.let { + navigator.navigateToAlarmAction( + it, + navOptions { + popUpTo(AlarmInteractionBaseRoute) { + inclusive = true + } + }, + ) + } ?: run { + navigator.navigateToHome( + navOptions { + popUpTo(AlarmInteractionBaseRoute) { + inclusive = true + } + }, + ) + } + } + } + + composable( + typeMap = mapOf(typeOf() to AlarmArgType), ) { AlarmActionRoute( navigator = navigator, ) } - composable( - route = "${AlarmInteractionDestination.AlarmSnoozeTimer.route}/{alarm}", - arguments = listOf( - navArgument("alarm") { - type = AlarmArgType() - defaultValue = Alarm() - }, - ), + composable( + typeMap = mapOf(typeOf() to AlarmArgType), ) { AlarmSnoozeTimerRoute( navigator = navigator, diff --git a/feature/fortune/src/main/java/com/yapp/fortune/FortuneNavGraph.kt b/feature/fortune/src/main/java/com/yapp/fortune/FortuneNavGraph.kt index 86f87fee..5f1b5133 100644 --- a/feature/fortune/src/main/java/com/yapp/fortune/FortuneNavGraph.kt +++ b/feature/fortune/src/main/java/com/yapp/fortune/FortuneNavGraph.kt @@ -1,77 +1,94 @@ package com.yapp.fortune import androidx.compose.material3.SnackbarHostState -import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.rememberCoroutineScope import androidx.navigation.NavGraphBuilder import androidx.navigation.compose.composable +import androidx.navigation.navOptions import androidx.navigation.navigation import com.yapp.common.navigation.OrbitNavigator -import com.yapp.common.navigation.destination.FortuneDestination import com.yapp.common.navigation.extensions.sharedHiltViewModel +import com.yapp.common.navigation.route.FortuneBaseRoute +import com.yapp.common.navigation.route.FortuneDestination import com.yapp.ui.component.snackbar.showCustomSnackBar +import kotlinx.coroutines.CoroutineScope fun NavGraphBuilder.fortuneNavGraph( navigator: OrbitNavigator, snackBarHostState: SnackbarHostState, ) { - navigation( - route = FortuneDestination.Route.route, - startDestination = FortuneDestination.Fortune.route, - ) { - FortuneDestination.routes.forEach { destination -> - composable(destination.route) { backStackEntry -> - val viewModel = backStackEntry.sharedHiltViewModel(navigator.navController) - val coroutineScope = rememberCoroutineScope() + navigation(startDestination = FortuneDestination.Fortune) { + composable { backStackEntry -> + val viewModel = backStackEntry.sharedHiltViewModel(navigator.navController) + val coroutineScope = rememberCoroutineScope() - LaunchedEffect(viewModel) { - viewModel.container.sideEffectFlow.collect { sideEffect -> - when (sideEffect) { - is FortuneContract.SideEffect.Navigate -> navigator.navigateTo( - route = sideEffect.route, - popUpTo = sideEffect.popUpTo, - inclusive = sideEffect.inclusive, - ) + LaunchedEffect(viewModel) { + viewModel.container.sideEffectFlow.collect { sideEffect -> + handleSideEffect(sideEffect, navigator, snackBarHostState, coroutineScope) + } + } - FortuneContract.SideEffect.NavigateBack -> navigator.navigateBack() + FortuneRoute( + viewModel = viewModel, + navigator = navigator, + ) + } - is FortuneContract.SideEffect.ShowSnackBar -> showCustomSnackBar( - scope = coroutineScope, - snackBarHostState = snackBarHostState, - message = sideEffect.message, - actionLabel = sideEffect.label, - iconRes = sideEffect.iconRes, - bottomPadding = sideEffect.bottomPadding, - durationMillis = sideEffect.durationMillis, - onDismiss = sideEffect.onDismiss, - onAction = sideEffect.onAction, - ) - } - } - } + composable { backStackEntry -> + val viewModel = backStackEntry.sharedHiltViewModel(navigator.navController) + val coroutineScope = rememberCoroutineScope() - when (destination) { - FortuneDestination.Fortune -> FortuneRoute( - viewModel = viewModel, - navigator = navigator, - ) - FortuneDestination.Reward -> FortuneRewardRoute(viewModel) - else -> {} + LaunchedEffect(viewModel) { + viewModel.container.sideEffectFlow.collect { sideEffect -> + handleSideEffect(sideEffect, navigator, snackBarHostState, coroutineScope) } } + + FortuneRewardRoute( + viewModel = viewModel, + ) } } } -@Composable -private fun handleFortuneSideEffect( +private suspend fun handleSideEffect( sideEffect: FortuneContract.SideEffect, navigator: OrbitNavigator, snackBarHostState: SnackbarHostState, + coroutineScope: CoroutineScope, ) { - val coroutineScope = rememberCoroutineScope() + when (sideEffect) { + FortuneContract.SideEffect.NavigateToFortuneReward -> { + navigator.navigateToFortuneReward( + navOptions = navOptions { + popUpTo(FortuneDestination.Fortune) { + inclusive = true + } + }, + ) + } + + FortuneContract.SideEffect.NavigateToHome -> navigator.navigateToHome( + navOptions = navOptions { + popUpTo(FortuneBaseRoute) { + inclusive = true + } + }, + ) + + FortuneContract.SideEffect.NavigateBack -> navigator.navigateBack() - LaunchedEffect(sideEffect) { + is FortuneContract.SideEffect.ShowSnackBar -> showCustomSnackBar( + scope = coroutineScope, + snackBarHostState = snackBarHostState, + message = sideEffect.message, + actionLabel = sideEffect.label, + iconRes = sideEffect.iconRes, + bottomPadding = sideEffect.bottomPadding, + durationMillis = sideEffect.durationMillis, + onDismiss = sideEffect.onDismiss, + onAction = sideEffect.onAction, + ) } } 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 ec43adbe..b044e9de 100644 --- a/feature/home/src/main/java/com/yapp/home/HomeNavGraph.kt +++ b/feature/home/src/main/java/com/yapp/home/HomeNavGraph.kt @@ -2,13 +2,12 @@ package com.yapp.home import androidx.compose.material3.SnackbarHostState import androidx.navigation.NavGraphBuilder -import androidx.navigation.NavType import androidx.navigation.compose.composable import androidx.navigation.compose.navigation -import androidx.navigation.navArgument import com.yapp.alarm.addedit.AlarmAddEditRoute import com.yapp.common.navigation.OrbitNavigator -import com.yapp.common.navigation.destination.HomeDestination +import com.yapp.common.navigation.route.HomeBaseRoute +import com.yapp.common.navigation.route.HomeDestination const val ADD_ALARM_RESULT_KEY = "addAlarmResult" const val UPDATE_ALARM_RESULT_KEY = "updateAlarmResult" @@ -18,26 +17,17 @@ fun NavGraphBuilder.homeNavGraph( navigator: OrbitNavigator, snackBarHostState: SnackbarHostState, ) { - navigation( - route = HomeDestination.Route.route, - startDestination = HomeDestination.Home.route, + navigation( + startDestination = HomeDestination.Route, ) { - composable(route = HomeDestination.Home.route) { + composable { HomeRoute( navigator = navigator, snackBarHostState = snackBarHostState, ) } - composable( - route = "${HomeDestination.AlarmAddEdit.route}?id={alarmId}", - arguments = listOf( - navArgument("alarmId") { - type = NavType.LongType - defaultValue = -1 - }, - ), - ) { + composable { AlarmAddEditRoute( navigator = navigator, snackBarHostState = snackBarHostState, diff --git a/feature/mission/src/main/java/com/yapp/mission/MissionNavGraph.kt b/feature/mission/src/main/java/com/yapp/mission/MissionNavGraph.kt index 076a59a6..a24f0545 100644 --- a/feature/mission/src/main/java/com/yapp/mission/MissionNavGraph.kt +++ b/feature/mission/src/main/java/com/yapp/mission/MissionNavGraph.kt @@ -4,51 +4,41 @@ import androidx.compose.runtime.LaunchedEffect import androidx.navigation.NavGraphBuilder import androidx.navigation.compose.composable import androidx.navigation.navDeepLink -import androidx.navigation.navigation +import androidx.navigation.navOptions import com.yapp.common.navigation.OrbitNavigator -import com.yapp.common.navigation.destination.MissionDestination import com.yapp.common.navigation.extensions.sharedHiltViewModel +import com.yapp.common.navigation.route.MissionRoute -fun NavGraphBuilder.missionNavGraph( +fun NavGraphBuilder.missionScreen( navigator: OrbitNavigator, ) { - navigation( - route = MissionDestination.Route.route, - startDestination = MissionDestination.Mission.route, + composable( + deepLinks = listOf( + navDeepLink { + uriPattern = "orbitapp://mission?notificationId={notificationId}" + }, + ), ) { - composable( - route = MissionDestination.Mission.route, - deepLinks = listOf( - navDeepLink { - uriPattern = "orbitapp://mission?notificationId={notificationId}" - }, - ), - ) { backStackEntry -> - val viewModel = backStackEntry.sharedHiltViewModel(navigator.navController) + val viewModel = it.sharedHiltViewModel(navigator.navController) - LaunchedEffect(viewModel) { - viewModel.container.sideEffectFlow.collect { sideEffect -> - handleMissionSideEffect(sideEffect, navigator, viewModel) + LaunchedEffect(viewModel) { + viewModel.container.sideEffectFlow.collect { sideEffect -> + when (sideEffect) { + MissionContract.SideEffect.NavigateToFortune -> { + navigator.navigateToFortune( + navOptions = navOptions { + popUpTo(MissionRoute) { + inclusive = true + } + }, + ) + } + + MissionContract.SideEffect.NavigateBack -> navigator.navigateBack() } } - - MissionRoute(viewModel) } - } -} - -private fun handleMissionSideEffect( - sideEffect: MissionContract.SideEffect, - navigator: OrbitNavigator, - viewModel: MissionViewModel, -) { - when (sideEffect) { - is MissionContract.SideEffect.Navigate -> navigator.navigateTo( - route = sideEffect.route, - popUpTo = sideEffect.popUpTo, - inclusive = sideEffect.inclusive, - ) - MissionContract.SideEffect.NavigateBack -> navigator.navigateBack() + MissionRoute(viewModel) } } 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 40be6215..082c2ca5 100644 --- a/feature/navigator/src/main/java/com/yapp/navigator/OrbitNavHost.kt +++ b/feature/navigator/src/main/java/com/yapp/navigator/OrbitNavHost.kt @@ -16,20 +16,18 @@ import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import androidx.navigation.compose.NavHost -import androidx.navigation.compose.composable import com.yapp.common.navigation.OrbitNavigator -import com.yapp.common.navigation.destination.SplashDestination import com.yapp.common.navigation.rememberOrbitNavigator import com.yapp.designsystem.theme.OrbitTheme import com.yapp.fortune.fortuneNavGraph import com.yapp.home.homeNavGraph -import com.yapp.mission.missionNavGraph +import com.yapp.mission.missionScreen import com.yapp.onboarding.onboardingNavGraph import com.yapp.setting.settingNavGraph -import com.yapp.splash.SplashRoute +import com.yapp.splash.splashScreen import com.yapp.ui.component.snackbar.CustomSnackBarVisuals import com.yapp.ui.component.snackbar.OrbitSnackBar -import com.yapp.webview.webViewNavGraph +import com.yapp.webview.webViewScreen @SuppressLint("UnusedMaterial3ScaffoldPaddingParameter") @Composable @@ -51,24 +49,19 @@ internal fun OrbitNavHost( startDestination = navigator.startDestination, modifier = Modifier.navigationBarsPadding(), ) { - composable(SplashDestination.Route.route) { - SplashRoute(navigator) - } - onboardingNavGraph( - navigator = navigator, - onFinishOnboarding = { }, - ) + splashScreen(navigator = navigator) + onboardingNavGraph(navigator = navigator) homeNavGraph( navigator = navigator, snackBarHostState = snackBarHostState, ) - missionNavGraph(navigator = navigator) + missionScreen(navigator = navigator) fortuneNavGraph( navigator = navigator, snackBarHostState = snackBarHostState, ) settingNavGraph(navigator = navigator) - webViewNavGraph(navigator = navigator) + webViewScreen(navigator = navigator) } } } diff --git a/feature/onboarding/src/main/java/com/yapp/onboarding/OnboardingNavGraph.kt b/feature/onboarding/src/main/java/com/yapp/onboarding/OnboardingNavGraph.kt index 903c1c30..fd669d65 100644 --- a/feature/onboarding/src/main/java/com/yapp/onboarding/OnboardingNavGraph.kt +++ b/feature/onboarding/src/main/java/com/yapp/onboarding/OnboardingNavGraph.kt @@ -4,61 +4,106 @@ import android.net.Uri import androidx.compose.runtime.LaunchedEffect import androidx.navigation.NavGraphBuilder import androidx.navigation.compose.composable +import androidx.navigation.navOptions import androidx.navigation.navigation import com.yapp.common.navigation.OrbitNavigator -import com.yapp.common.navigation.destination.OnboardingDestination -import com.yapp.common.navigation.destination.WebViewDestination import com.yapp.common.navigation.extensions.sharedHiltViewModel +import com.yapp.common.navigation.route.OnboardingBaseRoute +import com.yapp.common.navigation.route.OnboardingDestination import kotlinx.coroutines.flow.collectLatest fun NavGraphBuilder.onboardingNavGraph( navigator: OrbitNavigator, - onFinishOnboarding: () -> Unit, ) { - navigation( - route = OnboardingDestination.Route.route, - startDestination = OnboardingDestination.Explain.route, - ) { - OnboardingDestination.routes.forEach { destination -> - composable(destination.route) { backStackEntry -> - val viewModel = backStackEntry.sharedHiltViewModel(navigator.navController) + navigation(startDestination = OnboardingDestination.Explain) { + composable { + val viewModel = it.sharedHiltViewModel(navigator.navController) + LaunchedEffect(viewModel) { + viewModel.container.sideEffectFlow.collectLatest { sideEffect -> + handleSideEffect(sideEffect, navigator, viewModel) + } + } + OnboardingExplainRoute(viewModel) + } - LaunchedEffect(viewModel) { - viewModel.container.sideEffectFlow.collectLatest { sideEffect -> - handleSideEffect(sideEffect, navigator, viewModel, onFinishOnboarding) - } + composable { + val viewModel = it.sharedHiltViewModel(navigator.navController) + LaunchedEffect(viewModel) { + viewModel.container.sideEffectFlow.collectLatest { sideEffect -> + handleSideEffect(sideEffect, navigator, viewModel) } + } + OnboardingAlarmTimeSelectionRoute(viewModel) + } - 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(viewModel) - } - OnboardingDestination.Complete1 -> { - OnboardingCompleteRoute(viewModel) - } - OnboardingDestination.Complete2 -> { - OnboardingCompleteRoute2(viewModel) - } + composable { + val viewModel = it.sharedHiltViewModel(navigator.navController) + LaunchedEffect(viewModel) { + viewModel.container.sideEffectFlow.collectLatest { sideEffect -> + handleSideEffect(sideEffect, navigator, viewModel) + } + } + OnboardingBirthdayRoute(viewModel) + } + + composable { + val viewModel = it.sharedHiltViewModel(navigator.navController) + LaunchedEffect(viewModel) { + viewModel.container.sideEffectFlow.collectLatest { sideEffect -> + handleSideEffect(sideEffect, navigator, viewModel) + } + } + OnboardingTimeOfBirthRoute(viewModel) + } + + composable { + val viewModel = it.sharedHiltViewModel(navigator.navController) + LaunchedEffect(viewModel) { + viewModel.container.sideEffectFlow.collectLatest { sideEffect -> + handleSideEffect(sideEffect, navigator, viewModel) + } + } + OnboardingNameRoute(viewModel) + } + + composable { + val viewModel = it.sharedHiltViewModel(navigator.navController) + LaunchedEffect(viewModel) { + viewModel.container.sideEffectFlow.collectLatest { sideEffect -> + handleSideEffect(sideEffect, navigator, viewModel) + } + } + OnboardingGenderRoute(viewModel) + } + + composable { + val viewModel = it.sharedHiltViewModel(navigator.navController) + LaunchedEffect(viewModel) { + viewModel.container.sideEffectFlow.collectLatest { sideEffect -> + handleSideEffect(sideEffect, navigator, viewModel) + } + } + OnboardingAccessRoute(viewModel) + } + + composable { + val viewModel = it.sharedHiltViewModel(navigator.navController) + LaunchedEffect(viewModel) { + viewModel.container.sideEffectFlow.collectLatest { sideEffect -> + handleSideEffect(sideEffect, navigator, viewModel) + } + } + OnboardingCompleteRoute(viewModel) + } + + composable { + val viewModel = it.sharedHiltViewModel(navigator.navController) + LaunchedEffect(viewModel) { + viewModel.container.sideEffectFlow.collectLatest { sideEffect -> + handleSideEffect(sideEffect, navigator, viewModel) } } + OnboardingCompleteRoute2(viewModel) } } } @@ -67,22 +112,29 @@ 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.NavigateToNextStep -> { + navigator.navigateToOnboardingNextStep() + } + OnboardingContract.SideEffect.NavigateBack -> { viewModel.processAction(OnboardingContract.Action.Reset) navigator.navigateBack() } - OnboardingContract.SideEffect.OnboardingCompleted -> onFinishOnboarding() + + OnboardingContract.SideEffect.OnboardingCompleted -> { + navigator.navigateToHome( + navOptions = navOptions { + popUpTo(OnboardingBaseRoute) { + inclusive = true + } + }, + ) + } is OnboardingContract.SideEffect.OpenWebView -> { - navigator.navigateTo("${WebViewDestination.WebView.route}/${Uri.encode(sideEffect.url)}") + navigator.navigateToWebView(Uri.encode(sideEffect.url)) } } } diff --git a/feature/setting/src/main/java/com/yapp/setting/SettingNavGraph.kt b/feature/setting/src/main/java/com/yapp/setting/SettingNavGraph.kt index dfaf89ea..054c523b 100644 --- a/feature/setting/src/main/java/com/yapp/setting/SettingNavGraph.kt +++ b/feature/setting/src/main/java/com/yapp/setting/SettingNavGraph.kt @@ -8,129 +8,122 @@ import androidx.compose.animation.slideOutVertically import androidx.compose.runtime.LaunchedEffect import androidx.navigation.NavGraphBuilder import androidx.navigation.compose.composable +import androidx.navigation.navOptions import androidx.navigation.navigation import com.yapp.common.navigation.OrbitNavigator -import com.yapp.common.navigation.destination.SettingDestination -import com.yapp.common.navigation.destination.WebViewDestination import com.yapp.common.navigation.extensions.sharedHiltViewModel -import com.yapp.ui.base.BaseViewModel +import com.yapp.common.navigation.route.SettingBaseRoute +import com.yapp.common.navigation.route.SettingDestination import kotlinx.coroutines.flow.collectLatest fun NavGraphBuilder.settingNavGraph( navigator: OrbitNavigator, ) { - navigation( - route = SettingDestination.Route.route, - startDestination = SettingDestination.Setting.route, + navigation( + startDestination = SettingDestination.Setting, ) { - SettingDestination.routes.forEach { destination -> - when (destination) { - SettingDestination.Setting -> { - composable(route = destination.route) { backStackEntry -> - val viewModel = - backStackEntry.sharedHiltViewModel(navigator.navController) + composable { + val viewModel = it.sharedHiltViewModel(navigator.navController) - LaunchedEffect(viewModel) { - viewModel.container.sideEffectFlow.collectLatest { sideEffect -> - handleSettingSideEffect(sideEffect, navigator, viewModel) - } - } - - SettingRoute(viewModel) - } + LaunchedEffect(viewModel) { + viewModel.container.sideEffectFlow.collectLatest { sideEffect -> + handleSideEffect(sideEffect, navigator) } + } - SettingDestination.EditProfile -> { - composable(route = destination.route) { backStackEntry -> - val viewModel = - backStackEntry.sharedHiltViewModel(navigator.navController) + SettingRoute(viewModel) + } - LaunchedEffect(viewModel) { - viewModel.container.sideEffectFlow.collect { sideEffect -> - handleSettingSideEffect(sideEffect, navigator, viewModel) - } - } + composable { + val viewModel = it.sharedHiltViewModel(navigator.navController) - EditProfileRoute(viewModel) - } + LaunchedEffect(viewModel) { + viewModel.container.sideEffectFlow.collectLatest { sideEffect -> + handleSideEffect(sideEffect, navigator) } + } - SettingDestination.EditBirthday -> { - composable( - route = destination.route, - enterTransition = { - slideInVertically( - initialOffsetY = { it }, - animationSpec = tween( - durationMillis = 350, - easing = FastOutSlowInEasing, - ), - ) - }, - exitTransition = { - slideOutVertically( - targetOffsetY = { -it }, - animationSpec = tween( - durationMillis = 250, - easing = FastOutSlowInEasing, - ), - ) - }, - popEnterTransition = { - slideInVertically( - initialOffsetY = { -it }, - animationSpec = tween( - durationMillis = 300, - easing = FastOutSlowInEasing, - ), - ) - }, - popExitTransition = { - slideOutVertically( - targetOffsetY = { it }, - animationSpec = tween( - durationMillis = 300, - easing = FastOutSlowInEasing, - ), - ) - }, - ) { backStackEntry -> - val viewModel = - backStackEntry.sharedHiltViewModel(navigator.navController) + EditProfileRoute(viewModel) + } - LaunchedEffect(viewModel) { - viewModel.container.sideEffectFlow.collectLatest { sideEffect -> - handleSettingSideEffect(sideEffect, navigator, viewModel) - } - } + composable( + enterTransition = { + slideInVertically( + initialOffsetY = { it }, + animationSpec = tween( + durationMillis = 350, + easing = FastOutSlowInEasing, + ), + ) + }, + exitTransition = { + slideOutVertically( + targetOffsetY = { -it }, + animationSpec = tween( + durationMillis = 250, + easing = FastOutSlowInEasing, + ), + ) + }, + popEnterTransition = { + slideInVertically( + initialOffsetY = { -it }, + animationSpec = tween( + durationMillis = 300, + easing = FastOutSlowInEasing, + ), + ) + }, + popExitTransition = { + slideOutVertically( + targetOffsetY = { it }, + animationSpec = tween( + durationMillis = 300, + easing = FastOutSlowInEasing, + ), + ) + }, + ) { + val viewModel = it.sharedHiltViewModel(navigator.navController) - EditBirthdayRoute(viewModel) - } + LaunchedEffect(viewModel) { + viewModel.container.sideEffectFlow.collectLatest { sideEffect -> + handleSideEffect(sideEffect, navigator) } - - else -> {} } + + EditBirthdayRoute(viewModel) } } } -private fun handleSettingSideEffect( +private fun handleSideEffect( sideEffect: SettingContract.SideEffect, navigator: OrbitNavigator, - viewModel: BaseViewModel<*, *>, ) { when (sideEffect) { - is SettingContract.SideEffect.Navigate -> navigator.navigateTo( - route = sideEffect.route, - popUpTo = sideEffect.popUpTo, - inclusive = sideEffect.inclusive, - ) - SettingContract.SideEffect.NavigateBack -> navigator.navigateBack() + SettingContract.SideEffect.NavigateToSettingRoute -> { + navigator.navigateToSetting( + navOptions = navOptions { + popUpTo(SettingBaseRoute) { + inclusive = true + } + }, + ) + } + + SettingContract.SideEffect.NavigateToEditProfile -> { + navigator.navigateToEditProfile() + } + + SettingContract.SideEffect.NavigateToEditBirthday -> { + navigator.navigateToEditBirthDay() + } + is SettingContract.SideEffect.OpenWebView -> { - navigator.navigateTo("${WebViewDestination.WebView.route}/${Uri.encode(sideEffect.url)}") + navigator.navigateToWebView(Uri.encode(sideEffect.url)) } - else -> {} } } diff --git a/feature/splash/src/main/java/com/yapp/splash/SettingNavGraph.kt b/feature/splash/src/main/java/com/yapp/splash/SettingNavGraph.kt new file mode 100644 index 00000000..5a8e0e33 --- /dev/null +++ b/feature/splash/src/main/java/com/yapp/splash/SettingNavGraph.kt @@ -0,0 +1,14 @@ +package com.yapp.splash + +import androidx.navigation.NavGraphBuilder +import androidx.navigation.compose.composable +import com.yapp.common.navigation.OrbitNavigator +import com.yapp.common.navigation.route.SplashRoute + +fun NavGraphBuilder.splashScreen( + navigator: OrbitNavigator, +) { + composable { + SplashRoute(navigator) + } +} diff --git a/feature/webview/src/main/java/com/yapp/webview/WebViewNavGraph.kt b/feature/webview/src/main/java/com/yapp/webview/WebViewNavGraph.kt new file mode 100644 index 00000000..1e8c6458 --- /dev/null +++ b/feature/webview/src/main/java/com/yapp/webview/WebViewNavGraph.kt @@ -0,0 +1,19 @@ +package com.yapp.webview + +import androidx.navigation.NavGraphBuilder +import androidx.navigation.compose.composable +import androidx.navigation.toRoute +import com.yapp.common.navigation.OrbitNavigator +import com.yapp.common.navigation.route.WebViewRoute + +fun NavGraphBuilder.webViewScreen( + navigator: OrbitNavigator, +) { + composable { entry -> + val route = entry.toRoute() + WebViewRoute( + url = route.url, + navController = navigator.navController, + ) + } +} From 34fd208c1def1db23480ee5d86d8f14be318c935 Mon Sep 17 00:00:00 2001 From: dongchyeon Date: Tue, 3 Jun 2025 20:08:58 +0900 Subject: [PATCH 04/10] =?UTF-8?q?[REFACTOR/#212]=20=EA=B3=B5=ED=86=B5=20na?= =?UTF-8?q?vigateTo=20=ED=95=A8=EC=88=98=20=EC=A0=9C=EA=B1=B0=20=EB=B0=8F?= =?UTF-8?q?=20=EA=B0=81=20Route=20=EB=B3=84=20=EB=AA=85=EC=8B=9C=EC=A0=81?= =?UTF-8?q?=20=EB=9D=BC=EC=9A=B0=ED=8C=85=20=ED=95=A8=EC=88=98=20=EB=B6=84?= =?UTF-8?q?=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../navigation/extensions/RouteExtension.kt | 5 ++++ .../interaction/AlarmInteractionActivity.kt | 15 +++-------- .../interaction/action/AlarmActionContract.kt | 8 +++--- .../interaction/action/AlarmActionScreen.kt | 8 ++---- .../action/AlarmActionViewModel.kt | 20 +++++++------- .../snooze/AlarmSnoozeTimerContract.kt | 8 +----- .../snooze/AlarmSnoozeTimerScreen.kt | 12 +-------- .../java/com/yapp/fortune/FortuneContract.kt | 8 +++--- .../java/com/yapp/fortune/FortuneViewModel.kt | 18 ++----------- .../alarm/addedit/AlarmAddEditContract.kt | 6 ----- .../yapp/alarm/addedit/AlarmAddEditScreen.kt | 7 ----- .../main/java/com/yapp/home/HomeContract.kt | 13 +++++---- .../src/main/java/com/yapp/home/HomeScreen.kt | 21 ++++++++++----- .../main/java/com/yapp/home/HomeViewModel.kt | 17 +++--------- .../java/com/yapp/mission/MissionContract.kt | 6 +---- .../java/com/yapp/mission/MissionViewModel.kt | 27 +++---------------- .../com/yapp/onboarding/OnboardingContract.kt | 8 +++--- .../yapp/onboarding/OnboardingViewModel.kt | 20 +++++--------- .../com/yapp/setting/EditProfileViewModel.kt | 15 +++-------- .../java/com/yapp/setting/SettingContract.kt | 14 +++++----- .../java/com/yapp/setting/SettingScreen.kt | 4 +-- .../java/com/yapp/setting/SettingViewModel.kt | 5 ++-- .../java/com/yapp/splash/SplashContract.kt | 4 ++- .../main/java/com/yapp/splash/SplashScreen.kt | 25 ++++++++++++----- .../java/com/yapp/splash/SplashViewModel.kt | 9 +++---- 25 files changed, 109 insertions(+), 194 deletions(-) create mode 100644 core/common/src/main/java/com/yapp/common/navigation/extensions/RouteExtension.kt diff --git a/core/common/src/main/java/com/yapp/common/navigation/extensions/RouteExtension.kt b/core/common/src/main/java/com/yapp/common/navigation/extensions/RouteExtension.kt new file mode 100644 index 00000000..965bf67b --- /dev/null +++ b/core/common/src/main/java/com/yapp/common/navigation/extensions/RouteExtension.kt @@ -0,0 +1,5 @@ +package com.yapp.common.navigation.extensions + +import kotlin.reflect.KClass + +fun KClass.toRoute(): String = this.simpleName ?: error("Route name missing") diff --git a/feature/alarm-interaction/src/main/java/com/yapp/alarm/interaction/AlarmInteractionActivity.kt b/feature/alarm-interaction/src/main/java/com/yapp/alarm/interaction/AlarmInteractionActivity.kt index 443027a5..5860eb6d 100644 --- a/feature/alarm-interaction/src/main/java/com/yapp/alarm/interaction/AlarmInteractionActivity.kt +++ b/feature/alarm-interaction/src/main/java/com/yapp/alarm/interaction/AlarmInteractionActivity.kt @@ -16,14 +16,13 @@ import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.material3.Surface import androidx.compose.runtime.DisposableEffect -import androidx.compose.runtime.LaunchedEffect import androidx.compose.ui.Modifier import androidx.core.util.Consumer import androidx.navigation.compose.NavHost import com.yapp.alarm.AlarmConstants import com.yapp.alarm.receivers.AlarmInteractionActivityReceiver -import com.yapp.common.navigation.destination.AlarmInteractionDestination import com.yapp.common.navigation.rememberOrbitNavigator +import com.yapp.common.navigation.route.AlarmInteractionBaseRoute import com.yapp.designsystem.theme.OrbitTheme import com.yapp.domain.model.Alarm import dagger.hilt.android.AndroidEntryPoint @@ -70,11 +69,12 @@ class AlarmInteractionActivity : ComponentActivity() { ) { NavHost( navController = navigator.navController, - startDestination = AlarmInteractionDestination.Route.route, + startDestination = AlarmInteractionBaseRoute, modifier = Modifier.navigationBarsPadding(), ) { alarmInteractionNavGraph( navigator = navigator, + alarm = alarm, ) } } @@ -89,7 +89,7 @@ class AlarmInteractionActivity : ComponentActivity() { } Log.d("AlarmInteractionActivity", "New Intent: $newIntent") newAlarm?.let { alarm -> - navigator.navController.navigate("${AlarmInteractionDestination.AlarmAction.route}/$alarm") + navigator.navigateToAlarmAction(alarm = alarm) } } @@ -99,13 +99,6 @@ class AlarmInteractionActivity : ComponentActivity() { this@AlarmInteractionActivity.removeOnNewIntentListener(onNewIntentConsumer) } } - - LaunchedEffect(Unit) { - val route = "${AlarmInteractionDestination.AlarmAction.route}/$alarm" - navigator.navController.navigate(route) { - popUpTo(AlarmInteractionDestination.Route.route) { inclusive = true } - } - } } } diff --git a/feature/alarm-interaction/src/main/java/com/yapp/alarm/interaction/action/AlarmActionContract.kt b/feature/alarm-interaction/src/main/java/com/yapp/alarm/interaction/action/AlarmActionContract.kt index cbc6d959..470f89c3 100644 --- a/feature/alarm-interaction/src/main/java/com/yapp/alarm/interaction/action/AlarmActionContract.kt +++ b/feature/alarm-interaction/src/main/java/com/yapp/alarm/interaction/action/AlarmActionContract.kt @@ -1,5 +1,7 @@ package com.yapp.alarm.interaction.action +import com.yapp.domain.model.Alarm +import com.yapp.ui.base.SideEffect import com.yapp.ui.base.UiState class AlarmActionContract { @@ -22,10 +24,6 @@ class AlarmActionContract { } sealed class SideEffect : com.yapp.ui.base.SideEffect { - data class Navigate( - val route: String, - val popUpTo: String? = null, - val inclusive: Boolean = false, - ) : SideEffect() + data class NavigateToAlarmSnooze(val alarm: Alarm) : SideEffect() } } diff --git a/feature/alarm-interaction/src/main/java/com/yapp/alarm/interaction/action/AlarmActionScreen.kt b/feature/alarm-interaction/src/main/java/com/yapp/alarm/interaction/action/AlarmActionScreen.kt index c44edb40..4db7ed7b 100644 --- a/feature/alarm-interaction/src/main/java/com/yapp/alarm/interaction/action/AlarmActionScreen.kt +++ b/feature/alarm-interaction/src/main/java/com/yapp/alarm/interaction/action/AlarmActionScreen.kt @@ -49,12 +49,8 @@ internal fun AlarmActionRoute( LaunchedEffect(sideEffect) { sideEffect.collect { action -> when (action) { - is AlarmActionContract.SideEffect.Navigate -> { - navigator.navigateTo( - route = action.route, - popUpTo = action.popUpTo, - inclusive = action.inclusive, - ) + is AlarmActionContract.SideEffect.NavigateToAlarmSnooze -> { + navigator.navigateToAlarmSnoozeTimer(action.alarm) } } } diff --git a/feature/alarm-interaction/src/main/java/com/yapp/alarm/interaction/action/AlarmActionViewModel.kt b/feature/alarm-interaction/src/main/java/com/yapp/alarm/interaction/action/AlarmActionViewModel.kt index b6fa6e74..57e6cd8c 100644 --- a/feature/alarm-interaction/src/main/java/com/yapp/alarm/interaction/action/AlarmActionViewModel.kt +++ b/feature/alarm-interaction/src/main/java/com/yapp/alarm/interaction/action/AlarmActionViewModel.kt @@ -5,7 +5,6 @@ import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.viewModelScope import com.yapp.alarm.pendingIntent.interaction.createAlarmDismissIntent import com.yapp.alarm.pendingIntent.interaction.createAlarmSnoozeIntent -import com.yapp.common.navigation.Routes import com.yapp.datastore.UserPreferences import com.yapp.domain.model.Alarm import com.yapp.ui.base.BaseViewModel @@ -15,7 +14,10 @@ import kotlinx.coroutines.flow.firstOrNull import kotlinx.coroutines.isActive import kotlinx.coroutines.launch import java.time.LocalDate +import java.time.LocalTime import java.time.format.DateTimeFormatter +import java.time.format.TextStyle +import java.util.Locale import javax.inject.Inject @HiltViewModel @@ -57,9 +59,9 @@ class AlarmActionViewModel @Inject constructor( private fun startClock() { viewModelScope.launch { while (isActive) { - val now = java.time.LocalTime.now() - val today = java.time.LocalDate.now() - val dayOfWeek = today.dayOfWeek.getDisplayName(java.time.format.TextStyle.FULL, java.util.Locale.KOREAN) + val now = LocalTime.now() + val today = LocalDate.now() + val dayOfWeek = today.dayOfWeek.getDisplayName(TextStyle.FULL, Locale.KOREAN) updateState { copy( @@ -94,13 +96,9 @@ class AlarmActionViewModel @Inject constructor( }, ) } - emitSideEffect( - AlarmActionContract.SideEffect.Navigate( - route = "${Routes.AlarmInteraction.ALARM_SNOOZE_TIMER}/$alarm", - popUpTo = Routes.AlarmInteraction.ALARM_ACTION, - inclusive = true, - ), - ) + alarm?.let { + emitSideEffect(AlarmActionContract.SideEffect.NavigateToAlarmSnooze(it)) + } } private fun dismiss() { diff --git a/feature/alarm-interaction/src/main/java/com/yapp/alarm/interaction/snooze/AlarmSnoozeTimerContract.kt b/feature/alarm-interaction/src/main/java/com/yapp/alarm/interaction/snooze/AlarmSnoozeTimerContract.kt index f7adfee9..dcca8639 100644 --- a/feature/alarm-interaction/src/main/java/com/yapp/alarm/interaction/snooze/AlarmSnoozeTimerContract.kt +++ b/feature/alarm-interaction/src/main/java/com/yapp/alarm/interaction/snooze/AlarmSnoozeTimerContract.kt @@ -16,11 +16,5 @@ class AlarmSnoozeTimerContract { data object Dismiss : Action() } - sealed class SideEffect : com.yapp.ui.base.SideEffect { - data class Navigate( - val route: String, - val popUpTo: String? = null, - val inclusive: Boolean = false, - ) : SideEffect() - } + sealed class SideEffect : com.yapp.ui.base.SideEffect } diff --git a/feature/alarm-interaction/src/main/java/com/yapp/alarm/interaction/snooze/AlarmSnoozeTimerScreen.kt b/feature/alarm-interaction/src/main/java/com/yapp/alarm/interaction/snooze/AlarmSnoozeTimerScreen.kt index d770b69f..e914f506 100644 --- a/feature/alarm-interaction/src/main/java/com/yapp/alarm/interaction/snooze/AlarmSnoozeTimerScreen.kt +++ b/feature/alarm-interaction/src/main/java/com/yapp/alarm/interaction/snooze/AlarmSnoozeTimerScreen.kt @@ -57,17 +57,7 @@ internal fun AlarmSnoozeTimerRoute( val sideEffect = viewModel.container.sideEffectFlow LaunchedEffect(sideEffect) { - sideEffect.collect { action -> - when (action) { - is AlarmSnoozeTimerContract.SideEffect.Navigate -> { - navigator.navigateTo( - route = action.route, - popUpTo = action.popUpTo, - inclusive = action.inclusive, - ) - } - } - } + sideEffect.collect { } } AlarmSnoozeTimerScreen( diff --git a/feature/fortune/src/main/java/com/yapp/fortune/FortuneContract.kt b/feature/fortune/src/main/java/com/yapp/fortune/FortuneContract.kt index 0083828d..6c7528e0 100644 --- a/feature/fortune/src/main/java/com/yapp/fortune/FortuneContract.kt +++ b/feature/fortune/src/main/java/com/yapp/fortune/FortuneContract.kt @@ -25,11 +25,9 @@ sealed class FortuneContract { } sealed class SideEffect : com.yapp.ui.base.SideEffect { - data class Navigate( - val route: String, - val popUpTo: String? = null, - val inclusive: Boolean = false, - ) : SideEffect() + data object NavigateToFortuneReward : SideEffect() + + data object NavigateToHome : SideEffect() data object NavigateBack : SideEffect() diff --git a/feature/fortune/src/main/java/com/yapp/fortune/FortuneViewModel.kt b/feature/fortune/src/main/java/com/yapp/fortune/FortuneViewModel.kt index cfd930f5..b4890bfb 100644 --- a/feature/fortune/src/main/java/com/yapp/fortune/FortuneViewModel.kt +++ b/feature/fortune/src/main/java/com/yapp/fortune/FortuneViewModel.kt @@ -4,8 +4,6 @@ import android.app.Application import android.util.Log import androidx.annotation.DrawableRes import androidx.lifecycle.viewModelScope -import com.yapp.common.navigation.destination.FortuneDestination -import com.yapp.common.navigation.destination.HomeDestination import com.yapp.datastore.UserPreferences import com.yapp.domain.repository.FortuneRepository import com.yapp.domain.repository.ImageRepository @@ -78,13 +76,7 @@ class FortuneViewModel @Inject constructor( when (action) { is FortuneContract.Action.NextStep -> { if (state.hasReward) { - postSideEffect( - FortuneContract.SideEffect.Navigate( - route = FortuneDestination.Reward.route, - popUpTo = FortuneDestination.Fortune.route, - inclusive = true, - ), - ) + postSideEffect(FortuneContract.SideEffect.NavigateToFortuneReward) } else { reduce { state.copy(currentStep = (state.currentStep + 1).coerceAtMost(5)) } } @@ -102,13 +94,7 @@ class FortuneViewModel @Inject constructor( } private fun navigateToHome() { - emitSideEffect( - FortuneContract.SideEffect.Navigate( - route = HomeDestination.Route.route, - popUpTo = FortuneDestination.Route.route, - inclusive = true, - ), - ) + emitSideEffect(FortuneContract.SideEffect.NavigateToHome) } private fun saveImage(@DrawableRes resId: Int) = viewModelScope.launch { diff --git a/feature/home/src/main/java/com/yapp/alarm/addedit/AlarmAddEditContract.kt b/feature/home/src/main/java/com/yapp/alarm/addedit/AlarmAddEditContract.kt index 2f9c710f..de6da472 100644 --- a/feature/home/src/main/java/com/yapp/alarm/addedit/AlarmAddEditContract.kt +++ b/feature/home/src/main/java/com/yapp/alarm/addedit/AlarmAddEditContract.kt @@ -95,12 +95,6 @@ sealed class AlarmAddEditContract { } sealed class SideEffect : com.yapp.ui.base.SideEffect { - data class Navigate( - val route: String, - val popUpTo: String? = null, - val inclusive: Boolean = false, - ) : SideEffect() - data object NavigateBack : SideEffect() data class SaveAlarm(val id: Long) : SideEffect() diff --git a/feature/home/src/main/java/com/yapp/alarm/addedit/AlarmAddEditScreen.kt b/feature/home/src/main/java/com/yapp/alarm/addedit/AlarmAddEditScreen.kt index 5b7ba527..d479e3f6 100644 --- a/feature/home/src/main/java/com/yapp/alarm/addedit/AlarmAddEditScreen.kt +++ b/feature/home/src/main/java/com/yapp/alarm/addedit/AlarmAddEditScreen.kt @@ -88,13 +88,6 @@ fun AlarmAddEditRoute( is AlarmAddEditContract.SideEffect.NavigateBack -> { navigator.navigateBack() } - is AlarmAddEditContract.SideEffect.Navigate -> { - navigator.navigateTo( - route = effect.route, - popUpTo = effect.popUpTo, - inclusive = effect.inclusive, - ) - } is AlarmAddEditContract.SideEffect.SaveAlarm -> { navigator.navController.previousBackStackEntry ?.savedStateHandle diff --git a/feature/home/src/main/java/com/yapp/home/HomeContract.kt b/feature/home/src/main/java/com/yapp/home/HomeContract.kt index ab55314f..ee3f5dd1 100644 --- a/feature/home/src/main/java/com/yapp/home/HomeContract.kt +++ b/feature/home/src/main/java/com/yapp/home/HomeContract.kt @@ -3,6 +3,7 @@ package com.yapp.home import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp import com.yapp.domain.model.Alarm +import com.yapp.ui.base.SideEffect import com.yapp.ui.base.UiState sealed class HomeContract { @@ -72,11 +73,13 @@ sealed class HomeContract { } sealed class SideEffect : com.yapp.ui.base.SideEffect { - data class Navigate( - val route: String, - val popUpTo: String? = null, - val inclusive: Boolean = false, - ) : SideEffect() + data object NavigateToAddAlarm : SideEffect() + + data class NavigateToEditAlarm(val alarmId: Long) : SideEffect() + + data object NavigateToFortune : SideEffect() + + data object NavigateToSetting : SideEffect() data class ShowSnackBar( val message: String, diff --git a/feature/home/src/main/java/com/yapp/home/HomeScreen.kt b/feature/home/src/main/java/com/yapp/home/HomeScreen.kt index 270922a1..b8a4dc46 100644 --- a/feature/home/src/main/java/com/yapp/home/HomeScreen.kt +++ b/feature/home/src/main/java/com/yapp/home/HomeScreen.kt @@ -123,13 +123,22 @@ fun HomeRoute( LaunchedEffect(sideEffect) { sideEffect.collectLatest { effect -> when (effect) { - is HomeContract.SideEffect.Navigate -> { - navigator.navigateTo( - route = effect.route, - popUpTo = effect.popUpTo, - inclusive = effect.inclusive, - ) + is HomeContract.SideEffect.NavigateToAddAlarm -> { + navigator.navigateToAddAlarm() + } + + is HomeContract.SideEffect.NavigateToEditAlarm -> { + navigator.navigateToEditAlarm(effect.alarmId) + } + + is HomeContract.SideEffect.NavigateToFortune -> { + navigator.navigateToFortune() + } + + is HomeContract.SideEffect.NavigateToSetting -> { + navigator.navigateToSetting() } + is HomeContract.SideEffect.ShowSnackBar -> { val result = showCustomSnackBar( scope = coroutineScope, diff --git a/feature/home/src/main/java/com/yapp/home/HomeViewModel.kt b/feature/home/src/main/java/com/yapp/home/HomeViewModel.kt index 67d3ee67..9c5dccc6 100644 --- a/feature/home/src/main/java/com/yapp/home/HomeViewModel.kt +++ b/feature/home/src/main/java/com/yapp/home/HomeViewModel.kt @@ -3,9 +3,6 @@ package com.yapp.home import android.util.Log import androidx.lifecycle.viewModelScope import com.yapp.alarm.AlarmHelper -import com.yapp.common.navigation.destination.FortuneDestination -import com.yapp.common.navigation.destination.HomeDestination -import com.yapp.common.navigation.destination.SettingDestination import com.yapp.common.util.ResourceProvider import com.yapp.datastore.UserPreferences import com.yapp.domain.model.Alarm @@ -103,7 +100,7 @@ class HomeViewModel @Inject constructor( } private fun navigateToAlarmCreation() { - emitSideEffect(HomeContract.SideEffect.Navigate(HomeDestination.AlarmAddEdit.route)) + emitSideEffect(HomeContract.SideEffect.NavigateToAddAlarm) } private fun toggleMultiSelectionMode() { @@ -316,7 +313,7 @@ class HomeViewModel @Inject constructor( } private fun editAlarm(alarmId: Long) { - emitSideEffect(HomeContract.SideEffect.Navigate("${HomeDestination.AlarmAddEdit.route}?id=$alarmId")) + emitSideEffect(HomeContract.SideEffect.NavigateToEditAlarm(alarmId)) } private fun updateDeliveryTime(alarms: List) { @@ -404,9 +401,7 @@ class HomeViewModel @Inject constructor( processAction(HomeContract.Action.ShowNoDailyFortuneDialog) } else { userPreferences.markFortuneAsChecked() - emitSideEffect( - HomeContract.SideEffect.Navigate(FortuneDestination.Fortune.route), - ) + emitSideEffect(HomeContract.SideEffect.NavigateToFortune) } } } @@ -457,11 +452,7 @@ class HomeViewModel @Inject constructor( } private fun navigateToSetting() { - emitSideEffect( - HomeContract.SideEffect.Navigate( - route = SettingDestination.Route.route, - ), - ) + emitSideEffect(HomeContract.SideEffect.NavigateToSetting) } private fun showItemMenu(alarmId: Long, x: Float, y: Float) { diff --git a/feature/mission/src/main/java/com/yapp/mission/MissionContract.kt b/feature/mission/src/main/java/com/yapp/mission/MissionContract.kt index 505ae265..f1812c49 100644 --- a/feature/mission/src/main/java/com/yapp/mission/MissionContract.kt +++ b/feature/mission/src/main/java/com/yapp/mission/MissionContract.kt @@ -28,11 +28,7 @@ sealed class MissionContract { } sealed class SideEffect : com.yapp.ui.base.SideEffect { - data class Navigate( - val route: String, - val popUpTo: String? = null, - val inclusive: Boolean = false, - ) : SideEffect() + data object NavigateToFortune : SideEffect() data object NavigateBack : SideEffect() } diff --git a/feature/mission/src/main/java/com/yapp/mission/MissionViewModel.kt b/feature/mission/src/main/java/com/yapp/mission/MissionViewModel.kt index 94512478..38512436 100644 --- a/feature/mission/src/main/java/com/yapp/mission/MissionViewModel.kt +++ b/feature/mission/src/main/java/com/yapp/mission/MissionViewModel.kt @@ -7,9 +7,6 @@ import androidx.lifecycle.viewModelScope import com.yapp.alarm.pendingIntent.interaction.createAlarmDismissIntent import com.yapp.analytics.AnalyticsEvent import com.yapp.analytics.AnalyticsHelper -import com.yapp.common.navigation.destination.FortuneDestination -import com.yapp.common.navigation.destination.HomeDestination -import com.yapp.common.navigation.destination.MissionDestination import com.yapp.datastore.UserPreferences import com.yapp.domain.model.MissionType import com.yapp.domain.repository.FortuneRepository @@ -131,13 +128,7 @@ class MissionViewModel @Inject constructor( userPreferences.saveFortuneId(data.id) userPreferences.saveFortuneScore(data.avgFortuneScore) - emitSideEffect( - MissionContract.SideEffect.Navigate( - route = FortuneDestination.Route.route, - popUpTo = MissionDestination.Route.route, - inclusive = true, - ), - ) + emitSideEffect(MissionContract.SideEffect.NavigateToFortune) }.onFailure { error -> Log.e("MissionViewModel", "운세 데이터 요청 실패: ${error.message}") updateState { copy(errorMessage = error.message) } @@ -159,13 +150,7 @@ class MissionViewModel @Inject constructor( userPreferences.saveFortuneId(data.id) userPreferences.saveFortuneScore(data.avgFortuneScore) - emitSideEffect( - MissionContract.SideEffect.Navigate( - route = FortuneDestination.Route.route, - popUpTo = MissionDestination.Route.route, - inclusive = true, - ), - ) + emitSideEffect(MissionContract.SideEffect.NavigateToFortune) }.onFailure { Log.e("MissionViewModel", "운세 재요청 실패: ${it.message}") navigateToHome() @@ -195,13 +180,7 @@ class MissionViewModel @Inject constructor( } private fun navigateToHome() { - emitSideEffect( - MissionContract.SideEffect.Navigate( - route = HomeDestination.Route.route, - popUpTo = MissionDestination.Route.route, - inclusive = true, - ), - ) + emitSideEffect(MissionContract.SideEffect.NavigateToFortune) } private fun sendAlarmDismissIntent(id: Long) { diff --git a/feature/onboarding/src/main/java/com/yapp/onboarding/OnboardingContract.kt b/feature/onboarding/src/main/java/com/yapp/onboarding/OnboardingContract.kt index 5cb2a890..0b5a339b 100644 --- a/feature/onboarding/src/main/java/com/yapp/onboarding/OnboardingContract.kt +++ b/feature/onboarding/src/main/java/com/yapp/onboarding/OnboardingContract.kt @@ -72,14 +72,12 @@ sealed class OnboardingContract { } sealed class SideEffect : com.yapp.ui.base.SideEffect { - data class Navigate( - val route: String, - val popUpTo: String? = null, - val inclusive: Boolean = false, - ) : SideEffect() + data object NavigateToNextStep : SideEffect() data object NavigateBack : SideEffect() + data object OnboardingCompleted : SideEffect() + data class OpenWebView(val url: String) : SideEffect() } diff --git a/feature/onboarding/src/main/java/com/yapp/onboarding/OnboardingViewModel.kt b/feature/onboarding/src/main/java/com/yapp/onboarding/OnboardingViewModel.kt index 72e873a5..4628684f 100644 --- a/feature/onboarding/src/main/java/com/yapp/onboarding/OnboardingViewModel.kt +++ b/feature/onboarding/src/main/java/com/yapp/onboarding/OnboardingViewModel.kt @@ -5,8 +5,7 @@ import androidx.lifecycle.SavedStateHandle import androidx.lifecycle.viewModelScope import com.yapp.analytics.AnalyticsEvent import com.yapp.analytics.AnalyticsHelper -import com.yapp.common.navigation.destination.HomeDestination -import com.yapp.common.navigation.destination.OnboardingDestination +import com.yapp.common.navigation.route.OnboardingDestination import com.yapp.datastore.UserPreferences import com.yapp.domain.model.Alarm import com.yapp.domain.model.AlarmDay @@ -19,6 +18,7 @@ import com.yapp.ui.base.BaseViewModel import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.launch import javax.inject.Inject +import kotlin.reflect.KClass @HiltViewModel class OnboardingViewModel @Inject constructor( @@ -35,8 +35,8 @@ class OnboardingViewModel @Inject constructor( birthType = savedStateHandle["birthType"] ?: "양력", ), ) { - private val currentRoute: String? - get() = OnboardingDestination.routes.getOrNull(currentState.currentStep - 1)?.route + private val currentRoute: KClass? + get() = OnboardingDestination.routes.getOrNull(currentState.currentStep - 1) fun processAction(action: OnboardingContract.Action) { when (action) { @@ -104,7 +104,7 @@ class OnboardingViewModel @Inject constructor( if (nextRoute != null) { savedStateHandle["currentStep"] = nextStep updateState { copy(currentStep = nextStep) } - emitSideEffect(OnboardingContract.SideEffect.Navigate(nextRoute)) + emitSideEffect(OnboardingContract.SideEffect.NavigateToNextStep) } else { emitSideEffect(OnboardingContract.SideEffect.OnboardingCompleted) } @@ -201,7 +201,7 @@ class OnboardingViewModel @Inject constructor( } private fun updateBirthDate(lunar: String, year: Int, month: Int, day: Int) { - if (currentRoute != OnboardingDestination.Birthday.route) return + if (currentRoute != OnboardingDestination.Birthday::class) return val formattedDate = "$year-${month.toString().padStart(2, '0')}-${day.toString().padStart(2, '0')}" @@ -241,13 +241,7 @@ class OnboardingViewModel @Inject constructor( private fun completeOnboarding() { viewModelScope.launch { userPreferences.setOnboardingCompleted() - emitSideEffect( - OnboardingContract.SideEffect.Navigate( - route = HomeDestination.Route.route, - popUpTo = OnboardingDestination.Route.route, - inclusive = true, - ), - ) + emitSideEffect(OnboardingContract.SideEffect.OnboardingCompleted) } } diff --git a/feature/setting/src/main/java/com/yapp/setting/EditProfileViewModel.kt b/feature/setting/src/main/java/com/yapp/setting/EditProfileViewModel.kt index a5d3adf2..166388b3 100644 --- a/feature/setting/src/main/java/com/yapp/setting/EditProfileViewModel.kt +++ b/feature/setting/src/main/java/com/yapp/setting/EditProfileViewModel.kt @@ -2,7 +2,6 @@ package com.yapp.setting import android.util.Log import androidx.lifecycle.viewModelScope -import com.yapp.common.navigation.destination.SettingDestination import com.yapp.datastore.UserPreferences import com.yapp.domain.model.EditUser import com.yapp.domain.repository.UserInfoRepository @@ -150,15 +149,7 @@ class EditProfileViewModel @Inject constructor( if (result.isSuccess) { userPreferences.saveUserName(state.name) - emitSideEffect(SettingContract.SideEffect.UserInfoUpdated) - - emitSideEffect( - SettingContract.SideEffect.Navigate( - route = SettingDestination.Setting.route, - popUpTo = SettingDestination.Setting.route, - inclusive = true, - ), - ) + emitSideEffect(SettingContract.SideEffect.NavigateToSettingRoute) } else { Log.e("EditProfileViewModel", "사용자 정보 수정 실패") } @@ -168,9 +159,9 @@ class EditProfileViewModel @Inject constructor( return formattedDate.replace(Regex("[^0-9-]"), "") } - private fun navigateToEditBirthday() = intent { + private fun navigateToEditBirthday() { updateState { copy(shouldFetchUserInfo = false) } - emitSideEffect(SettingContract.SideEffect.Navigate(SettingDestination.EditBirthday.route)) + emitSideEffect(SettingContract.SideEffect.NavigateToEditBirthday) } private fun refreshUserInfo() { diff --git a/feature/setting/src/main/java/com/yapp/setting/SettingContract.kt b/feature/setting/src/main/java/com/yapp/setting/SettingContract.kt index b6b65a66..6f957cc3 100644 --- a/feature/setting/src/main/java/com/yapp/setting/SettingContract.kt +++ b/feature/setting/src/main/java/com/yapp/setting/SettingContract.kt @@ -65,14 +65,14 @@ sealed class SettingContract { } sealed class SideEffect : com.yapp.ui.base.SideEffect { - data class Navigate( - val route: String, - val popUpTo: String? = null, - val inclusive: Boolean = false, - ) : SideEffect() - data object NavigateBack : SideEffect() + + data object NavigateToSettingRoute : SideEffect() + + data object NavigateToEditProfile : SideEffect() + + data object NavigateToEditBirthday : SideEffect() + data class OpenWebView(val url: String) : SideEffect() - data object UserInfoUpdated : SideEffect() } } diff --git a/feature/setting/src/main/java/com/yapp/setting/SettingScreen.kt b/feature/setting/src/main/java/com/yapp/setting/SettingScreen.kt index 621d7904..03f79fd0 100644 --- a/feature/setting/src/main/java/com/yapp/setting/SettingScreen.kt +++ b/feature/setting/src/main/java/com/yapp/setting/SettingScreen.kt @@ -46,9 +46,7 @@ fun SettingRoute( SettingScreen( state = state, onNavigateToEditProfile = { - viewModel.onAction( - SettingContract.Action.NavigateToEditProfile, - ) + viewModel.onAction(SettingContract.Action.NavigateToEditProfile) }, onBackClick = { viewModel.onAction(SettingContract.Action.PreviousStep) }, onInquiryClick = { diff --git a/feature/setting/src/main/java/com/yapp/setting/SettingViewModel.kt b/feature/setting/src/main/java/com/yapp/setting/SettingViewModel.kt index 1dcbd1d7..2e0773c0 100644 --- a/feature/setting/src/main/java/com/yapp/setting/SettingViewModel.kt +++ b/feature/setting/src/main/java/com/yapp/setting/SettingViewModel.kt @@ -2,7 +2,6 @@ package com.yapp.setting import android.util.Log import androidx.lifecycle.viewModelScope -import com.yapp.common.navigation.destination.SettingDestination import com.yapp.datastore.UserPreferences import com.yapp.domain.repository.UserInfoRepository import com.yapp.ui.base.BaseViewModel @@ -49,8 +48,8 @@ class SettingViewModel @Inject constructor( } } - private fun navigateToEditProfile() = intent { - emitSideEffect(SettingContract.SideEffect.Navigate(SettingDestination.EditProfile.route)) + private fun navigateToEditProfile() { + emitSideEffect(SettingContract.SideEffect.NavigateToEditProfile) } private fun openWebView(url: String) { diff --git a/feature/splash/src/main/java/com/yapp/splash/SplashContract.kt b/feature/splash/src/main/java/com/yapp/splash/SplashContract.kt index 5cebff65..d83dff65 100644 --- a/feature/splash/src/main/java/com/yapp/splash/SplashContract.kt +++ b/feature/splash/src/main/java/com/yapp/splash/SplashContract.kt @@ -9,6 +9,8 @@ sealed class SplashContract { ) : UiState sealed class SideEffect : com.yapp.ui.base.SideEffect { - data class Navigate(val route: String) : SideEffect() + data object NavigateToHome : SideEffect() + + data object NavigateToOnboarding : SideEffect() } } diff --git a/feature/splash/src/main/java/com/yapp/splash/SplashScreen.kt b/feature/splash/src/main/java/com/yapp/splash/SplashScreen.kt index 152edd15..272dea8a 100644 --- a/feature/splash/src/main/java/com/yapp/splash/SplashScreen.kt +++ b/feature/splash/src/main/java/com/yapp/splash/SplashScreen.kt @@ -19,8 +19,9 @@ import androidx.compose.ui.res.painterResource import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle +import androidx.navigation.navOptions import com.yapp.common.navigation.OrbitNavigator -import com.yapp.common.navigation.destination.SplashDestination +import com.yapp.common.navigation.route.SplashRoute import com.yapp.designsystem.theme.OrbitTheme import kotlinx.coroutines.flow.collectLatest @@ -35,11 +36,23 @@ fun SplashRoute( LaunchedEffect(sideEffect) { sideEffect.collectLatest { effect -> when (effect) { - is SplashContract.SideEffect.Navigate -> { - navigator.navigateTo( - route = effect.route, - popUpTo = SplashDestination.Route.route, - inclusive = true, + is SplashContract.SideEffect.NavigateToOnboarding -> { + navigator.navigateToOnboarding( + navOptions = navOptions { + popUpTo(SplashRoute) { + inclusive = true + } + }, + ) + } + + is SplashContract.SideEffect.NavigateToHome -> { + navigator.navigateToHome( + navOptions = navOptions { + popUpTo(SplashRoute) { + inclusive = true + } + }, ) } } diff --git a/feature/splash/src/main/java/com/yapp/splash/SplashViewModel.kt b/feature/splash/src/main/java/com/yapp/splash/SplashViewModel.kt index 201acd55..db697f4b 100644 --- a/feature/splash/src/main/java/com/yapp/splash/SplashViewModel.kt +++ b/feature/splash/src/main/java/com/yapp/splash/SplashViewModel.kt @@ -1,8 +1,6 @@ package com.yapp.splash import androidx.lifecycle.viewModelScope -import com.yapp.common.navigation.destination.HomeDestination -import com.yapp.common.navigation.destination.OnboardingDestination import com.yapp.datastore.UserPreferences import com.yapp.ui.base.BaseViewModel import dagger.hilt.android.lifecycle.HiltViewModel @@ -40,12 +38,11 @@ class SplashViewModel @Inject constructor( ) { userId, onboardingCompleted -> Pair(userId, onboardingCompleted) }.collect { (userId, onboardingCompleted) -> - val destination = if (userId != null && onboardingCompleted) { - HomeDestination.Home.route + if (userId != null && onboardingCompleted) { + emitSideEffect(SplashContract.SideEffect.NavigateToHome) } else { - OnboardingDestination.Route.route + emitSideEffect(SplashContract.SideEffect.NavigateToOnboarding) } - emitSideEffect(SplashContract.SideEffect.Navigate(destination)) } } } From cd72e2911d7c04fb4c65392733605b68aad1e44e Mon Sep 17 00:00:00 2001 From: dongchyeon Date: Tue, 3 Jun 2025 20:54:44 +0900 Subject: [PATCH 05/10] =?UTF-8?q?[REFACTOR/#212]=20Onboarding=20=EB=8B=A8?= =?UTF-8?q?=EA=B3=84=20=EC=9D=B4=EB=8F=99=20=EC=8B=9C=20currentRoute=20?= =?UTF-8?q?=ED=8C=8C=EC=8B=B1=20=EB=8C=80=EC=8B=A0=20=EB=AA=85=EC=8B=9C?= =?UTF-8?q?=EC=A0=81=20currentStep=20=EC=9D=B8=EC=9E=90=EB=A1=9C=20?= =?UTF-8?q?=EB=8C=80=EC=B2=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../yapp/common/navigation/OrbitNavigator.kt | 11 +++++----- .../navigation/route/OnboardingRoute.kt | 20 +++++++++---------- feature/navigator/build.gradle.kts | 1 + .../com/yapp/onboarding/OnboardingContract.kt | 2 +- .../com/yapp/onboarding/OnboardingNavGraph.kt | 4 ++-- .../yapp/onboarding/OnboardingViewModel.kt | 2 +- gradle/libs.versions.toml | 2 ++ 7 files changed, 22 insertions(+), 20 deletions(-) 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 92e20cb5..cedf91f6 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 @@ -5,7 +5,6 @@ import androidx.compose.runtime.remember import androidx.navigation.NavHostController import androidx.navigation.NavOptions import androidx.navigation.compose.rememberNavController -import com.yapp.common.navigation.extensions.toRoute import com.yapp.common.navigation.route.AlarmInteractionDestination import com.yapp.common.navigation.route.FortuneBaseRoute import com.yapp.common.navigation.route.FortuneDestination @@ -28,13 +27,13 @@ class OrbitNavigator( navController.navigate(OnboardingBaseRoute, navOptions) } - fun navigateToOnboardingNextStep(navOptions: NavOptions? = null) { - val currentRoute = navController.currentBackStackEntry?.destination?.route ?: return + fun navigateToOnboardingNextStep(currentStep: Int, navOptions: NavOptions? = null) { + val nextRouteClass = OnboardingDestination.nextRoute(currentStep + 1) ?: return - val currentIndex = OnboardingDestination.routes.indexOfFirst { it.toRoute() == currentRoute } - val nextRouteClass = OnboardingDestination.nextRoute(currentIndex + 1) ?: return + val nextRouteInstance = nextRouteClass.objectInstance + ?: error("Cannot get object instance of route class: $nextRouteClass") - navController.navigate(nextRouteClass, navOptions) + navController.navigate(nextRouteInstance, navOptions) } fun navigateToAddAlarm(navOptions: NavOptions? = null) { diff --git a/core/common/src/main/java/com/yapp/common/navigation/route/OnboardingRoute.kt b/core/common/src/main/java/com/yapp/common/navigation/route/OnboardingRoute.kt index 52f0bb5b..1f1346b2 100644 --- a/core/common/src/main/java/com/yapp/common/navigation/route/OnboardingRoute.kt +++ b/core/common/src/main/java/com/yapp/common/navigation/route/OnboardingRoute.kt @@ -6,33 +6,33 @@ import kotlin.reflect.KClass @Serializable data object OnboardingBaseRoute -sealed interface OnboardingDestination { +sealed class OnboardingDestination { @Serializable - data object Explain : OnboardingDestination + data object Explain : OnboardingDestination() @Serializable - data object AlarmTimeSelection : OnboardingDestination + data object AlarmTimeSelection : OnboardingDestination() @Serializable - data object Birthday : OnboardingDestination + data object Birthday : OnboardingDestination() @Serializable - data object TimeOfBirth : OnboardingDestination + data object TimeOfBirth : OnboardingDestination() @Serializable - data object Name : OnboardingDestination + data object Name : OnboardingDestination() @Serializable - data object Gender : OnboardingDestination + data object Gender : OnboardingDestination() @Serializable - data object Access : OnboardingDestination + data object Access : OnboardingDestination() @Serializable - data object Complete1 : OnboardingDestination + data object Complete1 : OnboardingDestination() @Serializable - data object Complete2 : OnboardingDestination + data object Complete2 : OnboardingDestination() companion object { val routes: List> = listOf( diff --git a/feature/navigator/build.gradle.kts b/feature/navigator/build.gradle.kts index cc268c3d..a8db6273 100644 --- a/feature/navigator/build.gradle.kts +++ b/feature/navigator/build.gradle.kts @@ -14,6 +14,7 @@ dependencies { implementation(libs.orbit.core) implementation(libs.orbit.compose) implementation(libs.orbit.viewmodel) + implementation(libs.kotlin.reflect) implementation(projects.feature.home) implementation(projects.feature.alarmInteraction) implementation(projects.feature.onboarding) diff --git a/feature/onboarding/src/main/java/com/yapp/onboarding/OnboardingContract.kt b/feature/onboarding/src/main/java/com/yapp/onboarding/OnboardingContract.kt index 0b5a339b..5e8b83c2 100644 --- a/feature/onboarding/src/main/java/com/yapp/onboarding/OnboardingContract.kt +++ b/feature/onboarding/src/main/java/com/yapp/onboarding/OnboardingContract.kt @@ -72,7 +72,7 @@ sealed class OnboardingContract { } sealed class SideEffect : com.yapp.ui.base.SideEffect { - data object NavigateToNextStep : SideEffect() + data class NavigateToNextStep(val currentStep: Int) : SideEffect() data object NavigateBack : SideEffect() diff --git a/feature/onboarding/src/main/java/com/yapp/onboarding/OnboardingNavGraph.kt b/feature/onboarding/src/main/java/com/yapp/onboarding/OnboardingNavGraph.kt index fd669d65..ee57af2e 100644 --- a/feature/onboarding/src/main/java/com/yapp/onboarding/OnboardingNavGraph.kt +++ b/feature/onboarding/src/main/java/com/yapp/onboarding/OnboardingNavGraph.kt @@ -114,8 +114,8 @@ private fun handleSideEffect( viewModel: OnboardingViewModel, ) { when (sideEffect) { - OnboardingContract.SideEffect.NavigateToNextStep -> { - navigator.navigateToOnboardingNextStep() + is OnboardingContract.SideEffect.NavigateToNextStep -> { + navigator.navigateToOnboardingNextStep(sideEffect.currentStep) } OnboardingContract.SideEffect.NavigateBack -> { diff --git a/feature/onboarding/src/main/java/com/yapp/onboarding/OnboardingViewModel.kt b/feature/onboarding/src/main/java/com/yapp/onboarding/OnboardingViewModel.kt index 4628684f..e6eff571 100644 --- a/feature/onboarding/src/main/java/com/yapp/onboarding/OnboardingViewModel.kt +++ b/feature/onboarding/src/main/java/com/yapp/onboarding/OnboardingViewModel.kt @@ -104,7 +104,7 @@ class OnboardingViewModel @Inject constructor( if (nextRoute != null) { savedStateHandle["currentStep"] = nextStep updateState { copy(currentStep = nextStep) } - emitSideEffect(OnboardingContract.SideEffect.NavigateToNextStep) + emitSideEffect(OnboardingContract.SideEffect.NavigateToNextStep(currentStep)) } else { emitSideEffect(OnboardingContract.SideEffect.OnboardingCompleted) } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 73a719e9..f7234675 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -182,6 +182,8 @@ amplitude-analytics = { group = "com.amplitude", name = "analytics-android", ver play-services-ads = { group = "com.google.android.gms", name = "play-services-ads", version.ref = "playServicesAd" } +kotlin-reflect = { module = "org.jetbrains.kotlin:kotlin-reflect", version.ref = "kotlin" } + [plugins] ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" } kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } From 525b14b45423cae190eeb6107fd097edcb461cc0 Mon Sep 17 00:00:00 2001 From: dongchyeon Date: Tue, 3 Jun 2025 21:06:50 +0900 Subject: [PATCH 06/10] =?UTF-8?q?[FIX/#212]=20updateBirthDate=20=EB=B0=98?= =?UTF-8?q?=EC=98=81=20=EC=98=A4=EB=A5=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/yapp/onboarding/OnboardingViewModel.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/feature/onboarding/src/main/java/com/yapp/onboarding/OnboardingViewModel.kt b/feature/onboarding/src/main/java/com/yapp/onboarding/OnboardingViewModel.kt index e6eff571..1ab0758c 100644 --- a/feature/onboarding/src/main/java/com/yapp/onboarding/OnboardingViewModel.kt +++ b/feature/onboarding/src/main/java/com/yapp/onboarding/OnboardingViewModel.kt @@ -36,7 +36,7 @@ class OnboardingViewModel @Inject constructor( ), ) { private val currentRoute: KClass? - get() = OnboardingDestination.routes.getOrNull(currentState.currentStep - 1) + get() = OnboardingDestination.routes.getOrNull(currentState.currentStep) fun processAction(action: OnboardingContract.Action) { when (action) { From ee90f2ce6b0429039bee5d5bd23182567f51b219 Mon Sep 17 00:00:00 2001 From: dongchyeon Date: Wed, 4 Jun 2025 01:26:13 +0900 Subject: [PATCH 07/10] =?UTF-8?q?[REFACTOR/#212]=20=EC=98=A8=EB=B3=B4?= =?UTF-8?q?=EB=94=A9=20=EB=8B=A8=EA=B3=84=20=EC=9D=B4=EB=8F=99=20=ED=95=A8?= =?UTF-8?q?=EC=88=98=20=EB=84=A4=EC=9D=B4=EB=B0=8D=20=EA=B0=9C=EC=84=A0=20?= =?UTF-8?q?=EB=B0=8F=20null=20=EC=95=88=EC=A0=84=20=EC=B2=98=EB=A6=AC=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/yapp/common/navigation/OrbitNavigator.kt | 13 +++++++------ .../yapp/common/navigation/route/OnboardingRoute.kt | 4 ++-- .../java/com/yapp/onboarding/OnboardingViewModel.kt | 2 +- 3 files changed, 10 insertions(+), 9 deletions(-) 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 cedf91f6..34ceed6f 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 @@ -1,5 +1,6 @@ package com.yapp.common.navigation +import android.util.Log import androidx.compose.runtime.Composable import androidx.compose.runtime.remember import androidx.navigation.NavHostController @@ -28,12 +29,12 @@ class OrbitNavigator( } fun navigateToOnboardingNextStep(currentStep: Int, navOptions: NavOptions? = null) { - val nextRouteClass = OnboardingDestination.nextRoute(currentStep + 1) ?: return - - val nextRouteInstance = nextRouteClass.objectInstance - ?: error("Cannot get object instance of route class: $nextRouteClass") - - navController.navigate(nextRouteInstance, navOptions) + val instance = OnboardingDestination.getNextRouteForStep(currentStep)?.objectInstance + if (instance != null) { + navController.navigate(instance, navOptions) + } else { + Log.e("Navigator", "Invalid route at step: $currentStep") + } } fun navigateToAddAlarm(navOptions: NavOptions? = null) { diff --git a/core/common/src/main/java/com/yapp/common/navigation/route/OnboardingRoute.kt b/core/common/src/main/java/com/yapp/common/navigation/route/OnboardingRoute.kt index 1f1346b2..ff4faea4 100644 --- a/core/common/src/main/java/com/yapp/common/navigation/route/OnboardingRoute.kt +++ b/core/common/src/main/java/com/yapp/common/navigation/route/OnboardingRoute.kt @@ -47,8 +47,8 @@ sealed class OnboardingDestination { Complete2::class, ) - fun nextRoute(currentStep: Int): KClass? { - val nextRoute = routes.getOrNull(currentStep) + fun getNextRouteForStep(currentStep: Int): KClass? { + val nextRoute = routes.getOrNull(currentStep + 1) return nextRoute } } diff --git a/feature/onboarding/src/main/java/com/yapp/onboarding/OnboardingViewModel.kt b/feature/onboarding/src/main/java/com/yapp/onboarding/OnboardingViewModel.kt index 1ab0758c..ec145349 100644 --- a/feature/onboarding/src/main/java/com/yapp/onboarding/OnboardingViewModel.kt +++ b/feature/onboarding/src/main/java/com/yapp/onboarding/OnboardingViewModel.kt @@ -96,7 +96,7 @@ class OnboardingViewModel @Inject constructor( private fun moveToNextStep() { val currentStep = container.stateFlow.value.currentStep val nextStep = currentStep + 1 - val nextRoute = OnboardingDestination.nextRoute(currentStep) + val nextRoute = OnboardingDestination.getNextRouteForStep(currentStep) savedStateHandle["birthDate"] = currentState.birthDate savedStateHandle["birthType"] = currentState.birthType From 868fb8d04121f032b0022b6b49f9a81c90876415 Mon Sep 17 00:00:00 2001 From: dongchyeon Date: Sun, 8 Jun 2025 13:27:25 +0900 Subject: [PATCH 08/10] =?UTF-8?q?[RENAME/#212]=20=ED=8C=8C=EC=9D=BC=20?= =?UTF-8?q?=EC=9D=B4=EB=A6=84=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/yapp/splash/{SettingNavGraph.kt => SplashNavGraph.kt} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename feature/splash/src/main/java/com/yapp/splash/{SettingNavGraph.kt => SplashNavGraph.kt} (100%) diff --git a/feature/splash/src/main/java/com/yapp/splash/SettingNavGraph.kt b/feature/splash/src/main/java/com/yapp/splash/SplashNavGraph.kt similarity index 100% rename from feature/splash/src/main/java/com/yapp/splash/SettingNavGraph.kt rename to feature/splash/src/main/java/com/yapp/splash/SplashNavGraph.kt From 4cd446c1f01699e12f59d30597eb089dc71e0fdf Mon Sep 17 00:00:00 2001 From: dongchyeon Date: Sun, 8 Jun 2025 13:41:47 +0900 Subject: [PATCH 09/10] =?UTF-8?q?[REMOVE/#212]=20=EC=95=88=20=EC=93=B0?= =?UTF-8?q?=EB=8A=94=20=ED=95=A8=EC=88=98=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/yapp/common/navigation/extensions/RouteExtension.kt | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 core/common/src/main/java/com/yapp/common/navigation/extensions/RouteExtension.kt diff --git a/core/common/src/main/java/com/yapp/common/navigation/extensions/RouteExtension.kt b/core/common/src/main/java/com/yapp/common/navigation/extensions/RouteExtension.kt deleted file mode 100644 index 965bf67b..00000000 --- a/core/common/src/main/java/com/yapp/common/navigation/extensions/RouteExtension.kt +++ /dev/null @@ -1,5 +0,0 @@ -package com.yapp.common.navigation.extensions - -import kotlin.reflect.KClass - -fun KClass.toRoute(): String = this.simpleName ?: error("Route name missing") From 8a297e73051e3353000325d8d259992a7b0fdcd2 Mon Sep 17 00:00:00 2001 From: dongchyeon Date: Sun, 8 Jun 2025 13:57:12 +0900 Subject: [PATCH 10/10] =?UTF-8?q?[REFACTOR/#212]=20GSON=20->=20kotlinx.ser?= =?UTF-8?q?ialization=20=EB=A7=88=EC=9D=B4=EA=B7=B8=EB=A0=88=EC=9D=B4?= =?UTF-8?q?=EC=85=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- domain/build.gradle.kts | 1 - domain/src/main/java/com/yapp/domain/model/Alarm.kt | 8 ++++---- feature/alarm-interaction/build.gradle.kts | 2 +- .../yapp/alarm/interaction/AlarmInteractionNavGraph.kt | 4 ++-- gradle/libs.versions.toml | 1 - 5 files changed, 7 insertions(+), 9 deletions(-) diff --git a/domain/build.gradle.kts b/domain/build.gradle.kts index a9c80e75..e5567cb0 100644 --- a/domain/build.gradle.kts +++ b/domain/build.gradle.kts @@ -10,6 +10,5 @@ android { } dependencies { - implementation(libs.gson) implementation(libs.kotlinx.serialization.json) } diff --git a/domain/src/main/java/com/yapp/domain/model/Alarm.kt b/domain/src/main/java/com/yapp/domain/model/Alarm.kt index 9e05ffca..f04d4148 100644 --- a/domain/src/main/java/com/yapp/domain/model/Alarm.kt +++ b/domain/src/main/java/com/yapp/domain/model/Alarm.kt @@ -2,10 +2,10 @@ package com.yapp.domain.model import android.net.Uri import android.os.Parcelable -import com.google.gson.Gson -import com.google.gson.reflect.TypeToken import kotlinx.parcelize.Parcelize import kotlinx.serialization.Serializable +import kotlinx.serialization.encodeToString +import kotlinx.serialization.json.Json @Parcelize @Serializable @@ -39,11 +39,11 @@ data class Alarm( companion object { fun fromJson(json: String): Alarm { - return Gson().fromJson(json, object : TypeToken() {}.type) + return Json.decodeFromString(json) } } - override fun toString(): String = Uri.encode(Gson().toJson(this)) + override fun toString(): String = Uri.encode(Json.encodeToString(this)) } fun Alarm.copyFrom(source: Alarm): Alarm { diff --git a/feature/alarm-interaction/build.gradle.kts b/feature/alarm-interaction/build.gradle.kts index 50a1074e..efc6eeec 100644 --- a/feature/alarm-interaction/build.gradle.kts +++ b/feature/alarm-interaction/build.gradle.kts @@ -21,6 +21,6 @@ dependencies { implementation(libs.orbit.viewmodel) implementation(libs.androidx.material.android) implementation(libs.androidx.annotation) - implementation(libs.gson) implementation(libs.play.services.ads) + implementation(libs.kotlinx.serialization.json) } diff --git a/feature/alarm-interaction/src/main/java/com/yapp/alarm/interaction/AlarmInteractionNavGraph.kt b/feature/alarm-interaction/src/main/java/com/yapp/alarm/interaction/AlarmInteractionNavGraph.kt index 312ce293..bc8d0035 100644 --- a/feature/alarm-interaction/src/main/java/com/yapp/alarm/interaction/AlarmInteractionNavGraph.kt +++ b/feature/alarm-interaction/src/main/java/com/yapp/alarm/interaction/AlarmInteractionNavGraph.kt @@ -7,13 +7,13 @@ import androidx.navigation.NavType import androidx.navigation.compose.composable import androidx.navigation.navOptions import androidx.navigation.navigation -import com.google.gson.Gson import com.yapp.alarm.interaction.action.AlarmActionRoute import com.yapp.alarm.interaction.snooze.AlarmSnoozeTimerRoute import com.yapp.common.navigation.OrbitNavigator import com.yapp.common.navigation.route.AlarmInteractionBaseRoute import com.yapp.common.navigation.route.AlarmInteractionDestination import com.yapp.domain.model.Alarm +import kotlinx.serialization.json.Json import kotlin.reflect.typeOf val AlarmArgType = object : NavType(isNullableAllowed = false) { @@ -26,7 +26,7 @@ val AlarmArgType = object : NavType(isNullableAllowed = false) { } override fun put(bundle: Bundle, key: String, value: Alarm) { - bundle.putString(key, Gson().toJson(value)) + bundle.putString(key, Json.encodeToString(Alarm.serializer(), value)) } } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index f7234675..51c70bb2 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -149,7 +149,6 @@ okhttp-logging = { group = "com.squareup.okhttp3", name = "logging-interceptor", flexible-bottomsheet = { group = "com.github.skydoves", name = "flexible-bottomsheet-material3", version.ref = "flexible-bottomsheet" } #sentry-android = { group = "io.sentry", name = "sentry-android", version.ref = "sentry-android" } #sentry-compose = { group = "io.sentry", name = "sentry-compose", version.ref = "sentry-compose" } -gson = { group = "com.google.code.gson", name = "gson", version.ref = "gson" } # Google Libraries firebase-bom = { group = "com.google.firebase", name = "firebase-bom", version.ref = "firebase-bom" }