From 75793c987c8d0d6dd1d25a43870f2fb25d390a6f Mon Sep 17 00:00:00 2001 From: sohee <144779368+sohee6989@users.noreply.github.com> Date: Sun, 18 Jan 2026 23:08:05 +0900 Subject: [PATCH 01/24] =?UTF-8?q?[FEAT/#76]=20ImePadding=20=EC=9D=B4?= =?UTF-8?q?=EC=A4=91=20=ED=8C=A8=EB=94=A9=20=EA=B4=80=EB=A0=A8=20modifier?= =?UTF-8?q?=20=ED=99=95=EC=9E=A5=ED=95=A8=EC=88=98=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../core/common/extension/ModifierExt.kt | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/app/src/main/java/com/cherrish/android/core/common/extension/ModifierExt.kt b/app/src/main/java/com/cherrish/android/core/common/extension/ModifierExt.kt index 3ba4c8a87..5819d75c1 100644 --- a/app/src/main/java/com/cherrish/android/core/common/extension/ModifierExt.kt +++ b/app/src/main/java/com/cherrish/android/core/common/extension/ModifierExt.kt @@ -4,8 +4,14 @@ import android.graphics.BlurMaskFilter import androidx.compose.foundation.clickable import androidx.compose.foundation.gestures.detectTapGestures import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.consumeWindowInsets +import androidx.compose.foundation.layout.imePadding import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.composed import androidx.compose.ui.draw.drawBehind @@ -17,6 +23,9 @@ import androidx.compose.ui.graphics.Shape import androidx.compose.ui.graphics.drawOutline import androidx.compose.ui.graphics.drawscope.drawIntoCanvas import androidx.compose.ui.input.pointer.pointerInput +import androidx.compose.ui.layout.findRootCoordinates +import androidx.compose.ui.layout.onGloballyPositioned +import androidx.compose.ui.layout.positionInWindow import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.dp @@ -86,3 +95,15 @@ fun Modifier.dropShadow( } } } + +fun Modifier.advancedImePadding() = composed { + var consumePadding by remember { mutableStateOf(0) } + onGloballyPositioned { coordinates -> + consumePadding = coordinates.findRootCoordinates().size.height - + (coordinates.positionInWindow().y + coordinates.size.height).toInt().coerceAtLeast(0) + } + .consumeWindowInsets( + PaddingValues(bottom = with(LocalDensity.current) { consumePadding.toDp() }) + ) + .imePadding() +} From dd396928569583f66fe896875450256ee68ec8a7 Mon Sep 17 00:00:00 2001 From: sohee <144779368+sohee6989@users.noreply.github.com> Date: Sun, 18 Jan 2026 23:08:45 +0900 Subject: [PATCH 02/24] =?UTF-8?q?[FEAT/#76]=20ImePadding=20=ED=8C=A8?= =?UTF-8?q?=EB=94=A9=EA=B4=80=EB=A0=A8=20Manifest=EC=97=90=20adjustResize?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/AndroidManifest.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 42d29820a..267920f8a 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -16,6 +16,7 @@ android:theme="@style/Theme.Cherrish" > @@ -27,4 +28,4 @@ - \ No newline at end of file + From a765f39993319dbc0566ca11ce9dab2fd0bbd8ba Mon Sep 17 00:00:00 2001 From: sohee <144779368+sohee6989@users.noreply.github.com> Date: Sun, 18 Jan 2026 23:09:19 +0900 Subject: [PATCH 03/24] =?UTF-8?q?[FEAT/#76]=20Dto=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/request/OnboardingProfileRequestDto.kt | 12 ++++++++++++ .../dto/response/OnboardingProfileResponseDto.kt | 14 ++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 app/src/main/java/com/cherrish/android/data/remote/dto/request/OnboardingProfileRequestDto.kt create mode 100644 app/src/main/java/com/cherrish/android/data/remote/dto/response/OnboardingProfileResponseDto.kt diff --git a/app/src/main/java/com/cherrish/android/data/remote/dto/request/OnboardingProfileRequestDto.kt b/app/src/main/java/com/cherrish/android/data/remote/dto/request/OnboardingProfileRequestDto.kt new file mode 100644 index 000000000..133825005 --- /dev/null +++ b/app/src/main/java/com/cherrish/android/data/remote/dto/request/OnboardingProfileRequestDto.kt @@ -0,0 +1,12 @@ +package com.cherrish.android.data.remote.dto.request + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class OnboardingProfileRequestDto( + @SerialName("name") + val name: String, + @SerialName("age") + val age: Int +) diff --git a/app/src/main/java/com/cherrish/android/data/remote/dto/response/OnboardingProfileResponseDto.kt b/app/src/main/java/com/cherrish/android/data/remote/dto/response/OnboardingProfileResponseDto.kt new file mode 100644 index 000000000..57c5acd49 --- /dev/null +++ b/app/src/main/java/com/cherrish/android/data/remote/dto/response/OnboardingProfileResponseDto.kt @@ -0,0 +1,14 @@ +package com.cherrish.android.data.remote.dto.response + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +@Serializable +data class OnboardingProfileResponseDto ( + @SerialName("id") + val id: Long, + @SerialName("name") + val name: String, + @SerialName("date") + val date: String +) From fe0ce09a9eb5d65e739d16871e514e85585a50f3 Mon Sep 17 00:00:00 2001 From: sohee <144779368+sohee6989@users.noreply.github.com> Date: Sun, 18 Jan 2026 23:11:18 +0900 Subject: [PATCH 04/24] =?UTF-8?q?[FEAT/#76]=20Service=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../remote/service/OnboardingProfileService.kt | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 app/src/main/java/com/cherrish/android/data/remote/service/OnboardingProfileService.kt diff --git a/app/src/main/java/com/cherrish/android/data/remote/service/OnboardingProfileService.kt b/app/src/main/java/com/cherrish/android/data/remote/service/OnboardingProfileService.kt new file mode 100644 index 000000000..1ac217c7a --- /dev/null +++ b/app/src/main/java/com/cherrish/android/data/remote/service/OnboardingProfileService.kt @@ -0,0 +1,14 @@ +package com.cherrish.android.data.remote.service + +import com.cherrish.android.core.network.BaseResponse +import com.cherrish.android.data.remote.dto.request.OnboardingProfileRequestDto +import com.cherrish.android.data.remote.dto.response.OnboardingProfileResponseDto +import retrofit2.http.Body +import retrofit2.http.POST + +interface OnboardingProfileService { + @POST("/api/onboarding/profiles") + suspend fun postOnboardingProfile( + @Body request: OnboardingProfileRequestDto + ): BaseResponse +} From 34ff267b84f853fc6241506634b1eb74bd061d7b Mon Sep 17 00:00:00 2001 From: sohee <144779368+sohee6989@users.noreply.github.com> Date: Sun, 18 Jan 2026 23:11:46 +0900 Subject: [PATCH 05/24] =?UTF-8?q?[FEAT/#76]=20DataSource=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../datasource/OnboardingProfileDataSource.kt | 11 +++++++++++ .../OnboardingProfileDataSourceImpl.kt | 16 ++++++++++++++++ 2 files changed, 27 insertions(+) create mode 100644 app/src/main/java/com/cherrish/android/data/remote/datasource/OnboardingProfileDataSource.kt create mode 100644 app/src/main/java/com/cherrish/android/data/remote/datasourceimpl/OnboardingProfileDataSourceImpl.kt diff --git a/app/src/main/java/com/cherrish/android/data/remote/datasource/OnboardingProfileDataSource.kt b/app/src/main/java/com/cherrish/android/data/remote/datasource/OnboardingProfileDataSource.kt new file mode 100644 index 000000000..89fceef05 --- /dev/null +++ b/app/src/main/java/com/cherrish/android/data/remote/datasource/OnboardingProfileDataSource.kt @@ -0,0 +1,11 @@ +package com.cherrish.android.data.remote.datasource + +import com.cherrish.android.core.network.BaseResponse +import com.cherrish.android.data.remote.dto.request.OnboardingProfileRequestDto +import com.cherrish.android.data.remote.dto.response.OnboardingProfileResponseDto + +interface OnboardingProfileDataSource { + suspend fun postOnboardingProfile( + request: OnboardingProfileRequestDto + ): BaseResponse +} diff --git a/app/src/main/java/com/cherrish/android/data/remote/datasourceimpl/OnboardingProfileDataSourceImpl.kt b/app/src/main/java/com/cherrish/android/data/remote/datasourceimpl/OnboardingProfileDataSourceImpl.kt new file mode 100644 index 000000000..6fa2e56c9 --- /dev/null +++ b/app/src/main/java/com/cherrish/android/data/remote/datasourceimpl/OnboardingProfileDataSourceImpl.kt @@ -0,0 +1,16 @@ +package com.cherrish.android.data.remote.datasourceimpl + +import com.cherrish.android.core.network.BaseResponse +import com.cherrish.android.data.remote.datasource.OnboardingProfileDataSource +import com.cherrish.android.data.remote.dto.request.OnboardingProfileRequestDto +import com.cherrish.android.data.remote.dto.response.OnboardingProfileResponseDto +import com.cherrish.android.data.remote.service.OnboardingProfileService +import javax.inject.Inject + +class OnboardingProfileDataSourceImpl @Inject constructor( + private val onboardingProfileService: OnboardingProfileService +) : OnboardingProfileDataSource { + override suspend fun postOnboardingProfile(request: OnboardingProfileRequestDto): BaseResponse { + return onboardingProfileService.postOnboardingProfile(request) + } +} From fc7808cfbccebab375b27e6ace8bacdb3a11070b Mon Sep 17 00:00:00 2001 From: sohee <144779368+sohee6989@users.noreply.github.com> Date: Sun, 18 Jan 2026 23:11:53 +0900 Subject: [PATCH 06/24] =?UTF-8?q?[FEAT/#76]=20Model=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../data/model/OnboardingProfileRequestModel.kt | 13 +++++++++++++ .../data/model/OnboardingProfileResponseModel.kt | 15 +++++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 app/src/main/java/com/cherrish/android/data/model/OnboardingProfileRequestModel.kt create mode 100644 app/src/main/java/com/cherrish/android/data/model/OnboardingProfileResponseModel.kt diff --git a/app/src/main/java/com/cherrish/android/data/model/OnboardingProfileRequestModel.kt b/app/src/main/java/com/cherrish/android/data/model/OnboardingProfileRequestModel.kt new file mode 100644 index 000000000..decba6294 --- /dev/null +++ b/app/src/main/java/com/cherrish/android/data/model/OnboardingProfileRequestModel.kt @@ -0,0 +1,13 @@ +package com.cherrish.android.data.model + +import com.cherrish.android.data.remote.dto.request.OnboardingProfileRequestDto + +data class OnboardingProfileRequestModel( + val name: String, + val age: Int +) + +fun OnboardingProfileRequestModel.toDto() = OnboardingProfileRequestDto( + name = this.name, + age = this.age +) diff --git a/app/src/main/java/com/cherrish/android/data/model/OnboardingProfileResponseModel.kt b/app/src/main/java/com/cherrish/android/data/model/OnboardingProfileResponseModel.kt new file mode 100644 index 000000000..2c011a755 --- /dev/null +++ b/app/src/main/java/com/cherrish/android/data/model/OnboardingProfileResponseModel.kt @@ -0,0 +1,15 @@ +package com.cherrish.android.data.model + +import com.cherrish.android.data.remote.dto.response.OnboardingProfileResponseDto + +data class OnboardingProfileResponseModel( + val id: Long, + val name: String, + val date: String +) + +fun OnboardingProfileResponseDto.toModel() = OnboardingProfileResponseModel( + id = this.id, + name = this.name, + date = this.date +) From 6112d22ed3d21501259c7cb2f75f54ab28656ed3 Mon Sep 17 00:00:00 2001 From: sohee <144779368+sohee6989@users.noreply.github.com> Date: Sun, 18 Jan 2026 23:11:58 +0900 Subject: [PATCH 07/24] =?UTF-8?q?[FEAT/#76]=20Repository=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repository/OnboardingProfileRepository.kt | 10 ++++++++++ .../OnboardingProfileRepositoryImpl.kt | 19 +++++++++++++++++++ 2 files changed, 29 insertions(+) create mode 100644 app/src/main/java/com/cherrish/android/data/repository/OnboardingProfileRepository.kt create mode 100644 app/src/main/java/com/cherrish/android/data/repositoryimpl/OnboardingProfileRepositoryImpl.kt diff --git a/app/src/main/java/com/cherrish/android/data/repository/OnboardingProfileRepository.kt b/app/src/main/java/com/cherrish/android/data/repository/OnboardingProfileRepository.kt new file mode 100644 index 000000000..dbb14e609 --- /dev/null +++ b/app/src/main/java/com/cherrish/android/data/repository/OnboardingProfileRepository.kt @@ -0,0 +1,10 @@ +package com.cherrish.android.data.repository + +import com.cherrish.android.data.model.OnboardingProfileRequestModel +import com.cherrish.android.data.model.OnboardingProfileResponseModel + +interface OnboardingProfileRepository { + suspend fun postOnboardingProfile( + request: OnboardingProfileRequestModel + ): Result +} diff --git a/app/src/main/java/com/cherrish/android/data/repositoryimpl/OnboardingProfileRepositoryImpl.kt b/app/src/main/java/com/cherrish/android/data/repositoryimpl/OnboardingProfileRepositoryImpl.kt new file mode 100644 index 000000000..751f58cf6 --- /dev/null +++ b/app/src/main/java/com/cherrish/android/data/repositoryimpl/OnboardingProfileRepositoryImpl.kt @@ -0,0 +1,19 @@ +package com.cherrish.android.data.repositoryimpl + +import com.cherrish.android.core.util.suspendRunCatching +import com.cherrish.android.data.model.OnboardingProfileRequestModel +import com.cherrish.android.data.model.OnboardingProfileResponseModel +import com.cherrish.android.data.model.toDto +import com.cherrish.android.data.model.toModel +import com.cherrish.android.data.remote.datasource.OnboardingProfileDataSource +import com.cherrish.android.data.repository.OnboardingProfileRepository +import javax.inject.Inject + +class OnboardingProfileRepositoryImpl @Inject constructor( + private val onboardingProfileDataSource: OnboardingProfileDataSource +) : OnboardingProfileRepository{ + override suspend fun postOnboardingProfile(request: OnboardingProfileRequestModel): Result = + suspendRunCatching { + onboardingProfileDataSource.postOnboardingProfile(request = request.toDto()).data!!.toModel() + } +} From 73f6fe3a3f922b9ae8b401ef3ded9c84cdd4e0df Mon Sep 17 00:00:00 2001 From: sohee <144779368+sohee6989@users.noreply.github.com> Date: Sun, 18 Jan 2026 23:12:42 +0900 Subject: [PATCH 08/24] =?UTF-8?q?[FEAT/#76]=20=EB=84=A4=EB=B9=84=20?= =?UTF-8?q?=EA=B4=80=EB=A0=A8=20=EC=84=B8=ED=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../android/presentation/main/MainAppState.kt | 13 ++++++++- .../android/presentation/main/MainScreen.kt | 20 +++++++++++++ .../navigation/InformationNavigator.kt | 29 +++++++++++++++++++ 3 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 app/src/main/java/com/cherrish/android/presentation/onboarding/information/navigation/InformationNavigator.kt diff --git a/app/src/main/java/com/cherrish/android/presentation/main/MainAppState.kt b/app/src/main/java/com/cherrish/android/presentation/main/MainAppState.kt index 52f4ad4d5..803012f98 100644 --- a/app/src/main/java/com/cherrish/android/presentation/main/MainAppState.kt +++ b/app/src/main/java/com/cherrish/android/presentation/main/MainAppState.kt @@ -6,6 +6,7 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope import androidx.navigation.NavDestination.Companion.hasRoute import androidx.navigation.NavHostController +import androidx.navigation.NavOptions import androidx.navigation.compose.rememberNavController import androidx.navigation.navOptions import com.cherrish.android.presentation.calendar.navigation.navigateToCalendar @@ -13,6 +14,8 @@ import com.cherrish.android.presentation.challenge.navigation.navigateToChalleng import com.cherrish.android.presentation.home.navigation.Home import com.cherrish.android.presentation.home.navigation.navigateToHome import com.cherrish.android.presentation.mypage.navigation.navigateToMyPage +import com.cherrish.android.presentation.onboarding.information.navigation.OnboardingInformation +import com.cherrish.android.presentation.onboarding.information.navigation.navigateToOnboardingInformation import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow @@ -24,7 +27,7 @@ class MainAppState( val navController: NavHostController, coroutineScope: CoroutineScope ) { - val startDestination = Home + val startDestination = OnboardingInformation private val currentDestination = navController.currentBackStackEntryFlow .map { it.destination } @@ -77,6 +80,14 @@ class MainAppState( MainTab.CHALLENGE -> navController.navigateToChallenge(navOptions = navOptions) } } + + fun navigateToOnboardingInformation(navOptions: NavOptions) { + navController.navigateToOnboardingInformation(navOptions) + } + + fun navigateToHome(navOptions: NavOptions) { + navController.navigateToHome(navOptions) + } } @Composable diff --git a/app/src/main/java/com/cherrish/android/presentation/main/MainScreen.kt b/app/src/main/java/com/cherrish/android/presentation/main/MainScreen.kt index ecbd0203e..a6693e07a 100644 --- a/app/src/main/java/com/cherrish/android/presentation/main/MainScreen.kt +++ b/app/src/main/java/com/cherrish/android/presentation/main/MainScreen.kt @@ -7,11 +7,13 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.navigation.compose.NavHost +import androidx.navigation.navOptions import com.cherrish.android.presentation.calendar.navigation.calendarNavGraph import com.cherrish.android.presentation.challenge.navigation.challengeNavGraph import com.cherrish.android.presentation.home.navigation.homeNavGraph import com.cherrish.android.presentation.main.component.MainBottomBar import com.cherrish.android.presentation.mypage.navigation.myPageNavGraph +import com.cherrish.android.presentation.onboarding.information.navigation.onboardingInformationNavGraph import kotlinx.collections.immutable.toPersistentList @Composable @@ -21,6 +23,17 @@ fun MainScreen( val isBottomBarVisible by appState.isBottomBarVisible.collectAsStateWithLifecycle() val currentTab by appState.currentTab.collectAsStateWithLifecycle() + val clearStackNavOptions = navOptions { + popUpTo(0) { inclusive = true } + launchSingleTop = true + restoreState = false + } + + val keepStackNavOptions = navOptions { + launchSingleTop = true + restoreState = true + } + Scaffold( bottomBar = { MainBottomBar( @@ -39,6 +52,13 @@ fun MainScreen( navController = appState.navController, startDestination = appState.startDestination ) { + onboardingInformationNavGraph( + paddingValues = innerPadding, + navigateToHome = { + appState.navigateToHome(clearStackNavOptions) + } + ) + homeNavGraph(paddingValues = innerPadding) calendarNavGraph(paddingValues = innerPadding) diff --git a/app/src/main/java/com/cherrish/android/presentation/onboarding/information/navigation/InformationNavigator.kt b/app/src/main/java/com/cherrish/android/presentation/onboarding/information/navigation/InformationNavigator.kt new file mode 100644 index 000000000..17f991dff --- /dev/null +++ b/app/src/main/java/com/cherrish/android/presentation/onboarding/information/navigation/InformationNavigator.kt @@ -0,0 +1,29 @@ +package com.cherrish.android.presentation.onboarding.information.navigation + +import androidx.compose.foundation.layout.PaddingValues +import androidx.navigation.NavController +import androidx.navigation.NavGraphBuilder +import androidx.navigation.NavOptions +import androidx.navigation.compose.composable +import com.cherrish.android.core.common.navigation.Route +import com.cherrish.android.presentation.onboarding.information.InformationRoute +import kotlinx.serialization.Serializable + +@Serializable +data object OnboardingInformation: Route + +fun NavController.navigateToOnboardingInformation(navOptions: NavOptions? = null){ + navigate(route = OnboardingInformation, navOptions = navOptions) +} + +fun NavGraphBuilder.onboardingInformationNavGraph( + paddingValues: PaddingValues, + navigateToHome: () -> Unit +){ + composable { + InformationRoute( + paddingValues = paddingValues, + navigateToHome = navigateToHome + ) + } +} From f18c53f5ea771b9be07edea0ef6f5d070bb5ee90 Mon Sep 17 00:00:00 2001 From: sohee <144779368+sohee6989@users.noreply.github.com> Date: Sun, 18 Jan 2026 23:12:52 +0900 Subject: [PATCH 09/24] =?UTF-8?q?[FEAT/#76]=20=EB=AA=A8=EB=93=88=20?= =?UTF-8?q?=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/cherrish/android/data/di/DataSourceModule.kt | 8 ++++++++ .../com/cherrish/android/data/di/RepositoryModule.kt | 8 ++++++++ .../java/com/cherrish/android/data/di/ServiceModule.kt | 10 +++++++++- 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/cherrish/android/data/di/DataSourceModule.kt b/app/src/main/java/com/cherrish/android/data/di/DataSourceModule.kt index 7b7d851d5..e94fd08a5 100644 --- a/app/src/main/java/com/cherrish/android/data/di/DataSourceModule.kt +++ b/app/src/main/java/com/cherrish/android/data/di/DataSourceModule.kt @@ -1,7 +1,9 @@ package com.cherrish.android.data.di import com.cherrish.android.data.remote.datasource.CalendarDataSource +import com.cherrish.android.data.remote.datasource.OnboardingProfileDataSource import com.cherrish.android.data.remote.datasourceimpl.CalendarDataSourceImpl +import com.cherrish.android.data.remote.datasourceimpl.OnboardingProfileDataSourceImpl import dagger.Binds import dagger.Module import dagger.hilt.InstallIn @@ -16,4 +18,10 @@ abstract class DataSourceModule { abstract fun bindCalendarDataSource( calendarDataSourceImpl: CalendarDataSourceImpl ): CalendarDataSource + + @Binds + @Singleton + abstract fun bindOnboardingProfileDataSource( + onboardingProfileDataSourceImpl: OnboardingProfileDataSourceImpl + ): OnboardingProfileDataSource } diff --git a/app/src/main/java/com/cherrish/android/data/di/RepositoryModule.kt b/app/src/main/java/com/cherrish/android/data/di/RepositoryModule.kt index ce7225f16..e249f72dd 100644 --- a/app/src/main/java/com/cherrish/android/data/di/RepositoryModule.kt +++ b/app/src/main/java/com/cherrish/android/data/di/RepositoryModule.kt @@ -1,7 +1,9 @@ package com.cherrish.android.data.di import com.cherrish.android.data.repository.CalendarRepository +import com.cherrish.android.data.repository.OnboardingProfileRepository import com.cherrish.android.data.repositoryimpl.CalendarRepositoryImpl +import com.cherrish.android.data.repositoryimpl.OnboardingProfileRepositoryImpl import dagger.Binds import dagger.Module import dagger.hilt.InstallIn @@ -16,4 +18,10 @@ abstract class RepositoryModule { abstract fun bindCalendarRepository( calendarRepositoryImpl: CalendarRepositoryImpl ): CalendarRepository + + @Binds + @Singleton + abstract fun bindOnboardingProfileRepository( + onboardingProfileRepositoryImpl: OnboardingProfileRepositoryImpl + ): OnboardingProfileRepository } diff --git a/app/src/main/java/com/cherrish/android/data/di/ServiceModule.kt b/app/src/main/java/com/cherrish/android/data/di/ServiceModule.kt index 9bc6bbde6..539ecf0cc 100644 --- a/app/src/main/java/com/cherrish/android/data/di/ServiceModule.kt +++ b/app/src/main/java/com/cherrish/android/data/di/ServiceModule.kt @@ -1,12 +1,14 @@ package com.cherrish.android.data.di import com.cherrish.android.data.remote.service.CalendarService +import com.cherrish.android.data.remote.service.OnboardingProfileService import dagger.Module import dagger.Provides import dagger.hilt.InstallIn import dagger.hilt.components.SingletonComponent -import javax.inject.Singleton import retrofit2.Retrofit +import javax.annotation.Signed +import javax.inject.Singleton @Module @InstallIn(SingletonComponent::class) @@ -16,4 +18,10 @@ object ServiceModule { fun provideCalendarService( retrofit: Retrofit ): CalendarService = retrofit.create(CalendarService::class.java) + + @Provides + @Signed + fun provideOnboardingProfileService( + retrofit: Retrofit + ): OnboardingProfileService = retrofit.create(OnboardingProfileService::class.java) } From 37cec53c48aaa0b712c3a18beef53a7c377a5981 Mon Sep 17 00:00:00 2001 From: sohee <144779368+sohee6989@users.noreply.github.com> Date: Sun, 18 Jan 2026 23:13:08 +0900 Subject: [PATCH 10/24] =?UTF-8?q?[FEAT/#76]=20=EC=98=A8=EB=B3=B4=EB=94=A9-?= =?UTF-8?q?=EC=A0=95=EB=B3=B4=EC=9E=85=EB=A0=A5=20=EC=84=9C=EB=B2=84=20?= =?UTF-8?q?=EC=97=B0=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../information/InformationScreen.kt | 20 +++++++++++- .../information/InformationUiState.kt | 4 +++ .../information/InformationViewModel.kt | 31 +++++++++++++++++-- 3 files changed, 51 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/com/cherrish/android/presentation/onboarding/information/InformationScreen.kt b/app/src/main/java/com/cherrish/android/presentation/onboarding/information/InformationScreen.kt index 8139d0ea4..4bd02141c 100644 --- a/app/src/main/java/com/cherrish/android/presentation/onboarding/information/InformationScreen.kt +++ b/app/src/main/java/com/cherrish/android/presentation/onboarding/information/InformationScreen.kt @@ -7,10 +7,12 @@ import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember @@ -29,18 +31,29 @@ import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.cherrish.android.core.common.extension.addFocusCleaner +import com.cherrish.android.core.common.extension.advancedImePadding import com.cherrish.android.core.designsystem.component.button.CherrishButton import com.cherrish.android.core.designsystem.component.textfield.CherrishTextField import com.cherrish.android.core.designsystem.theme.CherrishTheme import com.cherrish.android.presentation.onboarding.information.extension.AgeSuffixTransformation +import kotlinx.coroutines.flow.collectLatest @Composable fun InformationRoute( paddingValues: PaddingValues, + navigateToHome: () -> Unit, viewModel: InformationViewModel = hiltViewModel() ) { val uiState by viewModel.uiState.collectAsStateWithLifecycle() + LaunchedEffect(Unit) { + viewModel.sideEffect.collectLatest { sideEffect -> + when (sideEffect) { + InformationSideEffect.NavigateToHome -> navigateToHome() + } + } + } + InformationScreen( paddingValues = paddingValues, username = uiState.username, @@ -75,6 +88,7 @@ private fun InformationScreen( .background(color = CherrishTheme.colors.gray0) .addFocusCleaner(focusManager) .padding(paddingValues = paddingValues) + .advancedImePadding() ) { Spacer(modifier = Modifier.weight(135f)) @@ -173,7 +187,6 @@ private fun UserInfoTextField( modifier = modifier .fillMaxWidth() .padding(horizontal = 26.dp), - verticalArrangement = Arrangement.spacedBy(8.dp) ) { Text( text = textFieldName, @@ -181,6 +194,8 @@ private fun UserInfoTextField( color = CherrishTheme.colors.gray1000 ) + Spacer(modifier = Modifier.height(8.dp)) + CherrishTextField( value = value, onValueChange = onValueChange, @@ -197,6 +212,9 @@ private fun UserInfoTextField( visualTransformation = visualTransformation, modifier = Modifier.fillMaxWidth() ) + + Spacer(modifier = Modifier.height(4.dp)) + } } diff --git a/app/src/main/java/com/cherrish/android/presentation/onboarding/information/InformationUiState.kt b/app/src/main/java/com/cherrish/android/presentation/onboarding/information/InformationUiState.kt index e8db292a3..44d599c7a 100644 --- a/app/src/main/java/com/cherrish/android/presentation/onboarding/information/InformationUiState.kt +++ b/app/src/main/java/com/cherrish/android/presentation/onboarding/information/InformationUiState.kt @@ -10,3 +10,7 @@ data class InformationUiState( val buttonEnabled: Boolean get() = username.isNotBlank() && age.toIntOrNull()?.let { it > 0 } == true } + +sealed interface InformationSideEffect{ + data object NavigateToHome: InformationSideEffect +} diff --git a/app/src/main/java/com/cherrish/android/presentation/onboarding/information/InformationViewModel.kt b/app/src/main/java/com/cherrish/android/presentation/onboarding/information/InformationViewModel.kt index be7b2dd7d..996759456 100644 --- a/app/src/main/java/com/cherrish/android/presentation/onboarding/information/InformationViewModel.kt +++ b/app/src/main/java/com/cherrish/android/presentation/onboarding/information/InformationViewModel.kt @@ -1,18 +1,33 @@ package com.cherrish.android.presentation.onboarding.information import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.cherrish.android.core.common.extension.onLogFailure +import com.cherrish.android.core.local.TokenManager +import com.cherrish.android.data.model.OnboardingProfileRequestModel +import com.cherrish.android.data.repository.OnboardingProfileRepository import dagger.hilt.android.lifecycle.HiltViewModel -import javax.inject.Inject +import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.SharedFlow import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asSharedFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.update +import kotlinx.coroutines.launch +import javax.inject.Inject @HiltViewModel -class InformationViewModel @Inject constructor() : ViewModel() { +class InformationViewModel @Inject constructor( + private val onboardingProfileRepository: OnboardingProfileRepository, + private val tokenManager: TokenManager +) : ViewModel() { private val _uiState = MutableStateFlow(InformationUiState()) val uiState: StateFlow = _uiState.asStateFlow() + private val _sideEffect = MutableSharedFlow() + val sideEffect: SharedFlow = _sideEffect.asSharedFlow() + fun onNameChanged(name: String) { _uiState.update { it.copy( @@ -27,6 +42,16 @@ class InformationViewModel @Inject constructor() : ViewModel() { } fun onNextClicked() { - // TODO: 다음 화면으로 이동 + viewModelScope.launch { + onboardingProfileRepository.postOnboardingProfile( + request = OnboardingProfileRequestModel( + name = uiState.value.username, + age = uiState.value.age.toInt() + ) + ).onSuccess { response -> + tokenManager.saveId(response.id) + _sideEffect.emit(InformationSideEffect.NavigateToHome) + }.onLogFailure {} + } } } From 8686f6b45cc34ee974b7d87e7256e29ef2fadee5 Mon Sep 17 00:00:00 2001 From: sohee <144779368+sohee6989@users.noreply.github.com> Date: Sun, 18 Jan 2026 23:13:21 +0900 Subject: [PATCH 11/24] =?UTF-8?q?[FEAT/#76]=20=EC=9E=90=EB=8F=99=20?= =?UTF-8?q?=ED=9A=8C=EC=A0=84=20=EB=A7=89=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/cherrish/android/presentation/main/MainActivity.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/src/main/java/com/cherrish/android/presentation/main/MainActivity.kt b/app/src/main/java/com/cherrish/android/presentation/main/MainActivity.kt index 8b0cae148..dea1d36c0 100644 --- a/app/src/main/java/com/cherrish/android/presentation/main/MainActivity.kt +++ b/app/src/main/java/com/cherrish/android/presentation/main/MainActivity.kt @@ -1,5 +1,6 @@ package com.cherrish.android.presentation.main +import android.content.pm.ActivityInfo import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent @@ -11,6 +12,7 @@ import dagger.hilt.android.AndroidEntryPoint class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) + requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED enableEdgeToEdge() setContent { CherrishTheme { From 17f15dc34e2d16eaa29de1163ba0eaae9cec18cb Mon Sep 17 00:00:00 2001 From: sohee <144779368+sohee6989@users.noreply.github.com> Date: Sun, 18 Jan 2026 23:19:36 +0900 Subject: [PATCH 12/24] =?UTF-8?q?[CHORE/#76]=20ktlint=20=EC=B2=B4=ED=81=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kotlin-compiler-1134150500919237970.salive | 0 .../android/core/common/extension/ModifierExt.kt | 4 +++- .../java/com/cherrish/android/data/di/ServiceModule.kt | 2 +- .../dto/response/OnboardingProfileResponseDto.kt | 2 +- .../repositoryimpl/OnboardingProfileRepositoryImpl.kt | 10 +++++++--- .../cherrish/android/presentation/main/MainAppState.kt | 1 - .../onboarding/information/InformationScreen.kt | 3 +-- .../onboarding/information/InformationUiState.kt | 4 ++-- .../onboarding/information/InformationViewModel.kt | 2 +- .../information/navigation/InformationNavigator.kt | 6 +++--- 10 files changed, 19 insertions(+), 15 deletions(-) delete mode 100644 .kotlin/sessions/kotlin-compiler-1134150500919237970.salive diff --git a/.kotlin/sessions/kotlin-compiler-1134150500919237970.salive b/.kotlin/sessions/kotlin-compiler-1134150500919237970.salive deleted file mode 100644 index e69de29bb..000000000 diff --git a/app/src/main/java/com/cherrish/android/core/common/extension/ModifierExt.kt b/app/src/main/java/com/cherrish/android/core/common/extension/ModifierExt.kt index 5819d75c1..038d8c781 100644 --- a/app/src/main/java/com/cherrish/android/core/common/extension/ModifierExt.kt +++ b/app/src/main/java/com/cherrish/android/core/common/extension/ModifierExt.kt @@ -100,7 +100,9 @@ fun Modifier.advancedImePadding() = composed { var consumePadding by remember { mutableStateOf(0) } onGloballyPositioned { coordinates -> consumePadding = coordinates.findRootCoordinates().size.height - - (coordinates.positionInWindow().y + coordinates.size.height).toInt().coerceAtLeast(0) + (coordinates.positionInWindow().y + coordinates.size.height).toInt().coerceAtLeast( + 0 + ) } .consumeWindowInsets( PaddingValues(bottom = with(LocalDensity.current) { consumePadding.toDp() }) diff --git a/app/src/main/java/com/cherrish/android/data/di/ServiceModule.kt b/app/src/main/java/com/cherrish/android/data/di/ServiceModule.kt index 539ecf0cc..4e42b6934 100644 --- a/app/src/main/java/com/cherrish/android/data/di/ServiceModule.kt +++ b/app/src/main/java/com/cherrish/android/data/di/ServiceModule.kt @@ -6,9 +6,9 @@ import dagger.Module import dagger.Provides import dagger.hilt.InstallIn import dagger.hilt.components.SingletonComponent -import retrofit2.Retrofit import javax.annotation.Signed import javax.inject.Singleton +import retrofit2.Retrofit @Module @InstallIn(SingletonComponent::class) diff --git a/app/src/main/java/com/cherrish/android/data/remote/dto/response/OnboardingProfileResponseDto.kt b/app/src/main/java/com/cherrish/android/data/remote/dto/response/OnboardingProfileResponseDto.kt index 57c5acd49..d7a18f2f2 100644 --- a/app/src/main/java/com/cherrish/android/data/remote/dto/response/OnboardingProfileResponseDto.kt +++ b/app/src/main/java/com/cherrish/android/data/remote/dto/response/OnboardingProfileResponseDto.kt @@ -4,7 +4,7 @@ import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable @Serializable -data class OnboardingProfileResponseDto ( +data class OnboardingProfileResponseDto( @SerialName("id") val id: Long, @SerialName("name") diff --git a/app/src/main/java/com/cherrish/android/data/repositoryimpl/OnboardingProfileRepositoryImpl.kt b/app/src/main/java/com/cherrish/android/data/repositoryimpl/OnboardingProfileRepositoryImpl.kt index 751f58cf6..64c3e08c8 100644 --- a/app/src/main/java/com/cherrish/android/data/repositoryimpl/OnboardingProfileRepositoryImpl.kt +++ b/app/src/main/java/com/cherrish/android/data/repositoryimpl/OnboardingProfileRepositoryImpl.kt @@ -11,9 +11,13 @@ import javax.inject.Inject class OnboardingProfileRepositoryImpl @Inject constructor( private val onboardingProfileDataSource: OnboardingProfileDataSource -) : OnboardingProfileRepository{ - override suspend fun postOnboardingProfile(request: OnboardingProfileRequestModel): Result = +) : OnboardingProfileRepository { + override suspend fun postOnboardingProfile( + request: OnboardingProfileRequestModel + ): Result = suspendRunCatching { - onboardingProfileDataSource.postOnboardingProfile(request = request.toDto()).data!!.toModel() + onboardingProfileDataSource.postOnboardingProfile( + request = request.toDto() + ).data!!.toModel() } } diff --git a/app/src/main/java/com/cherrish/android/presentation/main/MainAppState.kt b/app/src/main/java/com/cherrish/android/presentation/main/MainAppState.kt index 803012f98..aed4a14e2 100644 --- a/app/src/main/java/com/cherrish/android/presentation/main/MainAppState.kt +++ b/app/src/main/java/com/cherrish/android/presentation/main/MainAppState.kt @@ -11,7 +11,6 @@ import androidx.navigation.compose.rememberNavController import androidx.navigation.navOptions import com.cherrish.android.presentation.calendar.navigation.navigateToCalendar import com.cherrish.android.presentation.challenge.navigation.navigateToChallenge -import com.cherrish.android.presentation.home.navigation.Home import com.cherrish.android.presentation.home.navigation.navigateToHome import com.cherrish.android.presentation.mypage.navigation.navigateToMyPage import com.cherrish.android.presentation.onboarding.information.navigation.OnboardingInformation diff --git a/app/src/main/java/com/cherrish/android/presentation/onboarding/information/InformationScreen.kt b/app/src/main/java/com/cherrish/android/presentation/onboarding/information/InformationScreen.kt index 4bd02141c..342011898 100644 --- a/app/src/main/java/com/cherrish/android/presentation/onboarding/information/InformationScreen.kt +++ b/app/src/main/java/com/cherrish/android/presentation/onboarding/information/InformationScreen.kt @@ -186,7 +186,7 @@ private fun UserInfoTextField( Column( modifier = modifier .fillMaxWidth() - .padding(horizontal = 26.dp), + .padding(horizontal = 26.dp) ) { Text( text = textFieldName, @@ -214,7 +214,6 @@ private fun UserInfoTextField( ) Spacer(modifier = Modifier.height(4.dp)) - } } diff --git a/app/src/main/java/com/cherrish/android/presentation/onboarding/information/InformationUiState.kt b/app/src/main/java/com/cherrish/android/presentation/onboarding/information/InformationUiState.kt index 44d599c7a..5df279a0f 100644 --- a/app/src/main/java/com/cherrish/android/presentation/onboarding/information/InformationUiState.kt +++ b/app/src/main/java/com/cherrish/android/presentation/onboarding/information/InformationUiState.kt @@ -11,6 +11,6 @@ data class InformationUiState( get() = username.isNotBlank() && age.toIntOrNull()?.let { it > 0 } == true } -sealed interface InformationSideEffect{ - data object NavigateToHome: InformationSideEffect +sealed interface InformationSideEffect { + data object NavigateToHome : InformationSideEffect } diff --git a/app/src/main/java/com/cherrish/android/presentation/onboarding/information/InformationViewModel.kt b/app/src/main/java/com/cherrish/android/presentation/onboarding/information/InformationViewModel.kt index 996759456..4f10bbf14 100644 --- a/app/src/main/java/com/cherrish/android/presentation/onboarding/information/InformationViewModel.kt +++ b/app/src/main/java/com/cherrish/android/presentation/onboarding/information/InformationViewModel.kt @@ -7,6 +7,7 @@ import com.cherrish.android.core.local.TokenManager import com.cherrish.android.data.model.OnboardingProfileRequestModel import com.cherrish.android.data.repository.OnboardingProfileRepository import dagger.hilt.android.lifecycle.HiltViewModel +import javax.inject.Inject import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharedFlow @@ -15,7 +16,6 @@ import kotlinx.coroutines.flow.asSharedFlow import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch -import javax.inject.Inject @HiltViewModel class InformationViewModel @Inject constructor( diff --git a/app/src/main/java/com/cherrish/android/presentation/onboarding/information/navigation/InformationNavigator.kt b/app/src/main/java/com/cherrish/android/presentation/onboarding/information/navigation/InformationNavigator.kt index 17f991dff..7a840dd9a 100644 --- a/app/src/main/java/com/cherrish/android/presentation/onboarding/information/navigation/InformationNavigator.kt +++ b/app/src/main/java/com/cherrish/android/presentation/onboarding/information/navigation/InformationNavigator.kt @@ -10,16 +10,16 @@ import com.cherrish.android.presentation.onboarding.information.InformationRoute import kotlinx.serialization.Serializable @Serializable -data object OnboardingInformation: Route +data object OnboardingInformation : Route -fun NavController.navigateToOnboardingInformation(navOptions: NavOptions? = null){ +fun NavController.navigateToOnboardingInformation(navOptions: NavOptions? = null) { navigate(route = OnboardingInformation, navOptions = navOptions) } fun NavGraphBuilder.onboardingInformationNavGraph( paddingValues: PaddingValues, navigateToHome: () -> Unit -){ +) { composable { InformationRoute( paddingValues = paddingValues, From 3fc46e7578a72fea38b134d228fb499aaa014144 Mon Sep 17 00:00:00 2001 From: sohee <144779368+sohee6989@users.noreply.github.com> Date: Sun, 18 Jan 2026 23:21:07 +0900 Subject: [PATCH 13/24] =?UTF-8?q?[CHORE/#76]=20ktlint=20=EC=B2=B4=ED=81=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../remote/datasourceimpl/OnboardingProfileDataSourceImpl.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/cherrish/android/data/remote/datasourceimpl/OnboardingProfileDataSourceImpl.kt b/app/src/main/java/com/cherrish/android/data/remote/datasourceimpl/OnboardingProfileDataSourceImpl.kt index 6fa2e56c9..6ec9b140f 100644 --- a/app/src/main/java/com/cherrish/android/data/remote/datasourceimpl/OnboardingProfileDataSourceImpl.kt +++ b/app/src/main/java/com/cherrish/android/data/remote/datasourceimpl/OnboardingProfileDataSourceImpl.kt @@ -10,7 +10,9 @@ import javax.inject.Inject class OnboardingProfileDataSourceImpl @Inject constructor( private val onboardingProfileService: OnboardingProfileService ) : OnboardingProfileDataSource { - override suspend fun postOnboardingProfile(request: OnboardingProfileRequestDto): BaseResponse { + override suspend fun postOnboardingProfile( + request: OnboardingProfileRequestDto + ): BaseResponse { return onboardingProfileService.postOnboardingProfile(request) } } From 3d173a35a3723343e34895e45ea4403516221dd3 Mon Sep 17 00:00:00 2001 From: sohee <144779368+sohee6989@users.noreply.github.com> Date: Sun, 18 Jan 2026 23:48:24 +0900 Subject: [PATCH 14/24] =?UTF-8?q?[CHORE/#76]=20=EC=98=A4=ED=83=80=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/cherrish/android/data/di/ServiceModule.kt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/cherrish/android/data/di/ServiceModule.kt b/app/src/main/java/com/cherrish/android/data/di/ServiceModule.kt index 4e42b6934..710c49ce2 100644 --- a/app/src/main/java/com/cherrish/android/data/di/ServiceModule.kt +++ b/app/src/main/java/com/cherrish/android/data/di/ServiceModule.kt @@ -6,9 +6,8 @@ import dagger.Module import dagger.Provides import dagger.hilt.InstallIn import dagger.hilt.components.SingletonComponent -import javax.annotation.Signed -import javax.inject.Singleton import retrofit2.Retrofit +import javax.inject.Singleton @Module @InstallIn(SingletonComponent::class) @@ -20,7 +19,7 @@ object ServiceModule { ): CalendarService = retrofit.create(CalendarService::class.java) @Provides - @Signed + @Singleton fun provideOnboardingProfileService( retrofit: Retrofit ): OnboardingProfileService = retrofit.create(OnboardingProfileService::class.java) From 7761fb6ac27f0f06066a4042e89aef163b7d46ea Mon Sep 17 00:00:00 2001 From: sohee <144779368+sohee6989@users.noreply.github.com> Date: Sun, 18 Jan 2026 23:54:02 +0900 Subject: [PATCH 15/24] =?UTF-8?q?[FEAT/#76]=20=EC=9D=B4=EB=A6=84=20&=20?= =?UTF-8?q?=EB=82=98=EC=9D=B4=20=EC=97=90=EB=9F=AC=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 --- .../information/InformationScreen.kt | 29 +++++++++++++++---- .../information/InformationViewModel.kt | 8 ++++- 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/com/cherrish/android/presentation/onboarding/information/InformationScreen.kt b/app/src/main/java/com/cherrish/android/presentation/onboarding/information/InformationScreen.kt index 342011898..c3e72117a 100644 --- a/app/src/main/java/com/cherrish/android/presentation/onboarding/information/InformationScreen.kt +++ b/app/src/main/java/com/cherrish/android/presentation/onboarding/information/InformationScreen.kt @@ -21,6 +21,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.focus.FocusRequester import androidx.compose.ui.focus.focusRequester import androidx.compose.ui.focus.onFocusChanged +import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.platform.LocalSoftwareKeyboardController import androidx.compose.ui.text.input.ImeAction @@ -61,7 +62,9 @@ fun InformationRoute( age = uiState.age, onAgeChange = viewModel::onAgeChanged, onNextClick = viewModel::onNextClicked, - enabled = uiState.buttonEnabled + enabled = uiState.buttonEnabled, + nameErrorCase = viewModel.onNameErrorCase(uiState.username), + ageErrorCase = viewModel.onAgeErrorCase(uiState.age) ) } @@ -74,6 +77,8 @@ private fun InformationScreen( onAgeChange: (String) -> Unit, onNextClick: () -> Unit, enabled: Boolean, + nameErrorCase: Boolean, + ageErrorCase: Boolean, modifier: Modifier = Modifier ) { val focusManager = LocalFocusManager.current @@ -105,8 +110,10 @@ private fun InformationScreen( onNextAction = { ageFocusRequester.requestFocus() }, - keyboardType = KeyboardType.Text - ) + keyboardType = KeyboardType.Text, + errorText = "이름은 최대 7자까지 입력 가능합니다.", + errorCase = nameErrorCase, + ) Spacer(modifier = Modifier.weight(30f)) @@ -128,6 +135,8 @@ private fun InformationScreen( " 세" ) }, + errorText = "입력 가능한 최대 나이 100세를 초과했습니다.", + errorCase = ageErrorCase, modifier = Modifier .focusRequester(ageFocusRequester) .onFocusChanged { state -> @@ -178,10 +187,12 @@ private fun UserInfoTextField( placeholder: String, keyboardImeAction: ImeAction, keyboardType: KeyboardType, + errorText: String, modifier: Modifier = Modifier, onNextAction: () -> Unit = {}, onDoneAction: () -> Unit = {}, - visualTransformation: VisualTransformation = VisualTransformation.None + visualTransformation: VisualTransformation = VisualTransformation.None, + errorCase: Boolean = false ) { Column( modifier = modifier @@ -214,6 +225,12 @@ private fun UserInfoTextField( ) Spacer(modifier = Modifier.height(4.dp)) + + Text( + text = errorText, + style = CherrishTheme.typography.body1R14, + color = if (errorCase) CherrishTheme.colors.red700 else Color.Transparent + ) } } @@ -228,7 +245,9 @@ private fun Preview() { age = "", onAgeChange = {}, onNextClick = {}, - enabled = true + enabled = true, + nameErrorCase = false, + ageErrorCase = false ) } } diff --git a/app/src/main/java/com/cherrish/android/presentation/onboarding/information/InformationViewModel.kt b/app/src/main/java/com/cherrish/android/presentation/onboarding/information/InformationViewModel.kt index 4f10bbf14..0c3b34383 100644 --- a/app/src/main/java/com/cherrish/android/presentation/onboarding/information/InformationViewModel.kt +++ b/app/src/main/java/com/cherrish/android/presentation/onboarding/information/InformationViewModel.kt @@ -36,17 +36,23 @@ class InformationViewModel @Inject constructor( } } + fun onNameErrorCase(name: String): Boolean = name.length > 7 + fun onAgeChanged(input: String) { val filtered = input.filter { it.isDigit() } _uiState.update { it.copy(age = filtered) } } + fun onAgeErrorCase(age: String): Boolean = age.toIntOrNull() ?.let { it > 100 } ?: false + fun onNextClicked() { + val age = uiState.value.age.toIntOrNull() ?: return + viewModelScope.launch { onboardingProfileRepository.postOnboardingProfile( request = OnboardingProfileRequestModel( name = uiState.value.username, - age = uiState.value.age.toInt() + age = age ) ).onSuccess { response -> tokenManager.saveId(response.id) From 2a72d454f001cb391bc1a72af18830d2ff9a6500 Mon Sep 17 00:00:00 2001 From: sohee <144779368+sohee6989@users.noreply.github.com> Date: Sun, 18 Jan 2026 23:54:20 +0900 Subject: [PATCH 16/24] =?UTF-8?q?[CHORE/#76]=20ktlint=20=EC=B2=B4=ED=81=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/cherrish/android/data/di/ServiceModule.kt | 2 +- .../presentation/onboarding/information/InformationScreen.kt | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/com/cherrish/android/data/di/ServiceModule.kt b/app/src/main/java/com/cherrish/android/data/di/ServiceModule.kt index 710c49ce2..014d47866 100644 --- a/app/src/main/java/com/cherrish/android/data/di/ServiceModule.kt +++ b/app/src/main/java/com/cherrish/android/data/di/ServiceModule.kt @@ -6,8 +6,8 @@ import dagger.Module import dagger.Provides import dagger.hilt.InstallIn import dagger.hilt.components.SingletonComponent -import retrofit2.Retrofit import javax.inject.Singleton +import retrofit2.Retrofit @Module @InstallIn(SingletonComponent::class) diff --git a/app/src/main/java/com/cherrish/android/presentation/onboarding/information/InformationScreen.kt b/app/src/main/java/com/cherrish/android/presentation/onboarding/information/InformationScreen.kt index c3e72117a..443d5bcf8 100644 --- a/app/src/main/java/com/cherrish/android/presentation/onboarding/information/InformationScreen.kt +++ b/app/src/main/java/com/cherrish/android/presentation/onboarding/information/InformationScreen.kt @@ -112,8 +112,8 @@ private fun InformationScreen( }, keyboardType = KeyboardType.Text, errorText = "이름은 최대 7자까지 입력 가능합니다.", - errorCase = nameErrorCase, - ) + errorCase = nameErrorCase + ) Spacer(modifier = Modifier.weight(30f)) From 5c4e32dae1f16ce2fa24cd6837aecd58495ad180 Mon Sep 17 00:00:00 2001 From: sohee <144779368+sohee6989@users.noreply.github.com> Date: Mon, 19 Jan 2026 00:01:28 +0900 Subject: [PATCH 17/24] =?UTF-8?q?[CHORE/#76]=20=EB=B2=84=ED=8A=BC=20enable?= =?UTF-8?q?=20=EB=B6=84=EA=B8=B0=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../onboarding/information/InformationUiState.kt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/cherrish/android/presentation/onboarding/information/InformationUiState.kt b/app/src/main/java/com/cherrish/android/presentation/onboarding/information/InformationUiState.kt index 5df279a0f..1fb12b9d2 100644 --- a/app/src/main/java/com/cherrish/android/presentation/onboarding/information/InformationUiState.kt +++ b/app/src/main/java/com/cherrish/android/presentation/onboarding/information/InformationUiState.kt @@ -8,7 +8,10 @@ data class InformationUiState( val age: String = "" ) { val buttonEnabled: Boolean - get() = username.isNotBlank() && age.toIntOrNull()?.let { it > 0 } == true + get() { + val ageInt = age.toIntOrNull() ?: return false + return username.isNotBlank() && age.toIntOrNull()?.let { it > 0 } == true && ageInt in 1..100 && username.length <= 7 + } } sealed interface InformationSideEffect { From 1eb0debaede269ec0ce4d23d6568b59e06f0a3ca Mon Sep 17 00:00:00 2001 From: sohee <144779368+sohee6989@users.noreply.github.com> Date: Mon, 19 Jan 2026 00:02:17 +0900 Subject: [PATCH 18/24] =?UTF-8?q?[CHORE/#76]=20ktlint=20=EC=B2=B4=ED=81=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../presentation/onboarding/information/InformationUiState.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/cherrish/android/presentation/onboarding/information/InformationUiState.kt b/app/src/main/java/com/cherrish/android/presentation/onboarding/information/InformationUiState.kt index 1fb12b9d2..53fc9dbb5 100644 --- a/app/src/main/java/com/cherrish/android/presentation/onboarding/information/InformationUiState.kt +++ b/app/src/main/java/com/cherrish/android/presentation/onboarding/information/InformationUiState.kt @@ -10,7 +10,8 @@ data class InformationUiState( val buttonEnabled: Boolean get() { val ageInt = age.toIntOrNull() ?: return false - return username.isNotBlank() && age.toIntOrNull()?.let { it > 0 } == true && ageInt in 1..100 && username.length <= 7 + return username.isNotBlank() && age.toIntOrNull()?.let { it > 0 } == true && + ageInt in 1..100 && username.length <= 7 } } From 86f78c8c38e6765f77aec87f7f51eb8ced7cec2c Mon Sep 17 00:00:00 2001 From: sohee <144779368+sohee6989@users.noreply.github.com> Date: Mon, 19 Jan 2026 01:39:19 +0900 Subject: [PATCH 19/24] =?UTF-8?q?[FEAT/76]=20=EC=8A=A4=ED=94=8C=EB=9E=98?= =?UTF-8?q?=EC=8B=9C,=20=EC=98=A8=EB=B3=B4=EB=94=A9=20=ED=99=94=EB=A9=B4?= =?UTF-8?q?=20=EB=84=A4=EB=B9=84=20=EC=97=B0=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../android/presentation/main/MainAppState.kt | 7 ++++- .../android/presentation/main/MainScreen.kt | 14 +++++++-- .../onboarding/OnboardingScreen.kt | 25 ++++++++++++++-- .../onboarding/OnboardingSideEffect.kt | 5 ++++ .../onboarding/OnboardingViewModel.kt | 16 ++++++++-- ...reen.kt => OnboardingInformationScreen.kt} | 10 +++---- ...ate.kt => OnboardingInformationUiState.kt} | 0 ...l.kt => OnboardingInformationViewModel.kt} | 2 +- .../OnboardingInformationNavigator.kt} | 6 ++-- .../navigation/OnboardingNavigator.kt | 29 +++++++++++++++++++ 10 files changed, 96 insertions(+), 18 deletions(-) create mode 100644 app/src/main/java/com/cherrish/android/presentation/onboarding/OnboardingSideEffect.kt rename app/src/main/java/com/cherrish/android/presentation/onboarding/information/{InformationScreen.kt => OnboardingInformationScreen.kt} (97%) rename app/src/main/java/com/cherrish/android/presentation/onboarding/information/{InformationUiState.kt => OnboardingInformationUiState.kt} (100%) rename app/src/main/java/com/cherrish/android/presentation/onboarding/information/{InformationViewModel.kt => OnboardingInformationViewModel.kt} (97%) rename app/src/main/java/com/cherrish/android/presentation/onboarding/{information/navigation/InformationNavigator.kt => navigation/OnboardingInformationNavigator.kt} (87%) create mode 100644 app/src/main/java/com/cherrish/android/presentation/onboarding/navigation/OnboardingNavigator.kt diff --git a/app/src/main/java/com/cherrish/android/presentation/main/MainAppState.kt b/app/src/main/java/com/cherrish/android/presentation/main/MainAppState.kt index 80ca967a5..6f8d0f65f 100644 --- a/app/src/main/java/com/cherrish/android/presentation/main/MainAppState.kt +++ b/app/src/main/java/com/cherrish/android/presentation/main/MainAppState.kt @@ -13,7 +13,8 @@ import com.cherrish.android.presentation.calendar.navigation.navigateToCalendar import com.cherrish.android.presentation.challenge.navigation.navigateToChallenge import com.cherrish.android.presentation.home.navigation.navigateToHome import com.cherrish.android.presentation.mypage.navigation.navigateToMyPage -import com.cherrish.android.presentation.onboarding.information.navigation.navigateToOnboardingInformation +import com.cherrish.android.presentation.onboarding.navigation.navigateToOnboarding +import com.cherrish.android.presentation.onboarding.navigation.navigateToOnboardingInformation import com.cherrish.android.presentation.splash.navigation.Splash import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.SharingStarted @@ -80,6 +81,10 @@ class MainAppState( } } + fun navigateToOnboarding(navOptions: NavOptions) { + navController.navigateToOnboarding(navOptions) + } + fun navigateToOnboardingInformation(navOptions: NavOptions) { navController.navigateToOnboardingInformation(navOptions) } diff --git a/app/src/main/java/com/cherrish/android/presentation/main/MainScreen.kt b/app/src/main/java/com/cherrish/android/presentation/main/MainScreen.kt index d5be5f6d1..441430174 100644 --- a/app/src/main/java/com/cherrish/android/presentation/main/MainScreen.kt +++ b/app/src/main/java/com/cherrish/android/presentation/main/MainScreen.kt @@ -13,7 +13,8 @@ import com.cherrish.android.presentation.challenge.navigation.challengeNavGraph import com.cherrish.android.presentation.home.navigation.homeNavGraph import com.cherrish.android.presentation.main.component.MainBottomBar import com.cherrish.android.presentation.mypage.navigation.myPageNavGraph -import com.cherrish.android.presentation.onboarding.information.navigation.onboardingInformationNavGraph +import com.cherrish.android.presentation.onboarding.navigation.onboardingInformationNavGraph +import com.cherrish.android.presentation.onboarding.navigation.onboardingNavGraph import com.cherrish.android.presentation.splash.navigation.splashNavGraph import kotlinx.collections.immutable.toPersistentList @@ -54,10 +55,19 @@ fun MainScreen( startDestination = appState.startDestination ) { splashNavGraph( - navigateToOnboarding = {}, // TODO: 로직 넣어서 바꿀 예정 + navigateToOnboarding = { + appState.navigateToOnboarding(clearStackNavOptions) + }, paddingValues = innerPadding ) + onboardingNavGraph( + paddingValues = innerPadding, + navigateToOnboardingInformation = { + appState.navigateToOnboardingInformation(clearStackNavOptions) + } + ) + onboardingInformationNavGraph( paddingValues = innerPadding, navigateToHome = { diff --git a/app/src/main/java/com/cherrish/android/presentation/onboarding/OnboardingScreen.kt b/app/src/main/java/com/cherrish/android/presentation/onboarding/OnboardingScreen.kt index 64b9e8d00..cea3198dc 100644 --- a/app/src/main/java/com/cherrish/android/presentation/onboarding/OnboardingScreen.kt +++ b/app/src/main/java/com/cherrish/android/presentation/onboarding/OnboardingScreen.kt @@ -5,11 +5,13 @@ import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.wrapContentWidth @@ -61,16 +63,29 @@ import kotlinx.coroutines.android.awaitFrame @Composable fun OnboardingRoute( + paddingValues: PaddingValues, + navigateToOnboardingInformation: () -> Unit, viewModel: OnboardingViewModel = hiltViewModel() ) { + LaunchedEffect(Unit) { + viewModel.sideEffect.collect { sideEffect -> + when (sideEffect) { + OnboardingSideEffect.NavigateToOnboardingInformation -> { + navigateToOnboardingInformation() + } + } + } + } OnboardingScreen( - onCancelClick = viewModel::onCancelClick, - onNextClick = viewModel::onNextClick + paddingValues = paddingValues, + onCancelClick = viewModel::onClick, + onNextClick = viewModel::onClick ) } @Composable private fun OnboardingScreen( + paddingValues: PaddingValues, onCancelClick: () -> Unit, onNextClick: () -> Unit, modifier: Modifier = Modifier @@ -93,7 +108,9 @@ private fun OnboardingScreen( ) ) { Column( - modifier = Modifier.fillMaxSize() + modifier = Modifier + .fillMaxSize() + .padding(paddingValues) ) { Spacer(modifier = Modifier.height(54.dp)) @@ -140,6 +157,7 @@ private fun OnboardingScreen( modifier = Modifier .fillMaxWidth() .padding(horizontal = 24.dp) + .navigationBarsPadding() .graphicsLayer { alpha = if (showButton) 1f else 0f } @@ -470,6 +488,7 @@ private fun Preview() { modifier = Modifier.fillMaxSize() ) { OnboardingScreen( + paddingValues = PaddingValues(), onCancelClick = {}, onNextClick = {} ) diff --git a/app/src/main/java/com/cherrish/android/presentation/onboarding/OnboardingSideEffect.kt b/app/src/main/java/com/cherrish/android/presentation/onboarding/OnboardingSideEffect.kt new file mode 100644 index 000000000..3f42f4ffc --- /dev/null +++ b/app/src/main/java/com/cherrish/android/presentation/onboarding/OnboardingSideEffect.kt @@ -0,0 +1,5 @@ +package com.cherrish.android.presentation.onboarding + +sealed interface OnboardingSideEffect { + data object NavigateToOnboardingInformation : OnboardingSideEffect +} diff --git a/app/src/main/java/com/cherrish/android/presentation/onboarding/OnboardingViewModel.kt b/app/src/main/java/com/cherrish/android/presentation/onboarding/OnboardingViewModel.kt index d758d826e..36921aa5e 100644 --- a/app/src/main/java/com/cherrish/android/presentation/onboarding/OnboardingViewModel.kt +++ b/app/src/main/java/com/cherrish/android/presentation/onboarding/OnboardingViewModel.kt @@ -1,15 +1,25 @@ package com.cherrish.android.presentation.onboarding import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope import dagger.hilt.android.lifecycle.HiltViewModel import javax.inject.Inject +import kotlinx.coroutines.flow.MutableSharedFlow +import kotlinx.coroutines.flow.SharedFlow +import kotlinx.coroutines.flow.asSharedFlow +import kotlinx.coroutines.launch @HiltViewModel class OnboardingViewModel @Inject constructor() : ViewModel() { - fun onCancelClick() { - } + private val _sideEffect = MutableSharedFlow() + val sideEffect: SharedFlow = _sideEffect.asSharedFlow() - fun onNextClick() { + fun onClick() { + viewModelScope.launch { + _sideEffect.emit( + OnboardingSideEffect.NavigateToOnboardingInformation + ) + } } } diff --git a/app/src/main/java/com/cherrish/android/presentation/onboarding/information/InformationScreen.kt b/app/src/main/java/com/cherrish/android/presentation/onboarding/information/OnboardingInformationScreen.kt similarity index 97% rename from app/src/main/java/com/cherrish/android/presentation/onboarding/information/InformationScreen.kt rename to app/src/main/java/com/cherrish/android/presentation/onboarding/information/OnboardingInformationScreen.kt index 443d5bcf8..51800fc73 100644 --- a/app/src/main/java/com/cherrish/android/presentation/onboarding/information/InformationScreen.kt +++ b/app/src/main/java/com/cherrish/android/presentation/onboarding/information/OnboardingInformationScreen.kt @@ -40,10 +40,10 @@ import com.cherrish.android.presentation.onboarding.information.extension.AgeSuf import kotlinx.coroutines.flow.collectLatest @Composable -fun InformationRoute( +fun OnboardingInformationRoute( paddingValues: PaddingValues, navigateToHome: () -> Unit, - viewModel: InformationViewModel = hiltViewModel() + viewModel: OnboardingInformationViewModel = hiltViewModel() ) { val uiState by viewModel.uiState.collectAsStateWithLifecycle() @@ -55,7 +55,7 @@ fun InformationRoute( } } - InformationScreen( + OnboardingInformationScreen( paddingValues = paddingValues, username = uiState.username, onNameChange = viewModel::onNameChanged, @@ -69,7 +69,7 @@ fun InformationRoute( } @Composable -private fun InformationScreen( +private fun OnboardingInformationScreen( paddingValues: PaddingValues, username: String, onNameChange: (String) -> Unit, @@ -238,7 +238,7 @@ private fun UserInfoTextField( @Composable private fun Preview() { CherrishTheme { - InformationScreen( + OnboardingInformationScreen( paddingValues = PaddingValues(), username = "", onNameChange = {}, diff --git a/app/src/main/java/com/cherrish/android/presentation/onboarding/information/InformationUiState.kt b/app/src/main/java/com/cherrish/android/presentation/onboarding/information/OnboardingInformationUiState.kt similarity index 100% rename from app/src/main/java/com/cherrish/android/presentation/onboarding/information/InformationUiState.kt rename to app/src/main/java/com/cherrish/android/presentation/onboarding/information/OnboardingInformationUiState.kt diff --git a/app/src/main/java/com/cherrish/android/presentation/onboarding/information/InformationViewModel.kt b/app/src/main/java/com/cherrish/android/presentation/onboarding/information/OnboardingInformationViewModel.kt similarity index 97% rename from app/src/main/java/com/cherrish/android/presentation/onboarding/information/InformationViewModel.kt rename to app/src/main/java/com/cherrish/android/presentation/onboarding/information/OnboardingInformationViewModel.kt index 0c3b34383..a5d517364 100644 --- a/app/src/main/java/com/cherrish/android/presentation/onboarding/information/InformationViewModel.kt +++ b/app/src/main/java/com/cherrish/android/presentation/onboarding/information/OnboardingInformationViewModel.kt @@ -18,7 +18,7 @@ import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch @HiltViewModel -class InformationViewModel @Inject constructor( +class OnboardingInformationViewModel @Inject constructor( private val onboardingProfileRepository: OnboardingProfileRepository, private val tokenManager: TokenManager ) : ViewModel() { diff --git a/app/src/main/java/com/cherrish/android/presentation/onboarding/information/navigation/InformationNavigator.kt b/app/src/main/java/com/cherrish/android/presentation/onboarding/navigation/OnboardingInformationNavigator.kt similarity index 87% rename from app/src/main/java/com/cherrish/android/presentation/onboarding/information/navigation/InformationNavigator.kt rename to app/src/main/java/com/cherrish/android/presentation/onboarding/navigation/OnboardingInformationNavigator.kt index 7a840dd9a..1a697414b 100644 --- a/app/src/main/java/com/cherrish/android/presentation/onboarding/information/navigation/InformationNavigator.kt +++ b/app/src/main/java/com/cherrish/android/presentation/onboarding/navigation/OnboardingInformationNavigator.kt @@ -1,4 +1,4 @@ -package com.cherrish.android.presentation.onboarding.information.navigation +package com.cherrish.android.presentation.onboarding.navigation import androidx.compose.foundation.layout.PaddingValues import androidx.navigation.NavController @@ -6,7 +6,7 @@ import androidx.navigation.NavGraphBuilder import androidx.navigation.NavOptions import androidx.navigation.compose.composable import com.cherrish.android.core.common.navigation.Route -import com.cherrish.android.presentation.onboarding.information.InformationRoute +import com.cherrish.android.presentation.onboarding.information.OnboardingInformationRoute import kotlinx.serialization.Serializable @Serializable @@ -21,7 +21,7 @@ fun NavGraphBuilder.onboardingInformationNavGraph( navigateToHome: () -> Unit ) { composable { - InformationRoute( + OnboardingInformationRoute( paddingValues = paddingValues, navigateToHome = navigateToHome ) diff --git a/app/src/main/java/com/cherrish/android/presentation/onboarding/navigation/OnboardingNavigator.kt b/app/src/main/java/com/cherrish/android/presentation/onboarding/navigation/OnboardingNavigator.kt new file mode 100644 index 000000000..7633f8d1b --- /dev/null +++ b/app/src/main/java/com/cherrish/android/presentation/onboarding/navigation/OnboardingNavigator.kt @@ -0,0 +1,29 @@ +package com.cherrish.android.presentation.onboarding.navigation + +import androidx.compose.foundation.layout.PaddingValues +import androidx.navigation.NavController +import androidx.navigation.NavGraphBuilder +import androidx.navigation.NavOptions +import androidx.navigation.compose.composable +import com.cherrish.android.core.common.navigation.Route +import com.cherrish.android.presentation.onboarding.OnboardingRoute +import kotlinx.serialization.Serializable + +@Serializable +data object Onboarding : Route + +fun NavController.navigateToOnboarding(navOptions: NavOptions? = null) { + navigate(route = Onboarding, navOptions = navOptions) +} + +fun NavGraphBuilder.onboardingNavGraph( + paddingValues: PaddingValues, + navigateToOnboardingInformation: () -> Unit +) { + composable { + OnboardingRoute( + paddingValues = paddingValues, + navigateToOnboardingInformation = navigateToOnboardingInformation + ) + } +} From 1904cea86b705d439805fafdd8cc318886b77d14 Mon Sep 17 00:00:00 2001 From: sohee <144779368+sohee6989@users.noreply.github.com> Date: Mon, 19 Jan 2026 23:58:42 +0900 Subject: [PATCH 20/24] =?UTF-8?q?[CHORE/#85]=20=EC=BD=94=EB=93=9C=EB=A6=AC?= =?UTF-8?q?=EB=B7=B0=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/OnboardingProfileService.kt | 2 +- .../android/presentation/main/MainAppState.kt | 17 +++++++++++--- .../android/presentation/main/MainScreen.kt | 23 +++---------------- .../onboarding/OnboardingScreen.kt | 5 ++-- .../OnboardingInformationScreen.kt | 11 ++++----- 5 files changed, 24 insertions(+), 34 deletions(-) diff --git a/app/src/main/java/com/cherrish/android/data/remote/service/OnboardingProfileService.kt b/app/src/main/java/com/cherrish/android/data/remote/service/OnboardingProfileService.kt index 1ac217c7a..ec32a1451 100644 --- a/app/src/main/java/com/cherrish/android/data/remote/service/OnboardingProfileService.kt +++ b/app/src/main/java/com/cherrish/android/data/remote/service/OnboardingProfileService.kt @@ -7,7 +7,7 @@ import retrofit2.http.Body import retrofit2.http.POST interface OnboardingProfileService { - @POST("/api/onboarding/profiles") + @POST("api/onboarding/profiles") suspend fun postOnboardingProfile( @Body request: OnboardingProfileRequestDto ): BaseResponse diff --git a/app/src/main/java/com/cherrish/android/presentation/main/MainAppState.kt b/app/src/main/java/com/cherrish/android/presentation/main/MainAppState.kt index 6f8d0f65f..b5ecd850e 100644 --- a/app/src/main/java/com/cherrish/android/presentation/main/MainAppState.kt +++ b/app/src/main/java/com/cherrish/android/presentation/main/MainAppState.kt @@ -29,6 +29,17 @@ class MainAppState( ) { val startDestination = Splash + private val clearStackNavOptions = navOptions { + popUpTo(0) { inclusive = true } + launchSingleTop = true + restoreState = false + } + + private val keepStackNavOptions = navOptions { + launchSingleTop = true + restoreState = true + } + private val currentDestination = navController.currentBackStackEntryFlow .map { it.destination } .stateIn( @@ -81,15 +92,15 @@ class MainAppState( } } - fun navigateToOnboarding(navOptions: NavOptions) { + fun navigateToOnboarding(navOptions: NavOptions? = clearStackNavOptions) { navController.navigateToOnboarding(navOptions) } - fun navigateToOnboardingInformation(navOptions: NavOptions) { + fun navigateToOnboardingInformation(navOptions: NavOptions? = clearStackNavOptions) { navController.navigateToOnboardingInformation(navOptions) } - fun navigateToHome(navOptions: NavOptions) { + fun navigateToHome(navOptions: NavOptions? = clearStackNavOptions) { navController.navigateToHome(navOptions) } } diff --git a/app/src/main/java/com/cherrish/android/presentation/main/MainScreen.kt b/app/src/main/java/com/cherrish/android/presentation/main/MainScreen.kt index 441430174..2050f00ce 100644 --- a/app/src/main/java/com/cherrish/android/presentation/main/MainScreen.kt +++ b/app/src/main/java/com/cherrish/android/presentation/main/MainScreen.kt @@ -7,7 +7,6 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.navigation.compose.NavHost -import androidx.navigation.navOptions import com.cherrish.android.presentation.calendar.navigation.calendarNavGraph import com.cherrish.android.presentation.challenge.navigation.challengeNavGraph import com.cherrish.android.presentation.home.navigation.homeNavGraph @@ -25,16 +24,6 @@ fun MainScreen( val isBottomBarVisible by appState.isBottomBarVisible.collectAsStateWithLifecycle() val currentTab by appState.currentTab.collectAsStateWithLifecycle() - val clearStackNavOptions = navOptions { - popUpTo(0) { inclusive = true } - launchSingleTop = true - restoreState = false - } - - val keepStackNavOptions = navOptions { - launchSingleTop = true - restoreState = true - } Scaffold( bottomBar = { @@ -55,24 +44,18 @@ fun MainScreen( startDestination = appState.startDestination ) { splashNavGraph( - navigateToOnboarding = { - appState.navigateToOnboarding(clearStackNavOptions) - }, + navigateToOnboarding = appState::navigateToOnboarding, paddingValues = innerPadding ) onboardingNavGraph( paddingValues = innerPadding, - navigateToOnboardingInformation = { - appState.navigateToOnboardingInformation(clearStackNavOptions) - } + navigateToOnboardingInformation = appState::navigateToOnboardingInformation ) onboardingInformationNavGraph( paddingValues = innerPadding, - navigateToHome = { - appState.navigateToHome(clearStackNavOptions) - } + navigateToHome = appState::navigateToHome ) homeNavGraph(paddingValues = innerPadding) diff --git a/app/src/main/java/com/cherrish/android/presentation/onboarding/OnboardingScreen.kt b/app/src/main/java/com/cherrish/android/presentation/onboarding/OnboardingScreen.kt index cea3198dc..4689e0942 100644 --- a/app/src/main/java/com/cherrish/android/presentation/onboarding/OnboardingScreen.kt +++ b/app/src/main/java/com/cherrish/android/presentation/onboarding/OnboardingScreen.kt @@ -52,6 +52,7 @@ import androidx.constraintlayout.compose.ConstraintLayout import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.viewmodel.compose.viewModel import com.cherrish.android.R +import com.cherrish.android.core.common.extension.collectLatestSideEffect import com.cherrish.android.core.common.extension.noRippleClickable import com.cherrish.android.core.designsystem.component.button.CherrishButton import com.cherrish.android.core.designsystem.theme.CherrishTheme @@ -67,14 +68,12 @@ fun OnboardingRoute( navigateToOnboardingInformation: () -> Unit, viewModel: OnboardingViewModel = hiltViewModel() ) { - LaunchedEffect(Unit) { - viewModel.sideEffect.collect { sideEffect -> + viewModel.sideEffect.collectLatestSideEffect { sideEffect -> when (sideEffect) { OnboardingSideEffect.NavigateToOnboardingInformation -> { navigateToOnboardingInformation() } } - } } OnboardingScreen( paddingValues = paddingValues, diff --git a/app/src/main/java/com/cherrish/android/presentation/onboarding/information/OnboardingInformationScreen.kt b/app/src/main/java/com/cherrish/android/presentation/onboarding/information/OnboardingInformationScreen.kt index 51800fc73..acd8a7a7c 100644 --- a/app/src/main/java/com/cherrish/android/presentation/onboarding/information/OnboardingInformationScreen.kt +++ b/app/src/main/java/com/cherrish/android/presentation/onboarding/information/OnboardingInformationScreen.kt @@ -12,7 +12,6 @@ import androidx.compose.foundation.layout.padding import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.Text import androidx.compose.runtime.Composable -import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember @@ -33,11 +32,11 @@ import androidx.hilt.navigation.compose.hiltViewModel import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.cherrish.android.core.common.extension.addFocusCleaner import com.cherrish.android.core.common.extension.advancedImePadding +import com.cherrish.android.core.common.extension.collectLatestSideEffect import com.cherrish.android.core.designsystem.component.button.CherrishButton import com.cherrish.android.core.designsystem.component.textfield.CherrishTextField import com.cherrish.android.core.designsystem.theme.CherrishTheme import com.cherrish.android.presentation.onboarding.information.extension.AgeSuffixTransformation -import kotlinx.coroutines.flow.collectLatest @Composable fun OnboardingInformationRoute( @@ -47,11 +46,9 @@ fun OnboardingInformationRoute( ) { val uiState by viewModel.uiState.collectAsStateWithLifecycle() - LaunchedEffect(Unit) { - viewModel.sideEffect.collectLatest { sideEffect -> - when (sideEffect) { - InformationSideEffect.NavigateToHome -> navigateToHome() - } + viewModel.sideEffect.collectLatestSideEffect { sideEffect -> + when (sideEffect) { + InformationSideEffect.NavigateToHome -> navigateToHome() } } From 57542434b4bc437aeedb5c102c365dc87e956a59 Mon Sep 17 00:00:00 2001 From: sohee <144779368+sohee6989@users.noreply.github.com> Date: Tue, 20 Jan 2026 00:00:22 +0900 Subject: [PATCH 21/24] =?UTF-8?q?[CHORE/#76]=20ktlint=20=EC=B2=B4=ED=81=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cherrish/android/presentation/main/MainScreen.kt | 1 - .../presentation/onboarding/OnboardingScreen.kt | 10 +++++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/com/cherrish/android/presentation/main/MainScreen.kt b/app/src/main/java/com/cherrish/android/presentation/main/MainScreen.kt index 1190344cc..5ad6df56e 100644 --- a/app/src/main/java/com/cherrish/android/presentation/main/MainScreen.kt +++ b/app/src/main/java/com/cherrish/android/presentation/main/MainScreen.kt @@ -24,7 +24,6 @@ fun MainScreen( val isBottomBarVisible by appState.isBottomBarVisible.collectAsStateWithLifecycle() val currentTab by appState.currentTab.collectAsStateWithLifecycle() - Scaffold( bottomBar = { MainBottomBar( diff --git a/app/src/main/java/com/cherrish/android/presentation/onboarding/OnboardingScreen.kt b/app/src/main/java/com/cherrish/android/presentation/onboarding/OnboardingScreen.kt index 4689e0942..cab2dc74a 100644 --- a/app/src/main/java/com/cherrish/android/presentation/onboarding/OnboardingScreen.kt +++ b/app/src/main/java/com/cherrish/android/presentation/onboarding/OnboardingScreen.kt @@ -68,12 +68,12 @@ fun OnboardingRoute( navigateToOnboardingInformation: () -> Unit, viewModel: OnboardingViewModel = hiltViewModel() ) { - viewModel.sideEffect.collectLatestSideEffect { sideEffect -> - when (sideEffect) { - OnboardingSideEffect.NavigateToOnboardingInformation -> { - navigateToOnboardingInformation() - } + viewModel.sideEffect.collectLatestSideEffect { sideEffect -> + when (sideEffect) { + OnboardingSideEffect.NavigateToOnboardingInformation -> { + navigateToOnboardingInformation() } + } } OnboardingScreen( paddingValues = paddingValues, From 671d003d167efe86f350430884055ef4454c562a Mon Sep 17 00:00:00 2001 From: sohee <144779368+sohee6989@users.noreply.github.com> Date: Tue, 20 Jan 2026 00:04:20 +0900 Subject: [PATCH 22/24] =?UTF-8?q?[CHORE/#76]=20=EC=9E=84=ED=8F=AC=ED=8A=B8?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/cherrish/android/presentation/main/MainAppState.kt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/src/main/java/com/cherrish/android/presentation/main/MainAppState.kt b/app/src/main/java/com/cherrish/android/presentation/main/MainAppState.kt index ca077429a..63d611b5b 100644 --- a/app/src/main/java/com/cherrish/android/presentation/main/MainAppState.kt +++ b/app/src/main/java/com/cherrish/android/presentation/main/MainAppState.kt @@ -6,12 +6,16 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope import androidx.navigation.NavDestination.Companion.hasRoute import androidx.navigation.NavHostController +import androidx.navigation.NavOptions import androidx.navigation.compose.rememberNavController import androidx.navigation.navOptions import com.cherrish.android.presentation.calendar.navigation.navigateToCalendar +import com.cherrish.android.presentation.calendar.navigation.navigateToProcedure import com.cherrish.android.presentation.challenge.navigation.navigateToChallenge import com.cherrish.android.presentation.home.navigation.navigateToHome import com.cherrish.android.presentation.mypage.navigation.navigateToMyPage +import com.cherrish.android.presentation.onboarding.navigation.navigateToOnboarding +import com.cherrish.android.presentation.onboarding.navigation.navigateToOnboardingInformation import com.cherrish.android.presentation.splash.navigation.Splash import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.SharingStarted From bd235c767ba472d294bc0320f636b9df7bb71793 Mon Sep 17 00:00:00 2001 From: sohee <144779368+sohee6989@users.noreply.github.com> Date: Tue, 20 Jan 2026 00:14:52 +0900 Subject: [PATCH 23/24] =?UTF-8?q?[CHORE/#76]=20=EB=9E=98=EB=B9=97=EC=9D=B4?= =?UTF-8?q?=20=EB=A6=AC=EB=B7=B0=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cherrish/android/core/common/extension/ModifierExt.kt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/com/cherrish/android/core/common/extension/ModifierExt.kt b/app/src/main/java/com/cherrish/android/core/common/extension/ModifierExt.kt index 038d8c781..1a48a91f5 100644 --- a/app/src/main/java/com/cherrish/android/core/common/extension/ModifierExt.kt +++ b/app/src/main/java/com/cherrish/android/core/common/extension/ModifierExt.kt @@ -99,10 +99,10 @@ fun Modifier.dropShadow( fun Modifier.advancedImePadding() = composed { var consumePadding by remember { mutableStateOf(0) } onGloballyPositioned { coordinates -> - consumePadding = coordinates.findRootCoordinates().size.height - - (coordinates.positionInWindow().y + coordinates.size.height).toInt().coerceAtLeast( - 0 - ) + consumePadding = (coordinates.findRootCoordinates().size.height - + (coordinates.positionInWindow().y + coordinates.size.height).toInt()).coerceAtLeast( + 0 + ) } .consumeWindowInsets( PaddingValues(bottom = with(LocalDensity.current) { consumePadding.toDp() }) From 7d2fba7a7735e7d80300fee65026c46cc8fba9d3 Mon Sep 17 00:00:00 2001 From: sohee <144779368+sohee6989@users.noreply.github.com> Date: Tue, 20 Jan 2026 00:15:29 +0900 Subject: [PATCH 24/24] =?UTF-8?q?[CHORE/#76]=20ktlint=20=EC=B2=B4=ED=81=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cherrish/android/core/common/extension/ModifierExt.kt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/cherrish/android/core/common/extension/ModifierExt.kt b/app/src/main/java/com/cherrish/android/core/common/extension/ModifierExt.kt index 1a48a91f5..353ea5bdb 100644 --- a/app/src/main/java/com/cherrish/android/core/common/extension/ModifierExt.kt +++ b/app/src/main/java/com/cherrish/android/core/common/extension/ModifierExt.kt @@ -99,8 +99,10 @@ fun Modifier.dropShadow( fun Modifier.advancedImePadding() = composed { var consumePadding by remember { mutableStateOf(0) } onGloballyPositioned { coordinates -> - consumePadding = (coordinates.findRootCoordinates().size.height - - (coordinates.positionInWindow().y + coordinates.size.height).toInt()).coerceAtLeast( + consumePadding = ( + coordinates.findRootCoordinates().size.height - + (coordinates.positionInWindow().y + coordinates.size.height).toInt() + ).coerceAtLeast( 0 ) }