From 11a25f755690e08a060751f0c59ff3962e2575c0 Mon Sep 17 00:00:00 2001 From: MoonsuKang Date: Sat, 21 Jun 2025 17:16:44 +0900 Subject: [PATCH 01/12] =?UTF-8?q?[ADD/#283]=20=EC=8A=A4=ED=8A=B8=EB=A7=81?= =?UTF-8?q?=20=EC=B6=94=EC=B6=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/res/values/strings.xml | 77 +++++++++++++++++++++++++++-- 1 file changed, 74 insertions(+), 3 deletions(-) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index b7880a66..ac44e6ff 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,11 +1,24 @@ 클로디 + + + 업데이트 필요 + 새로운 버전 %1$s을 사용할 수 있습니다.\n지금 업데이트하시겠습니까? + 업데이트 + 나중에 + + + 필수 업데이트 + 버전 %1$s으로 업데이트가 필요합니다. + 앱 종료 + 행운을 전하는 감사일기 카카오로 로그인 - + + 만나서 반가워요!\n어떻게 불러 드릴까요? 닉네임을 입력해주세요 다음 @@ -51,7 +64,7 @@ 로디가 답장을 거의 다 써가요!\n조금만 기다려주세요 열어보기 확인 - 답장 확인 + 광고 보고 바로 답장 받기 %1$d월 %2$d일 @@ -74,9 +87,13 @@ 나가기 임시저장 - + 저장 %1$d월 %2$d일 + 추가하기 + 보내기 + 일상 속 작은 감사함을 적어보세요 + 2~50자 까지 입력할 수 있어요. 최대 5개까지 작성할 수 있어요. @@ -96,7 +113,52 @@ 작성된 감사일기가 없어요 %1$s일 /%1$s + 답장 확인 + 임시저장된 일기가 있어요. + 작성된 감사 일기가 없어요! + %1$d. %2$s + %1$s요일 + + + 클로버 %1$d개 + %1$d년 %2$d월 + 월 선택 + + + 이어 쓰기 + 답장 확인 + 일기 쓰기 + + + 데이터를 불러오는데 실패했습니다. + 알 수 없는 오류가 발생했습니다. + 일기 삭제 중 오류가 발생했습니다. + + + 기한이 지나면\n로디의 답장을 받을 수 없어요! + 답장 마감 전에 일기를 이어쓸 수 있도록\n알려드리기 위해서는 알림 설정이 필요해요. + [설정 > 애플리케이션 > 클로디 > 알림 > 알림표시] + 알림 받기 + 다음에 하기 + + + 이어쓰기 알림 설정을 완료했어요. + + + 임시저장된 일기를 이어 쓸까요? + 답장 기한이 지나서 답장은 받을 수 없어요. + 이어쓰기 + 아니오 + + + 정말 일기를 삭제할까요? + 아직 답장이 오지 않았거나 삭제하고\n다시 작성한 일기는 답장을 받을 수 없어요. + 삭제할래요 + 아니요 + + + 월 선택 설정 @@ -142,4 +204,13 @@ 확인 알람 시간 설정을 완료했어요. + + 삭제하기 + 다른 날짜 보기 + 완료 + + + 오전 + 오후 + %1$s %2$s시 %3$s분 From 2811b7c3084365a09a45bdb02b65303a12f56e7a Mon Sep 17 00:00:00 2001 From: MoonsuKang Date: Sat, 21 Jun 2025 17:17:42 +0900 Subject: [PATCH 02/12] =?UTF-8?q?[ADD/#283]=20AM/PM=20=EA=B5=AC=EB=B6=84?= =?UTF-8?q?=EC=9D=84=20=EC=9C=84=ED=95=9C=20TimePeriod=20enum=20=ED=81=B4?= =?UTF-8?q?=EB=9E=98=EC=8A=A4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../presentation/utils/extension/TimePeriod.kt | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 app/src/main/java/com/sopt/clody/presentation/utils/extension/TimePeriod.kt diff --git a/app/src/main/java/com/sopt/clody/presentation/utils/extension/TimePeriod.kt b/app/src/main/java/com/sopt/clody/presentation/utils/extension/TimePeriod.kt new file mode 100644 index 00000000..e40ce77f --- /dev/null +++ b/app/src/main/java/com/sopt/clody/presentation/utils/extension/TimePeriod.kt @@ -0,0 +1,15 @@ +package com.sopt.clody.presentation.utils.extension + +import androidx.annotation.StringRes +import androidx.compose.runtime.Composable +import androidx.compose.ui.res.stringResource +import com.sopt.clody.R + +enum class TimePeriod(@StringRes val labelResId: Int) { + AM(R.string.time_am), + PM(R.string.time_pm), + ; + + @Composable + fun getLabel(): String = stringResource(labelResId) +} From 30a63668bb9aec10c09778d9f109eae50cfc2a3a Mon Sep 17 00:00:00 2001 From: MoonsuKang Date: Sat, 21 Jun 2025 17:18:49 +0900 Subject: [PATCH 03/12] =?UTF-8?q?[ADD/#283]=20=EC=9A=94=EC=9D=BC=20?= =?UTF-8?q?=ED=97=A4=EB=8D=94=20=EB=8B=A4=EA=B5=AD=EC=96=B4(Korean/English?= =?UTF-8?q?)=20=EC=A7=80=EC=9B=90=20=EA=B8=B0=EB=8A=A5=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 --- .../ui/home/calendar/component/WeekHeader.kt | 87 +++++++++++++------ 1 file changed, 60 insertions(+), 27 deletions(-) diff --git a/app/src/main/java/com/sopt/clody/presentation/ui/home/calendar/component/WeekHeader.kt b/app/src/main/java/com/sopt/clody/presentation/ui/home/calendar/component/WeekHeader.kt index ba985f67..9751c3fb 100644 --- a/app/src/main/java/com/sopt/clody/presentation/ui/home/calendar/component/WeekHeader.kt +++ b/app/src/main/java/com/sopt/clody/presentation/ui/home/calendar/component/WeekHeader.kt @@ -17,26 +17,64 @@ import androidx.compose.ui.unit.dp import com.sopt.clody.ui.theme.ClodyTheme import kotlinx.datetime.DayOfWeek +enum class WeekLang { + KOREAN, ENGLISH +} + +fun DayOfWeek.toKoreanShortLabel(): String { + return when (this) { + DayOfWeek.SUNDAY -> "일" + DayOfWeek.MONDAY -> "월" + DayOfWeek.TUESDAY -> "화" + DayOfWeek.WEDNESDAY -> "수" + DayOfWeek.THURSDAY -> "목" + DayOfWeek.FRIDAY -> "금" + DayOfWeek.SATURDAY -> "토" + } +} + +fun DayOfWeek.toEnglishShortLabel(): String { + return when (this) { + DayOfWeek.SUNDAY -> "Sun" + DayOfWeek.MONDAY -> "Mon" + DayOfWeek.TUESDAY -> "Tue" + DayOfWeek.WEDNESDAY -> "Wed" + DayOfWeek.THURSDAY -> "Thu" + DayOfWeek.FRIDAY -> "Fri" + DayOfWeek.SATURDAY -> "Sat" + } +} + +fun DayOfWeek.getLabel(lang: WeekLang): String { + return when (lang) { + WeekLang.KOREAN -> this.toKoreanShortLabel() + WeekLang.ENGLISH -> this.toEnglishShortLabel() + } +} + @Composable -fun WeekHeader(modifier: Modifier = Modifier, itemWidth: Dp) { - val itemWidth = (LocalConfiguration.current.screenWidthDp.dp - 40.dp) / 7 +fun WeekHeader( + modifier: Modifier = Modifier, + itemWidth: Dp = (LocalConfiguration.current.screenWidthDp.dp - 40.dp) / 7, + lang: WeekLang = WeekLang.KOREAN, +) { + val weekLabelArray = listOf( + DayOfWeek.SUNDAY, + DayOfWeek.MONDAY, + DayOfWeek.TUESDAY, + DayOfWeek.WEDNESDAY, + DayOfWeek.THURSDAY, + DayOfWeek.FRIDAY, + DayOfWeek.SATURDAY, + ) + + val labels = weekLabelArray.map { it.getLabel(lang) } + Row( horizontalArrangement = Arrangement.SpaceBetween, modifier = modifier.fillMaxWidth(), ) { - val weekLabelArray = listOf( - DayOfWeek.SUNDAY, - DayOfWeek.MONDAY, - DayOfWeek.TUESDAY, - DayOfWeek.WEDNESDAY, - DayOfWeek.THURSDAY, - DayOfWeek.FRIDAY, - DayOfWeek.SATURDAY, - ) - - val koreanWeekLabels = weekLabelArray.map { it.toKoreanShortLabel() } - - koreanWeekLabels.forEach { week -> + labels.forEach { week -> Box( modifier = Modifier.width(itemWidth), contentAlignment = Alignment.Center, @@ -52,19 +90,14 @@ fun WeekHeader(modifier: Modifier = Modifier, itemWidth: Dp) { } } -fun DayOfWeek.toKoreanShortLabel(): String { - return when (this) { - DayOfWeek.SUNDAY -> "일" - DayOfWeek.MONDAY -> "월" - DayOfWeek.TUESDAY -> "화" - DayOfWeek.WEDNESDAY -> "수" - DayOfWeek.THURSDAY -> "목" - DayOfWeek.FRIDAY -> "금" - DayOfWeek.SATURDAY -> "토" - } +@Preview(showBackground = true) +@Composable +fun WeekHeaderKoreanPreview() { + WeekHeader(lang = WeekLang.KOREAN) } -@Composable @Preview(showBackground = true) -fun WeekHeaderPreview() { +@Composable +fun WeekHeaderEnglishPreview() { + WeekHeader(lang = WeekLang.ENGLISH) } From f160c3ee1c9fe7178c8ae50ab3687fc22ba26961 Mon Sep 17 00:00:00 2001 From: MoonsuKang Date: Sat, 21 Jun 2025 17:19:11 +0900 Subject: [PATCH 04/12] =?UTF-8?q?[DEL/#283]=20=EC=95=88=EC=93=B0=EB=8A=94?= =?UTF-8?q?=20=ED=8C=8C=EC=9D=BC=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ui/auth/component/button/NextButton.kt | 36 ------------------- 1 file changed, 36 deletions(-) delete mode 100644 app/src/main/java/com/sopt/clody/presentation/ui/auth/component/button/NextButton.kt diff --git a/app/src/main/java/com/sopt/clody/presentation/ui/auth/component/button/NextButton.kt b/app/src/main/java/com/sopt/clody/presentation/ui/auth/component/button/NextButton.kt deleted file mode 100644 index 70816f4c..00000000 --- a/app/src/main/java/com/sopt/clody/presentation/ui/auth/component/button/NextButton.kt +++ /dev/null @@ -1,36 +0,0 @@ -package com.sopt.clody.presentation.ui.auth.component.button - -import androidx.compose.foundation.Image -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.size -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.res.painterResource -import androidx.compose.ui.unit.dp - -@Composable -fun NextButton( - onClick: () -> Unit, - imageResource: Int, - contentDescription: String? = null, -) { - Box( - modifier = Modifier.run { - size(23.dp) - .clip(CircleShape) - .clickable( - onClick = onClick, - ) - }, - contentAlignment = Alignment.Center, - ) { - Image( - painter = painterResource(id = imageResource), - contentDescription = contentDescription, - ) - } -} From 9b8a3b64c998c6732ef5c20d55bd8600f03c6e4a Mon Sep 17 00:00:00 2001 From: MoonsuKang Date: Sat, 21 Jun 2025 17:20:20 +0900 Subject: [PATCH 05/12] =?UTF-8?q?[REFACTOR/#283]=20AM/PM=20=EC=8B=9C?= =?UTF-8?q?=EA=B0=84=20=EC=84=A0=ED=83=9D=EC=9D=84=20TimePeriod=20enum=20?= =?UTF-8?q?=EA=B8=B0=EB=B0=98=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD=20?= =?UTF-8?q?=EB=B0=8F=20=ED=95=98=EB=93=9C=EC=BD=94=EB=94=A9=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../timepicker/BottomSheetTimePicker.kt | 40 +++++++++---------- .../auth/timereminder/TimeReminderScreen.kt | 24 ++++++----- 2 files changed, 33 insertions(+), 31 deletions(-) diff --git a/app/src/main/java/com/sopt/clody/presentation/ui/auth/component/timepicker/BottomSheetTimePicker.kt b/app/src/main/java/com/sopt/clody/presentation/ui/auth/component/timepicker/BottomSheetTimePicker.kt index 6e486ad9..032d65e8 100644 --- a/app/src/main/java/com/sopt/clody/presentation/ui/auth/component/timepicker/BottomSheetTimePicker.kt +++ b/app/src/main/java/com/sopt/clody/presentation/ui/auth/component/timepicker/BottomSheetTimePicker.kt @@ -28,12 +28,13 @@ import com.sopt.clody.R import com.sopt.clody.presentation.ui.component.button.ClodyButton import com.sopt.clody.presentation.ui.component.timepicker.ClodyPicker import com.sopt.clody.presentation.ui.component.timepicker.rememberPickerState +import com.sopt.clody.presentation.utils.extension.TimePeriod import com.sopt.clody.ui.theme.ClodyTheme @Composable fun BottomSheetTimePicker( onDismissRequest: () -> Unit, - onRemindTimeSelected: (String, String, String) -> Unit, + onRemindTimeSelected: (TimePeriod, String, String) -> Unit, ) { Surface( modifier = Modifier @@ -49,7 +50,6 @@ fun BottomSheetTimePicker( .wrapContentSize() .background(color = ClodyTheme.colors.white) .padding(horizontal = 24.dp), - ) { Box( modifier = Modifier @@ -76,7 +76,9 @@ fun BottomSheetTimePicker( } } - val amPmItems = remember { listOf("오후", "오전") } + val amPmEnumItems = listOf(TimePeriod.AM, TimePeriod.PM) + val amPmLabelItems = amPmEnumItems.map { it.getLabel() } + val hourItems = remember { (1..12).map { it.toString() } } val minuteItems = remember { listOf("00", "10", "20", "30", "40", "50") } @@ -84,10 +86,7 @@ fun BottomSheetTimePicker( val hourPickerState = rememberPickerState() val minutePickerState = rememberPickerState() - Box( - modifier = Modifier - .fillMaxWidth(), - ) { + Box(modifier = Modifier.fillMaxWidth()) { Box( modifier = Modifier .fillMaxWidth() @@ -96,18 +95,16 @@ fun BottomSheetTimePicker( .background(ClodyTheme.colors.gray08, shape = RoundedCornerShape(8.dp)), ) Row( - modifier = Modifier - .fillMaxWidth(), + modifier = Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically, ) { ClodyPicker( state = amPmPickerState, - items = amPmItems, + items = amPmLabelItems, startIndex = 1, visibleItemsCount = 3, infiniteScroll = false, - modifier = Modifier - .weight(1f), + modifier = Modifier.weight(1f), textModifier = Modifier.padding(8.dp), ) ClodyPicker( @@ -116,8 +113,7 @@ fun BottomSheetTimePicker( startIndex = 8, visibleItemsCount = 5, infiniteScroll = true, - modifier = Modifier - .weight(1f), + modifier = Modifier.weight(1f), textModifier = Modifier.padding(8.dp), ) ClodyPicker( @@ -126,22 +122,22 @@ fun BottomSheetTimePicker( startIndex = 3, visibleItemsCount = 5, infiniteScroll = true, - modifier = Modifier - .weight(1f), + modifier = Modifier.weight(1f), textModifier = Modifier.padding(8.dp), ) } } ClodyButton( onClick = { - onRemindTimeSelected( - amPmPickerState.selectedItem, - hourPickerState.selectedItem, - minutePickerState.selectedItem, - ) + val selectedLabel = amPmPickerState.selectedItem + val selectedPeriod = amPmEnumItems.getOrNull(amPmLabelItems.indexOf(selectedLabel)) ?: TimePeriod.PM + val selectedHour = hourPickerState.selectedItem + val selectedMinute = minutePickerState.selectedItem + + onRemindTimeSelected(selectedPeriod, selectedHour, selectedMinute) onDismissRequest() }, - text = "완료", + text = stringResource(R.string.time_reminder_complete_button), enabled = true, modifier = Modifier .fillMaxWidth() diff --git a/app/src/main/java/com/sopt/clody/presentation/ui/auth/timereminder/TimeReminderScreen.kt b/app/src/main/java/com/sopt/clody/presentation/ui/auth/timereminder/TimeReminderScreen.kt index 44726859..e9f9f399 100644 --- a/app/src/main/java/com/sopt/clody/presentation/ui/auth/timereminder/TimeReminderScreen.kt +++ b/app/src/main/java/com/sopt/clody/presentation/ui/auth/timereminder/TimeReminderScreen.kt @@ -44,6 +44,7 @@ import com.sopt.clody.presentation.ui.component.popup.ClodyPopupBottomSheet import com.sopt.clody.presentation.ui.home.calendar.component.HorizontalDivider import com.sopt.clody.presentation.utils.amplitude.AmplitudeConstraints import com.sopt.clody.presentation.utils.amplitude.AmplitudeUtils +import com.sopt.clody.presentation.utils.extension.TimePeriod import com.sopt.clody.ui.theme.ClodyTheme @Composable @@ -101,11 +102,11 @@ fun TimeReminderRoute( TimeReminderScreen( onStartClick = { - viewModel.setFixedTime("21", "30") + viewModel.setFixedTime(TimePeriod.PM, "21", "30") viewModel.sendNotification(context, isNotificationPermissionGranted.value) }, - onTimeSelected = { amPm, hour, minute -> - viewModel.setSelectedTime(amPm, hour, minute) + onTimeSelected = { period, hour, minute -> + viewModel.setSelectedTime(period, hour, minute) }, onCompleteClick = { AmplitudeUtils.trackEvent(eventName = AmplitudeConstraints.ONBOARDING_ALARM) @@ -118,20 +119,20 @@ fun TimeReminderRoute( @Composable fun TimeReminderScreen( onStartClick: () -> Unit, - onTimeSelected: (String, String, String) -> Unit, + onTimeSelected: (TimePeriod, String, String) -> Unit, onCompleteClick: () -> Unit, isLoading: Boolean, ) { var showBottomSheet by remember { mutableStateOf(false) } - var selectedAmPm by remember { mutableStateOf("오후") } + var selectedTimePeriod by remember { mutableStateOf(TimePeriod.PM) } var selectedHour by remember { mutableStateOf("9") } var selectedMinute by remember { mutableStateOf("30") } - val onRemindTimeSelected: (String, String, String) -> Unit = { amPm, hour, minute -> - selectedAmPm = amPm + val onRemindTimeSelected: (TimePeriod, String, String) -> Unit = { period, hour, minute -> + selectedTimePeriod = period selectedHour = hour selectedMinute = minute - onTimeSelected(amPm, hour, minute) + onTimeSelected(period, hour, minute) } Scaffold( @@ -183,7 +184,12 @@ fun TimeReminderScreen( ) Spacer(modifier = Modifier.height(LocalConfiguration.current.screenHeightDp.dp * 0.05f)) PickerBox( - time = "$selectedAmPm ${selectedHour}시 ${selectedMinute}분", + time = stringResource( + id = R.string.time_reminder_time_format, + selectedTimePeriod.getLabel(), + selectedHour, + selectedMinute, + ), modifier = Modifier.fillMaxWidth(), onClick = { showBottomSheet = true }, ) From a751473817a8c47ca1f20c46f3a0dd7bb79808d9 Mon Sep 17 00:00:00 2001 From: MoonsuKang Date: Sat, 21 Jun 2025 17:21:15 +0900 Subject: [PATCH 06/12] =?UTF-8?q?[REFACTOR/#283]=20=EC=8B=9C=EA=B0=84=20?= =?UTF-8?q?=EC=84=A4=EC=A0=95=20=EC=8B=9C=20AM/PM=20=EB=AC=B8=EC=9E=90?= =?UTF-8?q?=EC=97=B4=20=EB=8C=80=EC=8B=A0=20TimePeriod=20enum=20=EC=82=AC?= =?UTF-8?q?=EC=9A=A9=EC=9C=BC=EB=A1=9C=20=ED=83=80=EC=9E=85=20=EC=95=88?= =?UTF-8?q?=EC=A0=84=EC=84=B1=20=ED=96=A5=EC=83=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../timereminder/TimeReminderViewModel.kt | 23 +++++++++---------- 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/com/sopt/clody/presentation/ui/auth/timereminder/TimeReminderViewModel.kt b/app/src/main/java/com/sopt/clody/presentation/ui/auth/timereminder/TimeReminderViewModel.kt index c8e45835..0d07fbec 100644 --- a/app/src/main/java/com/sopt/clody/presentation/ui/auth/timereminder/TimeReminderViewModel.kt +++ b/app/src/main/java/com/sopt/clody/presentation/ui/auth/timereminder/TimeReminderViewModel.kt @@ -9,6 +9,7 @@ import androidx.lifecycle.viewModelScope import com.sopt.clody.data.remote.dto.request.SendNotificationRequestDto import com.sopt.clody.data.remote.util.NetworkUtil import com.sopt.clody.domain.repository.NotificationRepository +import com.sopt.clody.presentation.utils.extension.TimePeriod import com.sopt.clody.presentation.utils.network.ErrorMessages.FAILURE_NETWORK_MESSAGE import com.sopt.clody.presentation.utils.network.ErrorMessages.FAILURE_TEMPORARY_MESSAGE import com.sopt.clody.presentation.utils.network.ErrorMessages.UNKNOWN_ERROR @@ -16,6 +17,7 @@ import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.launch +import java.util.Locale import javax.inject.Inject @HiltViewModel @@ -77,22 +79,19 @@ class TimeReminderViewModel @Inject constructor( return sharedPreferences.getString("fcm_token", null) } - fun setSelectedTime(amPm: String, hour: String, minute: String) { - selectedTime = formatTime(amPm, hour, minute) + fun setSelectedTime(period: TimePeriod, hour: String, minute: String) { + selectedTime = formatTime(period, hour, minute) } - fun setFixedTime(hour: String, minute: String) { - selectedTime = String.format("%02d:%02d", hour.toInt(), minute.toInt()) + fun setFixedTime(period: TimePeriod, hour: String, minute: String) { + selectedTime = formatTime(period, hour, minute) } - private fun formatTime(amPm: String, hour: String, minute: String): String { - val hourInt = if (amPm == "오후" && hour.toInt() != 12) { - hour.toInt() + 12 - } else if (amPm == "오전" && hour.toInt() == 12) { - 0 - } else { - hour.toInt() + private fun formatTime(period: TimePeriod, hour: String, minute: String): String { + val hourInt = when (period) { + TimePeriod.PM -> if (hour.toInt() != 12) hour.toInt() + 12 else 12 + TimePeriod.AM -> if (hour.toInt() == 12) 0 else hour.toInt() } - return String.format("%02d:%02d", hourInt, minute.toInt()) + return String.format(Locale.US, "%02d:%02d", hourInt, minute.toInt()) } } From 5f0ae0fcb10b3215d6bcd83eaf7cfa873f4ab4ee Mon Sep 17 00:00:00 2001 From: MoonsuKang Date: Sat, 21 Jun 2025 17:24:41 +0900 Subject: [PATCH 07/12] =?UTF-8?q?[REFACTOR/#283]=20=ED=95=98=EB=93=9C?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ui/auth/signup/page/NicknamePage.kt | 7 ++-- .../calendar/component/DailyDiaryListItem.kt | 10 ++++-- .../ui/home/component/CloverCount.kt | 4 ++- .../ui/home/component/DiaryStateButton.kt | 12 ++++--- .../ui/home/component/YearAndMonthTitle.kt | 6 ++-- .../presentation/ui/home/screen/HomeScreen.kt | 33 ++++++++--------- .../component/QuickReplyAdButton.kt | 3 +- .../presentation/ui/splash/SplashScreen.kt | 35 ++++++++++++++----- .../DeleteWriteDiaryBottomSheet.kt | 3 +- .../component/button/AddDiaryEntryFAB.kt | 3 +- .../writediary/component/button/SendButton.kt | 4 ++- .../textfield/WriteDiaryTextField.kt | 5 +-- 12 files changed, 80 insertions(+), 45 deletions(-) diff --git a/app/src/main/java/com/sopt/clody/presentation/ui/auth/signup/page/NicknamePage.kt b/app/src/main/java/com/sopt/clody/presentation/ui/auth/signup/page/NicknamePage.kt index 65e3ebc7..a716c61f 100644 --- a/app/src/main/java/com/sopt/clody/presentation/ui/auth/signup/page/NicknamePage.kt +++ b/app/src/main/java/com/sopt/clody/presentation/ui/auth/signup/page/NicknamePage.kt @@ -20,6 +20,7 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.SpanStyle import androidx.compose.ui.text.buildAnnotatedString import androidx.compose.ui.text.withStyle @@ -85,7 +86,7 @@ fun NickNamePage( focusManager.clearFocus() onCompleteClick() }, - text = "다음", + text = stringResource(R.string.nickname_next), enabled = nickname.isNotEmpty() && isValidNickname, ) }, @@ -98,12 +99,12 @@ fun NickNamePage( .padding(horizontal = 24.dp), ) { Spacer(modifier = Modifier.heightForScreenPercentage(0.056f)) - Text("닉네임 입력", style = ClodyTheme.typography.head1) + Text(stringResource(R.string.nickname_title), style = ClodyTheme.typography.head1) Spacer(modifier = Modifier.heightForScreenPercentage(0.06f)) NickNameTextField( value = nickname, onValueChange = onNicknameChange, - hint = "닉네임을 입력하세요", + hint = stringResource(R.string.nickname_input_hint), isFocused = isFocused, isValid = isValidNickname, onFocusChanged = onFocusChanged, diff --git a/app/src/main/java/com/sopt/clody/presentation/ui/home/calendar/component/DailyDiaryListItem.kt b/app/src/main/java/com/sopt/clody/presentation/ui/home/calendar/component/DailyDiaryListItem.kt index bceeb205..21192e99 100644 --- a/app/src/main/java/com/sopt/clody/presentation/ui/home/calendar/component/DailyDiaryListItem.kt +++ b/app/src/main/java/com/sopt/clody/presentation/ui/home/calendar/component/DailyDiaryListItem.kt @@ -18,6 +18,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import com.sopt.clody.R @@ -52,7 +53,10 @@ fun DailyDiaryListItem( modifier = Modifier.padding(vertical = 3.dp), ) Text( - text = "${dayOfWeek.toKoreanShortLabel()}요일", + text = stringResource( + id = R.string.daily_diary_day_of_week_format, + dayOfWeek.toKoreanShortLabel(), + ), style = ClodyTheme.typography.body2Medium, color = ClodyTheme.colors.gray02, modifier = Modifier.padding(horizontal = 6.dp, vertical = 2.dp), @@ -76,7 +80,7 @@ fun DailyDiaryListItem( .padding(vertical = 44.dp), ) { Text( - text = "임시저장된 일기가 있어요.", + text = stringResource(R.string.daily_diary_draft_message), style = ClodyTheme.typography.body3Regular, color = ClodyTheme.colors.gray05, textAlign = TextAlign.Center, @@ -92,7 +96,7 @@ fun DailyDiaryListItem( .padding(vertical = 44.dp), ) { Text( - text = "작성된 감사 일기가 없어요!", + text = stringResource(R.string.daily_diary_empty_message), style = ClodyTheme.typography.body3Regular, color = ClodyTheme.colors.gray05, textAlign = TextAlign.Center, diff --git a/app/src/main/java/com/sopt/clody/presentation/ui/home/component/CloverCount.kt b/app/src/main/java/com/sopt/clody/presentation/ui/home/component/CloverCount.kt index d85e720c..ff1029ba 100644 --- a/app/src/main/java/com/sopt/clody/presentation/ui/home/component/CloverCount.kt +++ b/app/src/main/java/com/sopt/clody/presentation/ui/home/component/CloverCount.kt @@ -10,13 +10,15 @@ import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp +import com.sopt.clody.R import com.sopt.clody.ui.theme.ClodyTheme @Composable fun CloverCount(cloverCount: Int) { - val text = "클로버 ${cloverCount}개" + val text = stringResource(R.string.home_clover_count_format, cloverCount) Box( modifier = Modifier diff --git a/app/src/main/java/com/sopt/clody/presentation/ui/home/component/DiaryStateButton.kt b/app/src/main/java/com/sopt/clody/presentation/ui/home/component/DiaryStateButton.kt index 851f5eae..5b921f05 100644 --- a/app/src/main/java/com/sopt/clody/presentation/ui/home/component/DiaryStateButton.kt +++ b/app/src/main/java/com/sopt/clody/presentation/ui/home/component/DiaryStateButton.kt @@ -4,7 +4,9 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp +import com.sopt.clody.R import com.sopt.clody.presentation.ui.component.button.ClodyButton import com.sopt.clody.presentation.ui.component.button.ClodyReplyButton import com.sopt.clody.ui.theme.ClodyTheme @@ -29,7 +31,7 @@ fun DiaryStateButton( hasDraft -> { ClodyButton( onClick = { onClickWriteDiary(year, month, day) }, - text = "이어쓰기", + text = stringResource(R.string.button_continue_draft), enabled = true, modifier = modifier, ) @@ -38,7 +40,7 @@ fun DiaryStateButton( isInvalidDraft -> { ClodyButton( onClick = { /* no-action */ }, - text = "답장확인", + text = stringResource(R.string.button_check_reply), enabled = false, modifier = modifier, disabledContainerColor = ClodyTheme.colors.gray05, @@ -49,7 +51,7 @@ fun DiaryStateButton( canReply -> { ClodyReplyButton( onClick = onClickReplyDiary, - text = "답장확인", + text = stringResource(R.string.button_check_reply), enabled = true, modifier = modifier, ) @@ -58,7 +60,7 @@ fun DiaryStateButton( canWrite -> { ClodyButton( onClick = { onClickWriteDiary(year, month, day) }, - text = "일기쓰기", + text = stringResource(R.string.button_write_diary), enabled = true, modifier = modifier, ) @@ -67,7 +69,7 @@ fun DiaryStateButton( else -> { ClodyButton( onClick = { onClickWriteDiary(year, month, day) }, - text = "일기쓰기", + text = stringResource(R.string.button_write_diary), enabled = false, modifier = modifier, ) diff --git a/app/src/main/java/com/sopt/clody/presentation/ui/home/component/YearAndMonthTitle.kt b/app/src/main/java/com/sopt/clody/presentation/ui/home/component/YearAndMonthTitle.kt index 32d9e7bf..b9677b37 100644 --- a/app/src/main/java/com/sopt/clody/presentation/ui/home/component/YearAndMonthTitle.kt +++ b/app/src/main/java/com/sopt/clody/presentation/ui/home/component/YearAndMonthTitle.kt @@ -12,6 +12,7 @@ import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import com.sopt.clody.R import com.sopt.clody.ui.theme.ClodyTheme @@ -22,7 +23,7 @@ fun YearAndMonthTitle( selectedYear: Int, selectedMonth: Int, ) { - val text = "${selectedYear}년 ${selectedMonth}월" + val text = stringResource(R.string.home_year_and_month_format, selectedYear, selectedMonth) Column { Row( @@ -41,8 +42,7 @@ fun YearAndMonthTitle( Image( painter = painterResource(id = R.drawable.ic_home_under_arrow), contentDescription = "choose month", - modifier = Modifier - .padding(horizontal = 6.dp, vertical = 6.dp), + modifier = Modifier.padding(horizontal = 6.dp, vertical = 6.dp), ) } } diff --git a/app/src/main/java/com/sopt/clody/presentation/ui/home/screen/HomeScreen.kt b/app/src/main/java/com/sopt/clody/presentation/ui/home/screen/HomeScreen.kt index a22ae328..2ef9cf90 100644 --- a/app/src/main/java/com/sopt/clody/presentation/ui/home/screen/HomeScreen.kt +++ b/app/src/main/java/com/sopt/clody/presentation/ui/home/screen/HomeScreen.kt @@ -23,6 +23,7 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel @@ -171,28 +172,28 @@ fun HomeRoute( .padding(horizontal = 16.dp), ) { Text( - text = "기한이 지나면\n로디의 답장을 받을 수 없어요!", + text = stringResource(R.string.home_draft_popup_title), color = ClodyTheme.colors.gray01, textAlign = TextAlign.Center, style = ClodyTheme.typography.head3, ) Spacer(modifier = Modifier.height(10.dp)) Text( - text = "답장 마감 전에 일기를 이어쓸 수 있도록\n알려드리기 위해서는 알림 설정이 필요해요.", + text = stringResource(R.string.home_draft_popup_description), color = ClodyTheme.colors.gray04, textAlign = TextAlign.Center, style = ClodyTheme.typography.body3Regular, ) Spacer(modifier = Modifier.height(4.dp)) Text( - text = "[설정 > 애플리케이션 > 클로디 > 알림 > 알림표시]", + text = stringResource(R.string.home_draft_popup_guide), color = ClodyTheme.colors.gray04, textAlign = TextAlign.Center, style = ClodyTheme.typography.body3Regular, ) Spacer(modifier = Modifier.height(28.dp)) ClodyButton( - text = "알림 받기", + text = stringResource(R.string.home_draft_popup_accept), onClick = { homeViewModel.enableDraftAlarm(context) homeViewModel.updateFirstDraftUse(false) @@ -201,7 +202,7 @@ fun HomeRoute( modifier = Modifier.fillMaxWidth(), ) Text( - text = "다음에 하기", + text = stringResource(R.string.home_draft_popup_dismiss), modifier = Modifier .clickable(onClick = { homeViewModel.updateFirstDraftUse(false) }) .padding(12.dp), @@ -220,7 +221,7 @@ fun HomeRoute( contentAlignment = Alignment.BottomCenter, content = { ClodyToastMessage( - message = "이어쓰기 알림 설정을 완료했어요.", + message = stringResource(R.string.home_draft_alarm_enabled_toast), iconResId = R.drawable.ic_toast_check_on_18, backgroundColor = ClodyTheme.colors.gray04, contentColor = ClodyTheme.colors.white, @@ -236,10 +237,10 @@ fun HomeRoute( if (showContinueDraftDialog) { ClodyDialog( - titleMassage = "임시저장된 일기를 이어 쓸까요?", - descriptionMassage = "답장 기한이 지나서 답장은 받을 수 없어요.", - confirmOption = "이어쓰기", - dismissOption = "아니오", + titleMassage = stringResource(R.string.home_continue_draft_title), + descriptionMassage = stringResource(R.string.home_continue_draft_description), + confirmOption = stringResource(R.string.home_continue_draft_confirm), + dismissOption = stringResource(R.string.home_continue_draft_dismiss), confirmAction = { homeViewModel.setShowContinueDraftDialog(false) val date = homeViewModel.selectedDate.value @@ -265,10 +266,10 @@ fun HomeRoute( if (showDiaryDeleteDialog) { ClodyDialog( - titleMassage = "정말 일기를 삭제할까요?", - descriptionMassage = "아직 답장이 오지 않았거나 삭제하고\n다시 작성한 일기는 답장을 받을 수 없어요.", - confirmOption = "삭제할래요", - dismissOption = "아니요", + titleMassage = stringResource(R.string.home_delete_diary_title), + descriptionMassage = stringResource(R.string.home_delete_diary_description), + confirmOption = stringResource(R.string.home_delete_diary_confirm), + dismissOption = stringResource(R.string.home_delete_diary_dismiss), confirmAction = { homeViewModel.deleteDailyDiary( selectedDiaryDate.year, @@ -374,7 +375,7 @@ fun HomeScreen( } is CalendarState.Error -> { - homeViewModel.setErrorState(true, calendarState.message ?: "알 수 없는 오류가 발생했습니다.") + homeViewModel.setErrorState(true, calendarState.message ?: stringResource(R.string.home_error_unknown)) } } @@ -389,7 +390,7 @@ fun HomeScreen( } is DeleteDiaryState.Failure -> { - homeViewModel.setErrorState(true, "일기 삭제 중 오류가 발생했습니다.") + homeViewModel.setErrorState(true, stringResource(R.string.home_error_delete_diary)) } } }, diff --git a/app/src/main/java/com/sopt/clody/presentation/ui/replyloading/component/QuickReplyAdButton.kt b/app/src/main/java/com/sopt/clody/presentation/ui/replyloading/component/QuickReplyAdButton.kt index 3507cd0e..49ddc451 100644 --- a/app/src/main/java/com/sopt/clody/presentation/ui/replyloading/component/QuickReplyAdButton.kt +++ b/app/src/main/java/com/sopt/clody/presentation/ui/replyloading/component/QuickReplyAdButton.kt @@ -14,6 +14,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.sopt.clody.R @@ -40,7 +41,7 @@ fun QuickReplyAdButton( tint = Color.Unspecified, ) Text( - text = "광고 보고 바로 답장 받기", + text = stringResource(R.string.loading_button_watch_ad_and_get_reply), style = ClodyTheme.typography.body4Medium, color = ClodyTheme.colors.blue, modifier = Modifier.padding(start = 5.dp), diff --git a/app/src/main/java/com/sopt/clody/presentation/ui/splash/SplashScreen.kt b/app/src/main/java/com/sopt/clody/presentation/ui/splash/SplashScreen.kt index 3e3b5ebd..a14ff51f 100644 --- a/app/src/main/java/com/sopt/clody/presentation/ui/splash/SplashScreen.kt +++ b/app/src/main/java/com/sopt/clody/presentation/ui/splash/SplashScreen.kt @@ -17,6 +17,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp import androidx.lifecycle.compose.LocalLifecycleOwner @@ -120,15 +121,23 @@ fun SoftUpdateDialog( ) { AlertDialog( onDismissRequest = onDismiss, - title = { Text("업데이트 필요") }, + title = { Text(stringResource(R.string.soft_update_title)) }, text = { Text( - text = "새로운 버전 ${latestVersion}을 사용할 수 있습니다.\n지금 업데이트하시겠습니까?", + text = stringResource(R.string.soft_update_message, latestVersion), textAlign = TextAlign.Center, ) }, - confirmButton = { TextButton(onClick = onConfirm) { Text("업데이트") } }, - dismissButton = { TextButton(onClick = onDismiss) { Text("나중에") } }, + confirmButton = { + TextButton(onClick = onConfirm) { + Text(stringResource(R.string.soft_update_confirm)) + } + }, + dismissButton = { + TextButton(onClick = onDismiss) { + Text(stringResource(R.string.soft_update_dismiss)) + } + }, ) } @@ -140,10 +149,20 @@ fun HardUpdateDialog( ) { AlertDialog( onDismissRequest = {}, - title = { Text("필수 업데이트") }, - text = { Text("버전 ${latestVersion}으로 업데이트가 필요합니다.") }, - confirmButton = { TextButton(onClick = onConfirm) { Text("업데이트") } }, - dismissButton = { TextButton(onClick = onExit) { Text("앱 종료") } }, + title = { Text(stringResource(R.string.hard_update_title)) }, + text = { + Text(stringResource(R.string.hard_update_message, latestVersion)) + }, + confirmButton = { + TextButton(onClick = onConfirm) { + Text(stringResource(R.string.soft_update_confirm)) + } + }, + dismissButton = { + TextButton(onClick = onExit) { + Text(stringResource(R.string.hard_update_exit)) + } + }, ) } diff --git a/app/src/main/java/com/sopt/clody/presentation/ui/writediary/component/bottomsheet/DeleteWriteDiaryBottomSheet.kt b/app/src/main/java/com/sopt/clody/presentation/ui/writediary/component/bottomsheet/DeleteWriteDiaryBottomSheet.kt index 0a723e1d..890be429 100644 --- a/app/src/main/java/com/sopt/clody/presentation/ui/writediary/component/bottomsheet/DeleteWriteDiaryBottomSheet.kt +++ b/app/src/main/java/com/sopt/clody/presentation/ui/writediary/component/bottomsheet/DeleteWriteDiaryBottomSheet.kt @@ -18,6 +18,7 @@ import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import com.sopt.clody.R @@ -60,7 +61,7 @@ fun DeleteWriteDiaryBottomSheet( ) Spacer(modifier = Modifier.width(8.dp)) Text( - text = "삭제하기", + text = stringResource(R.string.bottom_sheet_delete_button), style = ClodyTheme.typography.body4SemiBold, color = ClodyTheme.colors.gray01, ) diff --git a/app/src/main/java/com/sopt/clody/presentation/ui/writediary/component/button/AddDiaryEntryFAB.kt b/app/src/main/java/com/sopt/clody/presentation/ui/writediary/component/button/AddDiaryEntryFAB.kt index d976aac3..9f5b16ec 100644 --- a/app/src/main/java/com/sopt/clody/presentation/ui/writediary/component/button/AddDiaryEntryFAB.kt +++ b/app/src/main/java/com/sopt/clody/presentation/ui/writediary/component/button/AddDiaryEntryFAB.kt @@ -23,6 +23,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import com.sopt.clody.R import com.sopt.clody.presentation.utils.extension.clickableWithoutRipple @@ -85,7 +86,7 @@ fun BoxScope.AddDiaryEntryFAB( ) Spacer(modifier = Modifier.width(10.dp)) Text( - text = "추가하기", + text = stringResource(R.string.write_diary_add_entry_fab), color = contentColor, style = ClodyTheme.typography.body2SemiBold, ) diff --git a/app/src/main/java/com/sopt/clody/presentation/ui/writediary/component/button/SendButton.kt b/app/src/main/java/com/sopt/clody/presentation/ui/writediary/component/button/SendButton.kt index 7d69561c..059e94e6 100644 --- a/app/src/main/java/com/sopt/clody/presentation/ui/writediary/component/button/SendButton.kt +++ b/app/src/main/java/com/sopt/clody/presentation/ui/writediary/component/button/SendButton.kt @@ -11,7 +11,9 @@ import androidx.compose.runtime.getValue import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp +import com.sopt.clody.R import com.sopt.clody.ui.theme.ClodyTheme @Composable @@ -33,7 +35,7 @@ fun SendButton( contentAlignment = Alignment.Center, ) { Text( - text = "보내기", + text = stringResource(R.string.write_diary_text_button), color = if (isPressed) ClodyTheme.colors.gray07 else ClodyTheme.colors.gray01, style = ClodyTheme.typography.body2SemiBold, ) diff --git a/app/src/main/java/com/sopt/clody/presentation/ui/writediary/component/textfield/WriteDiaryTextField.kt b/app/src/main/java/com/sopt/clody/presentation/ui/writediary/component/textfield/WriteDiaryTextField.kt index e2593bde..1c495420 100644 --- a/app/src/main/java/com/sopt/clody/presentation/ui/writediary/component/textfield/WriteDiaryTextField.kt +++ b/app/src/main/java/com/sopt/clody/presentation/ui/writediary/component/textfield/WriteDiaryTextField.kt @@ -30,6 +30,7 @@ import androidx.compose.ui.focus.onFocusChanged import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.SolidColor import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.SpanStyle import androidx.compose.ui.text.TextStyle import androidx.compose.ui.text.buildAnnotatedString @@ -130,7 +131,7 @@ fun WriteDiaryTextField( decorationBox = { innerTextField -> if (text.isEmpty()) { Text( - text = "일상 속 작은 감사함을 적어보세요", + text = stringResource(R.string.write_diary_text_field_hint), style = ClodyTheme.typography.body3Medium, color = ClodyTheme.colors.gray06, ) @@ -165,7 +166,7 @@ fun WriteDiaryTextField( ) { if ((showWarning && !isTextValid) || isTextTooLong) { Text( - text = "2~50자 까지 입력할 수 있어요.", + text = stringResource(R.string.write_diary_text_field_warning), color = ClodyTheme.colors.red, style = ClodyTheme.typography.detail1Medium, modifier = Modifier.weight(1f), From 723333e6199bde489d480ece3313dfdd0249577a Mon Sep 17 00:00:00 2001 From: MoonsuKang Date: Sat, 21 Jun 2025 17:24:57 +0900 Subject: [PATCH 08/12] =?UTF-8?q?[MOD/#283]=20=EC=95=88=EC=93=B0=EB=8A=94?= =?UTF-8?q?=20string=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/res/values/strings.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index ac44e6ff..55136bc7 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -123,7 +123,6 @@ 클로버 %1$d개 %1$d년 %2$d월 - 월 선택 이어 쓰기 From b2b5aec652a52f35f8ba861c62c524eace61acec Mon Sep 17 00:00:00 2001 From: MoonsuKang Date: Sat, 21 Jun 2025 17:25:13 +0900 Subject: [PATCH 09/12] =?UTF-8?q?[REFACTOR/#283]=20=ED=95=98=EB=93=9C?= =?UTF-8?q?=EC=BD=94=EB=93=9C=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../presentation/ui/component/bottomsheet/DiaryDeleteSheet.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/com/sopt/clody/presentation/ui/component/bottomsheet/DiaryDeleteSheet.kt b/app/src/main/java/com/sopt/clody/presentation/ui/component/bottomsheet/DiaryDeleteSheet.kt index ba5f2b4e..feecc8e6 100644 --- a/app/src/main/java/com/sopt/clody/presentation/ui/component/bottomsheet/DiaryDeleteSheet.kt +++ b/app/src/main/java/com/sopt/clody/presentation/ui/component/bottomsheet/DiaryDeleteSheet.kt @@ -18,6 +18,7 @@ import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import com.sopt.clody.R import com.sopt.clody.ui.theme.ClodyTheme @@ -71,7 +72,7 @@ fun DiaryDeleteBottomSheetItem( ) Spacer(modifier = Modifier.width(8.dp)) Text( - text = "삭제하기", + text = stringResource(R.string.bottom_sheet_delete_button), style = ClodyTheme.typography.body4SemiBold, color = ClodyTheme.colors.gray01, ) From 9ea13383f17f658441d2e5e79974c7071817a8bf Mon Sep 17 00:00:00 2001 From: MoonsuKang Date: Sat, 21 Jun 2025 17:37:28 +0900 Subject: [PATCH 10/12] =?UTF-8?q?[ADD/#283]=20=EC=8A=A4=ED=8A=B8=EB=A7=81?= =?UTF-8?q?=20=EC=B6=94=EC=B6=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/res/values/strings.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 55136bc7..f5416386 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -212,4 +212,7 @@ 오전 오후 %1$s %2$s시 %3$s분 + + %1$d년 + %1$d월 From d3a549c1f9c25062ad618d664c5acc09ab6f44eb Mon Sep 17 00:00:00 2001 From: MoonsuKang Date: Sat, 21 Jun 2025 17:37:50 +0900 Subject: [PATCH 11/12] =?UTF-8?q?[ADD/#283]=20=EC=97=B0=EB=8F=84=20?= =?UTF-8?q?=EB=B0=8F=20=EC=9B=94=20=EB=A0=88=EC=9D=B4=EB=B8=94=EC=9D=84=20?= =?UTF-8?q?=EC=9C=84=ED=95=9C=20=EC=9C=A0=ED=8B=B8=EB=A6=AC=ED=8B=B0=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../utils/extension/YearMonthLabelUtil.kt | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 app/src/main/java/com/sopt/clody/presentation/utils/extension/YearMonthLabelUtil.kt diff --git a/app/src/main/java/com/sopt/clody/presentation/utils/extension/YearMonthLabelUtil.kt b/app/src/main/java/com/sopt/clody/presentation/utils/extension/YearMonthLabelUtil.kt new file mode 100644 index 00000000..cbddfeb0 --- /dev/null +++ b/app/src/main/java/com/sopt/clody/presentation/utils/extension/YearMonthLabelUtil.kt @@ -0,0 +1,16 @@ +package com.sopt.clody.presentation.utils.extension + +import androidx.compose.runtime.Composable +import androidx.compose.ui.res.stringResource +import com.sopt.clody.R + +object YearMonthLabelUtil { + const val MIN_YEAR = 2000 + const val MAX_YEAR = 2030 +} + +@Composable +fun Int.toLocalizedYearLabel(): String = stringResource(R.string.year_format, this) + +@Composable +fun Int.toLocalizedMonthLabel(): String = stringResource(R.string.month_format, this) From 05a5d8be02f1849fe6adc801ace9eecc0577d5dc Mon Sep 17 00:00:00 2001 From: MoonsuKang Date: Sat, 21 Jun 2025 17:38:31 +0900 Subject: [PATCH 12/12] =?UTF-8?q?[REFACTOR/#283]=20=EB=AC=B8=EC=9E=90?= =?UTF-8?q?=EC=97=B4=20=EB=A6=AC=EC=86=8C=EC=8A=A4=20=EB=B0=8F=20=EC=9C=A0?= =?UTF-8?q?=ED=8B=B8=EB=A6=AC=ED=8B=B0=20=ED=95=A8=EC=88=98=EB=A1=9C=20?= =?UTF-8?q?=EC=97=B0=EB=8F=84/=EC=9B=94=20=EB=A0=88=EC=9D=B4=EB=B8=94=20?= =?UTF-8?q?=EC=B2=98=EB=A6=AC=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../component/timepicker/YearMonthPicker.kt | 52 +++++++++---------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/app/src/main/java/com/sopt/clody/presentation/ui/component/timepicker/YearMonthPicker.kt b/app/src/main/java/com/sopt/clody/presentation/ui/component/timepicker/YearMonthPicker.kt index 9cd81c01..f04f68eb 100644 --- a/app/src/main/java/com/sopt/clody/presentation/ui/component/timepicker/YearMonthPicker.kt +++ b/app/src/main/java/com/sopt/clody/presentation/ui/component/timepicker/YearMonthPicker.kt @@ -23,9 +23,13 @@ import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import com.sopt.clody.R import com.sopt.clody.presentation.ui.component.button.ClodyButton +import com.sopt.clody.presentation.utils.extension.YearMonthLabelUtil +import com.sopt.clody.presentation.utils.extension.toLocalizedMonthLabel +import com.sopt.clody.presentation.utils.extension.toLocalizedYearLabel import com.sopt.clody.ui.theme.ClodyTheme @Composable @@ -35,6 +39,15 @@ fun YearMonthPicker( selectedMonth: Int, onYearMonthSelected: (Int, Int) -> Unit, ) { + val yearItems = remember { (YearMonthLabelUtil.MIN_YEAR..YearMonthLabelUtil.MAX_YEAR).toList() } + val monthItems = remember { (1..12).toList() } + + val yearPickerState = rememberPickerState() + val monthPickerState = rememberPickerState() + + val startYearIndex = (yearItems.indexOf(selectedYear) - 2).coerceAtLeast(0) + val startMonthIndex = (monthItems.indexOf(selectedMonth) - 2).coerceAtLeast(0) + Surface( modifier = Modifier .fillMaxWidth() @@ -49,7 +62,6 @@ fun YearMonthPicker( .wrapContentSize() .background(color = ClodyTheme.colors.white) .padding(horizontal = 24.dp), - ) { Box( modifier = Modifier @@ -57,7 +69,7 @@ fun YearMonthPicker( .padding(top = 16.dp, bottom = 30.dp), ) { Text( - text = "다른 날짜 보기", + text = stringResource(R.string.year_month_picker_title), style = ClodyTheme.typography.body2SemiBold, color = ClodyTheme.colors.gray01, modifier = Modifier.align(Alignment.Center), @@ -76,19 +88,10 @@ fun YearMonthPicker( } } - val yearItems = remember { (2000..2030).map { "${it}년" } } - val monthItems = remember { (1..12).map { "${it}월" } } - - val yearPickerState = rememberPickerState() - val monthPickerState = rememberPickerState() + val yearLabelItems = yearItems.map { it.toLocalizedYearLabel() } + val monthLabelItems = monthItems.map { it.toLocalizedMonthLabel() } - val startYearIndex = (yearItems.indexOf("${selectedYear}년") - 2).coerceAtLeast(0) - val startMonthIndex = (monthItems.indexOf("${selectedMonth}월") - 2).coerceAtLeast(0) - - Box( - modifier = Modifier - .fillMaxWidth(), - ) { + Box(modifier = Modifier.fillMaxWidth()) { Box( modifier = Modifier .fillMaxWidth() @@ -97,30 +100,27 @@ fun YearMonthPicker( .background(ClodyTheme.colors.gray08, shape = RoundedCornerShape(8.dp)), ) Row( - modifier = Modifier - .fillMaxWidth(), + modifier = Modifier.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically, ) { Spacer(modifier = Modifier.weight(1f)) YearMonthPickerItem( state = yearPickerState, - items = yearItems, + items = yearLabelItems, startIndex = startYearIndex, visibleItemsCount = 5, infiniteScroll = false, - modifier = Modifier - .weight(1f), + modifier = Modifier.weight(1f), textModifier = Modifier.padding(8.dp), ) Spacer(modifier = Modifier.width(20.dp)) YearMonthPickerItem( state = monthPickerState, - items = monthItems, + items = monthLabelItems, startIndex = startMonthIndex, visibleItemsCount = 5, infiniteScroll = false, - modifier = Modifier - .weight(1f), + modifier = Modifier.weight(1f), textModifier = Modifier.padding(8.dp), ) Spacer(modifier = Modifier.weight(1f)) @@ -128,12 +128,12 @@ fun YearMonthPicker( } ClodyButton( onClick = { - val selectedYear = yearPickerState.selectedItem.split("년")[0].toInt() - val selectedMonth = monthPickerState.selectedItem.split("월")[0].toInt() - onYearMonthSelected(selectedYear, selectedMonth) + val year = yearItems[yearLabelItems.indexOf(yearPickerState.selectedItem)] + val month = monthItems[monthLabelItems.indexOf(monthPickerState.selectedItem)] + onYearMonthSelected(year, month) onDismissRequest() }, - text = "완료", + text = stringResource(R.string.year_month_picker_confirm), enabled = true, modifier = Modifier .fillMaxWidth()