Skip to content

Commit

Permalink
⚙️ Add app language selection setting
Browse files Browse the repository at this point in the history
A language selection setting is added to the settings page.
The `MainActivity` now extends `AppCompatActivity` to handle changing the
app language. More info on this here:
https://developer.android.com/guide/topics/resources/app-languages#androidx-impl
  • Loading branch information
rubenquadros authored and LeoColman committed Oct 10, 2024
1 parent b6ef3d9 commit d00169a
Show file tree
Hide file tree
Showing 8 changed files with 102 additions and 3 deletions.
11 changes: 10 additions & 1 deletion app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
android:label="Petals"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@android:style/Theme.Holo.Light.NoActionBar">
android:theme="@style/AppTheme">
<activity
android:name=".MainActivity"
android:exported="true">
Expand Down Expand Up @@ -62,6 +62,15 @@
android:resource="@xml/file_paths" />
</provider>

<service
android:name="androidx.appcompat.app.AppLocalesMetadataHolderService"
android:enabled="false"
android:exported="false">
<meta-data
android:name="autoStoreLocales"
android:value="true" />
</service>

</application>

</manifest>
4 changes: 2 additions & 2 deletions app/src/main/kotlin/br/com/colman/petals/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@
package br.com.colman.petals

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.appcompat.app.AppCompatActivity
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
Expand Down Expand Up @@ -56,7 +56,7 @@ import org.koin.android.ext.android.inject
import java.time.LocalDateTime

@Suppress("FunctionName")
class MainActivity : ComponentActivity(), CoroutineScope by CoroutineScope(Dispatchers.Main) {
class MainActivity : AppCompatActivity(), CoroutineScope by CoroutineScope(Dispatchers.Main) {

private var authorizedUntil = LocalDateTime.MIN
private val settingsRepository by inject<SettingsRepository>()
Expand Down
25 changes: 25 additions & 0 deletions app/src/main/kotlin/br/com/colman/petals/settings/AppLanguage.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package br.com.colman.petals.settings

enum class AppLanguage(val languageName: String, val languageCode: String) {
German("Deutsch", "de"),
English("English", "en"),
French("Français", "fr"),
Spanish("Español", "es"),
Italian("Italiano", "it"),
Dutch("Nederlands", "nl"),
Norwegian("Norsk", "no"),
Portuguese("Português", "pt"),
Russian("Русский", "ru"),
Turkish("Türkçe", "tr"),
Ukrainian("Українськ", "uk");

companion object {
fun getAppLanguageName(code: String): String {
return entries.firstOrNull { it.languageCode == code }?.languageName ?: English.languageName
}

fun getAppLanguageCode(languageName: String): String {
return entries.firstOrNull { it.languageName == languageName }?.languageCode ?: English.languageCode
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ class SettingsRepository(
val isDarkModeEnabled: Flow<Boolean> = datastore.data.map { it[IsDarkModeOn] ?: true }
val isHitTimerMillisecondsEnabled = datastore.data.map { it[IsHitTimerMillisecondsEnabled] ?: false }
val isDayExtended = datastore.data.map { it[IsDayExtended] ?: false }
val appLanguages = AppLanguage.entries.map { it.languageName }

fun setCurrencyIcon(value: String): Unit = runBlocking {
datastore.edit { it[CurrencyIcon] = value }
Expand Down
17 changes: 17 additions & 0 deletions app/src/main/kotlin/br/com/colman/petals/settings/SettingsView.kt
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
package br.com.colman.petals.settings

import androidx.appcompat.app.AppCompatDelegate
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.core.os.LocaleListCompat
import br.com.colman.petals.settings.view.listitem.ClockListItem
import br.com.colman.petals.settings.view.listitem.CurrencyListItem
import br.com.colman.petals.settings.view.listitem.DateListItem
import br.com.colman.petals.settings.view.listitem.ExtendDayListItem
import br.com.colman.petals.settings.view.listitem.HitTimerMillisecondsEnabledListItem
import br.com.colman.petals.settings.view.listitem.LanguageListItem
import br.com.colman.petals.settings.view.listitem.PinListItem
import br.com.colman.petals.settings.view.listitem.PrecisionListItem
import br.com.colman.petals.settings.view.listitem.RepositoryListItem
Expand All @@ -29,6 +32,15 @@ fun SettingsView(settingsRepository: SettingsRepository) {
settingsRepository.decimalPrecisionList[2]
)
val currentExtendDay by settingsRepository.isDayExtended.collectAsState(false)

val setAppLanguage = { language: String ->
val languageCode = AppLanguage.getAppLanguageCode(language)
if (languageCode.isNotEmpty()) {
val appLocale = LocaleListCompat.forLanguageTags(languageCode)
AppCompatDelegate.setApplicationLocales(appLocale)
}
}

Column(Modifier.verticalScroll(rememberScrollState())) {
CurrencyListItem(currentCurrency, settingsRepository::setCurrencyIcon)
PinListItem(settingsRepository::setPin)
Expand All @@ -41,6 +53,11 @@ fun SettingsView(settingsRepository: SettingsRepository) {
settingsRepository.decimalPrecisionList,
settingsRepository::setDecimalPrecision
)
LanguageListItem(
AppLanguage.getAppLanguageName(AppCompatDelegate.getApplicationLocales().toLanguageTags()),
settingsRepository.appLanguages,
setAppLanguage
)
HitTimerMillisecondsEnabledListItem(
currentHitTimerMillisecondsEnabled,
settingsRepository::setIsHitTimerMillisecondsEnabled
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package br.com.colman.petals.settings.view.listitem

import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.Preview
import br.com.colman.petals.R.string.language_label
import br.com.colman.petals.R.string.what_language_should_be_used
import br.com.colman.petals.settings.view.dialog.SelectFromListDialog
import compose.icons.TablerIcons
import compose.icons.tablericons.Language

@Preview
@Composable
fun LanguageListItem(
appLanguage: String = "English",
appLanguageList: List<String> = listOf(),
setAppLanguage: (String) -> Unit = {}
) {
DialogListItem(
icon = TablerIcons.Language,
textId = language_label,
descriptionId = what_language_should_be_used,
dialog = { hideDialog -> LanguageDialog(appLanguage, appLanguageList, setAppLanguage, hideDialog) }
)
}

@Preview
@Composable
private fun LanguageDialog(
initialAppLanguage: String = "",
appLanguageList: List<String> = listOf(),
setAppLanguage: (String) -> Unit = {},
onDismiss: () -> Unit = {},
) {
SelectFromListDialog(
initialValue = initialAppLanguage,
possibleValues = appLanguageList,
setValue = setAppLanguage,
onDismiss = onDismiss,
label = language_label
)
}
2 changes: 2 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -175,4 +175,6 @@
<item quantity="one">Last %s day</item>
<item quantity="other">Last %s days</item>
</plurals>
<string name="language_label">App language</string>
<string name="what_language_should_be_used">What language should be used</string>
</resources>
4 changes: 4 additions & 0 deletions app/src/main/res/values/styles.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar"/>
</resources>

0 comments on commit d00169a

Please sign in to comment.