diff --git a/app/build.gradle.kts b/app/build.gradle.kts index d7f8de38..f7b16cf5 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -33,6 +33,7 @@ dependencies { implementation(project(":core:ui")) implementation(project(":core:common")) implementation(project(":feature:auth")) + implementation(project(":core:navigation")) implementation(libs.kakao.sdk) implementation(libs.androidx.appcompat) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 045b6bbf..fcc3e80d 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -3,7 +3,6 @@ xmlns:tools="http://schemas.android.com/tools"> - + + + + () + intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK + return intent + } +} diff --git a/app/src/main/kotlin/com/bff/wespot/di/NavigationModule.kt b/app/src/main/kotlin/com/bff/wespot/di/NavigationModule.kt new file mode 100644 index 00000000..f0013814 --- /dev/null +++ b/app/src/main/kotlin/com/bff/wespot/di/NavigationModule.kt @@ -0,0 +1,17 @@ +package com.bff.wespot.di + +import com.bff.wespot.NavigatorImpl +import com.danggeun.navigation.Navigator +import dagger.Binds +import dagger.Module +import dagger.hilt.InstallIn +import dagger.hilt.components.SingletonComponent +import javax.inject.Singleton + +@Module +@InstallIn(SingletonComponent::class) +interface NavigationModule { + @Binds + @Singleton + fun provideNavigator(navigator: NavigatorImpl): Navigator +} diff --git a/core/navigation/.gitignore b/core/navigation/.gitignore new file mode 100644 index 00000000..42afabfd --- /dev/null +++ b/core/navigation/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/core/navigation/build.gradle.kts b/core/navigation/build.gradle.kts new file mode 100644 index 00000000..1308c677 --- /dev/null +++ b/core/navigation/build.gradle.kts @@ -0,0 +1,9 @@ +plugins { + alias(libs.plugins.wespot.android.library) + alias(libs.plugins.wespot.android.hilt) +} + + +android { + namespace = "com.bff.wespot.navigation" +} diff --git a/core/navigation/consumer-rules.pro b/core/navigation/consumer-rules.pro new file mode 100644 index 00000000..e69de29b diff --git a/core/navigation/proguard-rules.pro b/core/navigation/proguard-rules.pro new file mode 100644 index 00000000..481bb434 --- /dev/null +++ b/core/navigation/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/core/navigation/src/main/AndroidManifest.xml b/core/navigation/src/main/AndroidManifest.xml new file mode 100644 index 00000000..a5918e68 --- /dev/null +++ b/core/navigation/src/main/AndroidManifest.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/core/navigation/src/main/java/com/danggeun/navigation/Navigator.kt b/core/navigation/src/main/java/com/danggeun/navigation/Navigator.kt new file mode 100644 index 00000000..21754b04 --- /dev/null +++ b/core/navigation/src/main/java/com/danggeun/navigation/Navigator.kt @@ -0,0 +1,10 @@ +package com.danggeun.navigation + +import android.content.Context +import android.content.Intent + +interface Navigator { + fun navigateToMain( + context: Context + ) : Intent +} \ No newline at end of file diff --git a/core/navigation/src/main/java/com/danggeun/navigation/util/Extension.kt b/core/navigation/src/main/java/com/danggeun/navigation/util/Extension.kt new file mode 100644 index 00000000..8f83357f --- /dev/null +++ b/core/navigation/src/main/java/com/danggeun/navigation/util/Extension.kt @@ -0,0 +1,12 @@ +package com.danggeun.navigation.util + +import android.app.Activity +import android.content.Context +import android.content.Intent +import androidx.core.os.bundleOf + +inline fun Context.buildIntent( + vararg argument: Pair, +) = Intent(this, T::class.java).apply { + putExtras(bundleOf(*argument)) +} \ No newline at end of file diff --git a/domain/src/main/kotlin/com/bff/wespot/domain/repository/usecase/KakaoLoginUseCase.kt b/domain/src/main/kotlin/com/bff/wespot/domain/usecase/KakaoLoginUseCase.kt similarity index 88% rename from domain/src/main/kotlin/com/bff/wespot/domain/repository/usecase/KakaoLoginUseCase.kt rename to domain/src/main/kotlin/com/bff/wespot/domain/usecase/KakaoLoginUseCase.kt index b01f8031..a810958a 100644 --- a/domain/src/main/kotlin/com/bff/wespot/domain/repository/usecase/KakaoLoginUseCase.kt +++ b/domain/src/main/kotlin/com/bff/wespot/domain/usecase/KakaoLoginUseCase.kt @@ -1,4 +1,4 @@ -package com.bff.wespot.domain.repository.usecase +package com.bff.wespot.domain.usecase import com.bff.wespot.domain.repository.auth.KakaoLoginManager import javax.inject.Inject diff --git a/feature/auth/src/main/kotlin/com/bff/wespot/auth/AuthActivity.kt b/feature/auth/src/main/kotlin/com/bff/wespot/auth/AuthActivity.kt new file mode 100644 index 00000000..960b0f8e --- /dev/null +++ b/feature/auth/src/main/kotlin/com/bff/wespot/auth/AuthActivity.kt @@ -0,0 +1,87 @@ +package com.bff.wespot.auth + +import android.os.Bundle +import androidx.activity.ComponentActivity +import androidx.activity.compose.setContent +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.material3.Surface +import androidx.compose.ui.Modifier +import androidx.lifecycle.viewmodel.compose.viewModel +import androidx.navigation.compose.rememberNavController +import com.bff.wespot.auth.screen.NavGraphs +import com.bff.wespot.auth.screen.destinations.ClassScreenDestination +import com.bff.wespot.auth.screen.destinations.CompleteScreenDestination +import com.bff.wespot.auth.screen.destinations.EditScreenDestination +import com.bff.wespot.auth.screen.destinations.GenderScreenDestination +import com.bff.wespot.auth.screen.destinations.GradeScreenDestination +import com.bff.wespot.auth.screen.destinations.NameScreenDestination +import com.bff.wespot.auth.screen.destinations.SchoolScreenDestination +import com.bff.wespot.auth.state.AuthSideEffect +import com.bff.wespot.auth.viewmodel.AuthViewModel +import com.bff.wespot.designsystem.theme.WeSpotTheme +import com.ramcosta.composedestinations.DestinationsNavHost +import com.ramcosta.composedestinations.navigation.dependency +import com.ramcosta.composedestinations.navigation.navigate +import com.ramcosta.composedestinations.rememberNavHostEngine +import org.orbitmvi.orbit.compose.collectSideEffect + +class AuthActivity : ComponentActivity() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContent { + val navController = rememberNavController() + val engine = rememberNavHostEngine() + val viewModel: AuthViewModel = viewModel() + + viewModel.collectSideEffect { + when (it) { + AuthSideEffect.PopBackStack -> navController.popBackStack() + is AuthSideEffect.NavigateToGradeScreen -> { + navController.navigate(GradeScreenDestination(it.edit)) + } + + is AuthSideEffect.NavigateToSchoolScreen -> { + navController.navigate(SchoolScreenDestination(it.edit)) + } + + is AuthSideEffect.NavigateToClassScreen -> { + navController.navigate(ClassScreenDestination(it.edit)) + } + + is AuthSideEffect.NavigateToGenderScreen -> { + navController.navigate(GenderScreenDestination(it.edit)) + } + + is AuthSideEffect.NavigateToNameScreen -> { + navController.navigate(NameScreenDestination(it.edit)) + } + + AuthSideEffect.NavigateToEditScreen -> { + navController.navigate(EditScreenDestination) + } + + AuthSideEffect.NavigateToCompleteScreen -> { + navController.navigate(CompleteScreenDestination, navOptionsBuilder = { + popUpTo(SchoolScreenDestination.route) { inclusive = true } + }) + } + } + } + + WeSpotTheme { + Surface( + modifier = Modifier.fillMaxSize(), + ) { + DestinationsNavHost( + navGraph = NavGraphs.root, + navController = navController, + engine = engine, + dependenciesContainerBuilder = { + dependency(viewModel) + }, + ) + } + } + } + } +} diff --git a/feature/auth/src/main/kotlin/com/bff/wespot/auth/screen/ClassScreen.kt b/feature/auth/src/main/kotlin/com/bff/wespot/auth/screen/ClassScreen.kt index 13f19fe0..e784a674 100644 --- a/feature/auth/src/main/kotlin/com/bff/wespot/auth/screen/ClassScreen.kt +++ b/feature/auth/src/main/kotlin/com/bff/wespot/auth/screen/ClassScreen.kt @@ -23,8 +23,8 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.unit.dp import com.bff.wespot.auth.R -import com.bff.wespot.auth.screen.destinations.GenderScreenDestination import com.bff.wespot.auth.state.AuthAction +import com.bff.wespot.auth.state.NavigationAction import com.bff.wespot.auth.viewmodel.AuthViewModel import com.bff.wespot.designsystem.component.button.WSButton import com.bff.wespot.designsystem.component.header.WSTopBar @@ -32,7 +32,6 @@ import com.bff.wespot.designsystem.component.input.WsTextField import com.bff.wespot.designsystem.theme.StaticTypeScale import com.bff.wespot.designsystem.theme.WeSpotThemeManager import com.ramcosta.composedestinations.annotation.Destination -import com.ramcosta.composedestinations.navigation.DestinationsNavigator import kotlinx.coroutines.delay import org.orbitmvi.orbit.compose.collectAsState @@ -42,7 +41,6 @@ import org.orbitmvi.orbit.compose.collectAsState fun ClassScreen( viewModel: AuthViewModel, edit: Boolean, - navigator: DestinationsNavigator, ) { val keyboard = LocalSoftwareKeyboardController.current @@ -56,7 +54,7 @@ fun ClassScreen( title = stringResource(id = R.string.register), canNavigateBack = true, navigateUp = { - navigator.navigateUp() + action(AuthAction.Navigation(NavigationAction.PopBackStack)) }, ) }, @@ -120,10 +118,10 @@ fun ClassScreen( WSButton( onClick = { if (edit) { - navigator.popBackStack() + action(AuthAction.Navigation(NavigationAction.PopBackStack)) return@WSButton } - navigator.navigate(GenderScreenDestination(edit = false)) + action(AuthAction.Navigation(NavigationAction.NavigateToGenderScreen(false))) }, text = stringResource( id = if (edit) { diff --git a/feature/auth/src/main/kotlin/com/bff/wespot/auth/screen/EditScreen.kt b/feature/auth/src/main/kotlin/com/bff/wespot/auth/screen/EditScreen.kt index 6c208bfc..38b3bd50 100644 --- a/feature/auth/src/main/kotlin/com/bff/wespot/auth/screen/EditScreen.kt +++ b/feature/auth/src/main/kotlin/com/bff/wespot/auth/screen/EditScreen.kt @@ -29,14 +29,9 @@ import androidx.compose.ui.draw.clip import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp -import androidx.navigation.NavOptions import com.bff.wespot.auth.R -import com.bff.wespot.auth.screen.destinations.ClassScreenDestination -import com.bff.wespot.auth.screen.destinations.CompleteScreenDestination -import com.bff.wespot.auth.screen.destinations.GenderScreenDestination -import com.bff.wespot.auth.screen.destinations.GradeScreenDestination -import com.bff.wespot.auth.screen.destinations.NameScreenDestination -import com.bff.wespot.auth.screen.destinations.SchoolScreenDestination +import com.bff.wespot.auth.state.AuthAction +import com.bff.wespot.auth.state.NavigationAction import com.bff.wespot.auth.viewmodel.AuthViewModel import com.bff.wespot.designsystem.component.button.WSButton import com.bff.wespot.designsystem.component.button.WSButtonType @@ -45,7 +40,6 @@ import com.bff.wespot.designsystem.theme.StaticTypeScale import com.bff.wespot.designsystem.theme.WeSpotThemeManager import com.bff.wespot.ui.WSBottomSheet import com.ramcosta.composedestinations.annotation.Destination -import com.ramcosta.composedestinations.navigation.DestinationsNavigator import org.orbitmvi.orbit.compose.collectAsState @OptIn(ExperimentalMaterial3Api::class) @@ -53,9 +47,9 @@ import org.orbitmvi.orbit.compose.collectAsState @Composable fun EditScreen( viewModel: AuthViewModel, - navigator: DestinationsNavigator, ) { val state by viewModel.collectAsState() + val action = viewModel::onAction var firstEnter by remember { mutableStateOf(true) @@ -70,7 +64,7 @@ fun EditScreen( title = stringResource(id = R.string.register), canNavigateBack = true, navigateUp = { - navigator.navigateUp() + action(AuthAction.Navigation(NavigationAction.PopBackStack)) }, ) }, @@ -83,7 +77,7 @@ fun EditScreen( title = stringResource(id = R.string.name), value = state.name, ) { - navigator.navigate(NameScreenDestination(edit = true)) + action(AuthAction.Navigation(NavigationAction.NavigateToNameScreen(true))) } EditField( @@ -94,28 +88,28 @@ fun EditScreen( stringResource(id = R.string.female_student) }, ) { - navigator.navigate(GenderScreenDestination(edit = true)) + action(AuthAction.Navigation(NavigationAction.NavigateToGenderScreen(true))) } EditField( title = stringResource(id = R.string.get_class), value = state.classNumber.toString(), ) { - navigator.navigate(ClassScreenDestination(edit = true)) + action(AuthAction.Navigation(NavigationAction.NavigateToClassScreen(true))) } EditField( title = stringResource(id = R.string.grade), value = "${state.grade}학년", ) { - navigator.navigate(GradeScreenDestination(edit = true)) + action(AuthAction.Navigation(NavigationAction.NavigateToGradeScreen(true))) } EditField( title = stringResource(id = R.string.school), value = state.selectedSchool?.name ?: "", ) { - navigator.navigate(SchoolScreenDestination(edit = true)) + action(AuthAction.Navigation(NavigationAction.NavigateToSchoolScreen(true))) } } } @@ -148,13 +142,7 @@ fun EditScreen( if (register) { WSBottomSheet(closeSheet = { register = true }) { RegisterBottomSheetContent { - navigator.navigate( - CompleteScreenDestination, - navOptions = NavOptions - .Builder() - .setPopUpTo(SchoolScreenDestination.route, inclusive = true) - .build(), - ) + action(AuthAction.Navigation(NavigationAction.NavigateToCompleteScreen)) } } } diff --git a/feature/auth/src/main/kotlin/com/bff/wespot/auth/screen/GenderScreen.kt b/feature/auth/src/main/kotlin/com/bff/wespot/auth/screen/GenderScreen.kt index f16ce8f9..98da904b 100644 --- a/feature/auth/src/main/kotlin/com/bff/wespot/auth/screen/GenderScreen.kt +++ b/feature/auth/src/main/kotlin/com/bff/wespot/auth/screen/GenderScreen.kt @@ -27,14 +27,13 @@ import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import com.bff.wespot.auth.R -import com.bff.wespot.auth.screen.destinations.NameScreenDestination import com.bff.wespot.auth.state.AuthAction +import com.bff.wespot.auth.state.NavigationAction import com.bff.wespot.auth.viewmodel.AuthViewModel import com.bff.wespot.designsystem.component.header.WSTopBar import com.bff.wespot.designsystem.theme.StaticTypeScale import com.bff.wespot.designsystem.theme.WeSpotThemeManager import com.ramcosta.composedestinations.annotation.Destination -import com.ramcosta.composedestinations.navigation.DestinationsNavigator import org.orbitmvi.orbit.compose.collectAsState @OptIn(ExperimentalMaterial3Api::class) @@ -43,7 +42,6 @@ import org.orbitmvi.orbit.compose.collectAsState fun GenderScreen( viewModel: AuthViewModel, edit: Boolean, - navigator: DestinationsNavigator, ) { val state by viewModel.collectAsState() val action = viewModel::onAction @@ -54,7 +52,7 @@ fun GenderScreen( title = stringResource(id = R.string.register), canNavigateBack = true, navigateUp = { - navigator.navigateUp() + action(AuthAction.Navigation(NavigationAction.PopBackStack)) }, ) }, @@ -87,10 +85,10 @@ fun GenderScreen( onClicked = { action(AuthAction.OnGenderChanged("male")) if (edit) { - navigator.popBackStack() + action(AuthAction.Navigation(NavigationAction.PopBackStack)) return@GenderBox } - navigator.navigate(NameScreenDestination(edit = false)) + action(AuthAction.Navigation(NavigationAction.NavigateToNameScreen(false))) }, ) GenderBox( @@ -102,10 +100,10 @@ fun GenderScreen( onClicked = { action(AuthAction.OnGenderChanged("female")) if (edit) { - navigator.popBackStack() + action(AuthAction.Navigation(NavigationAction.PopBackStack)) return@GenderBox } - navigator.navigate(NameScreenDestination(edit = false)) + action(AuthAction.Navigation(NavigationAction.NavigateToNameScreen(false))) }, ) } diff --git a/feature/auth/src/main/kotlin/com/bff/wespot/auth/screen/GradeScreen.kt b/feature/auth/src/main/kotlin/com/bff/wespot/auth/screen/GradeScreen.kt index 7c4c397e..97932414 100644 --- a/feature/auth/src/main/kotlin/com/bff/wespot/auth/screen/GradeScreen.kt +++ b/feature/auth/src/main/kotlin/com/bff/wespot/auth/screen/GradeScreen.kt @@ -25,8 +25,8 @@ import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import com.bff.wespot.auth.R -import com.bff.wespot.auth.screen.destinations.ClassScreenDestination import com.bff.wespot.auth.state.AuthAction +import com.bff.wespot.auth.state.NavigationAction import com.bff.wespot.auth.viewmodel.AuthViewModel import com.bff.wespot.designsystem.component.button.WSButton import com.bff.wespot.designsystem.component.button.WSOutlineButton @@ -37,7 +37,6 @@ import com.bff.wespot.designsystem.theme.StaticTypeScale import com.bff.wespot.designsystem.theme.WeSpotThemeManager import com.bff.wespot.ui.WSBottomSheet import com.ramcosta.composedestinations.annotation.Destination -import com.ramcosta.composedestinations.navigation.DestinationsNavigator import org.orbitmvi.orbit.compose.collectAsState @OptIn(ExperimentalMaterial3Api::class) @@ -46,7 +45,6 @@ import org.orbitmvi.orbit.compose.collectAsState fun GradeScreen( viewModel: AuthViewModel, edit: Boolean, - navigator: DestinationsNavigator, ) { val state by viewModel.collectAsState() val action = viewModel::onAction @@ -60,7 +58,7 @@ fun GradeScreen( title = stringResource(id = R.string.register), canNavigateBack = true, navigateUp = { - navigator.navigateUp() + action(AuthAction.Navigation(NavigationAction.PopBackStack)) }, ) }, @@ -141,10 +139,10 @@ fun GradeScreen( action(AuthAction.OnGradeChanged(grade)) if (edit) { - navigator.popBackStack() + action(AuthAction.Navigation(NavigationAction.PopBackStack)) return@BottomSheetContent } - navigator.navigate(ClassScreenDestination(edit = false)) + action(AuthAction.Navigation(NavigationAction.NavigateToClassScreen(false))) }, ) } @@ -154,10 +152,10 @@ fun GradeScreen( WSButton( onClick = { if (edit) { - navigator.popBackStack() + action(AuthAction.Navigation(NavigationAction.PopBackStack)) return@WSButton } - navigator.navigate(ClassScreenDestination(edit = false)) + action(AuthAction.Navigation(NavigationAction.NavigateToClassScreen(false))) }, text = stringResource( id = if (edit) { diff --git a/feature/auth/src/main/kotlin/com/bff/wespot/auth/screen/NameScreen.kt b/feature/auth/src/main/kotlin/com/bff/wespot/auth/screen/NameScreen.kt index cd33dbb1..755704d7 100644 --- a/feature/auth/src/main/kotlin/com/bff/wespot/auth/screen/NameScreen.kt +++ b/feature/auth/src/main/kotlin/com/bff/wespot/auth/screen/NameScreen.kt @@ -3,6 +3,7 @@ package com.bff.wespot.auth.screen import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding @@ -23,8 +24,8 @@ import androidx.compose.ui.platform.LocalSoftwareKeyboardController import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import com.bff.wespot.auth.R -import com.bff.wespot.auth.screen.destinations.EditScreenDestination import com.bff.wespot.auth.state.AuthAction +import com.bff.wespot.auth.state.NavigationAction import com.bff.wespot.auth.viewmodel.AuthViewModel import com.bff.wespot.designsystem.component.button.WSButton import com.bff.wespot.designsystem.component.header.WSTopBar @@ -32,7 +33,6 @@ import com.bff.wespot.designsystem.component.input.WsTextField import com.bff.wespot.designsystem.theme.StaticTypeScale import com.bff.wespot.designsystem.theme.WeSpotThemeManager import com.ramcosta.composedestinations.annotation.Destination -import com.ramcosta.composedestinations.navigation.DestinationsNavigator import kotlinx.coroutines.delay import org.orbitmvi.orbit.compose.collectAsState @@ -42,7 +42,6 @@ import org.orbitmvi.orbit.compose.collectAsState fun NameScreen( viewModel: AuthViewModel, edit: Boolean, - navigator: DestinationsNavigator, ) { val keyboard = LocalSoftwareKeyboardController.current @@ -63,13 +62,15 @@ fun NameScreen( title = stringResource(id = R.string.register), canNavigateBack = true, navigateUp = { - navigator.navigateUp() + action(AuthAction.Navigation(NavigationAction.PopBackStack)) }, ) }, ) { Column( - modifier = Modifier.padding(it).padding(horizontal = 20.dp), + modifier = Modifier + .padding(it) + .padding(horizontal = 20.dp), verticalArrangement = Arrangement.spacedBy(12.dp), ) { Text( @@ -97,20 +98,25 @@ fun NameScreen( focusRequester = focusRequester, ) - if (error) { - Text( - text = stringResource(id = R.string.name_error), - color = WeSpotThemeManager.colors.dangerColor, - style = StaticTypeScale.Default.body6, - ) - } + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.SpaceBetween, + ) { + if (error) { + Text( + text = stringResource(id = R.string.name_error), + color = WeSpotThemeManager.colors.dangerColor, + style = StaticTypeScale.Default.body6, + ) + } - Box(modifier = Modifier.fillMaxWidth(), contentAlignment = Alignment.TopEnd) { - Text( - text = "${state.name.length} / 5", - color = Color(0xFF7A7A7A), - style = StaticTypeScale.Default.body7, - ) + Box(modifier = Modifier.fillMaxWidth(), contentAlignment = Alignment.TopEnd) { + Text( + text = "${state.name.length} / 5", + color = Color(0xFF7A7A7A), + style = StaticTypeScale.Default.body7, + ) + } } } } @@ -119,10 +125,10 @@ fun NameScreen( WSButton( onClick = { if (edit) { - navigator.popBackStack() + action(AuthAction.Navigation(NavigationAction.PopBackStack)) return@WSButton } - navigator.navigate(EditScreenDestination) + action(AuthAction.Navigation(NavigationAction.NavigateToEditScreen)) }, text = stringResource( id = if (edit) { diff --git a/feature/auth/src/main/kotlin/com/bff/wespot/auth/screen/SchoolScreen.kt b/feature/auth/src/main/kotlin/com/bff/wespot/auth/screen/SchoolScreen.kt index 4f35d4e7..dc741115 100644 --- a/feature/auth/src/main/kotlin/com/bff/wespot/auth/screen/SchoolScreen.kt +++ b/feature/auth/src/main/kotlin/com/bff/wespot/auth/screen/SchoolScreen.kt @@ -24,8 +24,8 @@ import androidx.compose.ui.platform.LocalSoftwareKeyboardController import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import com.bff.wespot.auth.R -import com.bff.wespot.auth.screen.destinations.GradeScreenDestination import com.bff.wespot.auth.state.AuthAction +import com.bff.wespot.auth.state.NavigationAction import com.bff.wespot.auth.viewmodel.AuthViewModel import com.bff.wespot.designsystem.component.button.WSButton import com.bff.wespot.designsystem.component.button.WSTextButton @@ -37,7 +37,6 @@ import com.bff.wespot.designsystem.theme.StaticTypeScale import com.bff.wespot.designsystem.theme.WeSpotThemeManager import com.bff.wespot.ui.SchoolListItem import com.ramcosta.composedestinations.annotation.Destination -import com.ramcosta.composedestinations.navigation.DestinationsNavigator import kotlinx.coroutines.delay import org.orbitmvi.orbit.compose.collectAsState @@ -45,7 +44,6 @@ import org.orbitmvi.orbit.compose.collectAsState @Destination @Composable fun SchoolScreen( - navigator: DestinationsNavigator, edit: Boolean, viewModel: AuthViewModel, ) { @@ -61,7 +59,7 @@ fun SchoolScreen( title = stringResource(id = R.string.register), canNavigateBack = edit, navigateUp = { - navigator.popBackStack() + action(AuthAction.Navigation(NavigationAction.PopBackStack)) }, ) }, @@ -139,10 +137,10 @@ fun SchoolScreen( WSButton( onClick = { if (edit) { - navigator.popBackStack() + action(AuthAction.Navigation(NavigationAction.PopBackStack)) return@WSButton } - navigator.navigate(GradeScreenDestination(edit = false)) + action(AuthAction.Navigation(NavigationAction.NavigateToGradeScreen(false))) }, enabled = state.selectedSchool != null, text = stringResource( diff --git a/feature/auth/src/main/kotlin/com/bff/wespot/auth/state/AuthAction.kt b/feature/auth/src/main/kotlin/com/bff/wespot/auth/state/AuthAction.kt index 6528adca..6ff5d05b 100644 --- a/feature/auth/src/main/kotlin/com/bff/wespot/auth/state/AuthAction.kt +++ b/feature/auth/src/main/kotlin/com/bff/wespot/auth/state/AuthAction.kt @@ -16,4 +16,17 @@ sealed class AuthAction { data class OnGenderChanged(val gender: String) : AuthAction() data class OnNameChanged(val name: String) : AuthAction() + + data class Navigation(val navigate: NavigationAction) : AuthAction() +} + +sealed interface NavigationAction { + data object PopBackStack : NavigationAction + data class NavigateToGradeScreen(val edit: Boolean) : NavigationAction + data class NavigateToSchoolScreen(val edit: Boolean) : NavigationAction + data class NavigateToClassScreen(val edit: Boolean) : NavigationAction + data class NavigateToGenderScreen(val edit: Boolean) : NavigationAction + data class NavigateToNameScreen(val edit: Boolean) : NavigationAction + data object NavigateToEditScreen : NavigationAction + data object NavigateToCompleteScreen : NavigationAction } diff --git a/feature/auth/src/main/kotlin/com/bff/wespot/auth/state/AuthSideEffect.kt b/feature/auth/src/main/kotlin/com/bff/wespot/auth/state/AuthSideEffect.kt index 996b90d8..1b681121 100644 --- a/feature/auth/src/main/kotlin/com/bff/wespot/auth/state/AuthSideEffect.kt +++ b/feature/auth/src/main/kotlin/com/bff/wespot/auth/state/AuthSideEffect.kt @@ -1,3 +1,12 @@ package com.bff.wespot.auth.state -sealed class AuthSideEffect +sealed class AuthSideEffect { + data object PopBackStack : AuthSideEffect() + data class NavigateToGradeScreen(val edit: Boolean) : AuthSideEffect() + data class NavigateToSchoolScreen(val edit: Boolean) : AuthSideEffect() + data class NavigateToClassScreen(val edit: Boolean) : AuthSideEffect() + data class NavigateToGenderScreen(val edit: Boolean) : AuthSideEffect() + data class NavigateToNameScreen(val edit: Boolean) : AuthSideEffect() + data object NavigateToEditScreen : AuthSideEffect() + data object NavigateToCompleteScreen : AuthSideEffect() +} diff --git a/feature/auth/src/main/kotlin/com/bff/wespot/auth/viewmodel/AuthViewModel.kt b/feature/auth/src/main/kotlin/com/bff/wespot/auth/viewmodel/AuthViewModel.kt index 4c32253c..d1a9d7f1 100644 --- a/feature/auth/src/main/kotlin/com/bff/wespot/auth/viewmodel/AuthViewModel.kt +++ b/feature/auth/src/main/kotlin/com/bff/wespot/auth/viewmodel/AuthViewModel.kt @@ -5,12 +5,14 @@ import androidx.lifecycle.viewModelScope import com.bff.wespot.auth.state.AuthAction import com.bff.wespot.auth.state.AuthSideEffect import com.bff.wespot.auth.state.AuthUiState -import com.bff.wespot.domain.repository.usecase.KakaoLoginUseCase +import com.bff.wespot.auth.state.NavigationAction +import com.bff.wespot.domain.usecase.KakaoLoginUseCase import com.bff.wespot.model.SchoolItem import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.launch import org.orbitmvi.orbit.ContainerHost import org.orbitmvi.orbit.syntax.simple.intent +import org.orbitmvi.orbit.syntax.simple.postSideEffect import org.orbitmvi.orbit.syntax.simple.reduce import org.orbitmvi.orbit.viewmodel.container import javax.inject.Inject @@ -30,6 +32,7 @@ class AuthViewModel @Inject constructor( is AuthAction.OnClassNumberChanged -> handleClassNumberChanged(action.number) is AuthAction.OnGenderChanged -> handleGenderChanged(action.gender) is AuthAction.OnNameChanged -> handleNameChanged(action.name) + is AuthAction.Navigation -> handleNavigation(action.navigate) else -> {} } } @@ -101,4 +104,28 @@ class AuthViewModel @Inject constructor( ) } } + + private fun handleNavigation(navigate: NavigationAction) = intent { + val sideEffect = when (navigate) { + NavigationAction.PopBackStack -> AuthSideEffect.PopBackStack + is NavigationAction.NavigateToGradeScreen -> AuthSideEffect.NavigateToGradeScreen( + navigate.edit, + ) + is NavigationAction.NavigateToSchoolScreen -> AuthSideEffect.NavigateToSchoolScreen( + navigate.edit, + ) + is NavigationAction.NavigateToClassScreen -> AuthSideEffect.NavigateToClassScreen( + navigate.edit, + ) + is NavigationAction.NavigateToGenderScreen -> AuthSideEffect.NavigateToGenderScreen( + navigate.edit, + ) + is NavigationAction.NavigateToNameScreen -> AuthSideEffect.NavigateToNameScreen( + navigate.edit, + ) + NavigationAction.NavigateToEditScreen -> AuthSideEffect.NavigateToEditScreen + NavigationAction.NavigateToCompleteScreen -> AuthSideEffect.NavigateToCompleteScreen + } + postSideEffect(sideEffect) + } } diff --git a/settings.gradle.kts b/settings.gradle.kts index e05d91ee..5eea5344 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -33,3 +33,4 @@ include(":core:model") include(":core:common") include(":core:ui") include(":core:network") +include(":core:navigation")