From 9f70b4132e1a702af69299dd9d8606355d48cc9f Mon Sep 17 00:00:00 2001 From: chanho0908 Date: Fri, 6 Mar 2026 17:51:23 +0900 Subject: [PATCH 01/27] =?UTF-8?q?=E2=9C=A8=20Feat:=20=EC=98=A8=EB=B3=B4?= =?UTF-8?q?=EB=94=A9=20=EC=BB=A4=ED=94=8C=20=EC=97=B0=EA=B2=B0=20=ED=99=94?= =?UTF-8?q?=EB=A9=B4=20=EC=9D=BC=EB=9F=AC=EC=8A=A4=ED=8A=B8=20=EA=B5=90?= =?UTF-8?q?=EC=B2=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/res/drawable/ic_invite.xml | 450 ++++++++++++++++++ .../onboarding/couple/CoupleConnectRoute.kt | 7 +- .../main/res/drawable/img_couple_connect.xml | 183 ------- 3 files changed, 454 insertions(+), 186 deletions(-) create mode 100644 core/design-system/src/main/res/drawable/ic_invite.xml delete mode 100644 feature/onboarding/src/main/res/drawable/img_couple_connect.xml diff --git a/core/design-system/src/main/res/drawable/ic_invite.xml b/core/design-system/src/main/res/drawable/ic_invite.xml new file mode 100644 index 00000000..16c0b9df --- /dev/null +++ b/core/design-system/src/main/res/drawable/ic_invite.xml @@ -0,0 +1,450 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/feature/onboarding/src/main/java/com/twix/onboarding/couple/CoupleConnectRoute.kt b/feature/onboarding/src/main/java/com/twix/onboarding/couple/CoupleConnectRoute.kt index 51a31c09..a0b95fef 100644 --- a/feature/onboarding/src/main/java/com/twix/onboarding/couple/CoupleConnectRoute.kt +++ b/feature/onboarding/src/main/java/com/twix/onboarding/couple/CoupleConnectRoute.kt @@ -43,8 +43,9 @@ import com.twix.designsystem.theme.GrayColor import com.twix.designsystem.theme.TwixTheme import com.twix.domain.model.enums.AppTextStyle import com.twix.onboarding.OnBoardingViewModel -import com.twix.onboarding.R +import com.twix.designsystem.R import com.twix.onboarding.couple.component.ConnectButton +import com.twix.onboarding.couple.component.InvitationButton import com.twix.onboarding.couple.component.RestoreCoupleBottomSheetContent import com.twix.onboarding.model.OnBoardingIntent import com.twix.onboarding.model.OnBoardingSideEffect @@ -137,13 +138,13 @@ fun CoupleConnectScreen( Spacer(modifier = Modifier.height(11.76.dp)) Image( - imageVector = ImageVector.vectorResource(R.drawable.img_couple_connect), + imageVector = ImageVector.vectorResource(R.drawable.ic_invite), contentDescription = null, modifier = Modifier.align(Alignment.CenterHorizontally), ) Spacer(modifier = Modifier.height(47.dp)) - // InvitationButton(onClick = onClickSend) + InvitationButton(onClick = onClickSend) Spacer(modifier = Modifier.height(20.dp)) diff --git a/feature/onboarding/src/main/res/drawable/img_couple_connect.xml b/feature/onboarding/src/main/res/drawable/img_couple_connect.xml deleted file mode 100644 index b9b80ff7..00000000 --- a/feature/onboarding/src/main/res/drawable/img_couple_connect.xml +++ /dev/null @@ -1,183 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - From ae5dfa17fde5f703e10a20fff62817fc0568fc31 Mon Sep 17 00:00:00 2001 From: chanho0908 Date: Fri, 6 Mar 2026 18:00:17 +0900 Subject: [PATCH 02/27] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Refactor:=20?= =?UTF-8?q?=EC=98=A8=EB=B3=B4=EB=94=A9=20=EB=A6=AC=EC=86=8C=EC=8A=A4=20`de?= =?UTF-8?q?sign-system`=20=EB=AA=A8=EB=93=88=EB=A1=9C=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/res/drawable/ic_copy.xml | 0 .../src/main/res/drawable/ic_direct.xml | 0 .../src/main/res/values/strings.xml | 33 ++++++++++++++++ .../onboarding/couple/CoupleConnectRoute.kt | 2 +- .../couple/component/ConnectButton.kt | 2 +- .../couple/component/InvitationButton.kt | 4 +- .../RestoreCoupleBottomSheetContent.kt | 12 +++--- .../com/twix/onboarding/dday/DdayRoute.kt | 8 ++-- .../onboarding/dday/component/DDayField.kt | 5 +-- .../onboarding/invite/InviteCodeScreen.kt | 2 +- .../twix/onboarding/profile/ProfileScreen.kt | 13 +++---- .../src/main/res/values/strings.xml | 38 ------------------- 12 files changed, 56 insertions(+), 63 deletions(-) rename {feature/onboarding => core/design-system}/src/main/res/drawable/ic_copy.xml (100%) rename {feature/onboarding => core/design-system}/src/main/res/drawable/ic_direct.xml (100%) delete mode 100644 feature/onboarding/src/main/res/values/strings.xml diff --git a/feature/onboarding/src/main/res/drawable/ic_copy.xml b/core/design-system/src/main/res/drawable/ic_copy.xml similarity index 100% rename from feature/onboarding/src/main/res/drawable/ic_copy.xml rename to core/design-system/src/main/res/drawable/ic_copy.xml diff --git a/feature/onboarding/src/main/res/drawable/ic_direct.xml b/core/design-system/src/main/res/drawable/ic_direct.xml similarity index 100% rename from feature/onboarding/src/main/res/drawable/ic_direct.xml rename to core/design-system/src/main/res/drawable/ic_direct.xml diff --git a/core/design-system/src/main/res/values/strings.xml b/core/design-system/src/main/res/values/strings.xml index 67fdf85c..d675f2f1 100644 --- a/core/design-system/src/main/res/values/strings.xml +++ b/core/design-system/src/main/res/values/strings.xml @@ -160,4 +160,37 @@ 온보딩 정보를 불러오는 데 실패했습니다. 다시 시도해주세요 함께니까 멈추지 않아요.\n지금 바로 키피럽 시작하기! + + 닉네임을 입력해 주세요. + 닉네임 2~8자 + 짝꿍에게 보일\n내 이름을 입력해 주세요 + 닉네임을 입력해 주세요. + 닉네임 2~8자 + 완료 + 2자에서 8자 이내로 닉네임을 입력해주세요. + 프로필 설정 요청에 실패했습니다. + + 짝꿍과 연결하고\n함께 키피럽 시작하세요 + 초대장 보내기 + 짝꿍에게 코드를 받았다면? + 직접 + 연결하기 + 해지한 커플 복구하려면? + 아래 내용을 포함하여 문의해 주시기 바랍니다.\n고객센터 메일 - ttwixteamm@gmail.com + 본인 로그인 계정 메일 + 짝꿍의 로그인 계정 메일 + 해지 일시 + 내 조회코드 조회에 실패했습니다. + 커플 연결 요청에 실패했어요 + + 짝꿍에게 받은\n초대 코드를 써주세요 + 내 초대 코드 + 받은 코드 쓰기 + 초대 코드가 복사되었어요 + 잘못된 초대 코드입니다 + + 우리의 기념일을 등록해 주세요 + YYYY-MM-DD + 기념일 설정에 실패했습니다. + diff --git a/feature/onboarding/src/main/java/com/twix/onboarding/couple/CoupleConnectRoute.kt b/feature/onboarding/src/main/java/com/twix/onboarding/couple/CoupleConnectRoute.kt index a0b95fef..68e3bc4b 100644 --- a/feature/onboarding/src/main/java/com/twix/onboarding/couple/CoupleConnectRoute.kt +++ b/feature/onboarding/src/main/java/com/twix/onboarding/couple/CoupleConnectRoute.kt @@ -31,6 +31,7 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.core.app.NotificationManagerCompat import androidx.core.content.ContextCompat +import com.twix.designsystem.R import com.twix.designsystem.components.bottomsheet.CommonBottomSheet import com.twix.designsystem.components.bottomsheet.model.CommonBottomSheetConfig import com.twix.designsystem.components.dialog.MarketingDialog @@ -43,7 +44,6 @@ import com.twix.designsystem.theme.GrayColor import com.twix.designsystem.theme.TwixTheme import com.twix.domain.model.enums.AppTextStyle import com.twix.onboarding.OnBoardingViewModel -import com.twix.designsystem.R import com.twix.onboarding.couple.component.ConnectButton import com.twix.onboarding.couple.component.InvitationButton import com.twix.onboarding.couple.component.RestoreCoupleBottomSheetContent diff --git a/feature/onboarding/src/main/java/com/twix/onboarding/couple/component/ConnectButton.kt b/feature/onboarding/src/main/java/com/twix/onboarding/couple/component/ConnectButton.kt index 0c7b1a2d..961bbdf6 100644 --- a/feature/onboarding/src/main/java/com/twix/onboarding/couple/component/ConnectButton.kt +++ b/feature/onboarding/src/main/java/com/twix/onboarding/couple/component/ConnectButton.kt @@ -23,13 +23,13 @@ import androidx.compose.ui.text.font.FontWeight.Companion.ExtraBold import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp +import com.twix.designsystem.R import com.twix.designsystem.components.text.AppText import com.twix.designsystem.theme.CommonColor import com.twix.designsystem.theme.GrayColor import com.twix.designsystem.theme.NanumSquareNeoFamily import com.twix.designsystem.theme.TwixTheme import com.twix.domain.model.enums.AppTextStyle -import com.twix.onboarding.R import com.twix.ui.extension.noRippleClickable @Composable diff --git a/feature/onboarding/src/main/java/com/twix/onboarding/couple/component/InvitationButton.kt b/feature/onboarding/src/main/java/com/twix/onboarding/couple/component/InvitationButton.kt index a0d4a8ff..752fe5af 100644 --- a/feature/onboarding/src/main/java/com/twix/onboarding/couple/component/InvitationButton.kt +++ b/feature/onboarding/src/main/java/com/twix/onboarding/couple/component/InvitationButton.kt @@ -17,8 +17,8 @@ import com.twix.designsystem.theme.CommonColor import com.twix.designsystem.theme.GrayColor import com.twix.designsystem.theme.TwixTheme import com.twix.domain.model.enums.AppTextStyle -import com.twix.onboarding.R import com.twix.ui.extension.noRippleClickable +import com.twix.designsystem.R as DesR @Composable internal fun InvitationButton( @@ -36,7 +36,7 @@ internal fun InvitationButton( contentAlignment = Alignment.Center, ) { AppText( - text = stringResource(R.string.onboarding_couple_connect_send_invitation), + text = stringResource(DesR.string.onboarding_couple_connect_send_invitation), style = AppTextStyle.T2, color = CommonColor.White, ) diff --git a/feature/onboarding/src/main/java/com/twix/onboarding/couple/component/RestoreCoupleBottomSheetContent.kt b/feature/onboarding/src/main/java/com/twix/onboarding/couple/component/RestoreCoupleBottomSheetContent.kt index d2d4de61..009aa122 100644 --- a/feature/onboarding/src/main/java/com/twix/onboarding/couple/component/RestoreCoupleBottomSheetContent.kt +++ b/feature/onboarding/src/main/java/com/twix/onboarding/couple/component/RestoreCoupleBottomSheetContent.kt @@ -24,7 +24,7 @@ import com.twix.designsystem.components.text.AppText import com.twix.designsystem.theme.GrayColor import com.twix.designsystem.theme.TwixTheme import com.twix.domain.model.enums.AppTextStyle -import com.twix.onboarding.R +import com.twix.designsystem.R as DesR private val RestoreBgColor = Color(0xFFF6F7F7) private val BulletColor = Color(0xFF999999) @@ -39,13 +39,13 @@ internal fun RestoreCoupleBottomSheetContent() { verticalArrangement = Arrangement.spacedBy(18.dp), ) { AppText( - text = stringResource(R.string.onboarding_couple_restore), + text = stringResource(DesR.string.onboarding_couple_restore), style = AppTextStyle.T1, color = GrayColor.C500, ) AppText( - text = stringResource(R.string.onboarding_couple_restore_bottom_sheet_content), + text = stringResource(DesR.string.onboarding_couple_restore_bottom_sheet_content), style = AppTextStyle.B2, color = GrayColor.C400, ) @@ -58,9 +58,9 @@ internal fun RestoreCoupleBottomSheetContent() { .background(RestoreBgColor, RoundedCornerShape(12.dp)), verticalArrangement = Arrangement.Center, ) { - BulletItem(stringResource(R.string.onboarding_couple_restore_content_my_email)) - BulletItem(stringResource(R.string.onboarding_couple_restore_content_partner_email)) - BulletItem(stringResource(R.string.onboarding_couple_restore_content_restore_date)) + BulletItem(stringResource(DesR.string.onboarding_couple_restore_content_my_email)) + BulletItem(stringResource(DesR.string.onboarding_couple_restore_content_partner_email)) + BulletItem(stringResource(DesR.string.onboarding_couple_restore_content_restore_date)) } } } diff --git a/feature/onboarding/src/main/java/com/twix/onboarding/dday/DdayRoute.kt b/feature/onboarding/src/main/java/com/twix/onboarding/dday/DdayRoute.kt index 02cb7871..b48ea38f 100644 --- a/feature/onboarding/src/main/java/com/twix/onboarding/dday/DdayRoute.kt +++ b/feature/onboarding/src/main/java/com/twix/onboarding/dday/DdayRoute.kt @@ -31,7 +31,6 @@ import com.twix.designsystem.theme.GrayColor import com.twix.designsystem.theme.TwixTheme import com.twix.domain.model.enums.AppTextStyle import com.twix.onboarding.OnBoardingViewModel -import com.twix.onboarding.R import com.twix.onboarding.dday.component.DDayField import com.twix.onboarding.dday.component.DdayTopBar import com.twix.onboarding.model.OnBoardingIntent @@ -39,6 +38,7 @@ import com.twix.onboarding.model.OnBoardingSideEffect import com.twix.ui.base.ObserveAsEvents import org.koin.compose.koinInject import java.time.LocalDate +import com.twix.designsystem.R as DesR @Composable fun DdayRoute( @@ -50,7 +50,7 @@ fun DdayRoute( val uiState by viewModel.uiState.collectAsStateWithLifecycle() var showCalendarBottomSheet by remember { mutableStateOf(false) } - val ddaySetUpFailMessage = stringResource(R.string.onboarding_dday_setup_fail) + val ddaySetUpFailMessage = stringResource(DesR.string.onboarding_dday_setup_fail) ObserveAsEvents(viewModel.sideEffect) { sideEffect -> when (sideEffect) { OnBoardingSideEffect.DdaySetting.NavigateToHome -> navigateToHome() @@ -103,7 +103,7 @@ fun DdayScreen( Spacer(modifier = Modifier.height(8.dp)) AppText( - text = stringResource(R.string.onboarding_dday_plz_set_dday), + text = stringResource(DesR.string.onboarding_dday_plz_set_dday), style = AppTextStyle.H3, color = GrayColor.C500, modifier = Modifier.padding(start = 24.dp), @@ -119,7 +119,7 @@ fun DdayScreen( Spacer(Modifier.weight(1f)) AppButton( - text = stringResource(R.string.onboarding_profile_button_title), + text = stringResource(DesR.string.onboarding_profile_button_title), onClick = { onCompleted() }, backgroundColor = if (uiModel.isSelected) GrayColor.C500 else GrayColor.C100, textColor = if (uiModel.isSelected) CommonColor.White else GrayColor.C300, diff --git a/feature/onboarding/src/main/java/com/twix/onboarding/dday/component/DDayField.kt b/feature/onboarding/src/main/java/com/twix/onboarding/dday/component/DDayField.kt index 131d6164..69180cb4 100644 --- a/feature/onboarding/src/main/java/com/twix/onboarding/dday/component/DDayField.kt +++ b/feature/onboarding/src/main/java/com/twix/onboarding/dday/component/DDayField.kt @@ -16,15 +16,14 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.vectorResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp +import com.twix.designsystem.R import com.twix.designsystem.components.text.AppText import com.twix.designsystem.theme.GrayColor import com.twix.designsystem.theme.TwixTheme import com.twix.domain.model.enums.AppTextStyle -import com.twix.onboarding.R import com.twix.onboarding.dday.DdayUiModel import com.twix.ui.extension.noRippleClickable import java.time.LocalDate -import com.twix.designsystem.R as DesR @Composable internal fun DDayField( @@ -59,7 +58,7 @@ internal fun DDayField( ) Image( - imageVector = ImageVector.vectorResource(DesR.drawable.ic_calendar), + imageVector = ImageVector.vectorResource(R.drawable.ic_calendar), contentDescription = null, modifier = Modifier diff --git a/feature/onboarding/src/main/java/com/twix/onboarding/invite/InviteCodeScreen.kt b/feature/onboarding/src/main/java/com/twix/onboarding/invite/InviteCodeScreen.kt index fd000099..0bb18708 100644 --- a/feature/onboarding/src/main/java/com/twix/onboarding/invite/InviteCodeScreen.kt +++ b/feature/onboarding/src/main/java/com/twix/onboarding/invite/InviteCodeScreen.kt @@ -38,6 +38,7 @@ import androidx.compose.ui.res.vectorResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle +import com.twix.designsystem.R import com.twix.designsystem.components.button.AppButton import com.twix.designsystem.components.text.AppText import com.twix.designsystem.components.toast.ToastManager @@ -48,7 +49,6 @@ import com.twix.designsystem.theme.GrayColor import com.twix.designsystem.theme.TwixTheme import com.twix.domain.model.enums.AppTextStyle import com.twix.onboarding.OnBoardingViewModel -import com.twix.onboarding.R import com.twix.onboarding.invite.component.InviteCodeTextField import com.twix.onboarding.model.OnBoardingIntent import com.twix.onboarding.model.OnBoardingSideEffect diff --git a/feature/onboarding/src/main/java/com/twix/onboarding/profile/ProfileScreen.kt b/feature/onboarding/src/main/java/com/twix/onboarding/profile/ProfileScreen.kt index ff6c037f..504d0e9d 100644 --- a/feature/onboarding/src/main/java/com/twix/onboarding/profile/ProfileScreen.kt +++ b/feature/onboarding/src/main/java/com/twix/onboarding/profile/ProfileScreen.kt @@ -38,7 +38,6 @@ import com.twix.designsystem.theme.SystemColor import com.twix.designsystem.theme.TwixTheme import com.twix.domain.model.enums.AppTextStyle import com.twix.onboarding.OnBoardingViewModel -import com.twix.onboarding.R import com.twix.onboarding.model.OnBoardingIntent import com.twix.onboarding.model.OnBoardingSideEffect import com.twix.ui.base.ObserveAsEvents @@ -56,9 +55,9 @@ fun ProfileRoute( val uiState by viewModel.uiState.collectAsStateWithLifecycle() val notValidNickNameMessage = - stringResource(R.string.onboarding_profile_invalid_name_length_toast) + stringResource(DesR.string.onboarding_profile_invalid_name_length_toast) - val profileSetupFailMessage = stringResource(R.string.onboarding_profile_setup_fail) + val profileSetupFailMessage = stringResource(DesR.string.onboarding_profile_setup_fail) ObserveAsEvents(viewModel.sideEffect) { sideEffect -> when (sideEffect) { @@ -117,7 +116,7 @@ private fun ProfileScreen( Spacer(modifier = Modifier.height(80.dp)) AppText( - text = stringResource(R.string.onboarding_profile_title), + text = stringResource(DesR.string.onboarding_profile_title), style = AppTextStyle.H3, color = GrayColor.C500, modifier = Modifier.padding(start = 24.dp), @@ -127,7 +126,7 @@ private fun ProfileScreen( UnderlineTextField( value = uiModel.nickname, - placeHolder = stringResource(R.string.onboarding_name_placeholder), + placeHolder = stringResource(DesR.string.onboarding_name_placeholder), showTrailing = true, onValueChange = onChangeNickName, trailing = { @@ -160,14 +159,14 @@ private fun ProfileScreen( AppText( style = AppTextStyle.C2, color = if (uiModel.isValid) SystemColor.Success else GrayColor.C300, - text = stringResource(id = R.string.onboarding_name_helper), + text = stringResource(id = DesR.string.onboarding_name_helper), ) } Spacer(modifier = Modifier.weight(1f)) AppButton( - text = stringResource(R.string.onboarding_profile_button_title), + text = stringResource(DesR.string.onboarding_profile_button_title), onClick = { onCompleted() }, backgroundColor = if (uiModel.isValid) GrayColor.C500 else GrayColor.C100, textColor = if (uiModel.isValid) CommonColor.White else GrayColor.C300, diff --git a/feature/onboarding/src/main/res/values/strings.xml b/feature/onboarding/src/main/res/values/strings.xml deleted file mode 100644 index ef6d2daf..00000000 --- a/feature/onboarding/src/main/res/values/strings.xml +++ /dev/null @@ -1,38 +0,0 @@ - - - - 닉네임을 입력해 주세요. - 닉네임 2~8자 - 짝꿍에게 보일\n내 이름을 입력해 주세요 - 닉네임을 입력해 주세요. - 닉네임 2~8자 - 완료 - 2자에서 8자 이내로 닉네임을 입력해주세요. - 프로필 설정 요청에 실패했습니다. - - - 짝꿍과 연결하고\n함께 키피럽 시작하세요 - 초대장 보내기 - 짝꿍에게 코드를 받았다면? - 직접 - 연결하기 - 해지한 커플 복구하려면? - 아래 내용을 포함하여 문의해 주시기 바랍니다.\n고객센터 메일 - ttwixteamm@gmail.com - 본인 로그인 계정 메일 - 짝꿍의 로그인 계정 메일 - 해지 일시 - 내 조회코드 조회에 실패했습니다. - 커플 연결 요청에 실패했어요 - - - 짝꿍에게 받은\n초대 코드를 써주세요 - 내 초대 코드 - 받은 코드 쓰기 - 초대 코드가 복사되었어요 - 잘못된 초대 코드입니다 - - - 우리의 기념일을 등록해 주세요 - YYYY-MM-DD - 기념일 설정에 실패했습니다. - From 139b42b920e449e52577c93a78988f913027ada2 Mon Sep 17 00:00:00 2001 From: chanho0908 Date: Fri, 6 Mar 2026 18:21:26 +0900 Subject: [PATCH 03/27] =?UTF-8?q?=E2=9C=A8=20Feat:=20=EC=98=A8=EB=B3=B4?= =?UTF-8?q?=EB=94=A9=20=EC=BB=A4=ED=94=8C=20=EC=97=B0=EA=B2=B0=20=ED=99=94?= =?UTF-8?q?=EB=A9=B4=20=EB=92=A4=EB=A1=9C=EA=B0=80=EA=B8=B0=20=EB=B2=84?= =?UTF-8?q?=ED=8A=BC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/res/drawable/ic_arrow_left.xml | 13 +++++++ .../twix/login/navigation/LoginNavGraph.kt | 6 +--- .../onboarding/couple/CoupleConnectRoute.kt | 14 ++++++-- .../couple/component/CoupleConnectTopbar.kt | 34 +++++++++++++++++++ .../navigation/OnboardingNavGraph.kt | 1 + 5 files changed, 60 insertions(+), 8 deletions(-) create mode 100644 core/design-system/src/main/res/drawable/ic_arrow_left.xml create mode 100644 feature/onboarding/src/main/java/com/twix/onboarding/couple/component/CoupleConnectTopbar.kt diff --git a/core/design-system/src/main/res/drawable/ic_arrow_left.xml b/core/design-system/src/main/res/drawable/ic_arrow_left.xml new file mode 100644 index 00000000..ff4ad4f7 --- /dev/null +++ b/core/design-system/src/main/res/drawable/ic_arrow_left.xml @@ -0,0 +1,13 @@ + + + diff --git a/feature/login/src/main/java/com/twix/login/navigation/LoginNavGraph.kt b/feature/login/src/main/java/com/twix/login/navigation/LoginNavGraph.kt index 95901f41..31929a76 100644 --- a/feature/login/src/main/java/com/twix/login/navigation/LoginNavGraph.kt +++ b/feature/login/src/main/java/com/twix/login/navigation/LoginNavGraph.kt @@ -38,11 +38,7 @@ object LoginNavGraph : NavGraphContributor { OnboardingStatus.COMPLETED -> return@LoginRoute } - navController.navigate(destination) { - popUpTo(NavRoutes.LoginGraph.route) { - inclusive = true - } - } + navController.navigate(destination) }, ) } diff --git a/feature/onboarding/src/main/java/com/twix/onboarding/couple/CoupleConnectRoute.kt b/feature/onboarding/src/main/java/com/twix/onboarding/couple/CoupleConnectRoute.kt index 68e3bc4b..ffc9d140 100644 --- a/feature/onboarding/src/main/java/com/twix/onboarding/couple/CoupleConnectRoute.kt +++ b/feature/onboarding/src/main/java/com/twix/onboarding/couple/CoupleConnectRoute.kt @@ -45,6 +45,7 @@ import com.twix.designsystem.theme.TwixTheme import com.twix.domain.model.enums.AppTextStyle import com.twix.onboarding.OnBoardingViewModel import com.twix.onboarding.couple.component.ConnectButton +import com.twix.onboarding.couple.component.CoupleConnectTopbar import com.twix.onboarding.couple.component.InvitationButton import com.twix.onboarding.couple.component.RestoreCoupleBottomSheetContent import com.twix.onboarding.model.OnBoardingIntent @@ -58,6 +59,7 @@ fun CoupleConnectRoute( viewModel: OnBoardingViewModel, toastManager: ToastManager = koinInject(), navigateToNext: () -> Unit, + navigateToBack: () -> Unit, ) { var showMarketingDialog by rememberSaveable { mutableStateOf(true) } var showRestoreSheet by rememberSaveable { mutableStateOf(false) } @@ -92,6 +94,7 @@ fun CoupleConnectRoute( onClickConnect = navigateToNext, onClickRestore = { showRestoreSheet = true }, onDismissSheet = { showRestoreSheet = false }, + onClickBack = navigateToBack, ) MarketingDialog( @@ -118,6 +121,7 @@ fun CoupleConnectScreen( onClickConnect: () -> Unit, onClickRestore: () -> Unit, onDismissSheet: () -> Unit, + onClickBack: () -> Unit, ) { Box( modifier = @@ -126,7 +130,9 @@ fun CoupleConnectScreen( .background(color = CommonColor.White), ) { Column { - Spacer(modifier = Modifier.height(80.24.dp)) + CoupleConnectTopbar(onClickBack = onClickBack) + + Spacer(modifier = Modifier.height(8.dp)) AppText( text = stringResource(R.string.onboarding_couple_connect_description), @@ -135,7 +141,7 @@ fun CoupleConnectScreen( modifier = Modifier.padding(start = 24.dp), ) - Spacer(modifier = Modifier.height(11.76.dp)) + Spacer(modifier = Modifier.height(4.dp)) Image( imageVector = ImageVector.vectorResource(R.drawable.ic_invite), @@ -143,7 +149,8 @@ fun CoupleConnectScreen( modifier = Modifier.align(Alignment.CenterHorizontally), ) - Spacer(modifier = Modifier.height(47.dp)) + Spacer(modifier = Modifier.height(2.dp)) + InvitationButton(onClick = onClickSend) Spacer(modifier = Modifier.height(20.dp)) @@ -197,6 +204,7 @@ private fun CoupleConnectScreenPreview() { onClickConnect = {}, onClickRestore = {}, onDismissSheet = {}, + onClickBack = {}, ) } } diff --git a/feature/onboarding/src/main/java/com/twix/onboarding/couple/component/CoupleConnectTopbar.kt b/feature/onboarding/src/main/java/com/twix/onboarding/couple/component/CoupleConnectTopbar.kt new file mode 100644 index 00000000..4213b597 --- /dev/null +++ b/feature/onboarding/src/main/java/com/twix/onboarding/couple/component/CoupleConnectTopbar.kt @@ -0,0 +1,34 @@ +package com.twix.onboarding.couple.component + +import androidx.compose.foundation.Image +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.res.vectorResource +import androidx.compose.ui.unit.dp +import com.twix.designsystem.R +import com.twix.ui.extension.noRippleClickable + +@Composable +internal fun CoupleConnectTopbar(onClickBack: () -> Unit) { + Box( + Modifier + .fillMaxWidth() + .height(72.dp), + contentAlignment = Alignment.CenterStart, + ) { + Image( + imageVector = ImageVector.vectorResource(R.drawable.ic_arrow_left), + contentDescription = null, + modifier = + Modifier + .noRippleClickable(onClick = onClickBack) + .padding(start = 10.dp), + ) + } +} diff --git a/feature/onboarding/src/main/java/com/twix/onboarding/navigation/OnboardingNavGraph.kt b/feature/onboarding/src/main/java/com/twix/onboarding/navigation/OnboardingNavGraph.kt index 1408fb1f..446d6fba 100644 --- a/feature/onboarding/src/main/java/com/twix/onboarding/navigation/OnboardingNavGraph.kt +++ b/feature/onboarding/src/main/java/com/twix/onboarding/navigation/OnboardingNavGraph.kt @@ -34,6 +34,7 @@ object OnboardingNavGraph : NavGraphContributor { navigateToNext = { navController.navigate(NavRoutes.InviteRoute.route) }, + navigateToBack = navController::popBackStack, viewModel = vm, ) } From 5ffa4ddd649979dc7e6ed67af97e895d4fc9fc74 Mon Sep 17 00:00:00 2001 From: chanho0908 Date: Fri, 6 Mar 2026 18:43:09 +0900 Subject: [PATCH 04/27] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Refactor:=20?= =?UTF-8?q?=EC=BB=A4=ED=94=8C=EC=97=B0=EA=B2=B0=20=ED=86=A0=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EB=A9=94=EC=8B=9C=EC=A7=80=20=EC=B2=98=EB=A6=AC=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EA=B3=B5=ED=86=B5=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/res/values/strings.xml | 5 +-- .../twix/onboarding/OnBoardingViewModel.kt | 15 +++++++-- .../onboarding/invite/InviteCodeScreen.kt | 31 +++++-------------- .../onboarding/model/OnBoardingSideEffect.kt | 12 +++---- 4 files changed, 28 insertions(+), 35 deletions(-) diff --git a/core/design-system/src/main/res/values/strings.xml b/core/design-system/src/main/res/values/strings.xml index d675f2f1..e9b752b5 100644 --- a/core/design-system/src/main/res/values/strings.xml +++ b/core/design-system/src/main/res/values/strings.xml @@ -114,6 +114,9 @@ 인증샷 촬영을 위해서 카메라 권한이 필요해요. 알림 목록 조회에 실패했습니다. 찌르기에 실패했습니다. + 이미 사용된 초대 코드입니다. + 초대 코드가 복사되었어요 + 잘못된 초대 코드입니다 %s\n목표를 이루셨나요? @@ -186,8 +189,6 @@ 짝꿍에게 받은\n초대 코드를 써주세요 내 초대 코드 받은 코드 쓰기 - 초대 코드가 복사되었어요 - 잘못된 초대 코드입니다 우리의 기념일을 등록해 주세요 YYYY-MM-DD diff --git a/feature/onboarding/src/main/java/com/twix/onboarding/OnBoardingViewModel.kt b/feature/onboarding/src/main/java/com/twix/onboarding/OnBoardingViewModel.kt index 51f9543a..780c2341 100644 --- a/feature/onboarding/src/main/java/com/twix/onboarding/OnBoardingViewModel.kt +++ b/feature/onboarding/src/main/java/com/twix/onboarding/OnBoardingViewModel.kt @@ -1,6 +1,8 @@ package com.twix.onboarding import androidx.lifecycle.viewModelScope +import com.twix.designsystem.R +import com.twix.designsystem.components.toast.model.ToastType import com.twix.domain.model.OnboardingStatus import com.twix.domain.repository.NotificationRepository import com.twix.domain.repository.OnBoardingRepository @@ -30,7 +32,7 @@ class OnBoardingViewModel( is OnBoardingIntent.WriteInviteCode -> reduceInviteCode(intent.value) OnBoardingIntent.ConnectCouple -> connectCouple() OnBoardingIntent.CopyInviteCode -> - emitSideEffect(OnBoardingSideEffect.InviteCode.ShowCopyInviteCodeSuccessToast) + showToast(R.string.toast_invite_code_copy, ToastType.SUCCESS) // 프로필 설정 화면 is OnBoardingIntent.WriteNickName -> reduceNickName(intent.value) @@ -70,14 +72,14 @@ class OnBoardingViewModel( * 초대 코드를 잘못 입력한 경우 * */ if (error.message == INVALID_INVITE_CODE_MESSAGE) { - emitSideEffect(OnBoardingSideEffect.InviteCode.ShowInvalidInviteCodeToast) + showToast(R.string.toast_invalid_invite_code, ToastType.ERROR) } else if (error.message == ALREADY_USED_INVITE_CODE_MESSAGE) { /** * 상대방이 이미 연결한 경우 * */ emitSideEffect(OnBoardingSideEffect.InviteCode.NavigateToNext) } else { - emitSideEffect(OnBoardingSideEffect.InviteCode.ShowConnectCoupleConnectFailToast) + showToast(R.string.onboarding_couple_connection_fail, ToastType.ERROR) } } } @@ -161,6 +163,13 @@ class OnBoardingViewModel( ) } + private suspend fun showToast( + message: Int, + type: ToastType, + ) { + emitSideEffect(OnBoardingSideEffect.ShowToast(message, type)) + } + companion object { private const val ALREADY_USED_INVITE_CODE_MESSAGE = "이미 사용된 초대 코드입니다." private const val INVALID_INVITE_CODE_MESSAGE = "유효하지 않은 초대 코드입니다." diff --git a/feature/onboarding/src/main/java/com/twix/onboarding/invite/InviteCodeScreen.kt b/feature/onboarding/src/main/java/com/twix/onboarding/invite/InviteCodeScreen.kt index 0bb18708..bcc64a58 100644 --- a/feature/onboarding/src/main/java/com/twix/onboarding/invite/InviteCodeScreen.kt +++ b/feature/onboarding/src/main/java/com/twix/onboarding/invite/InviteCodeScreen.kt @@ -26,12 +26,14 @@ import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.runtime.rememberUpdatedState import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.focus.FocusRequester import androidx.compose.ui.focus.focusRequester import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.platform.LocalClipboard +import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.toClipEntry import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.vectorResource @@ -43,7 +45,6 @@ import com.twix.designsystem.components.button.AppButton import com.twix.designsystem.components.text.AppText import com.twix.designsystem.components.toast.ToastManager import com.twix.designsystem.components.toast.model.ToastData -import com.twix.designsystem.components.toast.model.ToastType import com.twix.designsystem.theme.CommonColor import com.twix.designsystem.theme.GrayColor import com.twix.designsystem.theme.TwixTheme @@ -69,35 +70,17 @@ internal fun InviteCodeRoute( val uiState by viewModel.uiState.collectAsStateWithLifecycle() val coroutineScope = rememberCoroutineScope() val keyboardState by keyboardAsState() + val context = LocalContext.current + val currentContext by rememberUpdatedState(context) val clipboard = LocalClipboard.current - val inviteCodeSuccessMessage = stringResource(R.string.onboarding_invite_code_copy) - val invalidInviteCodeMessage = stringResource(R.string.onboarding_invite_invalid_invite_code_fail) - val coupleConnectionFailMessage = stringResource(R.string.onboarding_couple_connection_fail) - ObserveAsEvents(viewModel.sideEffect) { sideEffect -> when (sideEffect) { - OnBoardingSideEffect.InviteCode.ShowCopyInviteCodeSuccessToast -> { - toastManager.tryShow( - ToastData( - message = inviteCodeSuccessMessage, - type = ToastType.SUCCESS, - ), - ) - } - OnBoardingSideEffect.InviteCode.ShowInvalidInviteCodeToast -> { - toastManager.tryShow( - ToastData( - message = invalidInviteCodeMessage, - type = ToastType.ERROR, - ), - ) - } - OnBoardingSideEffect.InviteCode.ShowConnectCoupleConnectFailToast -> { + is OnBoardingSideEffect.ShowToast -> { toastManager.tryShow( ToastData( - message = coupleConnectionFailMessage, - type = ToastType.ERROR, + message = currentContext.getString(sideEffect.message), + type = sideEffect.type, ), ) } diff --git a/feature/onboarding/src/main/java/com/twix/onboarding/model/OnBoardingSideEffect.kt b/feature/onboarding/src/main/java/com/twix/onboarding/model/OnBoardingSideEffect.kt index 9bff5899..52256947 100644 --- a/feature/onboarding/src/main/java/com/twix/onboarding/model/OnBoardingSideEffect.kt +++ b/feature/onboarding/src/main/java/com/twix/onboarding/model/OnBoardingSideEffect.kt @@ -1,5 +1,6 @@ package com.twix.onboarding.model +import com.twix.designsystem.components.toast.model.ToastType import com.twix.ui.base.SideEffect sealed interface OnBoardingSideEffect : SideEffect { @@ -18,12 +19,6 @@ sealed interface OnBoardingSideEffect : SideEffect { } sealed interface InviteCode : OnBoardingSideEffect { - data object ShowCopyInviteCodeSuccessToast : InviteCode - - data object ShowInvalidInviteCodeToast : InviteCode - - data object ShowConnectCoupleConnectFailToast : InviteCode - data object NavigateToNext : InviteCode } @@ -32,4 +27,9 @@ sealed interface OnBoardingSideEffect : SideEffect { data object ShowAnniversarySetupFailToast : DdaySetting } + + data class ShowToast( + val message: Int, + val type: ToastType, + ) : OnBoardingSideEffect } From 31f0849c4c7ce22f26efea2db10bb9fcaa2b6c2c Mon Sep 17 00:00:00 2001 From: chanho0908 Date: Fri, 6 Mar 2026 18:47:27 +0900 Subject: [PATCH 05/27] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Refactor:=20?= =?UTF-8?q?=EC=98=A8=EB=B3=B4=EB=94=A9=20=EC=B4=88=EB=8C=80=20=EC=BD=94?= =?UTF-8?q?=EB=93=9C=20=EC=A1=B0=ED=9A=8C=20=EB=A1=9C=EC=A7=81=20=EA=B0=9C?= =?UTF-8?q?=EC=84=A0=20=EB=B0=8F=20=EC=9E=90=EB=8F=99=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - `OnBoardingViewModel` 초기화 시 초대 코드를 자동으로 조회하도록 변경 - `OnBoardingSideEffect`에서 사용되지 않는 `CoupleConnection` 인터페이스 제거 - 특정 SideEffect 대신 공통 `showToast` 메서드를 사용하여 에러 메시지를 출력하도록 변경 - `CoupleConnectRoute`에서 수동으로 호출하던 `fetchMyInviteCode` 로직 제거 및 토스트 처리 로직 통합 --- .../com/twix/onboarding/OnBoardingViewModel.kt | 16 +++++++++++++--- .../twix/onboarding/couple/CoupleConnectRoute.kt | 11 ++--------- .../onboarding/model/OnBoardingSideEffect.kt | 4 ---- 3 files changed, 15 insertions(+), 16 deletions(-) diff --git a/feature/onboarding/src/main/java/com/twix/onboarding/OnBoardingViewModel.kt b/feature/onboarding/src/main/java/com/twix/onboarding/OnBoardingViewModel.kt index 780c2341..a00ed663 100644 --- a/feature/onboarding/src/main/java/com/twix/onboarding/OnBoardingViewModel.kt +++ b/feature/onboarding/src/main/java/com/twix/onboarding/OnBoardingViewModel.kt @@ -18,11 +18,17 @@ class OnBoardingViewModel( private val onBoardingRepository: OnBoardingRepository, private val notificationRepository: NotificationRepository, ) : BaseViewModel(OnBoardingUiState()) { - fun fetchMyInviteCode() { + init { + fetchMyInviteCode() + } + + private fun fetchMyInviteCode() { launchResult( block = { onBoardingRepository.fetchInviteCode() }, onSuccess = { reduce { updateMyInviteCode(it.value) } }, - onError = { emitSideEffect(OnBoardingSideEffect.CoupleConnection.ShowFetchMyInviteCodeFailToast) }, + onError = { + showToast(R.string.onboarding_couple_fetch_my_invite_code_fail, ToastType.ERROR) + }, ) } @@ -43,7 +49,11 @@ class OnBoardingViewModel( OnBoardingIntent.SubmitDday -> anniversarySetup() is OnBoardingIntent.SubmitMarketingConsent -> - initNotificationSettings(intent.isPushEnabled, intent.isMarketingEnabled, intent.isNightMarketingEnabled) + initNotificationSettings( + intent.isPushEnabled, + intent.isMarketingEnabled, + intent.isNightMarketingEnabled, + ) } } diff --git a/feature/onboarding/src/main/java/com/twix/onboarding/couple/CoupleConnectRoute.kt b/feature/onboarding/src/main/java/com/twix/onboarding/couple/CoupleConnectRoute.kt index ffc9d140..61d4cb07 100644 --- a/feature/onboarding/src/main/java/com/twix/onboarding/couple/CoupleConnectRoute.kt +++ b/feature/onboarding/src/main/java/com/twix/onboarding/couple/CoupleConnectRoute.kt @@ -14,7 +14,6 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.runtime.Composable -import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.rememberUpdatedState @@ -66,18 +65,12 @@ fun CoupleConnectRoute( val context = LocalContext.current val currentContext by rememberUpdatedState(context) - LaunchedEffect(Unit) { - viewModel.fetchMyInviteCode() - } - - val fetchMyInviteCodeFailMessage = - stringResource(R.string.onboarding_couple_fetch_my_invite_code_fail) ObserveAsEvents(viewModel.sideEffect) { sideEffect -> when (sideEffect) { - OnBoardingSideEffect.CoupleConnection.ShowFetchMyInviteCodeFailToast -> { + is OnBoardingSideEffect.ShowToast -> { toastManager.tryShow( ToastData( - message = fetchMyInviteCodeFailMessage, + message = currentContext.getString(sideEffect.message), type = ToastType.ERROR, ), ) diff --git a/feature/onboarding/src/main/java/com/twix/onboarding/model/OnBoardingSideEffect.kt b/feature/onboarding/src/main/java/com/twix/onboarding/model/OnBoardingSideEffect.kt index 52256947..4fd576be 100644 --- a/feature/onboarding/src/main/java/com/twix/onboarding/model/OnBoardingSideEffect.kt +++ b/feature/onboarding/src/main/java/com/twix/onboarding/model/OnBoardingSideEffect.kt @@ -14,10 +14,6 @@ sealed interface OnBoardingSideEffect : SideEffect { data object NavigateToHome : ProfileSetting } - sealed interface CoupleConnection : OnBoardingSideEffect { - data object ShowFetchMyInviteCodeFailToast : CoupleConnection - } - sealed interface InviteCode : OnBoardingSideEffect { data object NavigateToNext : InviteCode } From 5f1f98d0897037c5487862aac95abf88de52ad53 Mon Sep 17 00:00:00 2001 From: chanho0908 Date: Fri, 6 Mar 2026 18:51:21 +0900 Subject: [PATCH 06/27] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Refactor:=20?= =?UTF-8?q?=EC=98=A8=EB=B3=B4=EB=94=A9=20=ED=86=A0=EC=8A=A4=ED=8A=B8=20?= =?UTF-8?q?=EB=A9=94=EC=8B=9C=EC=A7=80=20=EC=B2=98=EB=A6=AC=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EA=B3=B5=ED=86=B5=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../twix/onboarding/OnBoardingViewModel.kt | 6 ++--- .../onboarding/couple/CoupleConnectRoute.kt | 3 +-- .../com/twix/onboarding/dday/DdayRoute.kt | 12 +++++---- .../onboarding/model/OnBoardingSideEffect.kt | 6 ----- .../twix/onboarding/profile/ProfileScreen.kt | 25 ++++++------------- 5 files changed, 18 insertions(+), 34 deletions(-) diff --git a/feature/onboarding/src/main/java/com/twix/onboarding/OnBoardingViewModel.kt b/feature/onboarding/src/main/java/com/twix/onboarding/OnBoardingViewModel.kt index a00ed663..cb7247aa 100644 --- a/feature/onboarding/src/main/java/com/twix/onboarding/OnBoardingViewModel.kt +++ b/feature/onboarding/src/main/java/com/twix/onboarding/OnBoardingViewModel.kt @@ -103,7 +103,7 @@ class OnBoardingViewModel( profileSetup() } else { viewModelScope.launch { - emitSideEffect(OnBoardingSideEffect.ProfileSetting.ShowInvalidNickNameToast) + showToast(R.string.onboarding_profile_invalid_name_length_toast, ToastType.ERROR) } } } @@ -112,7 +112,7 @@ class OnBoardingViewModel( launchResult( block = { onBoardingRepository.profileSetup(currentState.profile.nickname) }, onSuccess = { fetchOnboardingStatus() }, - onError = { emitSideEffect(OnBoardingSideEffect.ProfileSetting.ShowProfileSetupFailToast) }, + onError = { showToast(R.string.onboarding_profile_setup_fail, ToastType.ERROR) }, ) } @@ -151,7 +151,7 @@ class OnBoardingViewModel( viewModelScope.launch { emitSideEffect(OnBoardingSideEffect.DdaySetting.NavigateToHome) } }, onError = { - emitSideEffect(OnBoardingSideEffect.DdaySetting.ShowAnniversarySetupFailToast) + showToast(R.string.onboarding_dday_setup_fail, ToastType.ERROR) }, ) } diff --git a/feature/onboarding/src/main/java/com/twix/onboarding/couple/CoupleConnectRoute.kt b/feature/onboarding/src/main/java/com/twix/onboarding/couple/CoupleConnectRoute.kt index 61d4cb07..b0c6a099 100644 --- a/feature/onboarding/src/main/java/com/twix/onboarding/couple/CoupleConnectRoute.kt +++ b/feature/onboarding/src/main/java/com/twix/onboarding/couple/CoupleConnectRoute.kt @@ -37,7 +37,6 @@ import com.twix.designsystem.components.dialog.MarketingDialog import com.twix.designsystem.components.text.AppText import com.twix.designsystem.components.toast.ToastManager import com.twix.designsystem.components.toast.model.ToastData -import com.twix.designsystem.components.toast.model.ToastType import com.twix.designsystem.theme.CommonColor import com.twix.designsystem.theme.GrayColor import com.twix.designsystem.theme.TwixTheme @@ -71,7 +70,7 @@ fun CoupleConnectRoute( toastManager.tryShow( ToastData( message = currentContext.getString(sideEffect.message), - type = ToastType.ERROR, + type = sideEffect.type, ), ) } diff --git a/feature/onboarding/src/main/java/com/twix/onboarding/dday/DdayRoute.kt b/feature/onboarding/src/main/java/com/twix/onboarding/dday/DdayRoute.kt index b48ea38f..3eda3553 100644 --- a/feature/onboarding/src/main/java/com/twix/onboarding/dday/DdayRoute.kt +++ b/feature/onboarding/src/main/java/com/twix/onboarding/dday/DdayRoute.kt @@ -12,8 +12,10 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberUpdatedState import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp @@ -25,7 +27,6 @@ import com.twix.designsystem.components.calendar.Calendar import com.twix.designsystem.components.text.AppText import com.twix.designsystem.components.toast.ToastManager import com.twix.designsystem.components.toast.model.ToastData -import com.twix.designsystem.components.toast.model.ToastType import com.twix.designsystem.theme.CommonColor import com.twix.designsystem.theme.GrayColor import com.twix.designsystem.theme.TwixTheme @@ -48,17 +49,18 @@ fun DdayRoute( toastManager: ToastManager = koinInject(), ) { val uiState by viewModel.uiState.collectAsStateWithLifecycle() + val context = LocalContext.current + val currentContext by rememberUpdatedState(context) var showCalendarBottomSheet by remember { mutableStateOf(false) } - val ddaySetUpFailMessage = stringResource(DesR.string.onboarding_dday_setup_fail) ObserveAsEvents(viewModel.sideEffect) { sideEffect -> when (sideEffect) { OnBoardingSideEffect.DdaySetting.NavigateToHome -> navigateToHome() - OnBoardingSideEffect.DdaySetting.ShowAnniversarySetupFailToast -> { + is OnBoardingSideEffect.ShowToast -> { toastManager.tryShow( ToastData( - message = ddaySetUpFailMessage, - type = ToastType.ERROR, + message = currentContext.getString(sideEffect.message), + type = sideEffect.type, ), ) } diff --git a/feature/onboarding/src/main/java/com/twix/onboarding/model/OnBoardingSideEffect.kt b/feature/onboarding/src/main/java/com/twix/onboarding/model/OnBoardingSideEffect.kt index 4fd576be..2d4ba4ee 100644 --- a/feature/onboarding/src/main/java/com/twix/onboarding/model/OnBoardingSideEffect.kt +++ b/feature/onboarding/src/main/java/com/twix/onboarding/model/OnBoardingSideEffect.kt @@ -5,10 +5,6 @@ import com.twix.ui.base.SideEffect sealed interface OnBoardingSideEffect : SideEffect { sealed interface ProfileSetting : OnBoardingSideEffect { - data object ShowInvalidNickNameToast : ProfileSetting - - data object ShowProfileSetupFailToast : ProfileSetting - data object NavigateToDDaySetting : ProfileSetting data object NavigateToHome : ProfileSetting @@ -20,8 +16,6 @@ sealed interface OnBoardingSideEffect : SideEffect { sealed interface DdaySetting : OnBoardingSideEffect { data object NavigateToHome : DdaySetting - - data object ShowAnniversarySetupFailToast : DdaySetting } data class ShowToast( diff --git a/feature/onboarding/src/main/java/com/twix/onboarding/profile/ProfileScreen.kt b/feature/onboarding/src/main/java/com/twix/onboarding/profile/ProfileScreen.kt index 504d0e9d..b07f74b4 100644 --- a/feature/onboarding/src/main/java/com/twix/onboarding/profile/ProfileScreen.kt +++ b/feature/onboarding/src/main/java/com/twix/onboarding/profile/ProfileScreen.kt @@ -16,11 +16,13 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberUpdatedState import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.focus.FocusRequester import androidx.compose.ui.focus.focusRequester import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.vectorResource import androidx.compose.ui.tooling.preview.Preview @@ -31,7 +33,6 @@ import com.twix.designsystem.components.text.AppText import com.twix.designsystem.components.text_field.UnderlineTextField import com.twix.designsystem.components.toast.ToastManager import com.twix.designsystem.components.toast.model.ToastData -import com.twix.designsystem.components.toast.model.ToastType import com.twix.designsystem.theme.CommonColor import com.twix.designsystem.theme.GrayColor import com.twix.designsystem.theme.SystemColor @@ -53,28 +54,16 @@ fun ProfileRoute( toastManager: ToastManager = koinInject(), ) { val uiState by viewModel.uiState.collectAsStateWithLifecycle() - - val notValidNickNameMessage = - stringResource(DesR.string.onboarding_profile_invalid_name_length_toast) - - val profileSetupFailMessage = stringResource(DesR.string.onboarding_profile_setup_fail) + val context = LocalContext.current + val currentContext by rememberUpdatedState(context) ObserveAsEvents(viewModel.sideEffect) { sideEffect -> when (sideEffect) { - OnBoardingSideEffect.ProfileSetting.ShowInvalidNickNameToast -> { - toastManager.tryShow( - ToastData( - message = notValidNickNameMessage, - type = ToastType.ERROR, - ), - ) - } - - OnBoardingSideEffect.ProfileSetting.ShowProfileSetupFailToast -> { + is OnBoardingSideEffect.ShowToast -> { toastManager.tryShow( ToastData( - message = profileSetupFailMessage, - type = ToastType.ERROR, + message = currentContext.getString(sideEffect.message), + type = sideEffect.type, ), ) } From 899f9845173c6ee2677589b0432efb37d0c9dc89 Mon Sep 17 00:00:00 2001 From: chanho0908 Date: Fri, 6 Mar 2026 18:51:40 +0900 Subject: [PATCH 07/27] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Refactor:=20`OnBoard?= =?UTF-8?q?ingSideEffect`=20=EB=82=B4=20=EC=9D=B4=EB=8F=99=20=EA=B4=80?= =?UTF-8?q?=EB=A0=A8=20=EB=84=A4=EC=9D=B4=EB=B0=8D=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - `NavigateToDDaySetting`을 `NavigateToNext`로 변경하여 목적지 추상화 및 범용성 개선 - `OnBoardingViewModel` 및 `ProfileScreen` 내 관련 참조 업데이트 --- .../src/main/java/com/twix/onboarding/OnBoardingViewModel.kt | 2 +- .../main/java/com/twix/onboarding/model/OnBoardingSideEffect.kt | 2 +- .../src/main/java/com/twix/onboarding/profile/ProfileScreen.kt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/feature/onboarding/src/main/java/com/twix/onboarding/OnBoardingViewModel.kt b/feature/onboarding/src/main/java/com/twix/onboarding/OnBoardingViewModel.kt index cb7247aa..9d3644dd 100644 --- a/feature/onboarding/src/main/java/com/twix/onboarding/OnBoardingViewModel.kt +++ b/feature/onboarding/src/main/java/com/twix/onboarding/OnBoardingViewModel.kt @@ -124,7 +124,7 @@ class OnBoardingViewModel( val sideEffect = when (onboardingStatus) { OnboardingStatus.ANNIVERSARY_SETUP -> - OnBoardingSideEffect.ProfileSetting.NavigateToDDaySetting + OnBoardingSideEffect.ProfileSetting.NavigateToNext OnboardingStatus.COMPLETED -> OnBoardingSideEffect.ProfileSetting.NavigateToHome diff --git a/feature/onboarding/src/main/java/com/twix/onboarding/model/OnBoardingSideEffect.kt b/feature/onboarding/src/main/java/com/twix/onboarding/model/OnBoardingSideEffect.kt index 2d4ba4ee..fab5c987 100644 --- a/feature/onboarding/src/main/java/com/twix/onboarding/model/OnBoardingSideEffect.kt +++ b/feature/onboarding/src/main/java/com/twix/onboarding/model/OnBoardingSideEffect.kt @@ -5,7 +5,7 @@ import com.twix.ui.base.SideEffect sealed interface OnBoardingSideEffect : SideEffect { sealed interface ProfileSetting : OnBoardingSideEffect { - data object NavigateToDDaySetting : ProfileSetting + data object NavigateToNext : ProfileSetting data object NavigateToHome : ProfileSetting } diff --git a/feature/onboarding/src/main/java/com/twix/onboarding/profile/ProfileScreen.kt b/feature/onboarding/src/main/java/com/twix/onboarding/profile/ProfileScreen.kt index b07f74b4..1e35a7f6 100644 --- a/feature/onboarding/src/main/java/com/twix/onboarding/profile/ProfileScreen.kt +++ b/feature/onboarding/src/main/java/com/twix/onboarding/profile/ProfileScreen.kt @@ -69,7 +69,7 @@ fun ProfileRoute( } OnBoardingSideEffect.ProfileSetting.NavigateToHome -> navigateToHome() - OnBoardingSideEffect.ProfileSetting.NavigateToDDaySetting -> navigateToDday() + OnBoardingSideEffect.ProfileSetting.NavigateToNext -> navigateToDday() else -> Unit } } From ef3ad2246c4a7f238137af7ed7dc058b8621db78 Mon Sep 17 00:00:00 2001 From: chanho0908 Date: Fri, 6 Mar 2026 18:52:18 +0900 Subject: [PATCH 08/27] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Refactor:=20OnBoardi?= =?UTF-8?q?ng=20=EA=B4=80=EB=A0=A8=20MVI=20=ED=81=B4=EB=9E=98=EC=8A=A4=20?= =?UTF-8?q?=ED=8C=A8=ED=82=A4=EC=A7=80=20=EC=9C=84=EC=B9=98=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=20(`model`=20->=20`contract`)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/twix/onboarding/OnBoardingViewModel.kt | 6 +++--- .../twix/onboarding/{model => contract}/OnBoardingIntent.kt | 2 +- .../onboarding/{model => contract}/OnBoardingSideEffect.kt | 2 +- .../onboarding/{model => contract}/OnBoardingUiState.kt | 2 +- .../java/com/twix/onboarding/couple/CoupleConnectRoute.kt | 4 ++-- .../src/main/java/com/twix/onboarding/dday/DdayRoute.kt | 4 ++-- .../java/com/twix/onboarding/invite/InviteCodeScreen.kt | 4 ++-- .../main/java/com/twix/onboarding/profile/ProfileScreen.kt | 4 ++-- 8 files changed, 14 insertions(+), 14 deletions(-) rename feature/onboarding/src/main/java/com/twix/onboarding/{model => contract}/OnBoardingIntent.kt (95%) rename feature/onboarding/src/main/java/com/twix/onboarding/{model => contract}/OnBoardingSideEffect.kt (94%) rename feature/onboarding/src/main/java/com/twix/onboarding/{model => contract}/OnBoardingUiState.kt (96%) diff --git a/feature/onboarding/src/main/java/com/twix/onboarding/OnBoardingViewModel.kt b/feature/onboarding/src/main/java/com/twix/onboarding/OnBoardingViewModel.kt index 9d3644dd..0a35fd48 100644 --- a/feature/onboarding/src/main/java/com/twix/onboarding/OnBoardingViewModel.kt +++ b/feature/onboarding/src/main/java/com/twix/onboarding/OnBoardingViewModel.kt @@ -6,9 +6,9 @@ import com.twix.designsystem.components.toast.model.ToastType import com.twix.domain.model.OnboardingStatus import com.twix.domain.repository.NotificationRepository import com.twix.domain.repository.OnBoardingRepository -import com.twix.onboarding.model.OnBoardingIntent -import com.twix.onboarding.model.OnBoardingSideEffect -import com.twix.onboarding.model.OnBoardingUiState +import com.twix.onboarding.contract.OnBoardingIntent +import com.twix.onboarding.contract.OnBoardingSideEffect +import com.twix.onboarding.contract.OnBoardingUiState import com.twix.result.AppError import com.twix.ui.base.BaseViewModel import kotlinx.coroutines.launch diff --git a/feature/onboarding/src/main/java/com/twix/onboarding/model/OnBoardingIntent.kt b/feature/onboarding/src/main/java/com/twix/onboarding/contract/OnBoardingIntent.kt similarity index 95% rename from feature/onboarding/src/main/java/com/twix/onboarding/model/OnBoardingIntent.kt rename to feature/onboarding/src/main/java/com/twix/onboarding/contract/OnBoardingIntent.kt index e7ae7655..e13f74af 100644 --- a/feature/onboarding/src/main/java/com/twix/onboarding/model/OnBoardingIntent.kt +++ b/feature/onboarding/src/main/java/com/twix/onboarding/contract/OnBoardingIntent.kt @@ -1,4 +1,4 @@ -package com.twix.onboarding.model +package com.twix.onboarding.contract import com.twix.ui.base.Intent import java.time.LocalDate diff --git a/feature/onboarding/src/main/java/com/twix/onboarding/model/OnBoardingSideEffect.kt b/feature/onboarding/src/main/java/com/twix/onboarding/contract/OnBoardingSideEffect.kt similarity index 94% rename from feature/onboarding/src/main/java/com/twix/onboarding/model/OnBoardingSideEffect.kt rename to feature/onboarding/src/main/java/com/twix/onboarding/contract/OnBoardingSideEffect.kt index fab5c987..eba564f7 100644 --- a/feature/onboarding/src/main/java/com/twix/onboarding/model/OnBoardingSideEffect.kt +++ b/feature/onboarding/src/main/java/com/twix/onboarding/contract/OnBoardingSideEffect.kt @@ -1,4 +1,4 @@ -package com.twix.onboarding.model +package com.twix.onboarding.contract import com.twix.designsystem.components.toast.model.ToastType import com.twix.ui.base.SideEffect diff --git a/feature/onboarding/src/main/java/com/twix/onboarding/model/OnBoardingUiState.kt b/feature/onboarding/src/main/java/com/twix/onboarding/contract/OnBoardingUiState.kt similarity index 96% rename from feature/onboarding/src/main/java/com/twix/onboarding/model/OnBoardingUiState.kt rename to feature/onboarding/src/main/java/com/twix/onboarding/contract/OnBoardingUiState.kt index 8316982d..5cba6794 100644 --- a/feature/onboarding/src/main/java/com/twix/onboarding/model/OnBoardingUiState.kt +++ b/feature/onboarding/src/main/java/com/twix/onboarding/contract/OnBoardingUiState.kt @@ -1,4 +1,4 @@ -package com.twix.onboarding.model +package com.twix.onboarding.contract import androidx.compose.runtime.Immutable import com.twix.onboarding.dday.DdayUiModel diff --git a/feature/onboarding/src/main/java/com/twix/onboarding/couple/CoupleConnectRoute.kt b/feature/onboarding/src/main/java/com/twix/onboarding/couple/CoupleConnectRoute.kt index b0c6a099..d9e5719b 100644 --- a/feature/onboarding/src/main/java/com/twix/onboarding/couple/CoupleConnectRoute.kt +++ b/feature/onboarding/src/main/java/com/twix/onboarding/couple/CoupleConnectRoute.kt @@ -42,12 +42,12 @@ import com.twix.designsystem.theme.GrayColor import com.twix.designsystem.theme.TwixTheme import com.twix.domain.model.enums.AppTextStyle import com.twix.onboarding.OnBoardingViewModel +import com.twix.onboarding.contract.OnBoardingIntent +import com.twix.onboarding.contract.OnBoardingSideEffect import com.twix.onboarding.couple.component.ConnectButton import com.twix.onboarding.couple.component.CoupleConnectTopbar import com.twix.onboarding.couple.component.InvitationButton import com.twix.onboarding.couple.component.RestoreCoupleBottomSheetContent -import com.twix.onboarding.model.OnBoardingIntent -import com.twix.onboarding.model.OnBoardingSideEffect import com.twix.ui.base.ObserveAsEvents import com.twix.ui.extension.noRippleClickable import org.koin.compose.koinInject diff --git a/feature/onboarding/src/main/java/com/twix/onboarding/dday/DdayRoute.kt b/feature/onboarding/src/main/java/com/twix/onboarding/dday/DdayRoute.kt index 3eda3553..23925abc 100644 --- a/feature/onboarding/src/main/java/com/twix/onboarding/dday/DdayRoute.kt +++ b/feature/onboarding/src/main/java/com/twix/onboarding/dday/DdayRoute.kt @@ -32,10 +32,10 @@ import com.twix.designsystem.theme.GrayColor import com.twix.designsystem.theme.TwixTheme import com.twix.domain.model.enums.AppTextStyle import com.twix.onboarding.OnBoardingViewModel +import com.twix.onboarding.contract.OnBoardingIntent +import com.twix.onboarding.contract.OnBoardingSideEffect import com.twix.onboarding.dday.component.DDayField import com.twix.onboarding.dday.component.DdayTopBar -import com.twix.onboarding.model.OnBoardingIntent -import com.twix.onboarding.model.OnBoardingSideEffect import com.twix.ui.base.ObserveAsEvents import org.koin.compose.koinInject import java.time.LocalDate diff --git a/feature/onboarding/src/main/java/com/twix/onboarding/invite/InviteCodeScreen.kt b/feature/onboarding/src/main/java/com/twix/onboarding/invite/InviteCodeScreen.kt index bcc64a58..295acc89 100644 --- a/feature/onboarding/src/main/java/com/twix/onboarding/invite/InviteCodeScreen.kt +++ b/feature/onboarding/src/main/java/com/twix/onboarding/invite/InviteCodeScreen.kt @@ -50,9 +50,9 @@ import com.twix.designsystem.theme.GrayColor import com.twix.designsystem.theme.TwixTheme import com.twix.domain.model.enums.AppTextStyle import com.twix.onboarding.OnBoardingViewModel +import com.twix.onboarding.contract.OnBoardingIntent +import com.twix.onboarding.contract.OnBoardingSideEffect import com.twix.onboarding.invite.component.InviteCodeTextField -import com.twix.onboarding.model.OnBoardingIntent -import com.twix.onboarding.model.OnBoardingSideEffect import com.twix.ui.base.ObserveAsEvents import com.twix.ui.extension.noRippleClickable import com.twix.ui.keyboard.Keyboard diff --git a/feature/onboarding/src/main/java/com/twix/onboarding/profile/ProfileScreen.kt b/feature/onboarding/src/main/java/com/twix/onboarding/profile/ProfileScreen.kt index 1e35a7f6..da561404 100644 --- a/feature/onboarding/src/main/java/com/twix/onboarding/profile/ProfileScreen.kt +++ b/feature/onboarding/src/main/java/com/twix/onboarding/profile/ProfileScreen.kt @@ -39,8 +39,8 @@ import com.twix.designsystem.theme.SystemColor import com.twix.designsystem.theme.TwixTheme import com.twix.domain.model.enums.AppTextStyle import com.twix.onboarding.OnBoardingViewModel -import com.twix.onboarding.model.OnBoardingIntent -import com.twix.onboarding.model.OnBoardingSideEffect +import com.twix.onboarding.contract.OnBoardingIntent +import com.twix.onboarding.contract.OnBoardingSideEffect import com.twix.ui.base.ObserveAsEvents import com.twix.ui.extension.noRippleClickable import org.koin.compose.koinInject From ec5d644a68f7a14c50af2b5ccea09f7dc960d2b6 Mon Sep 17 00:00:00 2001 From: chanho0908 Date: Fri, 6 Mar 2026 19:49:27 +0900 Subject: [PATCH 09/27] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Refactor:=20?= =?UTF-8?q?=EC=A7=81=EC=A0=91=20=EC=97=B0=EA=B2=B0=ED=95=98=EA=B8=B0=20?= =?UTF-8?q?=ED=85=8D=EC=8A=A4=ED=8A=B8=20=EC=8A=A4=ED=83=80=EC=9D=BC=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 --- .../src/main/res/values/strings.xml | 3 +- .../couple/component/ConnectButton.kt | 40 +++++-------------- 2 files changed, 12 insertions(+), 31 deletions(-) diff --git a/core/design-system/src/main/res/values/strings.xml b/core/design-system/src/main/res/values/strings.xml index e9b752b5..dec32ae1 100644 --- a/core/design-system/src/main/res/values/strings.xml +++ b/core/design-system/src/main/res/values/strings.xml @@ -176,8 +176,7 @@ 짝꿍과 연결하고\n함께 키피럽 시작하세요 초대장 보내기 짝꿍에게 코드를 받았다면? - 직접 - 연결하기 + 직접 연결하기 해지한 커플 복구하려면? 아래 내용을 포함하여 문의해 주시기 바랍니다.\n고객센터 메일 - ttwixteamm@gmail.com 본인 로그인 계정 메일 diff --git a/feature/onboarding/src/main/java/com/twix/onboarding/couple/component/ConnectButton.kt b/feature/onboarding/src/main/java/com/twix/onboarding/couple/component/ConnectButton.kt index 961bbdf6..3cb05be8 100644 --- a/feature/onboarding/src/main/java/com/twix/onboarding/couple/component/ConnectButton.kt +++ b/feature/onboarding/src/main/java/com/twix/onboarding/couple/component/ConnectButton.kt @@ -3,7 +3,6 @@ package com.twix.onboarding.couple.component import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.border -import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer @@ -12,22 +11,18 @@ import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.width import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.vectorResource -import androidx.compose.ui.text.font.FontWeight.Companion.ExtraBold import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp import com.twix.designsystem.R import com.twix.designsystem.components.text.AppText import com.twix.designsystem.theme.CommonColor import com.twix.designsystem.theme.GrayColor -import com.twix.designsystem.theme.NanumSquareNeoFamily import com.twix.designsystem.theme.TwixTheme import com.twix.domain.model.enums.AppTextStyle import com.twix.ui.extension.noRippleClickable @@ -48,39 +43,26 @@ internal fun ConnectButton( color = GrayColor.C500, width = 1.2.dp, shape = RoundedCornerShape(12.dp), - ).noRippleClickable { onClickConnect() }, + ).noRippleClickable(onClick = onClickConnect), verticalAlignment = Alignment.CenterVertically, ) { Column( - modifier = Modifier.padding(start = 25.dp), - verticalArrangement = Arrangement.Center, + modifier = + Modifier + .padding(start = 25.dp), ) { AppText( text = stringResource(R.string.onboarding_couple_connect_direct_description), style = AppTextStyle.C1, color = GrayColor.C400, + modifier = Modifier.height(18.dp), + ) + AppText( + text = stringResource(R.string.onboarding_couple_direct_connect_button_title), + style = AppTextStyle.T2, + color = GrayColor.C500, + modifier = Modifier.height(24.dp), ) - - Spacer(modifier = Modifier.height(3.dp)) - - Row( - verticalAlignment = Alignment.CenterVertically, - ) { - Text( - text = stringResource(R.string.onboarding_couple_connect_direct), - fontFamily = NanumSquareNeoFamily, - fontWeight = ExtraBold, - color = GrayColor.C500, - fontSize = 16.sp, - lineHeight = 22.2.sp, - ) - - AppText( - text = stringResource(R.string.onboarding_couple_connect), - style = AppTextStyle.T2, - color = GrayColor.C500, - ) - } } Spacer(modifier = Modifier.weight(1f)) From d81c68a63f0886cb8434876077ffcebcd5274a55 Mon Sep 17 00:00:00 2001 From: chanho0908 Date: Fri, 6 Mar 2026 19:53:05 +0900 Subject: [PATCH 10/27] =?UTF-8?q?=E2=9C=A8=20Feat:=20=ED=95=B4=EC=A7=80?= =?UTF-8?q?=ED=95=9C=20=EC=BB=A4=ED=94=8C=20=EB=B3=B5=EA=B5=AC=20=EB=B2=84?= =?UTF-8?q?=ED=8A=BC=20UI=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../onboarding/couple/CoupleConnectRoute.kt | 25 ++++++++++++++----- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/feature/onboarding/src/main/java/com/twix/onboarding/couple/CoupleConnectRoute.kt b/feature/onboarding/src/main/java/com/twix/onboarding/couple/CoupleConnectRoute.kt index d9e5719b..cfca34d6 100644 --- a/feature/onboarding/src/main/java/com/twix/onboarding/couple/CoupleConnectRoute.kt +++ b/feature/onboarding/src/main/java/com/twix/onboarding/couple/CoupleConnectRoute.kt @@ -6,8 +6,10 @@ import android.content.pm.PackageManager import android.os.Build import androidx.compose.foundation.Image 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.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth @@ -23,6 +25,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.vectorResource import androidx.compose.ui.text.style.TextAlign @@ -151,16 +154,26 @@ fun CoupleConnectScreen( Spacer(modifier = Modifier.height(20.dp)) - AppText( - text = stringResource(R.string.onboarding_couple_restore), - style = AppTextStyle.B1, - color = GrayColor.C400, - textAlign = TextAlign.Center, + Row( modifier = Modifier .fillMaxWidth() .noRippleClickable(onClick = onClickRestore), - ) + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.Center + ) { + AppText( + text = stringResource(R.string.onboarding_couple_restore), + style = AppTextStyle.B1, + color = GrayColor.C400, + ) + + Image( + painter = painterResource(R.drawable.ic_arrow_m_right), + contentDescription = null + ) + } + } CommonBottomSheet( From 306ef3d260d72ea6343a0a1a4c3f4876175f3be1 Mon Sep 17 00:00:00 2001 From: chanho0908 Date: Fri, 6 Mar 2026 20:15:28 +0900 Subject: [PATCH 11/27] =?UTF-8?q?=E2=9C=A8=20Feat:=20=ED=95=B4=EC=A7=80?= =?UTF-8?q?=ED=95=9C=20=EC=BB=A4=ED=94=8C=20=EB=B0=94=ED=85=80=EC=8B=9C?= =?UTF-8?q?=ED=8A=B8=20=EB=94=94=EC=9E=90=EC=9D=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../onboarding/couple/CoupleConnectRoute.kt | 6 ++--- .../RestoreCoupleBottomSheetContent.kt | 22 ++++++++++--------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/feature/onboarding/src/main/java/com/twix/onboarding/couple/CoupleConnectRoute.kt b/feature/onboarding/src/main/java/com/twix/onboarding/couple/CoupleConnectRoute.kt index cfca34d6..247b4f1a 100644 --- a/feature/onboarding/src/main/java/com/twix/onboarding/couple/CoupleConnectRoute.kt +++ b/feature/onboarding/src/main/java/com/twix/onboarding/couple/CoupleConnectRoute.kt @@ -28,7 +28,6 @@ import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.vectorResource -import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.core.app.NotificationManagerCompat @@ -160,7 +159,7 @@ fun CoupleConnectScreen( .fillMaxWidth() .noRippleClickable(onClick = onClickRestore), verticalAlignment = Alignment.CenterVertically, - horizontalArrangement = Arrangement.Center + horizontalArrangement = Arrangement.Center, ) { AppText( text = stringResource(R.string.onboarding_couple_restore), @@ -170,10 +169,9 @@ fun CoupleConnectScreen( Image( painter = painterResource(R.drawable.ic_arrow_m_right), - contentDescription = null + contentDescription = null, ) } - } CommonBottomSheet( diff --git a/feature/onboarding/src/main/java/com/twix/onboarding/couple/component/RestoreCoupleBottomSheetContent.kt b/feature/onboarding/src/main/java/com/twix/onboarding/couple/component/RestoreCoupleBottomSheetContent.kt index 009aa122..6e778be4 100644 --- a/feature/onboarding/src/main/java/com/twix/onboarding/couple/component/RestoreCoupleBottomSheetContent.kt +++ b/feature/onboarding/src/main/java/com/twix/onboarding/couple/component/RestoreCoupleBottomSheetContent.kt @@ -16,7 +16,6 @@ import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp @@ -26,17 +25,14 @@ import com.twix.designsystem.theme.TwixTheme import com.twix.domain.model.enums.AppTextStyle import com.twix.designsystem.R as DesR -private val RestoreBgColor = Color(0xFFF6F7F7) -private val BulletColor = Color(0xFF999999) - @Composable internal fun RestoreCoupleBottomSheetContent() { Column( modifier = Modifier .fillMaxWidth() - .padding(30.dp), - verticalArrangement = Arrangement.spacedBy(18.dp), + .padding(bottom = 16.dp) + .padding(horizontal = 30.dp), ) { AppText( text = stringResource(DesR.string.onboarding_couple_restore), @@ -44,18 +40,22 @@ internal fun RestoreCoupleBottomSheetContent() { color = GrayColor.C500, ) + Spacer(Modifier.height(3.dp)) + AppText( text = stringResource(DesR.string.onboarding_couple_restore_bottom_sheet_content), style = AppTextStyle.B2, color = GrayColor.C400, ) + Spacer(Modifier.height(18.dp)) + Column( modifier = Modifier .fillMaxWidth() .height(78.dp) - .background(RestoreBgColor, RoundedCornerShape(12.dp)), + .background(GrayColor.C050, RoundedCornerShape(12.dp)), verticalArrangement = Arrangement.Center, ) { BulletItem(stringResource(DesR.string.onboarding_couple_restore_content_my_email)) @@ -69,13 +69,15 @@ internal fun RestoreCoupleBottomSheetContent() { private fun BulletItem(text: String) { Row( verticalAlignment = Alignment.CenterVertically, - modifier = Modifier.padding(start = 16.dp), + modifier = + Modifier + .padding(start = 16.dp), ) { Box( modifier = Modifier .size(6.dp) - .background(BulletColor, CircleShape), + .background(GrayColor.C300, CircleShape), ) Spacer(Modifier.width(8.dp)) @@ -83,7 +85,7 @@ private fun BulletItem(text: String) { AppText( text = text, style = AppTextStyle.B4, - color = BulletColor, + color = GrayColor.C300, ) } } From 9d0589a20798d70cddd769db1136855d7f0f6110 Mon Sep 17 00:00:00 2001 From: chanho0908 Date: Fri, 6 Mar 2026 20:19:43 +0900 Subject: [PATCH 12/27] =?UTF-8?q?=E2=9C=A8=20Feat:=20=EC=B4=88=EB=8C=80=20?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=ED=85=8D=EC=8A=A4=ED=8A=B8=ED=95=84?= =?UTF-8?q?=EB=93=9C=20=EC=9E=90=EB=8F=99=20=ED=99=9C=EC=84=B1=ED=99=94=20?= =?UTF-8?q?=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/twix/onboarding/invite/InviteCodeScreen.kt | 6 ------ 1 file changed, 6 deletions(-) diff --git a/feature/onboarding/src/main/java/com/twix/onboarding/invite/InviteCodeScreen.kt b/feature/onboarding/src/main/java/com/twix/onboarding/invite/InviteCodeScreen.kt index 295acc89..8a3c927b 100644 --- a/feature/onboarding/src/main/java/com/twix/onboarding/invite/InviteCodeScreen.kt +++ b/feature/onboarding/src/main/java/com/twix/onboarding/invite/InviteCodeScreen.kt @@ -118,12 +118,6 @@ private fun InviteCodeScreen( onComplete: () -> Unit, onCopyInviteCode: () -> Unit, ) { - val focusRequester = remember { FocusRequester() } - - LaunchedEffect(Unit) { - focusRequester.requestFocus() - } - Box( modifier = Modifier From 1cb423d6167d09f0b2cfd29c474fc48211d948a9 Mon Sep 17 00:00:00 2001 From: chanho0908 Date: Fri, 6 Mar 2026 20:29:43 +0900 Subject: [PATCH 13/27] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Refactor:=20`OnBoard?= =?UTF-8?q?ingUiState`=20=EB=82=B4=20=EC=83=81=ED=83=9C=20=EC=97=85?= =?UTF-8?q?=EB=8D=B0=EC=9D=B4=ED=8A=B8=20=ED=8E=B8=EC=9D=98=20=EB=A9=94?= =?UTF-8?q?=EC=84=9C=EB=93=9C=20=EC=A0=9C=EA=B1=B0=20=EB=B0=8F=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20viewModel=EB=A1=9C=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../twix/onboarding/OnBoardingViewModel.kt | 32 ++++++++++++++++--- .../onboarding/contract/OnBoardingUiState.kt | 9 ------ .../onboarding/invite/InviteCodeUiModel.kt | 13 +------- 3 files changed, 29 insertions(+), 25 deletions(-) diff --git a/feature/onboarding/src/main/java/com/twix/onboarding/OnBoardingViewModel.kt b/feature/onboarding/src/main/java/com/twix/onboarding/OnBoardingViewModel.kt index 0a35fd48..567e4e18 100644 --- a/feature/onboarding/src/main/java/com/twix/onboarding/OnBoardingViewModel.kt +++ b/feature/onboarding/src/main/java/com/twix/onboarding/OnBoardingViewModel.kt @@ -4,6 +4,7 @@ import androidx.lifecycle.viewModelScope import com.twix.designsystem.R import com.twix.designsystem.components.toast.model.ToastType import com.twix.domain.model.OnboardingStatus +import com.twix.domain.model.invitecode.InviteCode import com.twix.domain.repository.NotificationRepository import com.twix.domain.repository.OnBoardingRepository import com.twix.onboarding.contract.OnBoardingIntent @@ -25,7 +26,16 @@ class OnBoardingViewModel( private fun fetchMyInviteCode() { launchResult( block = { onBoardingRepository.fetchInviteCode() }, - onSuccess = { reduce { updateMyInviteCode(it.value) } }, + onSuccess = { fetchedInviteCode -> + reduce { + copy( + inviteCode = + inviteCode.copy( + myInviteCode = fetchedInviteCode.value, + ), + ) + } + }, onError = { showToast(R.string.onboarding_couple_fetch_my_invite_code_fail, ToastType.ERROR) }, @@ -58,7 +68,17 @@ class OnBoardingViewModel( } private fun reduceInviteCode(value: String) { - reduce { updatePartnerInviteCode(value) } + val isValidInviteCode = InviteCode.create(value).isSuccess + + reduce { + copy( + inviteCode = + inviteCode.copy( + partnerInviteCode = value, + isValid = isValidInviteCode, + ), + ) + } } private fun connectCouple() { @@ -95,7 +115,7 @@ class OnBoardingViewModel( } private fun reduceNickName(value: String) { - reduce { updateNickName(value) } + reduce { copy(profile = profile.updateNickname(value)) } } private fun handleSubmitNickname() { @@ -141,7 +161,11 @@ class OnBoardingViewModel( } private fun reduceDday(value: LocalDate) { - reduce { updateDday(value) } + reduce { + copy( + dDay = dDay.updateAnniversaryDate(value), + ) + } } private fun anniversarySetup() { diff --git a/feature/onboarding/src/main/java/com/twix/onboarding/contract/OnBoardingUiState.kt b/feature/onboarding/src/main/java/com/twix/onboarding/contract/OnBoardingUiState.kt index 5cba6794..c5e675d5 100644 --- a/feature/onboarding/src/main/java/com/twix/onboarding/contract/OnBoardingUiState.kt +++ b/feature/onboarding/src/main/java/com/twix/onboarding/contract/OnBoardingUiState.kt @@ -5,7 +5,6 @@ import com.twix.onboarding.dday.DdayUiModel import com.twix.onboarding.invite.InviteCodeUiModel import com.twix.onboarding.profile.ProfileUiModel import com.twix.ui.base.State -import java.time.LocalDate @Immutable data class OnBoardingUiState( @@ -15,12 +14,4 @@ data class OnBoardingUiState( ) : State { val isValidNickName: Boolean get() = profile.isValid - - fun updateNickName(value: String) = copy(profile = profile.updateNickname(value)) - - fun updateMyInviteCode(value: String) = copy(inviteCode = inviteCode.updateMyInviteCode(value)) - - fun updatePartnerInviteCode(value: String) = copy(inviteCode = inviteCode.updatePartnerInviteCode(value)) - - fun updateDday(value: LocalDate) = copy(dDay = dDay.updateAnniversaryDate(value)) } diff --git a/feature/onboarding/src/main/java/com/twix/onboarding/invite/InviteCodeUiModel.kt b/feature/onboarding/src/main/java/com/twix/onboarding/invite/InviteCodeUiModel.kt index 82f37d58..f24f98dc 100644 --- a/feature/onboarding/src/main/java/com/twix/onboarding/invite/InviteCodeUiModel.kt +++ b/feature/onboarding/src/main/java/com/twix/onboarding/invite/InviteCodeUiModel.kt @@ -1,21 +1,10 @@ package com.twix.onboarding.invite import androidx.compose.runtime.Immutable -import com.twix.domain.model.invitecode.InviteCode @Immutable data class InviteCodeUiModel( val myInviteCode: String = "", val partnerInviteCode: String = "", val isValid: Boolean = false, -) { - fun updateMyInviteCode(value: String): InviteCodeUiModel = copy(myInviteCode = value) - - fun updatePartnerInviteCode(value: String): InviteCodeUiModel = - InviteCode - .create(value) - .fold( - onSuccess = { copy(partnerInviteCode = value, isValid = true) }, - onFailure = { copy(partnerInviteCode = value, isValid = false) }, - ) -} +) From fcfaced454515cf618c19cb7ef11667b6b6441b6 Mon Sep 17 00:00:00 2001 From: chanho0908 Date: Fri, 6 Mar 2026 20:33:30 +0900 Subject: [PATCH 14/27] =?UTF-8?q?=E2=9C=A8=20Feat:=20=EC=B4=88=EB=8C=80=20?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EC=9E=85=EB=A0=A5=20=EC=8B=9C=20=EA=B3=B5?= =?UTF-8?q?=EB=B0=B1=20=EC=A0=9C=EA=B1=B0=20=EB=A1=9C=EC=A7=81=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../onboarding/invite/component/InviteCodeTextField.kt | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/feature/onboarding/src/main/java/com/twix/onboarding/invite/component/InviteCodeTextField.kt b/feature/onboarding/src/main/java/com/twix/onboarding/invite/component/InviteCodeTextField.kt index 5ddd979d..3d288526 100644 --- a/feature/onboarding/src/main/java/com/twix/onboarding/invite/component/InviteCodeTextField.kt +++ b/feature/onboarding/src/main/java/com/twix/onboarding/invite/component/InviteCodeTextField.kt @@ -37,9 +37,10 @@ fun InviteCodeTextField( BasicTextField( modifier = modifier, value = TextFieldValue(inviteCode, selection = TextRange(inviteCode.length)), - onValueChange = { - if (it.text.length <= InviteCode.INVITE_CODE_LENGTH) { - onValueChange(it.text) + onValueChange = { newValue -> + val filteredText = newValue.text.filterNot { char -> char.isWhitespace() } + if (filteredText.length <= InviteCode.INVITE_CODE_LENGTH) { + onValueChange(filteredText) } }, decorationBox = { From d24bfa8ea4de3168cd0b809a23cbe48429ffd1b3 Mon Sep 17 00:00:00 2001 From: chanho0908 Date: Fri, 6 Mar 2026 20:38:45 +0900 Subject: [PATCH 15/27] =?UTF-8?q?=E2=9C=A8=20Feat:=20=EC=B4=88=EB=8C=80=20?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EC=9E=85=EB=A0=A5=20=EC=8B=9C=20=EC=9E=90?= =?UTF-8?q?=EB=8F=99=20=EB=8C=80=EB=AC=B8=EC=9E=90=20=ED=82=A4=EB=B3=B4?= =?UTF-8?q?=EB=93=9C=20=EC=84=A4=EC=A0=95=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../twix/onboarding/invite/component/InviteCodeTextField.kt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/feature/onboarding/src/main/java/com/twix/onboarding/invite/component/InviteCodeTextField.kt b/feature/onboarding/src/main/java/com/twix/onboarding/invite/component/InviteCodeTextField.kt index 3d288526..00ae098f 100644 --- a/feature/onboarding/src/main/java/com/twix/onboarding/invite/component/InviteCodeTextField.kt +++ b/feature/onboarding/src/main/java/com/twix/onboarding/invite/component/InviteCodeTextField.kt @@ -14,11 +14,13 @@ import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.width import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.text.BasicTextField +import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.text.TextRange +import androidx.compose.ui.text.input.KeyboardCapitalization import androidx.compose.ui.text.input.TextFieldValue import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp @@ -52,6 +54,10 @@ fun InviteCodeTextField( } } }, + keyboardOptions = + KeyboardOptions( + capitalization = KeyboardCapitalization.Characters, + ), ) } From 6790ac63fad2e3d796800858e201b7c24b3a2c81 Mon Sep 17 00:00:00 2001 From: chanho0908 Date: Fri, 6 Mar 2026 21:24:27 +0900 Subject: [PATCH 16/27] =?UTF-8?q?=E2=9C=A8=20Feat:=20=EC=B4=88=EB=8C=80=20?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EB=B3=B5=EC=82=AC=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EA=B0=9C=EC=84=A0=20=EB=B0=8F=20SideEffect=20=EC=B2=98?= =?UTF-8?q?=EB=A6=AC=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - `OnBoardingSideEffect` 내에 `CopyInviteCode` 타입을 추가하여 UI 레이어에서 복사 로직을 처리하도록 변경 - `OnBoardingViewModel`에서 토스트 메시지를 직접 띄우는 대신 `CopyInviteCode` SideEffect를 방출하도록 수정 - `InviteCodeScreen`에서 클립보드 복사 및 Android 13(API 33) 이상 중복 알림 방지 로직 적용 --- .../twix/onboarding/OnBoardingViewModel.kt | 3 +- .../contract/OnBoardingSideEffect.kt | 4 ++ .../onboarding/invite/InviteCodeScreen.kt | 51 ++++++++++++------- 3 files changed, 37 insertions(+), 21 deletions(-) diff --git a/feature/onboarding/src/main/java/com/twix/onboarding/OnBoardingViewModel.kt b/feature/onboarding/src/main/java/com/twix/onboarding/OnBoardingViewModel.kt index 567e4e18..1376b30f 100644 --- a/feature/onboarding/src/main/java/com/twix/onboarding/OnBoardingViewModel.kt +++ b/feature/onboarding/src/main/java/com/twix/onboarding/OnBoardingViewModel.kt @@ -48,8 +48,7 @@ class OnBoardingViewModel( is OnBoardingIntent.WriteInviteCode -> reduceInviteCode(intent.value) OnBoardingIntent.ConnectCouple -> connectCouple() OnBoardingIntent.CopyInviteCode -> - showToast(R.string.toast_invite_code_copy, ToastType.SUCCESS) - + emitSideEffect(OnBoardingSideEffect.InviteCode.CopyInviteCode(currentState.inviteCode.myInviteCode)) // 프로필 설정 화면 is OnBoardingIntent.WriteNickName -> reduceNickName(intent.value) OnBoardingIntent.SubmitNickName -> handleSubmitNickname() diff --git a/feature/onboarding/src/main/java/com/twix/onboarding/contract/OnBoardingSideEffect.kt b/feature/onboarding/src/main/java/com/twix/onboarding/contract/OnBoardingSideEffect.kt index eba564f7..61a086c4 100644 --- a/feature/onboarding/src/main/java/com/twix/onboarding/contract/OnBoardingSideEffect.kt +++ b/feature/onboarding/src/main/java/com/twix/onboarding/contract/OnBoardingSideEffect.kt @@ -12,6 +12,10 @@ sealed interface OnBoardingSideEffect : SideEffect { sealed interface InviteCode : OnBoardingSideEffect { data object NavigateToNext : InviteCode + + data class CopyInviteCode( + val inviteCode: String, + ) : InviteCode } sealed interface DdaySetting : OnBoardingSideEffect { diff --git a/feature/onboarding/src/main/java/com/twix/onboarding/invite/InviteCodeScreen.kt b/feature/onboarding/src/main/java/com/twix/onboarding/invite/InviteCodeScreen.kt index 8a3c927b..0367a9f5 100644 --- a/feature/onboarding/src/main/java/com/twix/onboarding/invite/InviteCodeScreen.kt +++ b/feature/onboarding/src/main/java/com/twix/onboarding/invite/InviteCodeScreen.kt @@ -1,6 +1,7 @@ package com.twix.onboarding.invite import android.content.ClipData +import android.os.Build import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeOut @@ -22,15 +23,14 @@ import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.foundation.shape.RoundedCornerShape 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 import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.rememberUpdatedState +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.focus.FocusRequester -import androidx.compose.ui.focus.focusRequester import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.platform.LocalClipboard import androidx.compose.ui.platform.LocalContext @@ -45,6 +45,7 @@ import com.twix.designsystem.components.button.AppButton import com.twix.designsystem.components.text.AppText import com.twix.designsystem.components.toast.ToastManager import com.twix.designsystem.components.toast.model.ToastData +import com.twix.designsystem.components.toast.model.ToastType import com.twix.designsystem.theme.CommonColor import com.twix.designsystem.theme.GrayColor import com.twix.designsystem.theme.TwixTheme @@ -84,7 +85,32 @@ internal fun InviteCodeRoute( ), ) } + OnBoardingSideEffect.InviteCode.NavigateToNext -> navigateToNext() + is OnBoardingSideEffect.InviteCode.CopyInviteCode -> { + coroutineScope.launch { + val clipData = + ClipData + .newPlainText( + "inviteCode", + sideEffect.inviteCode, + ).toClipEntry() + clipboard.setClipEntry(clipData) + } + + /** + * https://developer.android.com/develop/ui/views/touch-and-input/copy-paste?hl=ko#duplicate-notifications + * */ + if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.S_V2) { + toastManager.tryShow( + ToastData( + currentContext.getString(R.string.toast_invite_code_copy), + ToastType.SUCCESS, + ), + ) + } + } + else -> Unit } } @@ -95,17 +121,7 @@ internal fun InviteCodeRoute( navigateToBack = navigateToBack, onChangeInviteCode = { viewModel.dispatch(OnBoardingIntent.WriteInviteCode(it)) }, onComplete = { viewModel.dispatch(OnBoardingIntent.ConnectCouple) }, - onCopyInviteCode = { - val clipData = - ClipData.newPlainText( - "inviteCode", - uiState.inviteCode.myInviteCode, - ) - coroutineScope.launch { - clipboard.setClipEntry(clipData.toClipEntry()) - } - viewModel.dispatch(OnBoardingIntent.CopyInviteCode) - }, + onCopyInviteCode = { viewModel.dispatch(OnBoardingIntent.CopyInviteCode) }, ) } @@ -133,7 +149,7 @@ private fun InviteCodeScreen( contentAlignment = Alignment.CenterStart, ) { Image( - imageVector = ImageVector.vectorResource(com.twix.designsystem.R.drawable.ic_arrow_m_left), + imageVector = ImageVector.vectorResource(R.drawable.ic_arrow_m_left), contentDescription = null, modifier = Modifier @@ -215,10 +231,7 @@ private fun InviteCodeScreen( InviteCodeTextField( inviteCode = uiModel.partnerInviteCode, onValueChange = onChangeInviteCode, - modifier = - Modifier - .focusRequester(focusRequester) - .align(Alignment.CenterHorizontally), + modifier = Modifier.align(Alignment.CenterHorizontally), ) } From 4a91aec8a8395fd18cae35e8053e9381891fac56 Mon Sep 17 00:00:00 2001 From: chanho0908 Date: Tue, 10 Mar 2026 14:32:54 +0900 Subject: [PATCH 17/27] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Refactor:=20StatsDet?= =?UTF-8?q?ailScreen=20=ED=8C=A8=EB=94=A9=20=EB=B0=8F=20=EA=B0=84=EA=B2=A9?= =?UTF-8?q?=20=EC=A1=B0=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/twix/login/LoginScreen.kt | 62 +++++-------------- 1 file changed, 16 insertions(+), 46 deletions(-) diff --git a/feature/login/src/main/java/com/twix/login/LoginScreen.kt b/feature/login/src/main/java/com/twix/login/LoginScreen.kt index bbca89cc..8df4bf71 100644 --- a/feature/login/src/main/java/com/twix/login/LoginScreen.kt +++ b/feature/login/src/main/java/com/twix/login/LoginScreen.kt @@ -3,30 +3,22 @@ package com.twix.login import androidx.compose.foundation.Image 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.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.offset import androidx.compose.foundation.layout.padding import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableFloatStateOf -import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.rememberUpdatedState import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.vector.ImageVector -import androidx.compose.ui.layout.boundsInParent -import androidx.compose.ui.layout.onGloballyPositioned import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.vectorResource import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.unit.IntOffset import androidx.compose.ui.unit.dp import com.twix.designsystem.R import com.twix.designsystem.components.button.LoginButton @@ -82,10 +74,6 @@ fun LoginRoute( @Composable private fun LoginScreen(onClickLogin: (LoginType) -> Unit) { - var imageBottomPx by remember { mutableFloatStateOf(0f) } - val density = LocalDensity.current - val offsetPx = with(density) { 34.dp.toPx() } - Column( modifier = Modifier @@ -111,41 +99,23 @@ private fun LoginScreen(onClickLogin: (LoginType) -> Unit) { Spacer(Modifier.height(27.dp)) - Box(modifier = Modifier.fillMaxSize()) { - Image( - imageVector = ImageVector.vectorResource(R.drawable.ic_singing), - contentDescription = null, - modifier = - Modifier - .onGloballyPositioned { coordinates -> - imageBottomPx = coordinates.boundsInParent().bottom - }, - ) + Image( + imageVector = ImageVector.vectorResource(R.drawable.ic_singing), + contentDescription = null, + ) - if (imageBottomPx != 0f) { - Column( - modifier = - Modifier - .padding(horizontal = 20.dp) - .offset { - IntOffset( - x = 0, - /** - * singing 이미지 하단 기준으로 로그인 버튼을 배치하고 - * 이미지와 버튼이 겹치는 만큼(34dp) 상단으로 이동 - * */ - y = (imageBottomPx - offsetPx).toInt(), - ) - }, - verticalArrangement = Arrangement.spacedBy(12.dp), - ) { - LoginType.entries.forEach { type -> - LoginButton( - type = type, - onClickLogin = onClickLogin, - ) - } - } + Column( + modifier = + Modifier + .padding(horizontal = 20.dp) + .padding(top = 29.dp, bottom = 27.dp), + verticalArrangement = Arrangement.spacedBy(12.dp), + ) { + LoginType.entries.forEach { type -> + LoginButton( + type = type, + onClickLogin = onClickLogin, + ) } } } From a7a713bd7c17e592fbfcaf294e82de0265bb70dc Mon Sep 17 00:00:00 2001 From: chanho0908 Date: Tue, 10 Mar 2026 14:52:16 +0900 Subject: [PATCH 18/27] =?UTF-8?q?=E2=9C=A8=20Feat:=20`ToastHost`=EC=97=90?= =?UTF-8?q?=20`imePadding`=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/twix/designsystem/components/toast/ToastHost.kt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/core/design-system/src/main/java/com/twix/designsystem/components/toast/ToastHost.kt b/core/design-system/src/main/java/com/twix/designsystem/components/toast/ToastHost.kt index 8c430c9f..41fd40bd 100644 --- a/core/design-system/src/main/java/com/twix/designsystem/components/toast/ToastHost.kt +++ b/core/design-system/src/main/java/com/twix/designsystem/components/toast/ToastHost.kt @@ -15,6 +15,7 @@ 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.imePadding import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width @@ -87,7 +88,10 @@ fun ToastHost( } Box( - modifier = modifier.fillMaxSize(), + modifier = + modifier + .fillMaxSize() + .imePadding(), contentAlignment = Alignment.BottomCenter, ) { AnimatedVisibility( From dda1ac6906c3e435e561c248d88c6eb1b842cc3c Mon Sep 17 00:00:00 2001 From: chanho0908 Date: Tue, 10 Mar 2026 15:02:19 +0900 Subject: [PATCH 19/27] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Refactor:=20`InviteC?= =?UTF-8?q?odeTextField`=20=EB=A1=9C=EC=A7=81=20=EB=8B=A8=EC=88=9C?= =?UTF-8?q?=ED=99=94=20=EB=B0=8F=20=EC=BB=A4=EC=84=9C=20=EC=95=A0=EB=8B=88?= =?UTF-8?q?=EB=A9=94=EC=9D=B4=EC=85=98=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - `TextFieldValue` 대신 `String`을 사용하도록 입력 로직 수정 - 커서의 깜빡임 애니메이션을 제거하고 `Cursor` 컴포넌트로 분리 - `Row` 내 아이템 간격 수정 (4.29.dp -> 4.dp) 및 코드 가독성 개선 --- .../invite/component/InviteCodeTextField.kt | 48 +++++++------------ 1 file changed, 18 insertions(+), 30 deletions(-) diff --git a/feature/onboarding/src/main/java/com/twix/onboarding/invite/component/InviteCodeTextField.kt b/feature/onboarding/src/main/java/com/twix/onboarding/invite/component/InviteCodeTextField.kt index 00ae098f..82cab94e 100644 --- a/feature/onboarding/src/main/java/com/twix/onboarding/invite/component/InviteCodeTextField.kt +++ b/feature/onboarding/src/main/java/com/twix/onboarding/invite/component/InviteCodeTextField.kt @@ -1,10 +1,5 @@ package com.twix.onboarding.invite.component -import androidx.compose.animation.core.RepeatMode -import androidx.compose.animation.core.animateFloat -import androidx.compose.animation.core.infiniteRepeatable -import androidx.compose.animation.core.rememberInfiniteTransition -import androidx.compose.animation.core.tween import androidx.compose.foundation.background import androidx.compose.foundation.border import androidx.compose.foundation.layout.Arrangement @@ -19,9 +14,7 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.text.TextRange import androidx.compose.ui.text.input.KeyboardCapitalization -import androidx.compose.ui.text.input.TextFieldValue import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.twix.designsystem.components.text.AppText @@ -38,17 +31,15 @@ fun InviteCodeTextField( ) { BasicTextField( modifier = modifier, - value = TextFieldValue(inviteCode, selection = TextRange(inviteCode.length)), - onValueChange = { newValue -> - val filteredText = newValue.text.filterNot { char -> char.isWhitespace() } - if (filteredText.length <= InviteCode.INVITE_CODE_LENGTH) { - onValueChange(filteredText) + value = inviteCode, + onValueChange = { newText -> + val filtered = newText.filterNot { it.isWhitespace() } + if (filtered.length <= InviteCode.INVITE_CODE_LENGTH && filtered != inviteCode) { + onValueChange(filtered) } }, decorationBox = { - Row( - horizontalArrangement = Arrangement.spacedBy(4.29.dp), - ) { + Row(horizontalArrangement = Arrangement.spacedBy(4.dp)) { repeat(InviteCode.INVITE_CODE_LENGTH) { index -> CodeBox(index, inviteCode) } @@ -67,12 +58,6 @@ private fun CodeBox( code: String, ) { val isFocused = code.length == index - val infiniteTransition = rememberInfiniteTransition() - val alpha by infiniteTransition.animateFloat( - 0f, - 1f, - infiniteRepeatable(tween(500), RepeatMode.Reverse), - ) Box( modifier = @@ -98,19 +83,22 @@ private fun CodeBox( ) } - isFocused -> { - Box( - modifier = - Modifier - .width(2.dp) - .height(24.dp) - .background(GrayColor.C500.copy(alpha = alpha)), - ) - } + isFocused -> Cursor() } } } +@Composable +private fun Cursor() { + Box( + modifier = + Modifier + .width(2.dp) + .height(24.dp) + .background(GrayColor.C500), + ) +} + @Preview(showBackground = true) @Composable fun InviteCodeTextFieldPreview() { From aa7374e8e6a08a16fcf48509c8b7a09a8744f763 Mon Sep 17 00:00:00 2001 From: chanho0908 Date: Tue, 10 Mar 2026 15:02:52 +0900 Subject: [PATCH 20/27] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Refactor:=20`OnBoard?= =?UTF-8?q?ingViewModel`=20=EB=82=B4=20=EB=AF=B8=EC=82=AC=EC=9A=A9=20`onEr?= =?UTF-8?q?ror`=20=EB=B8=94=EB=A1=9D=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/twix/onboarding/OnBoardingViewModel.kt | 3 --- 1 file changed, 3 deletions(-) diff --git a/feature/onboarding/src/main/java/com/twix/onboarding/OnBoardingViewModel.kt b/feature/onboarding/src/main/java/com/twix/onboarding/OnBoardingViewModel.kt index 1376b30f..14e4f3ea 100644 --- a/feature/onboarding/src/main/java/com/twix/onboarding/OnBoardingViewModel.kt +++ b/feature/onboarding/src/main/java/com/twix/onboarding/OnBoardingViewModel.kt @@ -153,9 +153,6 @@ class OnBoardingViewModel( emitSideEffect(sideEffect) } }, - onError = { - // 에러처리 추가 - }, ) } From 39ea35caa99d736ee4d0d626c27e3811b7db47fa Mon Sep 17 00:00:00 2001 From: chanho0908 Date: Tue, 10 Mar 2026 15:14:06 +0900 Subject: [PATCH 21/27] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Refactor:=20?= =?UTF-8?q?=EC=B4=88=EB=8C=80=20=EC=BD=94=EB=93=9C=20=ED=99=94=EB=A9=B4=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 --- .../onboarding/invite/InviteCodeScreen.kt | 57 ++++++++++++++----- 1 file changed, 42 insertions(+), 15 deletions(-) diff --git a/feature/onboarding/src/main/java/com/twix/onboarding/invite/InviteCodeScreen.kt b/feature/onboarding/src/main/java/com/twix/onboarding/invite/InviteCodeScreen.kt index 0367a9f5..f2b28cda 100644 --- a/feature/onboarding/src/main/java/com/twix/onboarding/invite/InviteCodeScreen.kt +++ b/feature/onboarding/src/main/java/com/twix/onboarding/invite/InviteCodeScreen.kt @@ -190,15 +190,28 @@ private fun InviteCodeScreen( horizontalAlignment = Alignment.CenterHorizontally, verticalArrangement = Arrangement.Center, ) { - AppText( - text = stringResource(R.string.onboarding_invite_code_my_invite_code), - style = AppTextStyle.B3, - color = GrayColor.C400, - ) + Box( + modifier = + Modifier + .height(18.dp) + .fillMaxWidth(), + contentAlignment = Alignment.Center, + ) { + AppText( + text = stringResource(R.string.onboarding_invite_code_my_invite_code), + style = AppTextStyle.B3, + color = GrayColor.C400, + ) + } Spacer(modifier = Modifier.height(6.dp)) Row( + modifier = + Modifier + .height(39.dp) + .fillMaxWidth(), + horizontalArrangement = Arrangement.Center, verticalAlignment = Alignment.CenterVertically, ) { AppText( @@ -219,12 +232,19 @@ private fun InviteCodeScreen( Spacer(modifier = Modifier.height(52.dp)) - AppText( - text = stringResource(R.string.onboarding_invite_code_write_invite_code), - style = AppTextStyle.B3, - color = GrayColor.C500, - modifier = Modifier.align(Alignment.CenterHorizontally), - ) + Box( + modifier = + Modifier + .fillMaxWidth() + .height(18.dp), + contentAlignment = Alignment.Center, + ) { + AppText( + text = stringResource(R.string.onboarding_invite_code_write_invite_code), + style = AppTextStyle.B3, + color = GrayColor.C500, + ) + } Spacer(modifier = Modifier.height(12.dp)) @@ -252,16 +272,23 @@ private fun InviteCodeScreen( } } -@Preview(name = "InviteCodeScreen", showBackground = true) +@Preview(showBackground = true) @Composable private fun InviteCodeScreenPreview() { TwixTheme { + var textState by remember { mutableStateOf("") } + InviteCodeScreen( - uiModel = InviteCodeUiModel(), - onChangeInviteCode = {}, + uiModel = + InviteCodeUiModel( + partnerInviteCode = textState, + myInviteCode = "ABCDEFG", + isValid = textState.length == 6, + ), + onChangeInviteCode = { textState = it }, onComplete = {}, navigateToBack = {}, - keyboardState = Keyboard.Opened, + keyboardState = Keyboard.Closed, onCopyInviteCode = {}, ) } From c6aad64ddd63685b6ffd4643a6e45c4147529078 Mon Sep 17 00:00:00 2001 From: chanho0908 Date: Tue, 10 Mar 2026 15:24:42 +0900 Subject: [PATCH 22/27] =?UTF-8?q?=E2=9C=A8=20Feat:=20CoupleConnectRoute=20?= =?UTF-8?q?=EC=84=B8=EB=A1=9C=20=EC=8A=A4=ED=81=AC=EB=A1=A4=20=EC=A0=81?= =?UTF-8?q?=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/twix/onboarding/couple/CoupleConnectRoute.kt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/feature/onboarding/src/main/java/com/twix/onboarding/couple/CoupleConnectRoute.kt b/feature/onboarding/src/main/java/com/twix/onboarding/couple/CoupleConnectRoute.kt index 247b4f1a..6364503c 100644 --- a/feature/onboarding/src/main/java/com/twix/onboarding/couple/CoupleConnectRoute.kt +++ b/feature/onboarding/src/main/java/com/twix/onboarding/couple/CoupleConnectRoute.kt @@ -15,6 +15,8 @@ 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.rememberScrollState +import androidx.compose.foundation.verticalScroll import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf @@ -117,11 +119,14 @@ fun CoupleConnectScreen( onDismissSheet: () -> Unit, onClickBack: () -> Unit, ) { + val scrollState = rememberScrollState() + Box( modifier = Modifier .fillMaxSize() - .background(color = CommonColor.White), + .background(color = CommonColor.White) + .verticalScroll(scrollState), ) { Column { CoupleConnectTopbar(onClickBack = onClickBack) From 33396edcdb27b3b5f6e333e8fe18bd7149c0f607 Mon Sep 17 00:00:00 2001 From: chanho0908 Date: Tue, 10 Mar 2026 15:25:11 +0900 Subject: [PATCH 23/27] =?UTF-8?q?=E2=9C=A8=20Feat:=20`InviteCodeScreen`=20?= =?UTF-8?q?=EC=8A=A4=ED=81=AC=EB=A1=A4=EC=8B=9C=20gradient=20=ED=9A=A8?= =?UTF-8?q?=EA=B3=BC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../onboarding/invite/InviteCodeScreen.kt | 79 +++++++++++++++---- 1 file changed, 63 insertions(+), 16 deletions(-) diff --git a/feature/onboarding/src/main/java/com/twix/onboarding/invite/InviteCodeScreen.kt b/feature/onboarding/src/main/java/com/twix/onboarding/invite/InviteCodeScreen.kt index f2b28cda..b7e1bd60 100644 --- a/feature/onboarding/src/main/java/com/twix/onboarding/invite/InviteCodeScreen.kt +++ b/feature/onboarding/src/main/java/com/twix/onboarding/invite/InviteCodeScreen.kt @@ -21,7 +21,9 @@ import androidx.compose.foundation.layout.imePadding import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width +import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.foundation.verticalScroll import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf @@ -31,6 +33,8 @@ import androidx.compose.runtime.rememberUpdatedState import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Brush +import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.platform.LocalClipboard import androidx.compose.ui.platform.LocalContext @@ -134,31 +138,20 @@ private fun InviteCodeScreen( onComplete: () -> Unit, onCopyInviteCode: () -> Unit, ) { + val scrollState = rememberScrollState() + Box( modifier = Modifier .fillMaxSize() .background(CommonColor.White), ) { - Box( + Column( modifier = Modifier - .fillMaxWidth() - .height(72.dp) - .padding(horizontal = 10.dp, vertical = 14.dp), - contentAlignment = Alignment.CenterStart, + .fillMaxSize() + .verticalScroll(scrollState), ) { - Image( - imageVector = ImageVector.vectorResource(R.drawable.ic_arrow_m_left), - contentDescription = null, - modifier = - Modifier - .size(44.dp) - .noRippleClickable(onClick = navigateToBack), - ) - } - - Column { Spacer(modifier = Modifier.height(8.dp)) AnimatedVisibility( @@ -255,6 +248,29 @@ private fun InviteCodeScreen( ) } + Box( + modifier = + Modifier + .fillMaxWidth() + .height(72.dp) + .padding(horizontal = 10.dp, vertical = 14.dp), + contentAlignment = Alignment.CenterStart, + ) { + Image( + imageVector = ImageVector.vectorResource(R.drawable.ic_arrow_m_left), + contentDescription = null, + modifier = + Modifier + .size(44.dp) + .noRippleClickable(onClick = navigateToBack), + ) + } + + TopGradientOverlay( + visible = scrollState.value > 0, + modifier = Modifier.align(Alignment.TopCenter), + ) + AppButton( text = stringResource(R.string.onboarding_profile_button_title), onClick = { onComplete() }, @@ -272,6 +288,37 @@ private fun InviteCodeScreen( } } +@Composable +private fun TopGradientOverlay( + visible: Boolean, + modifier: Modifier = Modifier, +) { + AnimatedVisibility( + visible = visible, + enter = fadeIn(), + exit = fadeOut(), + modifier = modifier, + ) { + Box( + modifier = + Modifier + .fillMaxWidth() + .height(96.dp) + .background( + brush = + Brush.verticalGradient( + colors = + listOf( + CommonColor.White, + CommonColor.White.copy(alpha = 0.6f), + Color.Transparent, + ), + ), + ), + ) + } +} + @Preview(showBackground = true) @Composable private fun InviteCodeScreenPreview() { From 59e4ef2327e5569b02d3e9d219de2e02cf355897 Mon Sep 17 00:00:00 2001 From: chanho0908 Date: Tue, 10 Mar 2026 15:51:46 +0900 Subject: [PATCH 24/27] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Refactor:=20?= =?UTF-8?q?=EB=B6=88=ED=95=84=EC=9A=94=ED=95=9C=20=EB=A6=AC=EC=86=8C?= =?UTF-8?q?=EC=8A=A4=20=EC=9E=84=ED=8F=AC=ED=8A=B8=20=EB=B3=84=EC=B9=AD=20?= =?UTF-8?q?=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../couple/component/InvitationButton.kt | 4 ++-- .../component/RestoreCoupleBottomSheetContent.kt | 12 ++++++------ .../java/com/twix/onboarding/dday/DdayRoute.kt | 6 +++--- .../com/twix/onboarding/profile/ProfileScreen.kt | 14 +++++++------- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/feature/onboarding/src/main/java/com/twix/onboarding/couple/component/InvitationButton.kt b/feature/onboarding/src/main/java/com/twix/onboarding/couple/component/InvitationButton.kt index 752fe5af..aced9136 100644 --- a/feature/onboarding/src/main/java/com/twix/onboarding/couple/component/InvitationButton.kt +++ b/feature/onboarding/src/main/java/com/twix/onboarding/couple/component/InvitationButton.kt @@ -12,13 +12,13 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp +import com.twix.designsystem.R import com.twix.designsystem.components.text.AppText import com.twix.designsystem.theme.CommonColor import com.twix.designsystem.theme.GrayColor import com.twix.designsystem.theme.TwixTheme import com.twix.domain.model.enums.AppTextStyle import com.twix.ui.extension.noRippleClickable -import com.twix.designsystem.R as DesR @Composable internal fun InvitationButton( @@ -36,7 +36,7 @@ internal fun InvitationButton( contentAlignment = Alignment.Center, ) { AppText( - text = stringResource(DesR.string.onboarding_couple_connect_send_invitation), + text = stringResource(R.string.onboarding_couple_connect_send_invitation), style = AppTextStyle.T2, color = CommonColor.White, ) diff --git a/feature/onboarding/src/main/java/com/twix/onboarding/couple/component/RestoreCoupleBottomSheetContent.kt b/feature/onboarding/src/main/java/com/twix/onboarding/couple/component/RestoreCoupleBottomSheetContent.kt index 6e778be4..d4fa7ba2 100644 --- a/feature/onboarding/src/main/java/com/twix/onboarding/couple/component/RestoreCoupleBottomSheetContent.kt +++ b/feature/onboarding/src/main/java/com/twix/onboarding/couple/component/RestoreCoupleBottomSheetContent.kt @@ -19,11 +19,11 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp +import com.twix.designsystem.R import com.twix.designsystem.components.text.AppText import com.twix.designsystem.theme.GrayColor import com.twix.designsystem.theme.TwixTheme import com.twix.domain.model.enums.AppTextStyle -import com.twix.designsystem.R as DesR @Composable internal fun RestoreCoupleBottomSheetContent() { @@ -35,7 +35,7 @@ internal fun RestoreCoupleBottomSheetContent() { .padding(horizontal = 30.dp), ) { AppText( - text = stringResource(DesR.string.onboarding_couple_restore), + text = stringResource(R.string.onboarding_couple_restore), style = AppTextStyle.T1, color = GrayColor.C500, ) @@ -43,7 +43,7 @@ internal fun RestoreCoupleBottomSheetContent() { Spacer(Modifier.height(3.dp)) AppText( - text = stringResource(DesR.string.onboarding_couple_restore_bottom_sheet_content), + text = stringResource(R.string.onboarding_couple_restore_bottom_sheet_content), style = AppTextStyle.B2, color = GrayColor.C400, ) @@ -58,9 +58,9 @@ internal fun RestoreCoupleBottomSheetContent() { .background(GrayColor.C050, RoundedCornerShape(12.dp)), verticalArrangement = Arrangement.Center, ) { - BulletItem(stringResource(DesR.string.onboarding_couple_restore_content_my_email)) - BulletItem(stringResource(DesR.string.onboarding_couple_restore_content_partner_email)) - BulletItem(stringResource(DesR.string.onboarding_couple_restore_content_restore_date)) + BulletItem(stringResource(R.string.onboarding_couple_restore_content_my_email)) + BulletItem(stringResource(R.string.onboarding_couple_restore_content_partner_email)) + BulletItem(stringResource(R.string.onboarding_couple_restore_content_restore_date)) } } } diff --git a/feature/onboarding/src/main/java/com/twix/onboarding/dday/DdayRoute.kt b/feature/onboarding/src/main/java/com/twix/onboarding/dday/DdayRoute.kt index 23925abc..0eb8ab97 100644 --- a/feature/onboarding/src/main/java/com/twix/onboarding/dday/DdayRoute.kt +++ b/feature/onboarding/src/main/java/com/twix/onboarding/dday/DdayRoute.kt @@ -20,6 +20,7 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle +import com.twix.designsystem.R import com.twix.designsystem.components.bottomsheet.CommonBottomSheet import com.twix.designsystem.components.bottomsheet.model.CommonBottomSheetConfig import com.twix.designsystem.components.button.AppButton @@ -39,7 +40,6 @@ import com.twix.onboarding.dday.component.DdayTopBar import com.twix.ui.base.ObserveAsEvents import org.koin.compose.koinInject import java.time.LocalDate -import com.twix.designsystem.R as DesR @Composable fun DdayRoute( @@ -105,7 +105,7 @@ fun DdayScreen( Spacer(modifier = Modifier.height(8.dp)) AppText( - text = stringResource(DesR.string.onboarding_dday_plz_set_dday), + text = stringResource(R.string.onboarding_dday_plz_set_dday), style = AppTextStyle.H3, color = GrayColor.C500, modifier = Modifier.padding(start = 24.dp), @@ -121,7 +121,7 @@ fun DdayScreen( Spacer(Modifier.weight(1f)) AppButton( - text = stringResource(DesR.string.onboarding_profile_button_title), + text = stringResource(R.string.onboarding_profile_button_title), onClick = { onCompleted() }, backgroundColor = if (uiModel.isSelected) GrayColor.C500 else GrayColor.C100, textColor = if (uiModel.isSelected) CommonColor.White else GrayColor.C300, diff --git a/feature/onboarding/src/main/java/com/twix/onboarding/profile/ProfileScreen.kt b/feature/onboarding/src/main/java/com/twix/onboarding/profile/ProfileScreen.kt index da561404..e257aeca 100644 --- a/feature/onboarding/src/main/java/com/twix/onboarding/profile/ProfileScreen.kt +++ b/feature/onboarding/src/main/java/com/twix/onboarding/profile/ProfileScreen.kt @@ -28,6 +28,7 @@ import androidx.compose.ui.res.vectorResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.collectAsStateWithLifecycle +import com.twix.designsystem.R import com.twix.designsystem.components.button.AppButton import com.twix.designsystem.components.text.AppText import com.twix.designsystem.components.text_field.UnderlineTextField @@ -44,7 +45,6 @@ import com.twix.onboarding.contract.OnBoardingSideEffect import com.twix.ui.base.ObserveAsEvents import com.twix.ui.extension.noRippleClickable import org.koin.compose.koinInject -import com.twix.designsystem.R as DesR @Composable fun ProfileRoute( @@ -105,7 +105,7 @@ private fun ProfileScreen( Spacer(modifier = Modifier.height(80.dp)) AppText( - text = stringResource(DesR.string.onboarding_profile_title), + text = stringResource(R.string.onboarding_profile_title), style = AppTextStyle.H3, color = GrayColor.C500, modifier = Modifier.padding(start = 24.dp), @@ -115,12 +115,12 @@ private fun ProfileScreen( UnderlineTextField( value = uiModel.nickname, - placeHolder = stringResource(DesR.string.onboarding_name_placeholder), + placeHolder = stringResource(R.string.onboarding_name_placeholder), showTrailing = true, onValueChange = onChangeNickName, trailing = { Image( - imageVector = ImageVector.vectorResource(DesR.drawable.ic_clear_text), + imageVector = ImageVector.vectorResource(R.drawable.ic_clear_text), contentDescription = null, modifier = Modifier.noRippleClickable { onChangeNickName("") }, ) @@ -138,7 +138,7 @@ private fun ProfileScreen( verticalAlignment = Alignment.CenterVertically, ) { Icon( - imageVector = ImageVector.vectorResource(DesR.drawable.ic_check_success), + imageVector = ImageVector.vectorResource(R.drawable.ic_check_success), contentDescription = null, tint = if (uiModel.isValid) SystemColor.Success else GrayColor.C300, ) @@ -148,14 +148,14 @@ private fun ProfileScreen( AppText( style = AppTextStyle.C2, color = if (uiModel.isValid) SystemColor.Success else GrayColor.C300, - text = stringResource(id = DesR.string.onboarding_name_helper), + text = stringResource(id = R.string.onboarding_name_helper), ) } Spacer(modifier = Modifier.weight(1f)) AppButton( - text = stringResource(DesR.string.onboarding_profile_button_title), + text = stringResource(R.string.onboarding_profile_button_title), onClick = { onCompleted() }, backgroundColor = if (uiModel.isValid) GrayColor.C500 else GrayColor.C100, textColor = if (uiModel.isValid) CommonColor.White else GrayColor.C300, From 0e085baca6f901bd34fb21f67e9f555925f57d5a Mon Sep 17 00:00:00 2001 From: chanho0908 Date: Tue, 10 Mar 2026 16:10:11 +0900 Subject: [PATCH 25/27] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Refactor:=20CoupleCo?= =?UTF-8?q?nnectRoute=20=EC=8A=A4=ED=81=AC=EB=A1=A4=20=EC=A0=81=EC=9A=A9?= =?UTF-8?q?=20=EC=9C=84=EC=B9=98=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - `verticalScroll`을 상위 레이아웃에서 내부 `Column`으로 이동하여 스크롤 동작 수정 --- .../java/com/twix/onboarding/couple/CoupleConnectRoute.kt | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/feature/onboarding/src/main/java/com/twix/onboarding/couple/CoupleConnectRoute.kt b/feature/onboarding/src/main/java/com/twix/onboarding/couple/CoupleConnectRoute.kt index 6364503c..6d89879e 100644 --- a/feature/onboarding/src/main/java/com/twix/onboarding/couple/CoupleConnectRoute.kt +++ b/feature/onboarding/src/main/java/com/twix/onboarding/couple/CoupleConnectRoute.kt @@ -125,10 +125,11 @@ fun CoupleConnectScreen( modifier = Modifier .fillMaxSize() - .background(color = CommonColor.White) - .verticalScroll(scrollState), + .background(color = CommonColor.White), ) { - Column { + Column( + Modifier.verticalScroll(scrollState), + ) { CoupleConnectTopbar(onClickBack = onClickBack) Spacer(modifier = Modifier.height(8.dp)) From f766466883a6e9cddeb5c0a5f03de60d0809ae1c Mon Sep 17 00:00:00 2001 From: chanho0908 Date: Tue, 10 Mar 2026 16:15:46 +0900 Subject: [PATCH 26/27] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Refactor:=20`Connect?= =?UTF-8?q?Button`=20=EB=A0=88=EC=9D=B4=EC=95=84=EC=9B=83=20=EB=B0=8F=20?= =?UTF-8?q?=ED=85=8D=EC=8A=A4=ED=8A=B8=20=EC=A0=95=EB=A0=AC=20=EA=B0=9C?= =?UTF-8?q?=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../couple/component/ConnectButton.kt | 33 +++++++++++++------ 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/feature/onboarding/src/main/java/com/twix/onboarding/couple/component/ConnectButton.kt b/feature/onboarding/src/main/java/com/twix/onboarding/couple/component/ConnectButton.kt index 3cb05be8..e619f454 100644 --- a/feature/onboarding/src/main/java/com/twix/onboarding/couple/component/ConnectButton.kt +++ b/feature/onboarding/src/main/java/com/twix/onboarding/couple/component/ConnectButton.kt @@ -3,6 +3,7 @@ package com.twix.onboarding.couple.component import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.border +import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer @@ -49,20 +50,32 @@ internal fun ConnectButton( Column( modifier = Modifier + .padding(vertical = 20.dp) .padding(start = 25.dp), ) { - AppText( - text = stringResource(R.string.onboarding_couple_connect_direct_description), - style = AppTextStyle.C1, - color = GrayColor.C400, + Box( modifier = Modifier.height(18.dp), - ) - AppText( - text = stringResource(R.string.onboarding_couple_direct_connect_button_title), - style = AppTextStyle.T2, - color = GrayColor.C500, + contentAlignment = Alignment.Center, + ) { + AppText( + text = stringResource(R.string.onboarding_couple_connect_direct_description), + style = AppTextStyle.C1, + color = GrayColor.C400, + ) + } + + Spacer(Modifier.weight(1f)) + + Box( modifier = Modifier.height(24.dp), - ) + contentAlignment = Alignment.Center, + ) { + AppText( + text = stringResource(R.string.onboarding_couple_direct_connect_button_title), + style = AppTextStyle.T2, + color = GrayColor.C500, + ) + } } Spacer(modifier = Modifier.weight(1f)) From 9cc29f60f458cfec19ba8ab1cd1fc782e7e30f88 Mon Sep 17 00:00:00 2001 From: chanho0908 Date: Tue, 10 Mar 2026 16:20:25 +0900 Subject: [PATCH 27/27] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Refactor:=20LoginBut?= =?UTF-8?q?ton=20login=20=EB=AA=A8=EB=93=88=EB=A1=9C=20=EC=9D=B4=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- feature/login/src/main/java/com/twix/login/LoginScreen.kt | 3 +-- .../src/main/java/com/twix/login/component}/LoginButton.kt | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) rename {core/design-system/src/main/java/com/twix/designsystem/components/button => feature/login/src/main/java/com/twix/login/component}/LoginButton.kt (97%) diff --git a/feature/login/src/main/java/com/twix/login/LoginScreen.kt b/feature/login/src/main/java/com/twix/login/LoginScreen.kt index 8df4bf71..91d7e219 100644 --- a/feature/login/src/main/java/com/twix/login/LoginScreen.kt +++ b/feature/login/src/main/java/com/twix/login/LoginScreen.kt @@ -12,7 +12,6 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.rememberUpdatedState -import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.platform.LocalContext @@ -21,7 +20,6 @@ import androidx.compose.ui.res.vectorResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.twix.designsystem.R -import com.twix.designsystem.components.button.LoginButton import com.twix.designsystem.components.text.AppText import com.twix.designsystem.components.toast.ToastManager import com.twix.designsystem.components.toast.model.ToastData @@ -31,6 +29,7 @@ import com.twix.designsystem.theme.TwixTheme import com.twix.domain.model.OnboardingStatus import com.twix.domain.model.enums.AppTextStyle import com.twix.domain.model.enums.LoginType +import com.twix.login.component.LoginButton import com.twix.login.contract.LoginIntent import com.twix.login.contract.LoginSideEffect import com.twix.ui.base.ObserveAsEvents diff --git a/core/design-system/src/main/java/com/twix/designsystem/components/button/LoginButton.kt b/feature/login/src/main/java/com/twix/login/component/LoginButton.kt similarity index 97% rename from core/design-system/src/main/java/com/twix/designsystem/components/button/LoginButton.kt rename to feature/login/src/main/java/com/twix/login/component/LoginButton.kt index bcb058ed..e86b976b 100644 --- a/core/design-system/src/main/java/com/twix/designsystem/components/button/LoginButton.kt +++ b/feature/login/src/main/java/com/twix/login/component/LoginButton.kt @@ -1,4 +1,4 @@ -package com.twix.designsystem.components.button +package com.twix.login.component import androidx.compose.foundation.Image import androidx.compose.foundation.background @@ -27,7 +27,7 @@ import com.twix.domain.model.enums.LoginType import com.twix.ui.extension.noRippleClickable @Composable -fun LoginButton( +internal fun LoginButton( type: LoginType, onClickLogin: (LoginType) -> Unit, modifier: Modifier = Modifier,