mirror of
https://github.com/Myzel394/Alibi.git
synced 2025-06-18 23:05:26 +02:00
feat: Add in-app language picker
This commit is contained in:
parent
7b0230d4f2
commit
56deb12373
3
app/src/main/java/app/myzel394/alibi/Constants.kt
Normal file
3
app/src/main/java/app/myzel394/alibi/Constants.kt
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
package app.myzel394.alibi
|
||||||
|
|
||||||
|
val SUPPORTED_LOCALES = arrayOf("en-US", "zh-CN")
|
@ -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,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
@ -17,6 +17,8 @@ import androidx.compose.ui.unit.dp
|
|||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun SettingsTile(
|
fun SettingsTile(
|
||||||
|
modifier: Modifier = Modifier,
|
||||||
|
firstModifier: Modifier = Modifier,
|
||||||
title: String,
|
title: String,
|
||||||
description: String? = null,
|
description: String? = null,
|
||||||
leading: @Composable () -> Unit = {},
|
leading: @Composable () -> Unit = {},
|
||||||
@ -27,8 +29,10 @@ fun SettingsTile(
|
|||||||
Row(
|
Row(
|
||||||
verticalAlignment = Alignment.CenterVertically,
|
verticalAlignment = Alignment.CenterVertically,
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
|
.then(firstModifier)
|
||||||
.fillMaxWidth()
|
.fillMaxWidth()
|
||||||
.padding(16.dp)
|
.padding(16.dp)
|
||||||
|
.then(modifier),
|
||||||
) {
|
) {
|
||||||
leading()
|
leading()
|
||||||
Spacer(modifier = Modifier.width(16.dp))
|
Spacer(modifier = Modifier.width(16.dp))
|
||||||
|
@ -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.BitrateTile
|
||||||
import app.myzel394.alibi.ui.components.SettingsScreen.atoms.EncoderTile
|
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.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.IntervalDurationTile
|
||||||
import app.myzel394.alibi.ui.components.SettingsScreen.atoms.MaxDurationTile
|
import app.myzel394.alibi.ui.components.SettingsScreen.atoms.MaxDurationTile
|
||||||
import app.myzel394.alibi.ui.components.SettingsScreen.atoms.OutputFormatTile
|
import app.myzel394.alibi.ui.components.SettingsScreen.atoms.OutputFormatTile
|
||||||
@ -120,6 +121,7 @@ fun SettingsScreen(
|
|||||||
MaxDurationTile()
|
MaxDurationTile()
|
||||||
IntervalDurationTile()
|
IntervalDurationTile()
|
||||||
ForceExactMaxDurationTile()
|
ForceExactMaxDurationTile()
|
||||||
|
InAppLanguagePicker()
|
||||||
AnimatedVisibility(visible = settings.showAdvancedSettings) {
|
AnimatedVisibility(visible = settings.showAdvancedSettings) {
|
||||||
Column {
|
Column {
|
||||||
Divider(
|
Divider(
|
||||||
|
@ -62,4 +62,6 @@
|
|||||||
<string name="ui_audioRecorder_state_paused_description">Audio Recording has been paused</string>
|
<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_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_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>
|
</resources>
|
Loading…
x
Reference in New Issue
Block a user