Skip to content

Conversation

@jvsena42
Copy link
Member

@jvsena42 jvsena42 commented Sep 23, 2025

Close #406 (comment) , #406 (comment)

FIGMA

Description

Roadmap item

This PR implements the language selection from inside the app and from android system settings

Preview

Screen_recording_20250924_081210.webm

QA Notes

  • App settings > General > Language > Select language
  • Android > App info > Language > Select a language

@jvsena42 jvsena42 self-assigned this Sep 23, 2025
@jvsena42 jvsena42 marked this pull request as ready for review September 24, 2025 11:15
@jvsena42 jvsena42 requested a review from Copilot September 24, 2025 11:16
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR implements language selection functionality for the Bitkit Android app, allowing users to change the app language both from within the app settings and through Android system settings. The implementation provides a comprehensive language management system with support for 12 languages plus system default.

  • Adds a new Language Settings screen accessible from General Settings
  • Implements AppLocaleManager for handling locale changes across different Android versions
  • Creates proper MVVM architecture with LanguageViewModel for language state management

Reviewed Changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
app/src/main/java/to/bitkit/models/Language.kt Defines Language enum with supported languages and utility functions for locale conversion
app/src/main/java/to/bitkit/ui/utils/AppLocaleManager.kt Handles locale management with Android version compatibility for API 33+ and legacy versions
app/src/main/java/to/bitkit/viewmodels/LanguageViewModel.kt Manages language selection state and interactions following MVVM pattern
app/src/main/java/to/bitkit/ui/settings/LanguageSettingsScreen.kt Composable screen for language selection with list of available languages
app/src/main/java/to/bitkit/ui/settings/general/GeneralSettingsScreen.kt Adds language settings button to general settings with current language display
app/src/main/java/to/bitkit/ui/ContentView.kt Adds navigation route and handler for language settings screen
app/src/main/java/to/bitkit/ui/shared/util/Modifiers.kt Adds screen modifier utility for consistent screen layout
app/build.gradle.kts Enables locale config generation for proper Android localization support
app/src/main/AndroidManifest.xml Adds AppCompat locale service for backward compatibility

@jvsena42 jvsena42 requested a review from ovitrif September 24, 2025 11:22
@jvsena42 jvsena42 enabled auto-merge September 24, 2025 11:22
Copy link
Collaborator

@ovitrif ovitrif left a comment

Choose a reason for hiding this comment

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

LGTM, works great in all checks:

  • via settings
  • via os app info
  • manually when system default is on and returning to the app

Kudos also for:
nice addition of `Modifier.screen()
nice and clean code

added a few remarks, non-blocking and non-mandatory that could help make the code even cleaner 🔮

}
}

@Preview
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: best to always use @Preview(showSystemUi = true) for screen previews, at times it could reveal some hidden issues with insets paddings. It's not the case now though, fortunately :)

Copy link
Member Author

Choose a reason for hiding this comment

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

I forgot in this one. Will add to AS quick actions

fun getCurrentLanguage(): Language {
val locale = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
val localeList = context.getSystemService(LocaleManager::class.java)?.applicationLocales
localeList?.get(0).takeIf { localeList != null && !localeList.isEmpty }
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: works but this doesn't make a lot of sense :)

localeList?.get(0).takeIf { localeList != null && !localeList.isEmpty }
is equal to localeList?.get(0).takeIf { it.isNotEmpty() }

we already use safe call AFAIU

Comment on lines +53 to +57
fun getSupportedLanguages(): List<Language> {
return Language.entries.sortedWith(
compareBy<Language> { !it.isSystemDefault }.thenBy { it.displayName }
)
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: doesn't need to be instance method on appLocaleManager, it's not using any state of the class

Comment on lines +1384 to +1387
fun NavController.navigateToLanguageSettings() = navigate(
route = Routes.LanguageSettings,
)

Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: wish I'd removed most of the navigateTo… methods, it's not really adding value, plus the entire nav setup might change entirely when we can adopt nav3

@jvsena42 jvsena42 merged commit 64f9da0 into master Sep 24, 2025
8 checks passed
@jvsena42 jvsena42 deleted the feat/language-settings branch September 24, 2025 13:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants