feat: Add in-app language picker

This commit is contained in:
Myzel394 2023-08-10 20:07:05 +02:00
parent 7b0230d4f2
commit 56deb12373
No known key found for this signature in database
GPG Key ID: 79CC92F37B3E1A2B
5 changed files with 112 additions and 0 deletions

View File

@ -0,0 +1,3 @@
package app.myzel394.alibi
val SUPPORTED_LOCALES = arrayOf("en-US", "zh-CN")

View File

@ -0,0 +1,101 @@
package app.myzel394.alibi.ui.components.SettingsScreen.atoms
import androidx.appcompat.app.AppCompatDelegate
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.AudioFile
import androidx.compose.material.icons.filled.CheckCircle
import androidx.compose.material.icons.filled.ChevronRight
import androidx.compose.material.icons.filled.Circle
import androidx.compose.material.icons.filled.Translate
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import androidx.core.os.LocaleListCompat
import app.myzel394.alibi.R
import app.myzel394.alibi.SUPPORTED_LOCALES
import app.myzel394.alibi.db.AudioRecorderSettings
import app.myzel394.alibi.ui.components.atoms.SettingsTile
import app.myzel394.alibi.ui.utils.IconResource
import com.maxkeppeker.sheets.core.models.base.ButtonStyle
import com.maxkeppeker.sheets.core.models.base.Header
import com.maxkeppeker.sheets.core.models.base.IconSource
import com.maxkeppeker.sheets.core.models.base.SelectionButton
import com.maxkeppeker.sheets.core.models.base.rememberUseCaseState
import com.maxkeppeler.sheets.list.ListDialog
import com.maxkeppeler.sheets.list.models.ListOption
import com.maxkeppeler.sheets.list.models.ListSelection
import java.util.Locale
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun InAppLanguagePicker() {
val showDialog = rememberUseCaseState()
val locales = Locale.getAvailableLocales().filter {
val locale = it.language +
(if (it.country.isNotBlank()) "-${it.country}" else "") +
(if (it.variant.isNotBlank()) "-${it.variant}" else "")
SUPPORTED_LOCALES.contains(locale)
}
ListDialog(
state = showDialog,
header = Header.Default(
title = stringResource(R.string.ui_settings_language_title),
icon = IconSource(
painter = IconResource.fromImageVector(Icons.Default.Translate).asPainterResource(),
contentDescription = null,
)
),
selection = ListSelection.Single(
showRadioButtons = true,
options = IntRange(0, locales.size - 1).map {index ->
val locale = locales[index]!!
ListOption(
titleText = locale.displayName,
subtitleText = locale.getDisplayName(Locale.ENGLISH),
)
}.toList(),
positiveButton = SelectionButton(
icon = IconSource(
painter = IconResource.fromImageVector(Icons.Default.CheckCircle).asPainterResource(),
contentDescription = null,
),
text = stringResource(android.R.string.ok),
type = ButtonStyle.TEXT,
)
) {index, _ ->
AppCompatDelegate.setApplicationLocales(
LocaleListCompat.forLanguageTags(
locales[index]!!.toLanguageTag(),
),
)
},
)
SettingsTile(
firstModifier = Modifier
.fillMaxHeight()
.clickable {
showDialog.show()
},
title = stringResource(R.string.ui_settings_language_title),
leading = {
Icon(
Icons.Default.Translate,
contentDescription = null,
)
},
)
}

View File

@ -17,6 +17,8 @@ import androidx.compose.ui.unit.dp
@Composable
fun SettingsTile(
modifier: Modifier = Modifier,
firstModifier: Modifier = Modifier,
title: String,
description: String? = null,
leading: @Composable () -> Unit = {},
@ -27,8 +29,10 @@ fun SettingsTile(
Row(
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier
.then(firstModifier)
.fillMaxWidth()
.padding(16.dp)
.then(modifier),
) {
leading()
Spacer(modifier = Modifier.width(16.dp))

View File

@ -38,6 +38,7 @@ import app.myzel394.alibi.db.AppSettings
import app.myzel394.alibi.ui.components.SettingsScreen.atoms.BitrateTile
import app.myzel394.alibi.ui.components.SettingsScreen.atoms.EncoderTile
import app.myzel394.alibi.ui.components.SettingsScreen.atoms.ForceExactMaxDurationTile
import app.myzel394.alibi.ui.components.SettingsScreen.atoms.InAppLanguagePicker
import app.myzel394.alibi.ui.components.SettingsScreen.atoms.IntervalDurationTile
import app.myzel394.alibi.ui.components.SettingsScreen.atoms.MaxDurationTile
import app.myzel394.alibi.ui.components.SettingsScreen.atoms.OutputFormatTile
@ -120,6 +121,7 @@ fun SettingsScreen(
MaxDurationTile()
IntervalDurationTile()
ForceExactMaxDurationTile()
InAppLanguagePicker()
AnimatedVisibility(visible = settings.showAdvancedSettings) {
Column {
Divider(

View File

@ -62,4 +62,6 @@
<string name="ui_audioRecorder_state_paused_description">Audio Recording has been paused</string>
<string name="ui_audioRecorder_error_recording_title">An error occured</string>
<string name="ui_audioRecorder_error_recording_description">Alibi encountered an error during recording. Would you like to try saving the recording?</string>
<string name="ui_settings_language_title">Language</string>
<string name="ui_settings_language_update_label">Change</string>
</resources>