some todos

This commit is contained in:
Helium314 2025-02-06 22:45:37 +01:00
parent 5f87dbc9cc
commit 00304855f2
18 changed files with 216 additions and 318 deletions

View file

@ -27,11 +27,11 @@ class AllPrefs(context: Context) {
fun filter(searchTerm: String): List<PrefDef> { fun filter(searchTerm: String): List<PrefDef> {
val term = searchTerm.lowercase() val term = searchTerm.lowercase()
val results = mutableSetOf<PrefDef>() val results = mutableSetOf<PrefDef>()
list.forEach { if (it.title.lowercase().startsWith(term)) results.add(it) } list.forEach { def -> if (def.title.lowercase().startsWith(term)) results.add(def) }
list.forEach { if (it.title.lowercase().split(' ').any { it.startsWith(term) }) results.add(it) } list.forEach { def -> if (def.title.lowercase().split(' ').any { it.startsWith(term) }) results.add(def) }
list.forEach { list.forEach { def ->
if (it.description?.lowercase()?.split(' ')?.any { it.startsWith(term) } == true) if (def.description?.lowercase()?.split(' ')?.any { it.startsWith(term) } == true)
results.add(it) results.add(def)
} }
return results.toList() return results.toList()
} }

View file

@ -6,7 +6,6 @@ import androidx.annotation.DrawableRes
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.RowScope import androidx.compose.foundation.layout.RowScope
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
@ -48,6 +47,7 @@ import helium314.keyboard.settings.dialogs.ListPickerDialog
import helium314.keyboard.settings.dialogs.ReorderDialog import helium314.keyboard.settings.dialogs.ReorderDialog
import helium314.keyboard.settings.dialogs.SliderDialog import helium314.keyboard.settings.dialogs.SliderDialog
import helium314.keyboard.settings.screens.GetIcon import helium314.keyboard.settings.screens.GetIcon
import kotlin.math.roundToInt
// partially taken from StreetComplete / SCEE // partially taken from StreetComplete / SCEE
@ -187,6 +187,7 @@ fun <T: Number> SliderPreference(
description: @Composable (T) -> String, description: @Composable (T) -> String,
default: T, default: T,
range: ClosedFloatingPointRange<Float>, range: ClosedFloatingPointRange<Float>,
stepSize: Int? = null,
onValueChanged: (Float) -> Unit = { }, onValueChanged: (Float) -> Unit = { },
) { ) {
val ctx = LocalContext.current val ctx = LocalContext.current
@ -203,7 +204,7 @@ fun <T: Number> SliderPreference(
name = name, name = name,
onClick = { showDialog = true }, onClick = { showDialog = true },
modifier = modifier, modifier = modifier,
description = description(initialValue as T) description = description(initialValue)
) )
if (showDialog) if (showDialog)
SliderDialog( SliderDialog(
@ -215,11 +216,16 @@ fun <T: Number> SliderPreference(
initialValue = initialValue.toFloat(), initialValue = initialValue.toFloat(),
range = range, range = range,
positionString = { positionString = {
description((if (default is Int) it.toInt() else it) as T) @Suppress("UNCHECKED_CAST")
description((if (default is Int) it.roundToInt() else it) as T)
}, },
onValueChanged = onValueChanged, onValueChanged = onValueChanged,
showDefault = true, showDefault = true,
onDefault = { prefs.edit().remove(pref).apply() } onDefault = { prefs.edit().remove(pref).apply() },
intermediateSteps = stepSize?.let {
// this is not nice, but slider wants it like this...
((range.endInclusive - range.start) / it - 1).toInt()
}
) )
} }
@ -299,6 +305,7 @@ fun ReorderSwitchPreference(def: PrefDef, default: String) {
private class KeyAndState(var name: String, var state: Boolean) private class KeyAndState(var name: String, var state: Boolean)
@Suppress("UNCHECKED_CAST")
private fun <T: Any> getPrefOfType(prefs: SharedPreferences, key: String, default: T): T = private fun <T: Any> getPrefOfType(prefs: SharedPreferences, key: String, default: T): T =
when (default) { when (default) {
is String -> prefs.getString(key, default) is String -> prefs.getString(key, default)

View file

@ -14,28 +14,27 @@ import helium314.keyboard.latin.utils.prefs
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
// todo (roughly in order) // todo (roughly in order)
// work on todos in other files // maybe move some large prefs out of their screens into separate files (backup/restore!)
// use better / more structured and clear names and arrangement of files
// the prefDef and AllPrefs, also be clear about pref <-> key <-> prefKey (all used, probably should be latter)
// there is a lot more ambiguous naming...
// dialogs should be rememberSaveable to survive display orientation change and stuff?
// check dark and light theme (don't have dynamic) // check dark and light theme (don't have dynamic)
// any way to get rid of the "old" background on starting settings? probably comes from app theme, can we avoid it? // any way to get rid of the "old" background on starting settings? probably comes from app theme, can we avoid it?
// rename both settingsActivities // rename both settingsActivities
// calling KeyboardSwitcher.getInstance().forceUpdateKeyboardTheme(requireContext()) while keyboard is showing shows just full screen background // calling KeyboardSwitcher.getInstance().forceUpdateKeyboardTheme(requireContext()) while keyboard is showing shows just full screen background
// but reload while keyboard is showing would be great (isn't it at least semi-done when changing one-handed mode?) // but reload while keyboard is showing would be great (isn't it at least semi-done when changing one-handed mode?)
// use better / more structured and clear names and arrangement of files
// the prefDef and AllPrefs, also be clear about pref <-> key <-> prefKey (all used, probably should be latter)
// there is a lot more ambiguous naming...
// animations when stuff (dis)appears
// LaunchedEffect, AnimatedVisibility
// bg image inconsistent about being on toolbar or not (is this new?) // bg image inconsistent about being on toolbar or not (is this new?)
// maybe move some large prefs out of their screens into separate files (backup/restore!)
// performance // performance
// find a nice way of testing (probably add logs for measuring time and recompositions) // find a nice way of testing (probably add logs for measuring time and recompositions)
// consider that stuff in composables can get called quite often on any changes // consider that stuff in composables can get called quite often on any changes
// -> use remember for things that are slow, but be careful they don't change from outside the composable // -> use remember for things that are slow, but be careful they don't change from outside the composable
// dialogs should be rememberSaveable to survive display orientation change and stuff?
// try making old fragment back stuff work better, and try the different themes (with and without top bar, it should only appear for old fragments) // try making old fragment back stuff work better, and try the different themes (with and without top bar, it should only appear for old fragments)
// PRs adding prefs -> need to do before continuing // PRs adding prefs -> need to do before continuing
// 1263 (no response for several weeks now...) // 1263 (no response for several weeks now...)
// merge main to implement all the new settings // merge main to implement all the new settings
// really use the restart dialog for debug settings stuff?
// could do it the old way, and hide debug settings from search
// what should be done, but not in this PR // what should be done, but not in this PR
// in general: changes to anything outside the new settings (unless necessary), and changes to how screens / fragments work // in general: changes to anything outside the new settings (unless necessary), and changes to how screens / fragments work

View file

@ -25,7 +25,7 @@ fun Theme(dark: Boolean = isSystemInDarkTheme(), content: @Composable () -> Unit
if (dark) dynamicDarkColorScheme(LocalContext.current) if (dark) dynamicDarkColorScheme(LocalContext.current)
else dynamicLightColorScheme(LocalContext.current) else dynamicLightColorScheme(LocalContext.current)
} else { } else {
// todo: more colors // todo (later): more colors
if (dark) darkColorScheme( if (dark) darkColorScheme(
primary = colorResource(R.color.accent), primary = colorResource(R.color.accent),
) )

View file

@ -95,7 +95,7 @@ fun CustomizeIconsDialog(
val iconsForName = allIcons[iconName].orEmpty() val iconsForName = allIcons[iconName].orEmpty()
val iconsSet = mutableSetOf<Int>() val iconsSet = mutableSetOf<Int>()
iconsSet.addAll(iconsForName) iconsSet.addAll(iconsForName)
KeyboardIconsSet.getAllIcons(ctx).forEach { iconsSet.addAll(it.value) } // todo: is this called again on UI interaction? KeyboardIconsSet.getAllIcons(ctx).forEach { iconsSet.addAll(it.value) }
val icons = iconsSet.toList() val icons = iconsSet.toList()
var selectedIcon by remember { mutableStateOf(KeyboardIconsSet.instance.iconIds[iconName]) } var selectedIcon by remember { mutableStateOf(KeyboardIconsSet.instance.iconIds[iconName]) }
ThreeButtonAlertDialog( ThreeButtonAlertDialog(

View file

@ -1,58 +0,0 @@
// SPDX-License-Identifier: GPL-3.0-only
package helium314.keyboard.settings.dialogs
import android.widget.Toast
import androidx.compose.foundation.layout.imePadding
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.window.DialogProperties
import helium314.keyboard.latin.R
import helium314.keyboard.latin.utils.Log
import helium314.keyboard.latin.utils.checkLayout
import helium314.keyboard.latin.utils.getCustomLayoutFile
import helium314.keyboard.latin.utils.getLayoutDisplayName
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
@Composable
fun CustomizeLayoutDialog(
layoutName: String,
onDismissRequest: () -> Unit,
startContent: String? = null,
displayName: String? = null,
) {
val ctx = LocalContext.current
val file = getCustomLayoutFile(layoutName, ctx)
val scope = rememberCoroutineScope()
var job: Job? = null
TextInputDialog(
onDismissRequest = onDismissRequest,
onConfirmed = { },
initialText = startContent ?: file.readText(),
title = { Text(displayName ?: getLayoutDisplayName(layoutName)) },
checkTextValid = {
val valid = checkLayout(it, ctx)
job?.cancel()
if (!valid) {
job = scope.launch {
delay(3000)
val message = Log.getLog(10)
.lastOrNull { it.tag == "CustomLayoutUtils" }?.message
?.split("\n")?.take(2)?.joinToString("\n")
Toast.makeText(ctx, ctx.getString(R.string.layout_error, message), Toast.LENGTH_LONG).show()
}
}
valid
},
singleLine = false,
modifier = Modifier.imePadding(),
// decorFitsSystemWindows = false is necessary so the dialog is not covered by keyboard
// but this also stops the background from being darkened... great idea to combine both
properties = DialogProperties(decorFitsSystemWindows = false)
)
}

View file

@ -1,22 +1,30 @@
// SPDX-License-Identifier: GPL-3.0-only // SPDX-License-Identifier: GPL-3.0-only
package helium314.keyboard.settings.dialogs package helium314.keyboard.settings.dialogs
import android.widget.Toast
import androidx.compose.foundation.layout.imePadding
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.window.DialogProperties
import helium314.keyboard.latin.R import helium314.keyboard.latin.R
import helium314.keyboard.latin.utils.Log
import helium314.keyboard.latin.utils.checkLayout import helium314.keyboard.latin.utils.checkLayout
import helium314.keyboard.latin.utils.getCustomLayoutFile import helium314.keyboard.latin.utils.getCustomLayoutFile
import helium314.keyboard.latin.utils.getLayoutDisplayName import helium314.keyboard.latin.utils.getLayoutDisplayName
import helium314.keyboard.latin.utils.onCustomLayoutFileListChanged import helium314.keyboard.latin.utils.onCustomLayoutFileListChanged
import helium314.keyboard.settings.keyboardNeedsReload import helium314.keyboard.settings.keyboardNeedsReload
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
// todo: height MUST respect keyboard, or it's impossible to fill the bottom part
@Composable @Composable
fun LayoutEditDialog( fun LayoutEditDialog(
onDismissRequest: () -> Unit, onDismissRequest: () -> Unit,
@ -26,9 +34,9 @@ fun LayoutEditDialog(
) { ) {
val ctx = LocalContext.current val ctx = LocalContext.current
val file = getCustomLayoutFile(layoutName, ctx) val file = getCustomLayoutFile(layoutName, ctx)
val initialText = startContent ?: file.readText() val scope = rememberCoroutineScope()
var job: Job? = null
var showDeleteConfirmation by remember { mutableStateOf(false) } var showDeleteConfirmation by remember { mutableStateOf(false) }
// todo: try make it really full width, at least if we have a json file
TextInputDialog( TextInputDialog(
onDismissRequest = onDismissRequest, onDismissRequest = onDismissRequest,
onConfirmed = { onConfirmed = {
@ -45,12 +53,27 @@ fun LayoutEditDialog(
onCustomLayoutFileListChanged() onCustomLayoutFileListChanged()
keyboardNeedsReload = true keyboardNeedsReload = true
}, },
initialText = initialText, initialText = startContent ?: file.readText(),
singleLine = false, singleLine = false,
title = { Text(displayName ?: getLayoutDisplayName(layoutName)) }, title = { Text(displayName ?: getLayoutDisplayName(layoutName)) },
checkTextValid = { checkTextValid = {
checkLayout(it, ctx) // todo: toast with reason why it doesn't work -> should re-do getting the reason val valid = checkLayout(it, ctx)
job?.cancel()
if (!valid) {
job = scope.launch {
delay(3000)
val message = Log.getLog(10)
.lastOrNull { it.tag == "CustomLayoutUtils" }?.message
?.split("\n")?.take(2)?.joinToString("\n")
Toast.makeText(ctx, ctx.getString(R.string.layout_error, message), Toast.LENGTH_LONG).show()
}
}
valid
}, },
modifier = Modifier.imePadding(),
// decorFitsSystemWindows = false is necessary so the dialog is not covered by keyboard
// but this also stops the background from being darkened... great idea to combine both
properties = DialogProperties(decorFitsSystemWindows = false)
) )
if (showDeleteConfirmation) if (showDeleteConfirmation)
ConfirmationDialog( ConfirmationDialog(

View file

@ -93,7 +93,6 @@ fun ToolbarKeysCustomizer(
) )
} }
// todo: show updated ToolbarKeysCustomizer after ok / default? because default button
@Composable @Composable
private fun ToolbarKeyCustomizer( private fun ToolbarKeyCustomizer(
key: ToolbarKey, key: ToolbarKey,

View file

@ -64,7 +64,7 @@ fun createAboutPrefs(context: Context) = listOf(
name = it.title, name = it.title,
description = it.description, description = it.description,
onClick = { }, onClick = { },
icon = R.drawable.ic_launcher_foreground // todo: maybe use the bitmap trick here? icon = R.drawable.ic_launcher_foreground // use the bitmap trick here if we really want the colored icon
) )
}, },
PrefDef(context, NonSettingsPrefs.VERSION, R.string.version) { PrefDef(context, NonSettingsPrefs.VERSION, R.string.version) {
@ -137,7 +137,7 @@ fun createAboutPrefs(context: Context) = listOf(
icon = R.drawable.ic_settings_about_github_foreground icon = R.drawable.ic_settings_about_github_foreground
) )
}, },
PrefDef(context, NonSettingsPrefs.SAVE_LOG, R.string.save_log) { PrefDef(context, NonSettingsPrefs.SAVE_LOG, R.string.save_log) { def ->
val ctx = LocalContext.current val ctx = LocalContext.current
val scope = rememberCoroutineScope() val scope = rememberCoroutineScope()
val launcher = rememberLauncherForActivityResult(ActivityResultContracts.StartActivityForResult()) { result -> val launcher = rememberLauncherForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
@ -150,8 +150,8 @@ fun createAboutPrefs(context: Context) = listOf(
} }
} }
Preference( Preference(
name = it.title, name = def.title,
description = it.description, description = def.description,
onClick = { onClick = {
val intent = Intent(Intent.ACTION_CREATE_DOCUMENT) val intent = Intent(Intent.ACTION_CREATE_DOCUMENT)
.addCategory(Intent.CATEGORY_OPENABLE) .addCategory(Intent.CATEGORY_OPENABLE)

View file

@ -68,7 +68,6 @@ import helium314.keyboard.settings.ListPreference
import helium314.keyboard.settings.NonSettingsPrefs import helium314.keyboard.settings.NonSettingsPrefs
import helium314.keyboard.settings.PrefDef import helium314.keyboard.settings.PrefDef
import helium314.keyboard.settings.Preference import helium314.keyboard.settings.Preference
import helium314.keyboard.settings.PreferenceCategory
import helium314.keyboard.settings.SearchPrefScreen import helium314.keyboard.settings.SearchPrefScreen
import helium314.keyboard.settings.SettingsActivity2 import helium314.keyboard.settings.SettingsActivity2
import helium314.keyboard.settings.SettingsDestination import helium314.keyboard.settings.SettingsDestination
@ -76,8 +75,8 @@ import helium314.keyboard.settings.SliderPreference
import helium314.keyboard.settings.SwitchPreference import helium314.keyboard.settings.SwitchPreference
import helium314.keyboard.settings.Theme import helium314.keyboard.settings.Theme
import helium314.keyboard.settings.dialogs.ConfirmationDialog import helium314.keyboard.settings.dialogs.ConfirmationDialog
import helium314.keyboard.settings.dialogs.CustomizeLayoutDialog
import helium314.keyboard.settings.dialogs.InfoDialog import helium314.keyboard.settings.dialogs.InfoDialog
import helium314.keyboard.settings.dialogs.LayoutEditDialog
import helium314.keyboard.settings.dialogs.ListPickerDialog import helium314.keyboard.settings.dialogs.ListPickerDialog
import helium314.keyboard.settings.dialogs.TextInputDialog import helium314.keyboard.settings.dialogs.TextInputDialog
import helium314.keyboard.settings.keyboardNeedsReload import helium314.keyboard.settings.keyboardNeedsReload
@ -130,16 +129,15 @@ fun AdvancedSettingsScreen(
@SuppressLint("ApplySharedPref") @SuppressLint("ApplySharedPref")
fun createAdvancedPrefs(context: Context) = listOf( fun createAdvancedPrefs(context: Context) = listOf(
PrefDef(context, Settings.PREF_ALWAYS_INCOGNITO_MODE, R.string.incognito, R.string.prefs_force_incognito_mode_summary) { PrefDef(context, Settings.PREF_ALWAYS_INCOGNITO_MODE,
SwitchPreference( R.string.incognito, R.string.prefs_force_incognito_mode_summary)
def = it, {
default = false SwitchPreference(it, false)
)
}, },
PrefDef(context, Settings.PREF_KEY_LONGPRESS_TIMEOUT, R.string.prefs_key_longpress_timeout_settings) { PrefDef(context, Settings.PREF_KEY_LONGPRESS_TIMEOUT, R.string.prefs_key_longpress_timeout_settings) { def ->
SliderPreference( SliderPreference(
name = it.title, name = def.title,
pref = it.key, pref = def.key,
default = 300, default = 300,
range = 100f..700f, range = 100f..700f,
description = { stringResource(R.string.abbreviation_unit_milliseconds, it.toString()) } description = { stringResource(R.string.abbreviation_unit_milliseconds, it.toString()) }
@ -164,53 +162,36 @@ fun createAdvancedPrefs(context: Context) = listOf(
ListPreference(def, items, "none") ListPreference(def, items, "none")
}, },
PrefDef(context, Settings.PREF_DELETE_SWIPE, R.string.delete_swipe, R.string.delete_swipe_summary) { PrefDef(context, Settings.PREF_DELETE_SWIPE, R.string.delete_swipe, R.string.delete_swipe_summary) {
SwitchPreference( SwitchPreference(it, true)
def = it,
default = true
)
}, },
PrefDef(context, Settings.PREF_SPACE_TO_CHANGE_LANG, R.string.prefs_long_press_keyboard_to_change_lang, R.string.prefs_long_press_keyboard_to_change_lang_summary) { PrefDef(context, Settings.PREF_SPACE_TO_CHANGE_LANG,
SwitchPreference( R.string.prefs_long_press_keyboard_to_change_lang,
def = it, R.string.prefs_long_press_keyboard_to_change_lang_summary)
default = true {
) SwitchPreference(it, true)
}, },
PrefDef(context, Settings.PREFS_LONG_PRESS_SYMBOLS_FOR_NUMPAD, R.string.prefs_long_press_symbol_for_numpad) { PrefDef(context, Settings.PREFS_LONG_PRESS_SYMBOLS_FOR_NUMPAD, R.string.prefs_long_press_symbol_for_numpad) {
SwitchPreference( SwitchPreference(it, false)
def = it,
default = false
)
}, },
PrefDef(context, Settings.PREF_ENABLE_EMOJI_ALT_PHYSICAL_KEY, R.string.prefs_enable_emoji_alt_physical_key, R.string.prefs_enable_emoji_alt_physical_key_summary) { PrefDef(context, Settings.PREF_ENABLE_EMOJI_ALT_PHYSICAL_KEY, R.string.prefs_enable_emoji_alt_physical_key,
SwitchPreference( R.string.prefs_enable_emoji_alt_physical_key_summary)
def = it, {
default = true SwitchPreference(it, true)
)
}, },
PrefDef(context, Settings.PREF_SHOW_SETUP_WIZARD_ICON, R.string.prefs_enable_emoji_alt_physical_key_summary) { PrefDef(context, Settings.PREF_SHOW_SETUP_WIZARD_ICON, R.string.prefs_enable_emoji_alt_physical_key_summary) {
val ctx = LocalContext.current val ctx = LocalContext.current
SwitchPreference( SwitchPreference(it, true) { SystemBroadcastReceiver.toggleAppIcon(ctx) }
def = it,
default = true
) { SystemBroadcastReceiver.toggleAppIcon(ctx) }
}, },
PrefDef(context, Settings.PREF_ABC_AFTER_SYMBOL_SPACE, R.string.switch_keyboard_after, R.string.after_symbol_and_space) { PrefDef(context, Settings.PREF_ABC_AFTER_SYMBOL_SPACE,
SwitchPreference( R.string.switch_keyboard_after, R.string.after_symbol_and_space)
def = it, {
default = true SwitchPreference(it, true)
)
}, },
PrefDef(context, Settings.PREF_ABC_AFTER_EMOJI, R.string.switch_keyboard_after, R.string.after_emoji) { PrefDef(context, Settings.PREF_ABC_AFTER_EMOJI, R.string.switch_keyboard_after, R.string.after_emoji) {
SwitchPreference( SwitchPreference(it, false)
def = it,
default = false
)
}, },
PrefDef(context, Settings.PREF_ABC_AFTER_CLIP, R.string.switch_keyboard_after, R.string.after_clip) { PrefDef(context, Settings.PREF_ABC_AFTER_CLIP, R.string.switch_keyboard_after, R.string.after_clip) {
SwitchPreference( SwitchPreference(it, false)
def = it,
default = false
)
}, },
PrefDef(context, Settings.PREF_CUSTOM_CURRENCY_KEY, R.string.customize_currencies) { def -> PrefDef(context, Settings.PREF_CUSTOM_CURRENCY_KEY, R.string.customize_currencies) { def ->
var showDialog by remember { mutableStateOf(false) } var showDialog by remember { mutableStateOf(false) }
@ -228,7 +209,7 @@ fun createAdvancedPrefs(context: Context) = listOf(
title = { Text(stringResource(R.string.customize_currencies)) }, title = { Text(stringResource(R.string.customize_currencies)) },
neutralButtonText = if (prefs.contains(def.key)) stringResource(R.string.button_default) else null, neutralButtonText = if (prefs.contains(def.key)) stringResource(R.string.button_default) else null,
onNeutral = { prefs.edit().remove(def.key).apply(); KeyboardLayoutSet.onSystemLocaleChanged() }, onNeutral = { prefs.edit().remove(def.key).apply(); KeyboardLayoutSet.onSystemLocaleChanged() },
checkTextValid = { it.splitOnWhitespace().none { it.length > 8 } } checkTextValid = { text -> text.splitOnWhitespace().none { it.length > 8 } }
) )
} }
}, },
@ -267,7 +248,7 @@ fun createAdvancedPrefs(context: Context) = listOf(
ctx.assets.list("layouts")?.firstOrNull { it.startsWith("$layout.") } ctx.assets.list("layouts")?.firstOrNull { it.startsWith("$layout.") }
?.let { ctx.assets.open("layouts" + File.separator + it).reader().readText() } ?.let { ctx.assets.open("layouts" + File.separator + it).reader().readText() }
} }
CustomizeLayoutDialog( LayoutEditDialog(
layoutName = customLayoutName ?: "$CUSTOM_LAYOUT_PREFIX$layout.", layoutName = customLayoutName ?: "$CUSTOM_LAYOUT_PREFIX$layout.",
startContent = originalLayout, startContent = originalLayout,
displayName = layout?.getStringResourceOrName("layout_", ctx), displayName = layout?.getStringResourceOrName("layout_", ctx),
@ -303,7 +284,7 @@ fun createAdvancedPrefs(context: Context) = listOf(
val defaultLayoutName = if (Settings.getInstance().isTablet) "functional_keys_tablet.json" else "functional_keys.json" val defaultLayoutName = if (Settings.getInstance().isTablet) "functional_keys_tablet.json" else "functional_keys.json"
ctx.assets.open("layouts" + File.separator + defaultLayoutName).reader().readText() ctx.assets.open("layouts" + File.separator + defaultLayoutName).reader().readText()
} }
CustomizeLayoutDialog( LayoutEditDialog(
layoutName = customLayoutName ?: "$CUSTOM_LAYOUT_PREFIX$layout.", layoutName = customLayoutName ?: "$CUSTOM_LAYOUT_PREFIX$layout.",
startContent = originalLayout, startContent = originalLayout,
displayName = layout?.substringAfter(CUSTOM_LAYOUT_PREFIX)?.getStringResourceOrName("layout_", ctx), displayName = layout?.substringAfter(CUSTOM_LAYOUT_PREFIX)?.getStringResourceOrName("layout_", ctx),
@ -324,9 +305,9 @@ fun createAdvancedPrefs(context: Context) = listOf(
"custom_background_image.*".toRegex(), "custom_background_image.*".toRegex(),
"custom_font".toRegex(), "custom_font".toRegex(),
) } ) }
val backupLauncher = rememberLauncherForActivityResult(ActivityResultContracts.StartActivityForResult()) { val backupLauncher = rememberLauncherForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
if (it.resultCode != Activity.RESULT_OK) return@rememberLauncherForActivityResult if (result.resultCode != Activity.RESULT_OK) return@rememberLauncherForActivityResult
val uri = it.data?.data ?: return@rememberLauncherForActivityResult val uri = result.data?.data ?: return@rememberLauncherForActivityResult
// zip all files matching the backup patterns // zip all files matching the backup patterns
// essentially this is the typed words information, and user-added dictionaries // essentially this is the typed words information, and user-added dictionaries
val filesDir = ctx.filesDir ?: return@rememberLauncherForActivityResult val filesDir = ctx.filesDir ?: return@rememberLauncherForActivityResult
@ -382,9 +363,9 @@ fun createAdvancedPrefs(context: Context) = listOf(
} }
wait.await() wait.await()
} }
val restoreLauncher = rememberLauncherForActivityResult(ActivityResultContracts.StartActivityForResult()) { val restoreLauncher = rememberLauncherForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
if (it.resultCode != Activity.RESULT_OK) return@rememberLauncherForActivityResult if (result.resultCode != Activity.RESULT_OK) return@rememberLauncherForActivityResult
val uri = it.data?.data ?: return@rememberLauncherForActivityResult val uri = result.data?.data ?: return@rememberLauncherForActivityResult
val wait = CountDownLatch(1) val wait = CountDownLatch(1)
ExecutorUtils.getBackgroundExecutor(ExecutorUtils.KEYBOARD).execute { ExecutorUtils.getBackgroundExecutor(ExecutorUtils.KEYBOARD).execute {
try { try {
@ -490,10 +471,10 @@ fun createAdvancedPrefs(context: Context) = listOf(
) )
} }
}, },
PrefDef(context, Settings.PREF_EMOJI_MAX_SDK, R.string.prefs_key_emoji_max_sdk) { PrefDef(context, Settings.PREF_EMOJI_MAX_SDK, R.string.prefs_key_emoji_max_sdk) { def ->
SliderPreference( SliderPreference(
name = it.title, name = def.title,
pref = it.key, pref = def.key,
default = Build.VERSION.SDK_INT, default = Build.VERSION.SDK_INT,
range = 21f..35f, range = 21f..35f,
description = { description = {
@ -520,18 +501,15 @@ fun createAdvancedPrefs(context: Context) = listOf(
) )
}, },
PrefDef(context, Settings.PREF_URL_DETECTION, R.string.url_detection_title, R.string.url_detection_summary) { PrefDef(context, Settings.PREF_URL_DETECTION, R.string.url_detection_title, R.string.url_detection_summary) {
SwitchPreference( SwitchPreference(it, false)
def = it,
default = false
)
}, },
PrefDef(context, NonSettingsPrefs.LOAD_GESTURE_LIB, R.string.load_gesture_library, R.string.load_gesture_library_summary) { PrefDef(context, NonSettingsPrefs.LOAD_GESTURE_LIB, R.string.load_gesture_library, R.string.load_gesture_library_summary) { def ->
var showDialog by remember { mutableStateOf(false) } var showDialog by remember { mutableStateOf(false) }
val ctx = LocalContext.current val ctx = LocalContext.current
val prefs = ctx.prefs() val prefs = ctx.prefs()
val abi = Build.SUPPORTED_ABIS[0] val abi = Build.SUPPORTED_ABIS[0]
val libFile = File(ctx.filesDir.absolutePath + File.separator + JniUtils.JNI_LIB_IMPORT_FILE_NAME) val libFile = File(ctx.filesDir.absolutePath + File.separator + JniUtils.JNI_LIB_IMPORT_FILE_NAME)
fun renameToLibfileAndRestart(file: File, checksum: String) { fun renameToLibFileAndRestart(file: File, checksum: String) {
libFile.delete() libFile.delete()
// store checksum in default preferences (soo JniUtils) // store checksum in default preferences (soo JniUtils)
prefs.edit().putString(Settings.PREF_LIBRARY_CHECKSUM, checksum).commit() prefs.edit().putString(Settings.PREF_LIBRARY_CHECKSUM, checksum).commit()
@ -539,9 +517,9 @@ fun createAdvancedPrefs(context: Context) = listOf(
Runtime.getRuntime().exit(0) // exit will restart the app, so library will be loaded Runtime.getRuntime().exit(0) // exit will restart the app, so library will be loaded
} }
var tempFilePath: String? by remember { mutableStateOf(null) } var tempFilePath: String? by remember { mutableStateOf(null) }
val launcher = rememberLauncherForActivityResult(ActivityResultContracts.StartActivityForResult()) { val launcher = rememberLauncherForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
if (it.resultCode != Activity.RESULT_OK) return@rememberLauncherForActivityResult if (result.resultCode != Activity.RESULT_OK) return@rememberLauncherForActivityResult
val uri = it.data?.data ?: return@rememberLauncherForActivityResult val uri = result.data?.data ?: return@rememberLauncherForActivityResult
val tmpfile = File(ctx.filesDir.absolutePath + File.separator + "tmplib") val tmpfile = File(ctx.filesDir.absolutePath + File.separator + "tmplib")
try { try {
val otherTemporaryFile = File(ctx.filesDir.absolutePath + File.separator + "tmpfile") val otherTemporaryFile = File(ctx.filesDir.absolutePath + File.separator + "tmpfile")
@ -556,12 +534,12 @@ fun createAdvancedPrefs(context: Context) = listOf(
val checksum = ChecksumCalculator.checksum(tmpfile.inputStream()) ?: "" val checksum = ChecksumCalculator.checksum(tmpfile.inputStream()) ?: ""
if (checksum == JniUtils.expectedDefaultChecksum()) { if (checksum == JniUtils.expectedDefaultChecksum()) {
renameToLibfileAndRestart(tmpfile, checksum) renameToLibFileAndRestart(tmpfile, checksum)
} else { } else {
tempFilePath = tmpfile.absolutePath tempFilePath = tmpfile.absolutePath
AlertDialog.Builder(ctx) AlertDialog.Builder(ctx)
.setMessage(ctx.getString(R.string.checksum_mismatch_message, abi)) .setMessage(ctx.getString(R.string.checksum_mismatch_message, abi))
.setPositiveButton(android.R.string.ok) { _, _ -> renameToLibfileAndRestart(tmpfile, checksum) } .setPositiveButton(android.R.string.ok) { _, _ -> renameToLibFileAndRestart(tmpfile, checksum) }
.setNegativeButton(android.R.string.cancel) { _, _ -> tmpfile.delete() } .setNegativeButton(android.R.string.cancel) { _, _ -> tmpfile.delete() }
.show() .show()
} }
@ -571,7 +549,7 @@ fun createAdvancedPrefs(context: Context) = listOf(
} }
} }
Preference( Preference(
name = it.title, name = def.title,
onClick = { showDialog = true } onClick = { showDialog = true }
) )
if (showDialog) { if (showDialog) {
@ -596,13 +574,13 @@ fun createAdvancedPrefs(context: Context) = listOf(
if (tempFilePath != null) if (tempFilePath != null)
ConfirmationDialog( ConfirmationDialog(
onDismissRequest = { onDismissRequest = {
File(tempFilePath).delete() File(tempFilePath!!).delete()
tempFilePath = null tempFilePath = null
}, },
text = { Text(stringResource(R.string.checksum_mismatch_message, abi))}, text = { Text(stringResource(R.string.checksum_mismatch_message, abi))},
onConfirmed = { onConfirmed = {
val tempFile = File(tempFilePath) val tempFile = File(tempFilePath!!)
renameToLibfileAndRestart(tempFile, ChecksumCalculator.checksum(tempFile.inputStream()) ?: "") renameToLibFileAndRestart(tempFile, ChecksumCalculator.checksum(tempFile.inputStream()) ?: "")
} }
) )
}, },

View file

@ -111,7 +111,7 @@ fun createAppearancePrefs(context: Context) = listOf(
KeyboardTheme.STYLE_MATERIAL KeyboardTheme.STYLE_MATERIAL
) { ) {
if (it != KeyboardTheme.STYLE_HOLO) { if (it != KeyboardTheme.STYLE_HOLO) {
// todo: use defaults once they exist // todo (later): use defaults once they exist
if (prefs.getString(Settings.PREF_THEME_COLORS, "") == KeyboardTheme.THEME_HOLO_WHITE) if (prefs.getString(Settings.PREF_THEME_COLORS, "") == KeyboardTheme.THEME_HOLO_WHITE)
prefs.edit().putString(Settings.PREF_THEME_COLORS, KeyboardTheme.THEME_LIGHT).apply() prefs.edit().putString(Settings.PREF_THEME_COLORS, KeyboardTheme.THEME_LIGHT).apply()
if (prefs.getString(Settings.PREF_THEME_COLORS_NIGHT, "") == KeyboardTheme.THEME_HOLO_WHITE) if (prefs.getString(Settings.PREF_THEME_COLORS_NIGHT, "") == KeyboardTheme.THEME_HOLO_WHITE)
@ -121,9 +121,7 @@ fun createAppearancePrefs(context: Context) = listOf(
}, },
PrefDef(context, Settings.PREF_ICON_STYLE, R.string.icon_style) { def -> PrefDef(context, Settings.PREF_ICON_STYLE, R.string.icon_style) { def ->
val ctx = LocalContext.current val ctx = LocalContext.current
val items = KeyboardTheme.STYLES.map { val items = KeyboardTheme.STYLES.map { it.getStringResourceOrName("style_name_", ctx) to it }
it.getStringResourceOrName("style_name_", ctx) to it
}
ListPreference( ListPreference(
def, def,
items, items,
@ -200,28 +198,30 @@ fun createAppearancePrefs(context: Context) = listOf(
} }
) )
}, },
PrefDef(context, Settings.PREF_THEME_KEY_BORDERS, R.string.key_borders) { def -> PrefDef(context, Settings.PREF_THEME_KEY_BORDERS, R.string.key_borders) {
SwitchPreference(def, false) SwitchPreference(it, false)
}, },
PrefDef(context, Settings.PREF_THEME_DAY_NIGHT, R.string.day_night_mode, R.string.day_night_mode_summary) { def -> PrefDef(context, Settings.PREF_THEME_DAY_NIGHT, R.string.day_night_mode, R.string.day_night_mode_summary) {
SwitchPreference(def, Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { keyboardNeedsReload = true } SwitchPreference(it, Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { keyboardNeedsReload = true }
}, },
PrefDef(context, Settings.PREF_NAVBAR_COLOR, R.string.theme_navbar, R.string.day_night_mode_summary) { def -> PrefDef(context, Settings.PREF_NAVBAR_COLOR, R.string.theme_navbar, R.string.day_night_mode_summary) {
SwitchPreference(def, Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) SwitchPreference(it, Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
}, },
PrefDef(context, NonSettingsPrefs.BACKGROUND_IMAGE, R.string.customize_background_image) { def -> PrefDef(context, NonSettingsPrefs.BACKGROUND_IMAGE, R.string.customize_background_image) {
BackgroundImagePref(def, false) BackgroundImagePref(it, false)
}, },
PrefDef(context, NonSettingsPrefs.BACKGROUND_IMAGE_LANDSCAPE, R.string.customize_background_image_landscape, R.string.summary_customize_background_image_landscape) { def -> PrefDef(context, NonSettingsPrefs.BACKGROUND_IMAGE_LANDSCAPE,
BackgroundImagePref(def, true) R.string.customize_background_image_landscape, R.string.summary_customize_background_image_landscape)
{
BackgroundImagePref(it, true)
}, },
PrefDef(context, Settings.PREF_ENABLE_SPLIT_KEYBOARD, R.string.enable_split_keyboard) { PrefDef(context, Settings.PREF_ENABLE_SPLIT_KEYBOARD, R.string.enable_split_keyboard) {
SwitchPreference(it, false) SwitchPreference(it, false)
}, },
PrefDef(context, Settings.PREF_SPLIT_SPACER_SCALE, R.string.split_spacer_scale) { PrefDef(context, Settings.PREF_SPLIT_SPACER_SCALE, R.string.split_spacer_scale) { def ->
SliderPreference( SliderPreference(
name = it.title, name = def.title,
pref = it.key, pref = def.key,
default = SettingsValues.DEFAULT_SIZE_SCALE, default = SettingsValues.DEFAULT_SIZE_SCALE,
range = 0.5f..2f, range = 0.5f..2f,
description = { "${(100 * it).toInt()}%" } description = { "${(100 * it).toInt()}%" }
@ -230,19 +230,19 @@ fun createAppearancePrefs(context: Context) = listOf(
PrefDef(context, Settings.PREF_NARROW_KEY_GAPS, R.string.prefs_narrow_key_gaps) { PrefDef(context, Settings.PREF_NARROW_KEY_GAPS, R.string.prefs_narrow_key_gaps) {
SwitchPreference(it, false) { keyboardNeedsReload = true } SwitchPreference(it, false) { keyboardNeedsReload = true }
}, },
PrefDef(context, Settings.PREF_KEYBOARD_HEIGHT_SCALE, R.string.prefs_keyboard_height_scale) { PrefDef(context, Settings.PREF_KEYBOARD_HEIGHT_SCALE, R.string.prefs_keyboard_height_scale) { def ->
SliderPreference( SliderPreference(
name = it.title, name = def.title,
pref = it.key, pref = def.key,
default = SettingsValues.DEFAULT_SIZE_SCALE, default = SettingsValues.DEFAULT_SIZE_SCALE,
range = 0.5f..1.5f, range = 0.5f..1.5f,
description = { "${(100 * it).toInt()}%" } description = { "${(100 * it).toInt()}%" }
) { keyboardNeedsReload = true } ) { keyboardNeedsReload = true }
}, },
PrefDef(context, Settings.PREF_BOTTOM_PADDING_SCALE, R.string.prefs_bottom_padding_scale) { PrefDef(context, Settings.PREF_BOTTOM_PADDING_SCALE, R.string.prefs_bottom_padding_scale) { def ->
SliderPreference( SliderPreference(
name = it.title, name = def.title,
pref = it.key, pref = def.key,
default = SettingsValues.DEFAULT_SIZE_SCALE, default = SettingsValues.DEFAULT_SIZE_SCALE,
range = 0f..5f, range = 0f..5f,
description = { "${(100 * it).toInt()}%" } description = { "${(100 * it).toInt()}%" }
@ -280,7 +280,7 @@ fun createAppearancePrefs(context: Context) = listOf(
val tempFile = File(DeviceProtectedUtils.getFilesDir(context), "temp_file") val tempFile = File(DeviceProtectedUtils.getFilesDir(context), "temp_file")
FileUtils.copyContentUriToNewFile(uri, ctx, tempFile) FileUtils.copyContentUriToNewFile(uri, ctx, tempFile)
try { try {
val typeface = Typeface.createFromFile(tempFile) Typeface.createFromFile(tempFile)
fontFile.delete() fontFile.delete()
tempFile.renameTo(fontFile) tempFile.renameTo(fontFile)
Settings.clearCachedTypeface() Settings.clearCachedTypeface()

View file

@ -16,8 +16,8 @@ fun ColorsScreen(
onClickBack: () -> Unit onClickBack: () -> Unit
) { ) {
var availableColors by remember { mutableStateOf(emptyList<ColorSetting>()) } // todo: type? var availableColors by remember { mutableStateOf(emptyList<ColorSetting>()) } // todo (later): type?
// todo: save / load / type selection here? or in ... menu as previously? // todo (later): save / load / type selection here? or in ... menu as previously?
SearchScreen( SearchScreen(
title = stringResource(if (night) R.string.select_user_colors_night else R.string.select_user_colors), title = stringResource(if (night) R.string.select_user_colors_night else R.string.select_user_colors),
onClickBack = onClickBack, onClickBack = onClickBack,

View file

@ -70,7 +70,7 @@ fun createDebugPrefs(context: Context) = listOf(
if (!it) prefs.edit().putBoolean(DebugSettings.PREF_SHOW_SUGGESTION_INFOS, false).apply() if (!it) prefs.edit().putBoolean(DebugSettings.PREF_SHOW_SUGGESTION_INFOS, false).apply()
showConfirmDialog = true showConfirmDialog = true
} }
if (showConfirmDialog) { // todo: maybe do it differently? if (showConfirmDialog) {
ConfirmationDialog( ConfirmationDialog(
onDismissRequest = { showConfirmDialog = false }, onDismissRequest = { showConfirmDialog = false },
onConfirmed = { Runtime.getRuntime().exit(0) }, onConfirmed = { Runtime.getRuntime().exit(0) },
@ -84,7 +84,7 @@ fun createDebugPrefs(context: Context) = listOf(
PrefDef(context, DebugSettings.PREF_FORCE_NON_DISTINCT_MULTITOUCH, R.string.prefs_force_non_distinct_multitouch) { def -> PrefDef(context, DebugSettings.PREF_FORCE_NON_DISTINCT_MULTITOUCH, R.string.prefs_force_non_distinct_multitouch) { def ->
var showConfirmDialog by remember { mutableStateOf(false) } var showConfirmDialog by remember { mutableStateOf(false) }
SwitchPreference(def, false) { showConfirmDialog = true } SwitchPreference(def, false) { showConfirmDialog = true }
if (showConfirmDialog) { // todo: maybe do it differently? if (showConfirmDialog) {
ConfirmationDialog( ConfirmationDialog(
onDismissRequest = { showConfirmDialog = false }, onDismissRequest = { showConfirmDialog = false },
onConfirmed = { Runtime.getRuntime().exit(0) }, onConfirmed = { Runtime.getRuntime().exit(0) },

View file

@ -53,29 +53,21 @@ fun GestureTypingScreen(
fun createGestureTypingPrefs(context: Context) = listOf( fun createGestureTypingPrefs(context: Context) = listOf(
PrefDef(context, Settings.PREF_GESTURE_INPUT, R.string.gesture_input, R.string.gesture_input_summary) { PrefDef(context, Settings.PREF_GESTURE_INPUT, R.string.gesture_input, R.string.gesture_input_summary) {
SwitchPreference( SwitchPreference(it, true)
def = it,
default = true
)
}, },
PrefDef(context, Settings.PREF_GESTURE_PREVIEW_TRAIL, R.string.gesture_preview_trail) { PrefDef(context, Settings.PREF_GESTURE_PREVIEW_TRAIL, R.string.gesture_preview_trail) {
SwitchPreference( SwitchPreference(it, true)
def = it,
default = true
)
}, },
PrefDef(context, Settings.PREF_GESTURE_FLOATING_PREVIEW_TEXT, R.string.gesture_floating_preview_static, R.string.gesture_floating_preview_static_summary) { PrefDef(context, Settings.PREF_GESTURE_FLOATING_PREVIEW_TEXT,
SwitchPreference( R.string.gesture_floating_preview_static, R.string.gesture_floating_preview_static_summary)
def = it, {
default = true SwitchPreference(it, true)
)
}, },
PrefDef(context, Settings.PREF_GESTURE_FLOATING_PREVIEW_DYNAMIC, R.string.gesture_floating_preview_text, R.string.gesture_floating_preview_dynamic_summary) { PrefDef(context, Settings.PREF_GESTURE_FLOATING_PREVIEW_DYNAMIC,
R.string.gesture_floating_preview_text, R.string.gesture_floating_preview_dynamic_summary)
{ def ->
val ctx = LocalContext.current val ctx = LocalContext.current
SwitchPreference( SwitchPreference(def, true) {
def = it,
default = true
) {
// is this complexity and 2 pref keys for one setting really needed? // is this complexity and 2 pref keys for one setting really needed?
// default value is based on system reduced motion // default value is based on system reduced motion
val default = Settings.readGestureDynamicPreviewDefault(ctx) val default = Settings.readGestureDynamicPreviewDefault(ctx)
@ -86,15 +78,12 @@ fun createGestureTypingPrefs(context: Context) = listOf(
} }
}, },
PrefDef(context, Settings.PREF_GESTURE_SPACE_AWARE, R.string.gesture_space_aware, R.string.gesture_space_aware_summary) { PrefDef(context, Settings.PREF_GESTURE_SPACE_AWARE, R.string.gesture_space_aware, R.string.gesture_space_aware_summary) {
SwitchPreference( SwitchPreference(it, false)
def = it,
default = false
)
}, },
PrefDef(context, Settings.PREF_GESTURE_FAST_TYPING_COOLDOWN, R.string.gesture_fast_typing_cooldown) { PrefDef(context, Settings.PREF_GESTURE_FAST_TYPING_COOLDOWN, R.string.gesture_fast_typing_cooldown) { def ->
SliderPreference( SliderPreference(
name = it.title, name = def.title,
pref = it.key, pref = def.key,
default = 500, default = 500,
range = 0f..500f, range = 0f..500f,
description = { description = {
@ -103,18 +92,14 @@ fun createGestureTypingPrefs(context: Context) = listOf(
} }
) )
}, },
PrefDef(context, Settings.PREF_GESTURE_TRAIL_FADEOUT_DURATION, R.string.gesture_trail_fadeout_duration) { PrefDef(context, Settings.PREF_GESTURE_TRAIL_FADEOUT_DURATION, R.string.gesture_trail_fadeout_duration) { def ->
// todo: there is some weird stuff going on
// for some uses there is an additional 100 ms delay
// see config_gesture_trail_fadeout_start_delay
// -> check whether this should be changes, or at least made less complicated
SliderPreference( SliderPreference(
name = it.title, name = def.title,
pref = it.key, pref = def.key,
default = 800, default = 800,
range = 100f..1900f, range = 100f..1900f,
description = { stringResource(R.string.abbreviation_unit_milliseconds, (it + 100).toString()) }, description = { stringResource(R.string.abbreviation_unit_milliseconds, (it + 100).toString()) },
// todo: 50 ms steps? stepSize = 10,
) { keyboardNeedsReload = true } ) { keyboardNeedsReload = true }
}, },
) )

View file

@ -104,7 +104,9 @@ fun createPreferencesPrefs(context: Context) = listOf(
PrefDef(context, Settings.PREF_SOUND_ON, R.string.sound_on_keypress) { PrefDef(context, Settings.PREF_SOUND_ON, R.string.sound_on_keypress) {
SwitchPreference(it, false) SwitchPreference(it, false)
}, },
PrefDef(context, Settings.PREF_ENABLE_CLIPBOARD_HISTORY, R.string.enable_clipboard_history, R.string.enable_clipboard_history_summary) { PrefDef(context, Settings.PREF_ENABLE_CLIPBOARD_HISTORY,
R.string.enable_clipboard_history, R.string.enable_clipboard_history_summary)
{
SwitchPreference(it, true) SwitchPreference(it, true)
}, },
PrefDef(context, Settings.PREF_SHOW_NUMBER_ROW, R.string.number_row, R.string.number_row_summary) { PrefDef(context, Settings.PREF_SHOW_NUMBER_ROW, R.string.number_row, R.string.number_row_summary) {
@ -130,7 +132,9 @@ fun createPreferencesPrefs(context: Context) = listOf(
PrefDef(context, Settings.PREF_SHOW_EMOJI_KEY, R.string.show_emoji_key) { PrefDef(context, Settings.PREF_SHOW_EMOJI_KEY, R.string.show_emoji_key) {
SwitchPreference(it, false) SwitchPreference(it, false)
}, },
PrefDef(context, Settings.PREF_REMOVE_REDUNDANT_POPUPS, R.string.remove_redundant_popups, R.string.remove_redundant_popups_summary) { PrefDef(context, Settings.PREF_REMOVE_REDUNDANT_POPUPS,
R.string.remove_redundant_popups, R.string.remove_redundant_popups_summary)
{
SwitchPreference(it, false) { keyboardNeedsReload = true } SwitchPreference(it, false) { keyboardNeedsReload = true }
}, },
PrefDef(context, Settings.PREF_CLIPBOARD_HISTORY_RETENTION_TIME, R.string.clipboard_history_retention_time) { def -> PrefDef(context, Settings.PREF_CLIPBOARD_HISTORY_RETENTION_TIME, R.string.clipboard_history_retention_time) { def ->
@ -174,7 +178,7 @@ fun createPreferencesPrefs(context: Context) = listOf(
}, },
) )
// todo: not good to have it hardcoded, but reading a bunch of files may be noticeably slow // todo (later): not good to have it hardcoded, but reading a bunch of files may be noticeably slow
private val localesWithLocalizedNumberRow = listOf("ar", "bn", "fa", "gu", "hi", "kn", "mr", "ne", "ur") private val localesWithLocalizedNumberRow = listOf("ar", "bn", "fa", "gu", "hi", "kn", "mr", "ne", "ur")
@Preview @Preview

View file

@ -93,84 +93,61 @@ fun createCorrectionPrefs(context: Context) = listOf(
) )
} }
}, },
PrefDef(context, PrefDef(context, Settings.PREF_BLOCK_POTENTIALLY_OFFENSIVE,
Settings.PREF_BLOCK_POTENTIALLY_OFFENSIVE, R.string.prefs_block_potentially_offensive_title, R.string.prefs_block_potentially_offensive_summary
R.string.prefs_block_potentially_offensive_title,
R.string.prefs_block_potentially_offensive_summary
) { ) {
SwitchPreference(it, true) SwitchPreference(it, true)
}, },
PrefDef(context, PrefDef(context, Settings.PREF_AUTO_CORRECTION,
Settings.PREF_AUTO_CORRECTION, R.string.autocorrect, R.string.auto_correction_summary
R.string.autocorrect,
R.string.auto_correction_summary
) { ) {
SwitchPreference(it, true) SwitchPreference(it, true)
}, },
PrefDef(context, PrefDef(context, Settings.PREF_MORE_AUTO_CORRECTION,
Settings.PREF_MORE_AUTO_CORRECTION, R.string.more_autocorrect, R.string.more_autocorrect_summary
R.string.more_autocorrect,
R.string.more_autocorrect_summary
) { ) {
SwitchPreference(it, true) // todo: shouldn't it better be false? SwitchPreference(it, true) // todo (later): shouldn't it better be false?
}, },
PrefDef(context, PrefDef(context, Settings.PREF_AUTOCORRECT_SHORTCUTS,
Settings.PREF_AUTOCORRECT_SHORTCUTS, R.string.auto_correct_shortcuts, R.string.auto_correct_shortcuts_summary
R.string.auto_correct_shortcuts,
R.string.auto_correct_shortcuts_summary
) { ) {
SwitchPreference(it, true) SwitchPreference(it, true)
}, },
PrefDef(context, PrefDef(context, Settings.PREF_AUTO_CORRECTION_CONFIDENCE, R.string.auto_correction_confidence) {
Settings.PREF_AUTO_CORRECTION_CONFIDENCE,
R.string.auto_correction_confidence,
) { def ->
val items = listOf( val items = listOf(
stringResource(R.string.auto_correction_threshold_mode_modest) to "0", stringResource(R.string.auto_correction_threshold_mode_modest) to "0",
stringResource(R.string.auto_correction_threshold_mode_aggressive) to "1", stringResource(R.string.auto_correction_threshold_mode_aggressive) to "1",
stringResource(R.string.auto_correction_threshold_mode_very_aggressive) to "2", stringResource(R.string.auto_correction_threshold_mode_very_aggressive) to "2",
) )
ListPreference(def, items, "0") ListPreference(it, items, "0")
}, },
PrefDef(context, PrefDef(context, Settings.PREF_AUTO_CAP,
Settings.PREF_AUTO_CAP, R.string.auto_cap, R.string.auto_cap_summary
R.string.auto_cap,
R.string.auto_cap_summary
) { ) {
SwitchPreference(it, true) SwitchPreference(it, true)
}, },
PrefDef(context, PrefDef(context, Settings.PREF_KEY_USE_DOUBLE_SPACE_PERIOD,
Settings.PREF_KEY_USE_DOUBLE_SPACE_PERIOD, R.string.use_double_space_period, R.string.use_double_space_period_summary
R.string.use_double_space_period,
R.string.use_double_space_period_summary
) { ) {
SwitchPreference(it, true) SwitchPreference(it, true)
}, },
PrefDef(context, PrefDef(context, Settings.PREF_AUTOSPACE_AFTER_PUNCTUATION,
Settings.PREF_AUTOSPACE_AFTER_PUNCTUATION, R.string.autospace_after_punctuation, R.string.autospace_after_punctuation_summary
R.string.autospace_after_punctuation,
R.string.autospace_after_punctuation_summary
) { ) {
SwitchPreference(it, false) SwitchPreference(it, false)
}, },
PrefDef(context, PrefDef(context, Settings.PREF_SHOW_SUGGESTIONS,
Settings.PREF_SHOW_SUGGESTIONS, R.string.prefs_show_suggestions, R.string.prefs_show_suggestions_summary
R.string.prefs_show_suggestions,
R.string.prefs_show_suggestions_summary
) { ) {
SwitchPreference(it, true) SwitchPreference(it, true)
}, },
PrefDef(context, PrefDef(context, Settings.PREF_ALWAYS_SHOW_SUGGESTIONS,
Settings.PREF_ALWAYS_SHOW_SUGGESTIONS, R.string.prefs_always_show_suggestions, R.string.prefs_always_show_suggestions_summary
R.string.prefs_always_show_suggestions,
R.string.prefs_always_show_suggestions_summary
) { ) {
SwitchPreference(it, false) SwitchPreference(it, false)
}, },
PrefDef(context, PrefDef(context, Settings.PREF_KEY_USE_PERSONALIZED_DICTS,
Settings.PREF_KEY_USE_PERSONALIZED_DICTS, R.string.use_personalized_dicts, R.string.use_personalized_dicts_summary
R.string.use_personalized_dicts,
R.string.use_personalized_dicts_summary
) { prefDef -> ) { prefDef ->
var showConfirmDialog by remember { mutableStateOf(false) } var showConfirmDialog by remember { mutableStateOf(false) }
SwitchPreference( SwitchPreference(
@ -193,31 +170,23 @@ fun createCorrectionPrefs(context: Context) = listOf(
} }
}, },
PrefDef(context, PrefDef(context, Settings.PREF_BIGRAM_PREDICTIONS,
Settings.PREF_BIGRAM_PREDICTIONS, R.string.bigram_prediction, R.string.bigram_prediction_summary
R.string.bigram_prediction,
R.string.bigram_prediction_summary
) { ) {
SwitchPreference(it, true) { keyboardNeedsReload = true } SwitchPreference(it, true) { keyboardNeedsReload = true }
}, },
PrefDef(context, PrefDef(context, Settings.PREF_CENTER_SUGGESTION_TEXT_TO_ENTER,
Settings.PREF_CENTER_SUGGESTION_TEXT_TO_ENTER, R.string.center_suggestion_text_to_enter, R.string.center_suggestion_text_to_enter_summary
R.string.center_suggestion_text_to_enter,
R.string.center_suggestion_text_to_enter_summary
) { ) {
SwitchPreference(it, false) SwitchPreference(it, false)
}, },
PrefDef(context, PrefDef(context, Settings.PREF_SUGGEST_CLIPBOARD_CONTENT,
Settings.PREF_SUGGEST_CLIPBOARD_CONTENT, R.string.suggest_clipboard_content, R.string.suggest_clipboard_content_summary
R.string.suggest_clipboard_content,
R.string.suggest_clipboard_content_summary
) { ) {
SwitchPreference(it, true) SwitchPreference(it, true)
}, },
PrefDef(context, PrefDef(context, Settings.PREF_USE_CONTACTS,
Settings.PREF_USE_CONTACTS, R.string.use_contacts_dict, R.string.use_contacts_dict_summary
R.string.use_contacts_dict,
R.string.use_contacts_dict_summary
) { def -> ) { def ->
val activity = LocalContext.current.getActivity() ?: return@PrefDef val activity = LocalContext.current.getActivity() ?: return@PrefDef
var granted by remember { mutableStateOf(PermissionsUtil.checkAllPermissionsGranted(activity, Manifest.permission.READ_CONTACTS)) } var granted by remember { mutableStateOf(PermissionsUtil.checkAllPermissionsGranted(activity, Manifest.permission.READ_CONTACTS)) }
@ -237,10 +206,8 @@ fun createCorrectionPrefs(context: Context) = listOf(
} }
) )
}, },
PrefDef(context, PrefDef(context, Settings.PREF_ADD_TO_PERSONAL_DICTIONARY,
Settings.PREF_ADD_TO_PERSONAL_DICTIONARY, R.string.add_to_personal_dictionary, R.string.add_to_personal_dictionary_summary
R.string.add_to_personal_dictionary,
R.string.add_to_personal_dictionary_summary
) { ) {
SwitchPreference(it, false) SwitchPreference(it, false)
}, },

View file

@ -63,19 +63,19 @@ fun ToolbarScreen(
} }
fun createToolbarPrefs(context: Context) = listOf( fun createToolbarPrefs(context: Context) = listOf(
PrefDef(context, Settings.PREF_TOOLBAR_KEYS, R.string.toolbar_keys) { def -> PrefDef(context, Settings.PREF_TOOLBAR_KEYS, R.string.toolbar_keys) {
ReorderSwitchPreference(def, defaultToolbarPref) ReorderSwitchPreference(it, defaultToolbarPref)
}, },
PrefDef(context, Settings.PREF_PINNED_TOOLBAR_KEYS, R.string.pinned_toolbar_keys) { def -> PrefDef(context, Settings.PREF_PINNED_TOOLBAR_KEYS, R.string.pinned_toolbar_keys) {
ReorderSwitchPreference(def, defaultPinnedToolbarPref) ReorderSwitchPreference(it, defaultPinnedToolbarPref)
}, },
PrefDef(context, Settings.PREF_CLIPBOARD_TOOLBAR_KEYS, R.string.clipboard_toolbar_keys) { def -> PrefDef(context, Settings.PREF_CLIPBOARD_TOOLBAR_KEYS, R.string.clipboard_toolbar_keys) {
ReorderSwitchPreference(def, defaultClipboardToolbarPref) ReorderSwitchPreference(it, defaultClipboardToolbarPref)
}, },
PrefDef(context, NonSettingsPrefs.CUSTOM_KEY_CODES, R.string.customize_toolbar_key_codes) { def -> PrefDef(context, NonSettingsPrefs.CUSTOM_KEY_CODES, R.string.customize_toolbar_key_codes) {
var showDialog by remember { mutableStateOf(false) } var showDialog by remember { mutableStateOf(false) }
Preference( Preference(
name = def.title, name = it.title,
onClick = { showDialog = true }, onClick = { showDialog = true },
) )
if (showDialog) if (showDialog)
@ -84,29 +84,23 @@ fun createToolbarPrefs(context: Context) = listOf(
onDismissRequest = { showDialog = false } onDismissRequest = { showDialog = false }
) )
}, },
PrefDef(context, Settings.PREF_QUICK_PIN_TOOLBAR_KEYS, R.string.quick_pin_toolbar_keys, R.string.quick_pin_toolbar_keys_summary) { def -> PrefDef(context, Settings.PREF_QUICK_PIN_TOOLBAR_KEYS,
SwitchPreference( R.string.quick_pin_toolbar_keys, R.string.quick_pin_toolbar_keys_summary)
def, {
false, SwitchPreference(it, false,) { keyboardNeedsReload = true }
) { keyboardNeedsReload = true }
}, },
PrefDef(context, Settings.PREF_AUTO_SHOW_TOOLBAR, R.string.auto_show_toolbar, R.string.auto_show_toolbar_summary) { def -> PrefDef(context, Settings.PREF_AUTO_SHOW_TOOLBAR, R.string.auto_show_toolbar, R.string.auto_show_toolbar_summary)
SwitchPreference( {
def, SwitchPreference(it, false,)
false,
)
}, },
PrefDef(context, Settings.PREF_AUTO_HIDE_TOOLBAR, R.string.auto_hide_toolbar, R.string.auto_hide_toolbar_summary) { def -> PrefDef(context, Settings.PREF_AUTO_HIDE_TOOLBAR, R.string.auto_hide_toolbar, R.string.auto_hide_toolbar_summary)
SwitchPreference( {
def, SwitchPreference(it, false,)
false,
)
}, },
PrefDef(context, Settings.PREF_VARIABLE_TOOLBAR_DIRECTION, R.string.var_toolbar_direction, R.string.var_toolbar_direction_summary) { def -> PrefDef(context, Settings.PREF_VARIABLE_TOOLBAR_DIRECTION,
SwitchPreference( R.string.var_toolbar_direction, R.string.var_toolbar_direction_summary)
def, {
true, SwitchPreference(it, true,)
)
} }
) )

View file

@ -969,5 +969,5 @@ New dictionary:
<!-- Confirmation message when resetting all custom icons --> <!-- Confirmation message when resetting all custom icons -->
<string name="customize_icons_reset_message">Really reset all customized icons?</string> <string name="customize_icons_reset_message">Really reset all customized icons?</string>
<!-- Dialog message when restart of the app is required (sometimes actually does start again) --> <!-- Dialog message when restart of the app is required (sometimes actually does start again) -->
<string name="message_restart_required">A restart is required to apply the changes. Quit now?</string> <string name="message_restart_required">Application restart is required to apply the changes. Quit now?</string>
</resources> </resources>