Skip to content

[Feat/#299] 영어 버전 기능 분기 처리를 진행합니다.#302

Merged
SYAAINN merged 8 commits intodevelopfrom
feat/#299-en-localization-feature
Jul 16, 2025
Merged

[Feat/#299] 영어 버전 기능 분기 처리를 진행합니다.#302
SYAAINN merged 8 commits intodevelopfrom
feat/#299-en-localization-feature

Conversation

@SYAAINN
Copy link
Contributor

@SYAAINN SYAAINN commented Jul 15, 2025

📌 ISSUE

closed #299

📄 Work Description

  • 영어 버전 Typo 추가 (TextUnit 확장함수를 통한 lineHeight 계산 방식으로 개선)
  • LanguageProvider를 앱의 중앙 언어 분기 로직의 단일 진입점으로 구성. 언어별 기능 분기는 해당 Provider 활용
  • LanguageProvider -> ViewModel -> UI 흐름으로 기능 분기 처리 진행

남은 작업은 아래와 같습니다.

  • UI 레이아웃 점검
  • strings.xml 로 대응 안된 부분들 번역 (특히 오류처리 개선)
  • 연/월/일 나타내는 부분 해결 (단순 번역이 아닌 표기 방식이 다름.)

✨ PR Point

LanguageProvider에 언어 분기 로직을 집중시키면서 Typo 또한 그렇게 가능할지 고민을 해봤습니다.

val LocalLanguageProvider = staticCompositionLocalOf<LanguageProvider> {
    error("No LanguageProvider provided")
}

// Theme.kt

@Composable
fun ClodyTheme(
    languageProvider: LanguageProvider,
    content: @Composable () -> Unit,
) {
    val colors = defaultClodyColors
    val typography = if (~) clodyKoreanTypography else clodyEnglishTypography

    CompositionLocalProvider(
        LocalClodyColors provides colors,
        LocalClodyTypography provides typography,
        LocalLanguageProvider provides languageProvider,
        content = content,
    )
}

object ClodyTheme {
    val colors: ClodyColors
        @Composable
        @ReadOnlyComposable
        get() = LocalClodyColors.current

    val typography: ClodyTypography
        @Composable
        @ReadOnlyComposable
        get() = LocalClodyTypography.current

    val languageProvider: LanguageProvider
        @Composable
        @ReadOnlyComposable
        get() = LocalLanguageProvider.current
}

일단 현재 구조도 충분히 깔끔하다고 생각되어 일단 진행하지는 않았습니다.

또한 이렇게 하면 현재처럼 ViewModel -> UI 가 아닌 UI 쪽에서 바로 ClodyTheme object를 통해 바로 접근할 수 있는건가? 싶어서 편해보였지만,, 이런 기능 분기 로직이 ViewModel 쪽을 안거치고 그렇게 사용되도 되나? ViewModel 검증 로직에서는 Composable 관련한 기능이 사용이 안될텐데 못가져오지 않을까 생각했습니다.

지금처럼 진행하는 편이 무난하겠죠? 더 좋은 아이디어가 있다면 ..! 리뷰 부탁드립니다

📸 ScreenShot/Video

  • N/A (추후 첨부?)

Summary by CodeRabbit

  • New Features

    • Added support for language-specific configurations, including login type, input length limits, and localized URLs throughout the app.
    • Introduced dynamic maximum length settings for nickname and diary entry fields, adapting to the user's language.
    • Enabled language-based theming for typography and improved theme management.
  • Enhancements

    • Login and sign-up screens now support both Kakao and Google login options, with UI adapting to the selected login type.
    • Settings and terms-related screens now display URLs and information based on the current language.
    • Updated UI components to reflect dynamic input constraints and localized resources.
  • Bug Fixes

    • Corrected confirmation button text in the hard update dialog.
  • Style

    • Improved typography and layout to better support both Korean and English users.
  • Documentation

    • Added new and updated string resources for improved localization.

@SYAAINN SYAAINN requested a review from MoonsuKang July 15, 2025 06:07
@SYAAINN SYAAINN self-assigned this Jul 15, 2025
@SYAAINN SYAAINN added ✨ FEAT 기능 개발 🔥 민재 민재 labels Jul 15, 2025
@coderabbitai
Copy link

coderabbitai bot commented Jul 15, 2025

Walkthrough

This update introduces language-aware branching throughout the application. A new LanguageProvider abstraction and its implementation are injected into ViewModels and UI components to provide locale-dependent configurations, such as login type (Kakao for Korean, Google for English), maximum lengths for nickname and diary entries, and localized web view URLs. Typography and theming are also adapted based on the current locale. Numerous composable and ViewModel signatures are updated to accept or propagate dynamic values, removing hardcoded constants. Supporting string resources and enums are added or revised, and UI logic is refactored to use these new mechanisms.

Changes

File(s) Change Summary
.../presentation/di/LanguageModule.kt, .../utils/language/LanguageProvider.kt, .../utils/language/LanguageProviderImpl.kt Added Hilt module, interface, and implementation for language-dependent configuration.
.../ui/login/LoginType.kt Added LoginType enum for login method branching.
.../ui/setting/screen/SettingOptionUrls.kt Replaced URL constants object with enum for localized URLs.
.../ui/theme/Type.kt, .../ui/theme/Theme.kt Introduced locale-aware typography via new data class, providers, and composition locals.
.../ui/auth/component/textfield/NickNameTextField.kt, .../ui/setting/component/NicknameChangeTextField.kt Made nickname max length configurable via parameter, removed hardcoded value.
.../ui/auth/signup/page/NicknamePage.kt, .../ui/setting/component/NicknameChangeBottomSheet.kt Updated composable signatures to accept and display dynamic nickname max length.
.../ui/auth/signup/SignUpContract.kt, .../ui/login/LoginContract.kt Extended state and intents to support dynamic login type, nickname length, and URLs.
.../ui/auth/signup/SignUpViewModel.kt, .../ui/login/LoginViewModel.kt, .../ui/setting/screen/AccountManagementViewModel.kt, .../ui/setting/screen/SettingViewModel.kt, .../ui/writediary/screen/WriteDiaryViewModel.kt Injected LanguageProvider, refactored logic to use dynamic values for login type, nickname/diary length, and URLs.
.../ui/auth/signup/SignUpScreen.kt, .../ui/auth/signup/page/TermsOfServicePage.kt, .../ui/setting/screen/AccountManagementScreen.kt, .../ui/setting/screen/SettingScreen.kt, .../ui/writediary/screen/WriteDiaryScreen.kt Refactored to propagate dynamic configuration (nickname/diary length, URLs) through composable hierarchies.
.../ui/login/LoginScreen.kt Refactored to support multiple login types and update UI accordingly.
.../ui/writediary/component/textfield/WriteDiaryTextField.kt Made diary entry validation use dynamic max length.
.../ui/writediary/component/topbar/WriteDiaryTopBar.kt Changed navigation icon's content description to null.
.../ui/splash/SplashScreen.kt Reordered dialog parameters, fixed string resource usage.
.../res/values/strings.xml, .../res/values-ko/strings.xml Added string resource for hard update dialog confirm button.

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)
Loading

Suggested labels

♻️ REFACTOR, 🌊 문수

Poem

A bunny hops from code to code,
Adapting apps for every mode.
English or Korean, it’s all the same—
Dynamic lengths and names in the game!
URLs that change, logins that shift,
Locale-aware magic—what a nifty gift!
🐇✨


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ac6664c and c28221c.

📒 Files selected for processing (1)
  • app/src/main/java/com/sopt/clody/ui/theme/Theme.kt (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • app/src/main/java/com/sopt/clody/ui/theme/Theme.kt
⏰ 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
✨ Finishing Touches
  • 📝 Generate Docstrings

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.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need 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)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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-null contentDescription for accessibility

Screen-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_icon to all supported locales.

app/src/main/java/com/sopt/clody/presentation/ui/component/bottomsheet/DiaryDeleteSheet.kt (1)

70-72: Provide contentDescription for the trash icon here as well

Mirror 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.

  1. If the backend ever sends an unknown provider, enum deserialization (e.g. with Moshi/Kotlinx) will crash.
  2. If these constants are sent over the wire, annotate with @JsonClass/@SerializedName or provide a fallback via @JsonEnumDefaultValue.
  3. For more flexibility you could replace the enum with a sealed interface + object implementations 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 string

The 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 file

The 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

📥 Commits

Reviewing files that changed from the base of the PR and between ec57404 and 8fc9d6f.

⛔ Files ignored due to path filters (4)
  • app/src/main/res/drawable-ko/img_splash_logo.png is excluded by !**/*.png
  • app/src/main/res/drawable-xhdpi/img_splash_logo.png is excluded by !**/*.png
  • app/src/main/res/drawable/img_google_button_logo.png is excluded by !**/*.png
  • app/src/main/res/drawable/img_splash_logo.png is 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_start to guide_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 BoardingPage data class has been simplified by removing the subtitle property, 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 verified

All new resource IDs—guide_btn_next, guide_btn_start, and every guide_page[1-4]_title/_description—are present in both values/strings.xml and values-ko/strings.xml, and the old guide_next/guide_start entries 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_delete aligns 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 applied

The switch to bottom_sheet_diary_delete matches 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 coverage

All 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 both values/strings.xml and the new English overlay include:

dialog_soft_update_title
dialog_soft_update_description
dialog_soft_update_confirm
dialog_soft_update_dismiss

Missing keys will break the build at compile-time.
No other issues spotted here.


163-165: 👍 Exit label rename matches scheme

The 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_format to home_year_month_format aligns 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_format to home_total_clover is 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 SettingOptionUrls enum 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_button to write_diary_btn_send follows a clearer naming convention with the btn_ 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_btn to failure_screen_btn_refresh follows the established btn_ 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 ensure strings.xml (en) and any other language files got the new failure_dialog_btn_confirm entry 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_logout follows 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_entry might translate longer in some locales. The expanded FAB has fixed 16 dp horizontal padding; if you see clipping, consider minWidth or 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 needed

The key diary_list_selected_year_month is 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 locales

The toast_notification_setting_time_change string 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 of account_management_btn_revoke in all locales
The string key is defined in both

  • app/src/main/res/values/strings.xml
  • app/src/main/res/values-ko/strings.xml

No 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 detected

The string key account_management_btn_change_nickname was 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_title present

Verified that the string resource key bottom_sheet_time_reminder_picker_title exists in all app/src/main/res/values*/strings.xml files (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 nicknameMaxLength parameter 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 verified

All old string keys have been replaced, and both reply_loading_btn_ad_request and reply_loading_btn_open are 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_* to diary_list_* and add appropriate prefixes like btn_ 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 maxLength parameter 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 LanguageProviderImpl to the LanguageProvider interface using the appropriate SingletonComponent scope 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 serviceUrl and privacyUrl parameters enables locale-specific terms of service and privacy policy URLs, supporting the internationalization effort.


90-90: Proper implementation of dynamic nickname length constraint.

The nicknameMaxLength parameter 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 loginType state property and LoginWithGoogle intent 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_enabled is 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 LocalConfiguration to 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 ClodyTheme correctly provides both colors and typography through CompositionLocalProvider, 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 LanguageProvider dependency 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 LanguageProvider interface 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 maxLength to 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 support

The 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 implementation

The threading of diaryMaxLength through 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 consistent

The 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 implementation

The nicknameMaxLength parameter 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 integration

The injection of LanguageProvider and initialization of _diaryMaxLength StateFlow follows good dependency injection patterns and reactive programming principles.

Also applies to: 72-74


162-162: Dynamic regex construction is well-implemented

The validation regex correctly uses the dynamic _diaryMaxLength.value instead 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 nicknameMaxLength parameter 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_next to nickname_btn_next follows 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 SetNicknameMaxLength and SetWebViewUrl intents 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 LoginScreen function 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
The LoginType enum is defined in app/src/main/java/com/sopt/clody/presentation/ui/login/LoginType.kt with the expected values (KAKAO, GOOGLE), and since LoginScreen.kt resides in the same package, no explicit import is 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 serviceUrl and privacyUrl parameters 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 navigateToWebView calls 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_next aligns 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 ClodyTypography data 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 lineHeight extension function on TextUnit provides 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) and pretendardEnglishTextStyle (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 letterMedium with 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 clodyEnglishTypography as the default in LocalClodyTypography is 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 Merge

I searched the entire Kotlin codebase and found no remaining references to the old parameter names. All SettingScreen(…) invocations now use onClickNotice and onClickSupportFeedback, so this change is fully applied.

• No instances of onClickAnnouncement found
• No instances of onClickInquiriesSuggestions found
• All SettingScreen calls use the new parameter names

app/src/main/java/com/sopt/clody/presentation/ui/setting/component/NicknameChangeBottomSheet.kt (4)

40-40: Good externalization of nickname length constraints.

Adding the nicknameMaxLength parameter 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 NickNameChangeTextField maintains 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: All NicknameChangeBottomSheet callers updated

Verified that every invocation now includes the new nicknameMaxLength argument (e.g. in app/src/main/java/com/sopt/clody/presentation/ui/setting/screen/AccountManagementScreen.kt). No further changes required.

Comment on lines 175 to 180
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)
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Optimize validation logic to avoid redundant operations.

The current implementation has two issues:

  1. setState call on line 177 is redundant since setNicknameMaxLength() is already called during initialization
  2. 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.

Suggested change
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 MoonsuKang changed the base branch from develop to feat/#293-en-localization July 15, 2025 11:25
@SYAAINN SYAAINN changed the base branch from feat/#293-en-localization to develop July 15, 2025 11:28
Copy link
Contributor

@MoonsuKang MoonsuKang left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GOOD BOY~ 리뷰 한번만 봐주세요~

Comment on lines +11 to +12
return if (locale.language == "ko") clodyKoreanTypography else clodyEnglishTypography
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3
Local이 안바뀌니까 remember로 감싸는게 좋을 것 같다는 생각이 납니다.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

locale 캐싱해놓고 변경되는 순간에만 다른 타이포 제공이라 좋을 것 같네요 반영하겠슴당

Comment on lines +13 to +14
private val locale: Locale
get() = context.resources.configuration.locales[0]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P3

private val locale: Locale by lazy {
    context.resources.configuration.locales[0]
}

앱 내부에서 실시간 언어 변경이 없기 때문에 lazy 사용해서 locale을 캐싱하는 것이 더 좋을 것 같지 않나유?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 부분은 Theme.kt랑 살짝 다른 케이스 같습니다. 말씀해주신 방식으로 하면 지연초기화 말고 어떤 장점이 있는지 정확히는 모르겠으나, 앱을 사용하다가 시스템 언어 설정 바꾸고 들어오면 반영이 안될 것 같습니다..? 반면 LocalConfiguration이 바뀌면서 UI나 다른것들은 바뀐 시스템 언어 설정을 반영하기 때문에 미스매치가 좀 생길거 같아서 혼란하네요 .. 반영하는게 맞을까요?

private val locale: Locale = context.resources.configuration.locales[0]
반영한다면 위 방식이랑 어떤 차이가 있을까요 ??

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

앱 사용 중간에 언어 변경해서 바꿀 수 있는거였나요..? 몰랐네 그건
만약 그렇게 동적으로 적용하는 의도라면 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}$"))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P5
어라 이 친구 object에서 뺀 이유가 있을까여?

Copy link
Contributor Author

@SYAAINN SYAAINN Jul 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

object에 들어가있어서 _diaryMaxLength.value 부분을 정규식에 집어넣지를 못해서 빼게 됐습니다!
일기 작성 최대 글자수 변경하는 작업하느냐고 뷰모델부터 Screen들을 대충 쭉 봤는데 정규식이 여기도 있고 스크린에도 있고 한 상태라 한번 뒤엎는 작업이 필요하지 않을까.. 싶습니다.

@SYAAINN SYAAINN changed the title [Feat/#299] 영어 버전 기능 분기 처리를 진행하고, 미대응된 부분들을 번역합니다. [Feat/#299] 영어 버전 기능 분기 처리를 진행합니다. Jul 16, 2025
SYAAINN added 2 commits July 16, 2025 11:22
- 하드 업데이트 다이얼로그 문자열 리소스 추가
- 일기 작성 텍스트필드 정규식 조정
Copy link
Contributor

@MoonsuKang MoonsuKang left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GOOD

@SYAAINN SYAAINN merged commit e665301 into develop Jul 16, 2025
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

✨ FEAT 기능 개발 🔥 민재 민재

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEAT] 영어 버전 기능 분기 처리를 진행합니다.

2 participants