Conversation
- lineHeight 계산 확장함수 생성 - 네이밍 변경
- 카카오 로그인 -> 구글 로그인 - 온보딩/설정 닉네임 10자 -> 15자 - 일기 작성 한칸 당 50자 -> 100자 - 웹뷰 링크
WalkthroughThis update introduces language-aware branching throughout the application. A new Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant UI
participant ViewModel
participant LanguageProvider
User->>UI: Interacts (e.g., login, nickname input)
UI->>ViewModel: Passes user input
ViewModel->>LanguageProvider: Requests config (login type, max lengths, URLs)
LanguageProvider-->>ViewModel: Returns locale-specific values
ViewModel->>UI: Updates state with dynamic values
UI->>User: Presents locale-adapted UI (login button, input limits, URLs, typography)
Suggested labels
Poem
📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
✨ Finishing Touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Actionable comments posted: 6
🧹 Nitpick comments (9)
app/src/main/java/com/sopt/clody/presentation/ui/writediary/component/bottomsheet/DeleteWriteDiaryBottomSheet.kt (1)
58-61: Add a non-nullcontentDescriptionfor accessibilityScreen-reader users will not get any context for the trash icon. A short label such as “delete diary” (localised via
strings.xml) is enough and does not change visual layout.-Image( - painter = painterResource(id = R.drawable.ic_bottomsheet_trash), - contentDescription = null, -) +Image( + painter = painterResource(id = R.drawable.ic_bottomsheet_trash), + contentDescription = stringResource(R.string.content_description_delete_icon), +)Remember to add
content_description_delete_iconto all supported locales.app/src/main/java/com/sopt/clody/presentation/ui/component/bottomsheet/DiaryDeleteSheet.kt (1)
70-72: ProvidecontentDescriptionfor the trash icon here as wellMirror the accessibility improvement suggested in the other bottom-sheet to keep behaviour consistent across screens.
-Image( - painter = painterResource(id = R.drawable.ic_bottomsheet_trash), - contentDescription = null, -) +Image( + painter = painterResource(id = R.drawable.ic_bottomsheet_trash), + contentDescription = stringResource(R.string.content_description_delete_icon), +)app/src/main/java/com/sopt/clody/presentation/utils/language/LanguageProviderImpl.kt (1)
13-14: Consider defensive programming for locale access.The current implementation assumes
context.resources.configuration.locales[0]will always be available. Consider adding defensive programming to handle edge cases where the locales array might be empty.private val locale: Locale - get() = context.resources.configuration.locales[0] + get() = if (context.resources.configuration.locales.isEmpty()) { + Locale.getDefault() + } else { + context.resources.configuration.locales[0] + }app/src/main/java/com/sopt/clody/presentation/ui/login/LoginType.kt (1)
1-5: Enum is fine, but think about forward-compatibility & serialization.
- If the backend ever sends an unknown provider, enum deserialization (e.g. with Moshi/Kotlinx) will crash.
- If these constants are sent over the wire, annotate with
@JsonClass/@SerializedNameor provide a fallback via@JsonEnumDefaultValue.- For more flexibility you could replace the enum with a sealed interface +
objectimplementations to allow easy extension without breaking binary compatibility.Example if you use kotlinx-serialization:
+import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + -enum class LoginType { - KAKAO, GOOGLE -} +@Serializable +enum class LoginType { + @SerialName("kakao") KAKAO, + @SerialName("google") GOOGLE, + + /** Fallback for future providers */ + @SerialName("unknown") UNKNOWN +}app/src/main/java/com/sopt/clody/presentation/ui/auth/component/timepicker/BottomSheetTimePicker.kt (1)
146-147: Confirm reuse of generic “confirm” button stringThe confirm button now references
bottom_sheet_year_month_picker_btn_confirm. Re-using a year-month picker label for a time picker might confuse translators later. Consider introducing a dedicated key (bottom_sheet_time_picker_btn_confirm) for clarity.app/src/main/java/com/sopt/clody/presentation/ui/writediary/component/textfield/WriteDiaryTextField.kt (1)
121-121: Clean up duplicate character range in regex pattern.The regex pattern contains a duplicate character range
가-힣which appears twice. Consider simplifying the pattern for better readability:-isTextValid = textWithoutSpaces.matches(Regex("^[a-zA-Z가-힣0-9ㄱ-ㅎㅏ-ㅣ가-힣]{2,$maxLength}$")) +isTextValid = textWithoutSpaces.matches(Regex("^[a-zA-Z가-힣0-9ㄱ-ㅎㅏ-ㅣ]{2,$maxLength}$"))app/src/main/java/com/sopt/clody/presentation/ui/auth/component/button/GoogleButton.kt (2)
34-34: Consider height consistency with other buttons.The button height of 48dp differs from the ClodyButton height of 50dp (as seen in the relevant code snippets). Consider using a consistent height across all buttons for visual harmony.
- modifier = modifier.height(48.dp), + modifier = modifier.height(50.dp),
42-44: Consider adding accessibility support.The Google logo image has
contentDescription = null. Consider adding a meaningful description for better accessibility support.- contentDescription = null, + contentDescription = "Google logo",app/src/main/res/values-ko/strings.xml (1)
7-7: Mixed language in Korean resource fileThe Korean resource file contains English text for the Google login button. Consider whether this should be translated to Korean for consistency or if keeping English is intentional for branding purposes.
- <string name="signup_btn_google">Sign Up With Google</string> + <string name="signup_btn_google">Google로 가입하기</string>
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (4)
app/src/main/res/drawable-ko/img_splash_logo.pngis excluded by!**/*.pngapp/src/main/res/drawable-xhdpi/img_splash_logo.pngis excluded by!**/*.pngapp/src/main/res/drawable/img_google_button_logo.pngis excluded by!**/*.pngapp/src/main/res/drawable/img_splash_logo.pngis excluded by!**/*.png
📒 Files selected for processing (56)
app/src/main/java/com/sopt/clody/presentation/di/LanguageModule.kt(1 hunks)app/src/main/java/com/sopt/clody/presentation/ui/auth/component/button/GoogleButton.kt(1 hunks)app/src/main/java/com/sopt/clody/presentation/ui/auth/component/button/KaKaoButton.kt(1 hunks)app/src/main/java/com/sopt/clody/presentation/ui/auth/component/textfield/NickNameTextField.kt(2 hunks)app/src/main/java/com/sopt/clody/presentation/ui/auth/component/timepicker/BottomSheetTimePicker.kt(2 hunks)app/src/main/java/com/sopt/clody/presentation/ui/auth/guide/GuideScreen.kt(1 hunks)app/src/main/java/com/sopt/clody/presentation/ui/auth/signup/SignUpContract.kt(2 hunks)app/src/main/java/com/sopt/clody/presentation/ui/auth/signup/SignUpScreen.kt(2 hunks)app/src/main/java/com/sopt/clody/presentation/ui/auth/signup/SignUpViewModel.kt(7 hunks)app/src/main/java/com/sopt/clody/presentation/ui/auth/signup/page/NicknamePage.kt(5 hunks)app/src/main/java/com/sopt/clody/presentation/ui/auth/signup/page/TermsOfServicePage.kt(4 hunks)app/src/main/java/com/sopt/clody/presentation/ui/auth/timereminder/TimeReminderScreen.kt(1 hunks)app/src/main/java/com/sopt/clody/presentation/ui/component/FailureScreen.kt(1 hunks)app/src/main/java/com/sopt/clody/presentation/ui/component/bottomsheet/DiaryDeleteSheet.kt(1 hunks)app/src/main/java/com/sopt/clody/presentation/ui/component/dialog/FailureDialog.kt(1 hunks)app/src/main/java/com/sopt/clody/presentation/ui/component/timepicker/YearMonthPicker.kt(2 hunks)app/src/main/java/com/sopt/clody/presentation/ui/diarylist/component/DailyDiaryCard.kt(2 hunks)app/src/main/java/com/sopt/clody/presentation/ui/diarylist/component/DiaryListTopAppBar.kt(1 hunks)app/src/main/java/com/sopt/clody/presentation/ui/diarylist/screen/DiaryListScreen.kt(1 hunks)app/src/main/java/com/sopt/clody/presentation/ui/home/calendar/component/DailyDiaryListItem.kt(3 hunks)app/src/main/java/com/sopt/clody/presentation/ui/home/component/CloverCount.kt(1 hunks)app/src/main/java/com/sopt/clody/presentation/ui/home/component/DiaryStateButton.kt(5 hunks)app/src/main/java/com/sopt/clody/presentation/ui/home/component/YearAndMonthTitle.kt(1 hunks)app/src/main/java/com/sopt/clody/presentation/ui/home/screen/HomeScreen.kt(5 hunks)app/src/main/java/com/sopt/clody/presentation/ui/login/LoginContract.kt(1 hunks)app/src/main/java/com/sopt/clody/presentation/ui/login/LoginScreen.kt(7 hunks)app/src/main/java/com/sopt/clody/presentation/ui/login/LoginType.kt(1 hunks)app/src/main/java/com/sopt/clody/presentation/ui/login/LoginViewModel.kt(5 hunks)app/src/main/java/com/sopt/clody/presentation/ui/replydiary/ReplyDiaryScreen.kt(2 hunks)app/src/main/java/com/sopt/clody/presentation/ui/replyloading/component/QuickReplyAdButton.kt(1 hunks)app/src/main/java/com/sopt/clody/presentation/ui/replyloading/screen/ReplyLoadingScreen.kt(2 hunks)app/src/main/java/com/sopt/clody/presentation/ui/setting/component/AccountManagementLogoutOption.kt(1 hunks)app/src/main/java/com/sopt/clody/presentation/ui/setting/component/AccountManagementNicknameOption.kt(1 hunks)app/src/main/java/com/sopt/clody/presentation/ui/setting/component/AccountManagementRevokeOption.kt(1 hunks)app/src/main/java/com/sopt/clody/presentation/ui/setting/component/NicknameChangeBottomSheet.kt(6 hunks)app/src/main/java/com/sopt/clody/presentation/ui/setting/component/NicknameChangeTextField.kt(1 hunks)app/src/main/java/com/sopt/clody/presentation/ui/setting/notificationsetting/component/NotificationSettingTimePicker.kt(2 hunks)app/src/main/java/com/sopt/clody/presentation/ui/setting/notificationsetting/screen/NotificationSettingScreen.kt(1 hunks)app/src/main/java/com/sopt/clody/presentation/ui/setting/screen/AccountManagementScreen.kt(7 hunks)app/src/main/java/com/sopt/clody/presentation/ui/setting/screen/AccountManagementViewModel.kt(4 hunks)app/src/main/java/com/sopt/clody/presentation/ui/setting/screen/SettingOptionUrls.kt(1 hunks)app/src/main/java/com/sopt/clody/presentation/ui/setting/screen/SettingScreen.kt(4 hunks)app/src/main/java/com/sopt/clody/presentation/ui/setting/screen/SettingViewModel.kt(2 hunks)app/src/main/java/com/sopt/clody/presentation/ui/splash/SplashScreen.kt(2 hunks)app/src/main/java/com/sopt/clody/presentation/ui/writediary/component/bottomsheet/DeleteWriteDiaryBottomSheet.kt(1 hunks)app/src/main/java/com/sopt/clody/presentation/ui/writediary/component/button/AddDiaryEntryFAB.kt(1 hunks)app/src/main/java/com/sopt/clody/presentation/ui/writediary/component/button/SendButton.kt(1 hunks)app/src/main/java/com/sopt/clody/presentation/ui/writediary/component/textfield/WriteDiaryTextField.kt(1 hunks)app/src/main/java/com/sopt/clody/presentation/ui/writediary/screen/WriteDiaryScreen.kt(9 hunks)app/src/main/java/com/sopt/clody/presentation/ui/writediary/screen/WriteDiaryViewModel.kt(4 hunks)app/src/main/java/com/sopt/clody/presentation/utils/language/LanguageProvider.kt(1 hunks)app/src/main/java/com/sopt/clody/presentation/utils/language/LanguageProviderImpl.kt(1 hunks)app/src/main/java/com/sopt/clody/ui/theme/Theme.kt(1 hunks)app/src/main/java/com/sopt/clody/ui/theme/Type.kt(1 hunks)app/src/main/res/values-ko/strings.xml(1 hunks)app/src/main/res/values/strings.xml(1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (3)
app/src/main/java/com/sopt/clody/presentation/ui/home/screen/HomeScreen.kt (1)
app/src/main/java/com/sopt/clody/presentation/ui/component/button/ClodyButton.kt (1)
ClodyButton(15-44)
app/src/main/java/com/sopt/clody/presentation/ui/auth/signup/page/TermsOfServicePage.kt (2)
app/src/main/java/com/sopt/clody/presentation/ui/home/calendar/component/HorizontalDivider.kt (1)
HorizontalDivider(14-26)app/src/main/java/com/sopt/clody/presentation/ui/setting/navigation/SettingNavigation.kt (1)
navigateToWebView(66-71)
app/src/main/java/com/sopt/clody/presentation/ui/login/LoginScreen.kt (2)
app/src/main/java/com/sopt/clody/presentation/ui/auth/component/button/KaKaoButton.kt (1)
KaKaoButton(24-54)app/src/main/java/com/sopt/clody/presentation/ui/auth/component/button/GoogleButton.kt (1)
GoogleButton(24-54)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: build
🔇 Additional comments (85)
app/src/main/java/com/sopt/clody/presentation/ui/auth/guide/GuideScreen.kt (3)
102-106: LGTM: Improved string resource naming convention.The string resource naming has been updated from
guide_next/guide_starttoguide_btn_next/guide_btn_start, which provides better clarity and follows a more descriptive naming convention. This aligns well with the broader localization effort mentioned in the PR objectives.
183-187: LGTM: Simplified data structure improves maintainability.The
BoardingPagedata class has been simplified by removing thesubtitleproperty, reducing complexity while maintaining all essential information needed for the onboarding flow. The remaining properties (title, description, imageRes) are sufficient for the current UI requirements.
57-78: String resources updated and verifiedAll new resource IDs—
guide_btn_next,guide_btn_start, and everyguide_page[1-4]_title/_description—are present in bothvalues/strings.xmlandvalues-ko/strings.xml, and the oldguide_next/guide_startentries have been removed. No further action needed.app/src/main/java/com/sopt/clody/presentation/ui/writediary/component/bottomsheet/DeleteWriteDiaryBottomSheet.kt (1)
64-67: String-key rename looks correct
R.string.bottom_sheet_diary_deletealigns with the new naming convention and keeps the UI copy in sync with the other bottom-sheet component.app/src/main/java/com/sopt/clody/presentation/ui/component/bottomsheet/DiaryDeleteSheet.kt (1)
75-78: Consistent string resource appliedThe switch to
bottom_sheet_diary_deletematches the earlier component and improves key consistency.app/src/main/java/com/sopt/clody/presentation/ui/splash/SplashScreen.kt (2)
124-140: Resource-key rename looks good – just double-check XML coverageAll usages have been switched to the new
dialog_*prefix, which keeps the naming scheme consistent with the rest of the PR.
Please run an aapt / Gradle sync to ensure bothvalues/strings.xmland the new English overlay include:dialog_soft_update_title dialog_soft_update_description dialog_soft_update_confirm dialog_soft_update_dismissMissing keys will break the build at compile-time.
No other issues spotted here.
163-165: 👍 Exit label rename matches schemeThe exit button now uses
dialog_hard_update_exit, aligning with the pattern and helping translators.app/src/main/java/com/sopt/clody/presentation/ui/home/component/YearAndMonthTitle.kt (1)
26-26: LGTM - String resource key update for consistency.The string resource key update from
home_year_and_month_formattohome_year_month_formataligns with the systematic resource naming convention improvements across the codebase.app/src/main/java/com/sopt/clody/presentation/ui/home/component/CloverCount.kt (1)
21-21: LGTM - String resource key update for consistency.The string resource key update from
home_clover_count_formattohome_total_cloveris consistent with the systematic resource naming improvements being applied across the application.app/src/main/java/com/sopt/clody/presentation/utils/language/LanguageProviderImpl.kt (5)
16-16: LGTM - Clean language detection implementation.The
isKorean()method provides a clear abstraction for language detection using the standard ISO 639-1 language code.
18-20: LGTM - Appropriate login type selection based on locale.The logic to default to Kakao for Korean users and Google for others makes sense from a regional service availability perspective.
22-28: Verify the appropriateness of character limits for different languages.The implementation correctly provides different maximum lengths for Korean vs English, but the specific values should be verified:
- Korean nickname: 10 characters
- English nickname: 15 characters
- Korean diary: 50 characters
- English diary: 100 characters
These ratios seem reasonable given that Korean characters typically convey more meaning per character than English.
30-32: LGTM - Clean URL resolution based on locale.The method correctly delegates URL selection to the
SettingOptionUrlsenum based on locale, maintaining good separation of concerns.
35-40: LGTM - Well-organized constants with appropriate values.The constants are clearly named and the different limits for Korean vs English make sense linguistically. The 2:1 ratio for diary length and 2:3 ratio for nickname length are reasonable considering the density differences between Korean and English text.
app/src/main/java/com/sopt/clody/presentation/ui/writediary/component/button/SendButton.kt (1)
38-38: LGTM - String resource key update follows improved naming convention.The update from
write_diary_text_buttontowrite_diary_btn_sendfollows a clearer naming convention with thebtn_prefix for button text resources, improving resource organization.app/src/main/java/com/sopt/clody/presentation/ui/component/FailureScreen.kt (1)
62-62: LGTM - String resource key update completes consistent naming pattern.The update from
failure_screen_refresh_btntofailure_screen_btn_refreshfollows the establishedbtn_prefix convention, completing the systematic resource naming improvements across the codebase.app/src/main/java/com/sopt/clody/presentation/ui/component/dialog/FailureDialog.kt (1)
86-88: Resource-key rename looks correct – just double-check that it’s translated in every locale.Nothing else changed in this block, compile will fail if the key is missing, but untranslated locales will fall back to the default.
Please ensurestrings.xml (en)and any other language files got the newfailure_dialog_btn_confirmentry to avoid mixed-language UI.app/src/main/java/com/sopt/clody/presentation/ui/replyloading/component/QuickReplyAdButton.kt (1)
44-47: Key renamed; verify length & tone still fit the button width.Since button width is fixed to content padding, a much longer translation might overflow on smaller devices.
Consider running an RTL / long-text check after the key change.app/src/main/java/com/sopt/clody/presentation/ui/setting/component/AccountManagementLogoutOption.kt (1)
44-52: Consistent naming ‑ good; check pluralisation/tense for EN resource.
account_management_btn_logoutfollows the new_btn_convention.
Just confirm that the English copy (“Log out”) matches product style-guide (capitalisation, spacing).app/src/main/java/com/sopt/clody/presentation/ui/writediary/component/button/AddDiaryEntryFAB.kt (1)
89-92: Key rename LGTM – mind potential truncation on smaller widths.
write_diary_fab_add_entrymight translate longer in some locales. The expanded FAB has fixed 16 dp horizontal padding; if you see clipping, considerminWidthor ellipsis.app/src/main/java/com/sopt/clody/presentation/ui/diarylist/component/DiaryListTopAppBar.kt (1)
53-53: String resource exists in all locales – no further action neededThe key
diary_list_selected_year_monthis present in both default and Korean resource files:
- app/src/main/res/values/strings.xml (line 76)
- app/src/main/res/values-ko/strings.xml (line 76)
app/src/main/java/com/sopt/clody/presentation/ui/setting/notificationsetting/screen/NotificationSettingScreen.kt (1)
88-88: Resource declaration confirmed in all localesThe
toast_notification_setting_time_changestring is present in both supported resource folders:
- app/src/main/res/values/strings.xml (line 162)
- app/src/main/res/values-ko/strings.xml (line 162)
No missing resource—toast won’t crash.
app/src/main/java/com/sopt/clody/presentation/ui/setting/component/AccountManagementRevokeOption.kt (1)
31-31: Confirmed availability ofaccount_management_btn_revokein all locales
The string key is defined in both
app/src/main/res/values/strings.xmlapp/src/main/res/values-ko/strings.xmlNo further action needed—approving these changes.
app/src/main/java/com/sopt/clody/presentation/ui/setting/component/AccountManagementNicknameOption.kt (1)
46-46: No missing resource keys detectedThe string key
account_management_btn_change_nicknamewas found in both:
- app/src/main/res/values/strings.xml
- app/src/main/res/values-ko/strings.xml
No further changes needed.
app/src/main/java/com/sopt/clody/presentation/ui/auth/component/timepicker/BottomSheetTimePicker.kt (1)
76-77: All locales:bottom_sheet_time_reminder_picker_titlepresentVerified that the string resource key
bottom_sheet_time_reminder_picker_titleexists in allapp/src/main/res/values*/strings.xmlfiles (values and values-ko). No further action needed.app/src/main/java/com/sopt/clody/presentation/ui/component/timepicker/YearMonthPicker.kt (1)
72-72: LGTM! String resource naming improvements.The updated string resource keys follow a consistent naming convention with contextual prefixes (
bottom_sheet_and_btn_), which improves resource organization and supports better localization management across the app.Also applies to: 136-136
app/src/main/java/com/sopt/clody/presentation/ui/auth/timereminder/TimeReminderScreen.kt (1)
150-150: LGTM! Consistent button resource naming.The string resource updates follow the established pattern of using
_btn_infix for button text resources, improving consistency across the codebase. The semantic change from "next_setting" to "skip" also better reflects the actual user action.Also applies to: 156-156
app/src/main/java/com/sopt/clody/presentation/ui/home/component/DiaryStateButton.kt (1)
34-34: Excellent systematic resource naming.All button text resources have been consistently updated to use the
home_btn_prefix pattern, clearly identifying these as home screen button texts. The systematic application across all conditional branches demonstrates good attention to detail.Also applies to: 43-43, 54-54, 63-63, 72-72
app/src/main/java/com/sopt/clody/presentation/ui/setting/notificationsetting/component/NotificationSettingTimePicker.kt (1)
69-69: LGTM! Consistent bottom sheet resource naming.The string resource updates follow the established
bottom_sheet_prefix pattern and provide more descriptive names that clearly indicate their purpose for notification time change functionality.Also applies to: 147-147
app/src/main/java/com/sopt/clody/presentation/ui/setting/component/NicknameChangeTextField.kt (1)
34-34: Good parameterization for language-aware configuration.Adding the
nicknameMaxLengthparameter enables dynamic configuration of nickname length limits based on language/locale, which supports the English version feature branching objectives. The parameter is properly integrated with the existing validation logic.app/src/main/java/com/sopt/clody/presentation/ui/replyloading/screen/ReplyLoadingScreen.kt (1)
182-184: ✅ Resource key migration verifiedAll old string keys have been replaced, and both
reply_loading_btn_ad_requestandreply_loading_btn_openare defined in your XML and referenced in code without any missing or stale entries. No further action needed.app/src/main/java/com/sopt/clody/presentation/ui/diarylist/screen/DiaryListScreen.kt (1)
200-203: LGTM! Resource key standardization improves organization.The consistent
dialog_prefix for dialog-related string resources enhances maintainability and makes localization more organized.app/src/main/java/com/sopt/clody/presentation/ui/auth/component/button/KaKaoButton.kt (1)
34-34: LGTM! Improved component modularity.Removing the fixed width and padding constraints makes the KaKaoButton more reusable and allows parent components to control layout, which is a good practice for component composition.
app/src/main/java/com/sopt/clody/presentation/ui/diarylist/component/DailyDiaryCard.kt (1)
88-88: LGTM! Consistent resource key naming convention.The updates standardize the naming pattern from
diarylist_*todiary_list_*and add appropriate prefixes likebtn_for button text, which improves resource organization.Also applies to: 95-95, 158-158
app/src/main/java/com/sopt/clody/presentation/ui/home/calendar/component/DailyDiaryListItem.kt (1)
57-57: LGTM! Resource namespacing improves organization.Adding the
home_prefix helps organize string resources by screen/feature and prevents naming conflicts, which is excellent for maintainability.Also applies to: 83-83, 99-99
app/src/main/java/com/sopt/clody/presentation/ui/writediary/component/textfield/WriteDiaryTextField.kt (1)
121-121: Good implementation of dynamic max length validation.The update to use the dynamic
maxLengthparameter instead of a hardcoded value aligns well with the language-aware configuration approach introduced in this PR.app/src/main/java/com/sopt/clody/presentation/di/LanguageModule.kt (1)
10-18: Well-structured Dagger Hilt module.The module correctly binds the
LanguageProviderImplto theLanguageProviderinterface using the appropriateSingletonComponentscope for app-wide language configuration.app/src/main/java/com/sopt/clody/presentation/ui/auth/signup/SignUpScreen.kt (2)
71-72: Good integration of dynamic URL configuration.The addition of
serviceUrlandprivacyUrlparameters enables locale-specific terms of service and privacy policy URLs, supporting the internationalization effort.
90-90: Proper implementation of dynamic nickname length constraint.The
nicknameMaxLengthparameter properly propagates the language-aware maximum length configuration to the UI component.app/src/main/java/com/sopt/clody/presentation/ui/login/LoginContract.kt (1)
9-9: Good additions for multi-provider login support.The new
loginTypestate property andLoginWithGoogleintent properly support the multi-provider login functionality being introduced.Also applies to: 17-17
app/src/main/java/com/sopt/clody/presentation/ui/replydiary/ReplyDiaryScreen.kt (1)
155-155: Consistent string resource key updates for localization.The updated string resource keys follow a more consistent naming convention and support the broader localization effort in this PR.
Also applies to: 190-192
app/src/main/java/com/sopt/clody/presentation/ui/home/screen/HomeScreen.kt (4)
175-175: LGTM: Improved string resource naming consistency.The string resource key updates follow a clear, more descriptive naming convention that better reflects the UI component hierarchy (e.g.,
bottom_sheet_home_initial_draft_*vs.home_draft_popup_*).Also applies to: 182-182, 189-189, 196-196, 205-205
224-224: LGTM: Toast message key follows updated naming convention.The new key
toast_home_draft_alarm_enabledis more descriptive and consistent with the overall naming strategy.
240-244: LGTM: Dialog string keys follow consistent naming pattern.The updated keys with
dialog_home_continue_draft_*prefix clearly indicate these are dialog-related strings, improving maintainability.
269-272: LGTM: Delete dialog keys follow consistent naming pattern.The migration to
dialog_diary_delete_*keys maintains consistency with other dialog-related string resources.app/src/main/java/com/sopt/clody/presentation/ui/auth/component/button/GoogleButton.kt (1)
25-54: LGTM: Well-structured Google button component.The button implementation follows good Compose practices with proper theming, layout, and styling. The preview function aids development workflow.
app/src/main/java/com/sopt/clody/presentation/ui/setting/screen/SettingViewModel.kt (2)
20-20: LGTM: Proper dependency injection of LanguageProvider.The LanguageProvider is correctly injected and will enable locale-aware URL provisioning.
22-25: LGTM: Clean language-aware URL provisioning.The URL properties are well-named and properly utilize the LanguageProvider for localization. The immutable nature ensures consistent behavior throughout the ViewModel lifecycle.
app/src/main/java/com/sopt/clody/ui/theme/Theme.kt (2)
8-12: LGTM: Efficient locale-aware typography selection.The function correctly uses
LocalConfigurationto detect the Korean locale and falls back to English typography for other languages. The implementation is clean and performant.
18-25: LGTM: Proper theme composition with locale-aware typography.The updated
ClodyThemecorrectly provides both colors and typography throughCompositionLocalProvider, enabling the typography to adapt based on the user's locale while maintaining existing functionality.app/src/main/java/com/sopt/clody/presentation/ui/setting/screen/AccountManagementViewModel.kt (3)
27-27: LGTM: Proper LanguageProvider injection.The LanguageProvider dependency is correctly injected to enable locale-aware nickname length configuration.
53-54: LGTM: Reactive nickname max length configuration.The StateFlow implementation allows for reactive updates to the maximum nickname length based on locale settings, maintaining consistency with the reactive architecture.
115-115: LGTM: Dynamic regex validation with locale-aware max length.The regex correctly incorporates the dynamic maximum length from the language provider while maintaining the existing character validation rules. This enables proper nickname validation across different locales.
app/src/main/java/com/sopt/clody/presentation/ui/login/LoginViewModel.kt (1)
30-30: Good integration of LanguageProvider.The
LanguageProviderdependency is properly injected and used to set the initial login type. The pattern of posting an intent in the init block and handling it in the intent handler is consistent with the existing architecture.Also applies to: 42-42, 51-51
app/src/main/java/com/sopt/clody/presentation/utils/language/LanguageProvider.kt (1)
6-11: Well-designed interface for language-specific configurations.The
LanguageProviderinterface provides a clean abstraction for locale-dependent behavior. The method signatures are clear and cover the main areas needing language-specific configuration: authentication, input constraints, and external URLs.app/src/main/java/com/sopt/clody/presentation/ui/auth/component/textfield/NickNameTextField.kt (1)
32-32: Excellent parameterization of maximum length.The change from hardcoded
maxLengthto a parameter enables dynamic configuration based on language settings. The implementation correctly uses the parameter in the length validation logic.Also applies to: 43-46, 104-104
app/src/main/java/com/sopt/clody/presentation/ui/auth/signup/SignUpContract.kt (1)
12-12: Well-implemented dynamic configuration supportThe addition of language-dependent properties (
nicknameMaxLength,serviceUrl,privacyUrl) and corresponding intents follows good architectural patterns. The default values are reasonable and the changes integrate cleanly with the existing contract structure.Also applies to: 17-17, 19-19, 32-32, 40-40
app/src/main/java/com/sopt/clody/presentation/ui/writediary/screen/WriteDiaryScreen.kt (2)
78-78: Proper dynamic length configuration implementationThe threading of
diaryMaxLengththrough the composable hierarchy is well-implemented. The parameter flows correctly from the ViewModel state to the UI components that need it.Also applies to: 117-117, 188-188, 271-271
287-290: String resource updates look consistentThe dialog string resource key updates align with the broader localization effort and maintain consistency across the codebase.
Also applies to: 306-309
app/src/main/java/com/sopt/clody/presentation/ui/setting/screen/AccountManagementScreen.kt (1)
54-54: Consistent dynamic configuration implementationThe
nicknameMaxLengthparameter is properly collected from the ViewModel and threaded through the composable hierarchy, following the same pattern established elsewhere in the codebase.Also applies to: 85-85, 105-105, 166-166
app/src/main/java/com/sopt/clody/presentation/ui/writediary/screen/WriteDiaryViewModel.kt (2)
34-34: Clean LanguageProvider integrationThe injection of
LanguageProviderand initialization of_diaryMaxLengthStateFlow follows good dependency injection patterns and reactive programming principles.Also applies to: 72-74
162-162: Dynamic regex construction is well-implementedThe validation regex correctly uses the dynamic
_diaryMaxLength.valueinstead of a hardcoded limit, maintaining the same character set validation while supporting configurable length constraints.app/src/main/java/com/sopt/clody/presentation/ui/auth/signup/page/NicknamePage.kt (2)
38-49: LGTM! Clean parameterization of nickname length.The addition of
nicknameMaxLengthparameter properly replaces hardcoded values and integrates well with the existing component structure.
90-90: Good consistency improvement with button text resource naming.The update from
nickname_nexttonickname_btn_nextfollows a consistent naming convention for button text resources.app/src/main/java/com/sopt/clody/presentation/ui/auth/signup/SignUpViewModel.kt (2)
42-49: LGTM! Proper initialization of language-dependent values.The initialization calls for
SetNicknameMaxLengthandSetWebViewUrlintents ensure that language-dependent values are set up correctly when the ViewModel is created.
117-124: LGTM! Clean implementation of dynamic URL configuration.The
setWebViewUrl()method properly integrates with the LanguageProvider to set locale-specific URLs for terms of service and privacy policy.app/src/main/java/com/sopt/clody/presentation/ui/login/LoginScreen.kt (3)
76-80: LGTM! Improved function signature with unified state.The updated
LoginScreenfunction signature properly accepts a unified state object and separate callbacks for different login providers, making the component more maintainable.
123-128: LGTM! Simplified logo display.The centered logo display with proper sizing improves the UI layout consistency.
93-113: LoginType enum and import checks out
TheLoginTypeenum is defined inapp/src/main/java/com/sopt/clody/presentation/ui/login/LoginType.ktwith the expected values (KAKAO,LoginScreen.ktresides in the same package, no explicitimportis required. Everything is correct here.app/src/main/java/com/sopt/clody/presentation/ui/auth/signup/page/TermsOfServicePage.kt (3)
35-47: LGTM! Proper parameterization of URLs for localization.The addition of
serviceUrlandprivacyUrlparameters enables dynamic, locale-specific URLs for terms of service and privacy policy, replacing the previous hardcoded constants.
116-116: LGTM! Correct usage of dynamic URLs.The
navigateToWebViewcalls now properly use the parameterized URLs instead of hardcoded constants, enabling locale-specific navigation.Also applies to: 123-123
72-72: Good consistency improvement with button text resource naming.The update to
terms_btn_nextaligns with the consistent naming convention for button text resources across the app.app/src/main/java/com/sopt/clody/ui/theme/Type.kt (5)
14-36: Excellent architectural improvement with immutable typography data class.The new
ClodyTypographydata class provides a clean, immutable structure for typography definitions, improving maintainability and type safety compared to individual TextStyle definitions.
38-38: Smart helper function for consistent line height calculations.The
lineHeightextension function onTextUnitprovides a clean, reusable way to calculate line heights with consistent ratios across different typography variants.
46-53: LGTM! Proper separation of Korean and English base styles.The distinction between
pretendardKoreanTextStyle(with letterSpacing) andpretendardEnglishTextStyle(without letterSpacing) correctly addresses the different typography requirements for these languages.
55-156: Comprehensive typography definitions with appropriate locale-specific ratios.The Korean and English typography variants are well-implemented with:
- Korean: 1.5f line height ratio (appropriate for Hangul character spacing)
- English: 1.3f-1.4f line height ratios (better for Latin characters)
- Consistent font sizes and weights across both variants
- Special case for
letterMediumwith higher ratios (1.9f Korean, 1.8f English)This provides excellent foundation for locale-aware typography throughout the app.
Also applies to: 158-259
261-261: Appropriate default typography selection.Setting
clodyEnglishTypographyas the default inLocalClodyTypographyis a reasonable choice, likely to be overridden by the theme provider based on actual locale.app/src/main/java/com/sopt/clody/presentation/ui/setting/screen/SettingScreen.kt (4)
32-35: LGTM! Good localization implementation.The delegated properties pattern effectively enables language-dependent URL configuration. This approach cleanly separates concerns by having the ViewModel handle language-specific logic while keeping the UI layer focused on composition.
44-44: String resource update aligns with localization goals.The change to a more specific string resource key supports better organization of localized strings.
48-51: Dynamic URL usage enables proper localization.Replacing hardcoded URLs with dynamic values from the ViewModel correctly implements language-dependent configuration.
62-63: Parameter Renames Verified and Safe to MergeI searched the entire Kotlin codebase and found no remaining references to the old parameter names. All
SettingScreen(…)invocations now useonClickNoticeandonClickSupportFeedback, so this change is fully applied.• No instances of
onClickAnnouncementfound
• No instances ofonClickInquiriesSuggestionsfound
• AllSettingScreencalls use the new parameter namesapp/src/main/java/com/sopt/clody/presentation/ui/setting/component/NicknameChangeBottomSheet.kt (4)
40-40: Good externalization of nickname length constraints.Adding the
nicknameMaxLengthparameter enables language-dependent validation rules, which is essential for proper localization support.Also applies to: 50-50, 64-64
115-115: Proper parameter threading to child component.Correctly passing the dynamic max length to
NickNameChangeTextFieldmaintains consistency throughout the component hierarchy.
87-87: String resource updates support localization structure.The updated string resource keys with
bottom_sheet_nickname_change_prefix improve organization for translation management.Also applies to: 167-167
36-43: AllNicknameChangeBottomSheetcallers updatedVerified that every invocation now includes the new
nicknameMaxLengthargument (e.g. inapp/src/main/java/com/sopt/clody/presentation/ui/setting/screen/AccountManagementScreen.kt). No further changes required.
app/src/main/java/com/sopt/clody/presentation/ui/login/LoginViewModel.kt
Show resolved
Hide resolved
app/src/main/java/com/sopt/clody/presentation/ui/setting/screen/SettingOptionUrls.kt
Show resolved
Hide resolved
| private fun validateNickname(nickname: String): Boolean { | ||
| val regex = "^[a-zA-Z가-힣0-9ㄱ-ㅎㅏ-ㅣ가-힣]{2,10}$".toRegex() | ||
| val state = withState(this@SignUpViewModel) { it } | ||
| setState { copy(nicknameMaxLength = languageProvider.getNicknameMaxLength()) } | ||
| val regex = "^[a-zA-Z가-힣0-9ㄱ-ㅎㅏ-ㅣ가-힣]{2,${state.nicknameMaxLength}$".toRegex() | ||
| return nickname.matches(regex) | ||
| } |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Optimize validation logic to avoid redundant operations.
The current implementation has two issues:
setStatecall on line 177 is redundant sincesetNicknameMaxLength()is already called during initialization- Regex is reconstructed on every validation call, which is inefficient
Apply this diff to improve performance:
private fun validateNickname(nickname: String): Boolean {
- val state = withState(this@SignUpViewModel) { it }
- setState { copy(nicknameMaxLength = languageProvider.getNicknameMaxLength()) }
- val regex = "^[a-zA-Z가-힣0-9ㄱ-ㅎㅏ-ㅣ가-힣]{2,${state.nicknameMaxLength}$".toRegex()
+ val state = withState(this@SignUpViewModel) { it }
+ val regex = "^[a-zA-Z가-힣0-9ㄱ-ㅎㅏ-ㅣ가-힣]{2,${state.nicknameMaxLength}}$".toRegex()
return nickname.matches(regex)
}Consider caching the regex pattern or moving validation logic to a separate class for better performance and testability.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| private fun validateNickname(nickname: String): Boolean { | |
| val regex = "^[a-zA-Z가-힣0-9ㄱ-ㅎㅏ-ㅣ가-힣]{2,10}$".toRegex() | |
| val state = withState(this@SignUpViewModel) { it } | |
| setState { copy(nicknameMaxLength = languageProvider.getNicknameMaxLength()) } | |
| val regex = "^[a-zA-Z가-힣0-9ㄱ-ㅎㅏ-ㅣ가-힣]{2,${state.nicknameMaxLength}$".toRegex() | |
| return nickname.matches(regex) | |
| } | |
| private fun validateNickname(nickname: String): Boolean { | |
| val state = withState(this@SignUpViewModel) { it } | |
| val regex = "^[a-zA-Z가-힣0-9ㄱ-ㅎㅏ-ㅣ가-힣]{2,${state.nicknameMaxLength}}$".toRegex() | |
| return nickname.matches(regex) | |
| } |
🤖 Prompt for AI Agents
In
app/src/main/java/com/sopt/clody/presentation/ui/auth/signup/SignUpViewModel.kt
around lines 175 to 180, remove the redundant setState call that updates
nicknameMaxLength since it is already set during initialization. Also, avoid
reconstructing the regex pattern on every validation call by caching the regex
as a class-level property or moving the validation logic to a separate class
where the regex can be compiled once and reused, improving performance and
testability.
MoonsuKang
left a comment
There was a problem hiding this comment.
GOOD BOY~ 리뷰 한번만 봐주세요~
| return if (locale.language == "ko") clodyKoreanTypography else clodyEnglishTypography | ||
| } |
There was a problem hiding this comment.
P3
Local이 안바뀌니까 remember로 감싸는게 좋을 것 같다는 생각이 납니다.
There was a problem hiding this comment.
locale 캐싱해놓고 변경되는 순간에만 다른 타이포 제공이라 좋을 것 같네요 반영하겠슴당
| private val locale: Locale | ||
| get() = context.resources.configuration.locales[0] |
There was a problem hiding this comment.
P3
private val locale: Locale by lazy {
context.resources.configuration.locales[0]
}앱 내부에서 실시간 언어 변경이 없기 때문에 lazy 사용해서 locale을 캐싱하는 것이 더 좋을 것 같지 않나유?
There was a problem hiding this comment.
이 부분은 Theme.kt랑 살짝 다른 케이스 같습니다. 말씀해주신 방식으로 하면 지연초기화 말고 어떤 장점이 있는지 정확히는 모르겠으나, 앱을 사용하다가 시스템 언어 설정 바꾸고 들어오면 반영이 안될 것 같습니다..? 반면 LocalConfiguration이 바뀌면서 UI나 다른것들은 바뀐 시스템 언어 설정을 반영하기 때문에 미스매치가 좀 생길거 같아서 혼란하네요 .. 반영하는게 맞을까요?
private val locale: Locale = context.resources.configuration.locales[0]
반영한다면 위 방식이랑 어떤 차이가 있을까요 ??
There was a problem hiding this comment.
앱 사용 중간에 언어 변경해서 바꿀 수 있는거였나요..? 몰랐네 그건
만약 그렇게 동적으로 적용하는 의도라면 lazy안쓰는게 맞습니다~!
| private fun isValidEntry(text: String): Boolean { | ||
| val textWithoutSpaces = text.replace("\\s".toRegex(), "") | ||
| return textWithoutSpaces.matches(Regex(ENTRY_REGEX)) | ||
| return textWithoutSpaces.matches(Regex("^[a-zA-Z가-힣0-9ㄱ-ㅎㅏ-ㅣ가-힣\\W]{2,${_diaryMaxLength.value}$")) |
There was a problem hiding this comment.
P5
어라 이 친구 object에서 뺀 이유가 있을까여?
There was a problem hiding this comment.
object에 들어가있어서 _diaryMaxLength.value 부분을 정규식에 집어넣지를 못해서 빼게 됐습니다!
일기 작성 최대 글자수 변경하는 작업하느냐고 뷰모델부터 Screen들을 대충 쭉 봤는데 정규식이 여기도 있고 스크린에도 있고 한 상태라 한번 뒤엎는 작업이 필요하지 않을까.. 싶습니다.
- 하드 업데이트 다이얼로그 문자열 리소스 추가 - 일기 작성 텍스트필드 정규식 조정
📌 ISSUE
closed #299
📄 Work Description
LanguageProvider를 앱의 중앙 언어 분기 로직의 단일 진입점으로 구성. 언어별 기능 분기는 해당 Provider 활용남은 작업은 아래와 같습니다.
✨ PR Point
LanguageProvider에 언어 분기 로직을 집중시키면서 Typo 또한 그렇게 가능할지 고민을 해봤습니다.
일단 현재 구조도 충분히 깔끔하다고 생각되어 일단 진행하지는 않았습니다.
또한 이렇게 하면 현재처럼 ViewModel -> UI 가 아닌 UI 쪽에서 바로 ClodyTheme object를 통해 바로 접근할 수 있는건가? 싶어서 편해보였지만,, 이런 기능 분기 로직이 ViewModel 쪽을 안거치고 그렇게 사용되도 되나? ViewModel 검증 로직에서는 Composable 관련한 기능이 사용이 안될텐데 못가져오지 않을까 생각했습니다.
지금처럼 진행하는 편이 무난하겠죠? 더 좋은 아이디어가 있다면 ..! 리뷰 부탁드립니다
📸 ScreenShot/Video
Summary by CodeRabbit
New Features
Enhancements
Bug Fixes
Style
Documentation