Add an option to change in-app language

closes #77
This commit is contained in:
Sad Ellie 2023-09-05 13:02:18 +03:00
parent 368ab8c162
commit a2173abf61
9 changed files with 96 additions and 6 deletions

View File

@ -117,6 +117,7 @@ dependencies {
implementation(libs.com.github.sadellie.themmo)
implementation(libs.com.google.accompanist.systemuicontroller)
implementation(libs.androidx.datastore)
implementation(libs.androidx.appcompat)
implementation(project(mapOf("path" to ":feature:converter")))
implementation(project(mapOf("path" to ":feature:calculator")))

View File

@ -7,8 +7,8 @@
android:name=".UnittoApplication"
android:icon="@mipmap/ic_launcher_icon"
android:label="@string/calculator"
android:supportsRtl="false"
android:localeConfig="@xml/locales_config"
android:theme="@style/Theme.Unitto">
<activity
android:windowSoftInputMode="adjustPan"
@ -36,6 +36,15 @@
<action android:name="android.service.quicksettings.action.QS_TILE" />
</intent-filter>
</service>
<service
android:name="androidx.appcompat.app.AppLocalesMetadataHolderService"
android:enabled="false"
android:exported="false">
<meta-data
android:name="autoStoreLocales"
android:value="true" />
</service>
</application>
</manifest>

View File

@ -23,8 +23,8 @@ import android.content.Context
import android.os.Bundle
import android.util.AttributeSet
import android.view.View
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.appcompat.app.AppCompatActivity
import androidx.core.view.WindowCompat
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.sadellie.unitto.data.userprefs.UserPreferencesRepository
@ -32,7 +32,7 @@ import dagger.hilt.android.AndroidEntryPoint
import javax.inject.Inject
@AndroidEntryPoint
internal class MainActivity : ComponentActivity() {
internal class MainActivity : AppCompatActivity() {
@Inject
lateinit var userPrefsRepository: UserPreferencesRepository

View File

@ -1,5 +1,5 @@
<resources>
<style name="Theme.Unitto" parent="@android:style/Theme.Material.NoActionBar">
<style name="Theme.Unitto" parent="Theme.AppCompat.DayNight.NoActionBar">
<item name="android:windowBackground">@color/window_background</item>
<item name="android:statusBarColor">@color/window_background</item>
<item name="android:navigationBarColor">@color/window_background</item>

View File

@ -1382,4 +1382,13 @@ Used in this dialog window. Should be short -->
<string name="add">Add</string>
<string name="subtract">Subtract</string>
<string name="date_calculator">Date calculator</string>
<string name="locale_en" translatable="false">English</string>
<string name="locale_de" translatable="false">Deutsch</string>
<string name="locale_en_rGB" translatable="false">English (UK)</string>
<string name="locale_fr" translatable="false">Français</string>
<string name="locale_it" translatable="false">Italiano</string>
<string name="locale_ru" translatable="false">Русский</string>
<string name="language_setting">Language</string>
<string name="language_setting_support">Change the app language</string>
</resources>

View File

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?><!--
~ Unitto is a unit converter for Android
~ Copyright (c) 2023 Elshan Agaev
~
~ This program is free software: you can redistribute it and/or modify
~ it under the terms of the GNU General Public License as published by
~ the Free Software Foundation, either version 3 of the License, or
~ (at your option) any later version.
~
~ This program is distributed in the hope that it will be useful,
~ but WITHOUT ANY WARRANTY; without even the implied warranty of
~ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
~ GNU General Public License for more details.
~
~ You should have received a copy of the GNU General Public License
~ along with this program. If not, see <https://www.gnu.org/licenses/>.
-->
<locale-config xmlns:android="http://schemas.android.com/apk/res/android">
<locale android:name="en"/>
<locale android:name="de"/>
<locale android:name="en-rGB"/>
<locale android:name="fr"/>
<locale android:name="it"/>
<locale android:name="ru"/>
</locale-config>

View File

@ -30,6 +30,7 @@ android {
dependencies {
implementation(libs.com.github.sadellie.themmo)
implementation(libs.org.burnoutcrew.composereorderable)
implementation(libs.androidx.appcompat)
implementation(project(mapOf("path" to ":data:common")))
implementation(project(mapOf("path" to ":data:model")))

View File

@ -18,12 +18,14 @@
package com.sadellie.unitto.feature.settings
import androidx.appcompat.app.AppCompatDelegate
import androidx.compose.foundation.clickable
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ExposureZero
import androidx.compose.material.icons.filled.Home
import androidx.compose.material.icons.filled.Info
import androidx.compose.material.icons.filled.Language
import androidx.compose.material.icons.filled.Palette
import androidx.compose.material.icons.filled.RateReview
import androidx.compose.material.icons.filled.Rule
@ -42,6 +44,7 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.core.os.LocaleListCompat
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.sadellie.unitto.core.base.BuildConfig
@ -63,7 +66,7 @@ import com.sadellie.unitto.feature.settings.navigation.unitsGroupRoute
internal fun SettingsScreen(
viewModel: SettingsViewModel = hiltViewModel(),
menuButtonClick: () -> Unit,
navControllerAction: (String) -> Unit
navControllerAction: (String) -> Unit,
) {
val mContext = LocalContext.current
val userPrefs = viewModel.userPrefs.collectAsStateWithLifecycle()
@ -206,6 +209,21 @@ internal fun SettingsScreen(
)
}
// LANGUAGE
item {
ListItem(
leadingContent = {
Icon(
Icons.Default.Language,
stringResource(R.string.language_setting)
)
},
headlineContent = { Text(stringResource(R.string.language_setting)) },
supportingContent = { Text(stringResource(R.string.language_setting_support)) },
modifier = Modifier.clickable { dialogState = DialogState.LANGUAGE }
)
}
// RATE THIS APP
if (BuildConfig.STORE_LINK.isNotEmpty()) {
item {
@ -257,6 +275,7 @@ internal fun SettingsScreen(
dismissAction = { resetDialog() }
)
}
DialogState.UNIT_LIST_SORTING -> {
AlertDialogWithList(
title = stringResource(R.string.units_sorting),
@ -271,6 +290,29 @@ internal fun SettingsScreen(
dismissAction = { resetDialog() }
)
}
DialogState.LANGUAGE -> {
AlertDialogWithList(
title = stringResource(R.string.language_setting),
listItems = mapOf(
"" to R.string.auto_label,
"en" to R.string.locale_en,
"de" to R.string.locale_de,
"en_rGB" to R.string.locale_en_rGB,
"fr" to R.string.locale_fr,
"it" to R.string.locale_it,
"ru" to R.string.locale_ru,
),
selectedItemIndex = AppCompatDelegate.getApplicationLocales().toLanguageTags(),
selectAction = {
val selectedLocale = if (it == "") LocaleListCompat.getEmptyLocaleList()
else LocaleListCompat.forLanguageTags(it)
AppCompatDelegate.setApplicationLocales(selectedLocale)
},
dismissAction = { resetDialog() }
)
}
// Dismissing alert dialog
else -> {}
}
@ -280,5 +322,5 @@ internal fun SettingsScreen(
* All possible states for alert dialog that opens when user clicks on settings.
*/
private enum class DialogState {
NONE, START_SCREEN, UNIT_LIST_SORTING
NONE, START_SCREEN, UNIT_LIST_SORTING, LANGUAGE
}

View File

@ -12,6 +12,7 @@ androidxComposeMaterial3 = "1.2.0-alpha04"
androidxNavigation = "2.6.0"
androidxLifecycleRuntimeCompose = "2.6.1"
androidxHilt = "1.0.0"
androidxAppCompat = "1.6.1"
comGoogleDagger = "2.47"
androidxComposeMaterialIconsExtended = "1.6.0-alpha02"
androidxDatastore = "1.0.0"
@ -61,6 +62,7 @@ com-squareup-retrofit2 = { group = "com.squareup.retrofit2", name = "converter-m
com-github-sadellie-themmo = { group = "com.github.sadellie", name = "themmo", version.ref = "comGithubSadellieThemmo" }
org-burnoutcrew-composereorderable = { group = "org.burnoutcrew.composereorderable", name = "reorderable", version.ref = "orgBurnoutcrewComposereorderable" }
android-desugarJdkLibs = { group = "com.android.tools", name = "desugar_jdk_libs", version.ref = "androidDesugarJdkLibs" }
androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "androidxAppCompat" }
# classpath
android-gradlePlugin = { group = "com.android.tools.build", name = "gradle", version.ref = "androidGradlePlugin" }