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 committed Oct 8, 2024
1 parent fc8b29e commit e1f95a5
Show file tree
Hide file tree
Showing 8 changed files with 122 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
49 changes: 49 additions & 0 deletions app/src/main/kotlin/br/com/colman/petals/settings/AppLanguages.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package br.com.colman.petals.settings

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

companion object {
fun getAppLanguageName(code: String): String {
return when (code) {
"de" -> Deutsch.name
"fr" -> Français.name
"es" -> Español.name
"it" -> Italiano.name
"nl" -> Nederlands.name
"no" -> Norsk.name
"pt" -> Português.name
"ru" -> Русский.name
"tr" -> Türkçe.name
"uk" -> Українськ.name
else -> English.name
}
}

fun getAppLanguageCode(languageName: String): String {
return when (languageName) {
Deutsch.name -> Deutsch.code
Français.name -> Français.code
Español.name -> Español.code
Italiano.name -> Italiano.code
Nederlands.name -> Nederlands.code
Norsk.name -> Norsk.code
Português.name -> Português.code
Русский.name -> Русский.code
Türkçe.name -> Türkçe.code
Українськ.name -> Українськ.code
else -> English.code
}
}
}
}
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.name }

fun setCurrencyIcon(value: String): Unit = runBlocking {
datastore.edit { it[CurrencyIcon] = value }
Expand Down
13 changes: 13 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,7 @@ 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 e1f95a5

Please sign in to comment.