modify some separators we don't get into trouble when storing more data in extra values, and when storing extra values in prefs

This commit is contained in:
Helium314 2025-02-15 21:45:26 +01:00
parent 4c060689fa
commit d005ffac06
11 changed files with 96 additions and 60 deletions

View file

@ -13,8 +13,8 @@ android {
applicationId = "helium314.keyboard"
minSdk = 21
targetSdk = 34
versionCode = 2305
versionName = "2.3+dev4"
versionCode = 2306
versionName = "2.3+dev5"
ndk {
abiFilters.clear()
abiFilters.addAll(listOf("armeabi-v7a", "arm64-v8a", "x86", "x86_64"))

View file

@ -8,6 +8,7 @@ import helium314.keyboard.keyboard.ColorSetting
import helium314.keyboard.keyboard.KeyboardTheme
import helium314.keyboard.keyboard.internal.keyboard_parser.floris.KeyCode.checkAndConvertCode
import helium314.keyboard.latin.common.ColorType
import helium314.keyboard.latin.common.Constants.Separators
import helium314.keyboard.latin.common.LocaleUtils.constructLocale
import helium314.keyboard.latin.common.encodeBase36
import helium314.keyboard.latin.settings.Defaults
@ -350,7 +351,8 @@ fun checkVersionUpgrade(context: Context) {
}
}
if (prefs.contains(Settings.PREF_ADDITIONAL_SUBTYPES))
prefs.edit().putString(Settings.PREF_ADDITIONAL_SUBTYPES, prefs.getString(Settings.PREF_ADDITIONAL_SUBTYPES, "")!!.replace(":", "§")).apply()
prefs.edit().putString(Settings.PREF_ADDITIONAL_SUBTYPES, prefs.getString(Settings.PREF_ADDITIONAL_SUBTYPES, "")!!
.replace(":", Separators.SET)).apply()
}
if (oldVersion <= 2304) {
// rename layout files for latin scripts, and adjust layouts stored in prefs accordingly
@ -373,6 +375,23 @@ fun checkVersionUpgrade(context: Context) {
}
}
}
if (oldVersion <= 2305) {
(prefs.all.keys.filter { it.startsWith(Settings.PREF_POPUP_KEYS_ORDER) || it.startsWith(Settings.PREF_POPUP_KEYS_LABELS_ORDER) } +
listOf(Settings.PREF_TOOLBAR_KEYS, Settings.PREF_PINNED_TOOLBAR_KEYS, Settings.PREF_CLIPBOARD_TOOLBAR_KEYS)).forEach {
if (!prefs.contains(it)) return@forEach
val newValue = prefs.getString(it, "")!!.replace(",", Separators.KV).replace(";", Separators.ENTRY)
prefs.edit().putString(it, newValue).apply()
}
listOf(Settings.PREF_ENABLED_SUBTYPES, Settings.PREF_SELECTED_SUBTYPE, Settings.PREF_ADDITIONAL_SUBTYPES).forEach {
if (!prefs.contains(it)) return@forEach
val value = prefs.getString(it, "")!!.replace(":", Separators.SET)
prefs.edit().putString(it, value).apply()
}
prefs.all.keys.filter { it.startsWith(Settings.PREF_SECONDARY_LOCALES_PREFIX) }.forEach {
val newValue = prefs.getString(it, "")!!.replace(";", Separators.KV)
prefs.edit().putString(it, newValue).apply()
}
}
upgradeToolbarPrefs(prefs)
LayoutUtilsCustom.onLayoutFileChanged() // just to be sure
prefs.edit { putInt(Settings.PREF_VERSION_CODE, BuildConfig.VERSION_CODE) }

View file

@ -102,6 +102,18 @@ public final class Constants {
}
}
/** Separators for use in extra values and preferences. Notably cannot be = and , as they are already used in extra values */
public static final class Separators {
/** key-value separator (to be used in subtype extra values) */
public static final String KV = ":";
/** separator between entries that might be key-value pairs (to be used in subtype extra values) */
public static final String ENTRY = "|";
/** separator between sets of entries (to be used for storing data for additional subtypes) */
public static final String SET = "§";
/** separator for sets (to be used for storing multiple extra additional subtypes in prefs) */
public static final String SETS = ";";
}
public static final class TextUtils {
/**
* Capitalization mode for {@link android.text.TextUtils#getCapsMode}: don't capitalize

View file

@ -7,11 +7,11 @@ import android.util.TypedValue
import android.view.Gravity
import helium314.keyboard.keyboard.KeyboardTheme
import helium314.keyboard.latin.BuildConfig
import helium314.keyboard.latin.common.Constants.Separators
import helium314.keyboard.latin.utils.JniUtils
import helium314.keyboard.latin.utils.LayoutType
import helium314.keyboard.latin.utils.POPUP_KEYS_LABEL_DEFAULT
import helium314.keyboard.latin.utils.POPUP_KEYS_ORDER_DEFAULT
import helium314.keyboard.latin.utils.SubtypeUtilsAdditional
import helium314.keyboard.latin.utils.defaultClipboardToolbarPref
import helium314.keyboard.latin.utils.defaultPinnedToolbarPref
import helium314.keyboard.latin.utils.defaultToolbarPref
@ -73,10 +73,9 @@ object Defaults {
const val PREF_LANGUAGE_SWITCH_KEY = "internal"
const val PREF_SHOW_EMOJI_KEY = false
const val PREF_VARIABLE_TOOLBAR_DIRECTION = true
private const val ls = SubtypeUtilsAdditional.LOCALE_AND_EXTRA_SEPARATOR
private const val subs = SubtypeUtilsAdditional.PREF_SUBTYPE_SEPARATOR
const val PREF_ADDITIONAL_SUBTYPES = "de${ls}qwerty${ls}AsciiCapable${subs}" +
"fr${ls}qwertz:${ls}AsciiCapable${subs}hu${ls}qwerty${ls}AsciiCapable"
const val PREF_ADDITIONAL_SUBTYPES = "de${Separators.SET}qwerty${Separators.SET}AsciiCapable${Separators.SETS}" +
"fr${Separators.SET}qwertz${Separators.SET}AsciiCapable${Separators.SETS}" +
"hu${Separators.SET}qwerty${Separators.SET}AsciiCapable"
const val PREF_ENABLE_SPLIT_KEYBOARD = false
const val PREF_ENABLE_SPLIT_KEYBOARD_LANDSCAPE = false
const val PREF_SPLIT_SPACER_SCALE = SettingsValues.DEFAULT_SIZE_SCALE

View file

@ -28,6 +28,7 @@ import helium314.keyboard.latin.AudioAndHapticFeedbackManager;
import helium314.keyboard.latin.InputAttributes;
import helium314.keyboard.latin.R;
import helium314.keyboard.latin.common.Colors;
import helium314.keyboard.latin.common.Constants;
import helium314.keyboard.latin.common.LocaleUtils;
import helium314.keyboard.latin.utils.DeviceProtectedUtils;
import helium314.keyboard.latin.utils.KtxKt;
@ -479,7 +480,7 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
final String localesString = prefs.getString(PREF_SECONDARY_LOCALES_PREFIX + mainLocale.toLanguageTag(), Defaults.PREF_SECONDARY_LOCALES);
final ArrayList<Locale> locales = new ArrayList<>();
for (String languageTag : localesString.split(";")) {
for (String languageTag : localesString.split(Constants.Separators.KV)) {
if (languageTag.isEmpty()) continue;
locales.add(LocaleUtils.constructLocale(languageTag));
}
@ -493,7 +494,7 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang
}
final StringBuilder sb = new StringBuilder();
for (Locale locale : locales) {
sb.append(";").append(locale.toLanguageTag());
sb.append(Constants.Separators.KV).append(locale.toLanguageTag());
}
prefs.edit().putString(PREF_SECONDARY_LOCALES_PREFIX + mainLocale.toLanguageTag(), sb.toString()).apply();
}

View file

@ -1,6 +1,7 @@
package helium314.keyboard.latin.utils
import helium314.keyboard.latin.R
import helium314.keyboard.latin.common.Constants.Separators
import java.io.File
import java.util.EnumMap
@ -9,12 +10,12 @@ enum class LayoutType {
NUMPAD_LANDSCAPE, PHONE, PHONE_SYMBOLS, EMOJI_BOTTOM, CLIPBOARD_BOTTOM;
companion object {
fun EnumMap<LayoutType, String>.toExtraValue() = map { "${it.key.name}:${it.value}" }.joinToString("|")
fun EnumMap<LayoutType, String>.toExtraValue() = map { it.key.name + Separators.KV + it.value }.joinToString(Separators.ENTRY)
fun getLayoutMap(extraValue: String): EnumMap<LayoutType, String> {
val map = EnumMap<LayoutType, String>(LayoutType::class.java)
extraValue.split("|").forEach {
val s = it.split(":")
extraValue.split(Separators.ENTRY).forEach {
val s = it.split(Separators.KV)
runCatching { map[LayoutType.valueOf(s[0])] = s[1] }
}
return map

View file

@ -4,18 +4,22 @@ package helium314.keyboard.latin.utils
import android.content.SharedPreferences
import helium314.keyboard.keyboard.Key
import helium314.keyboard.keyboard.internal.KeySpecParser
import helium314.keyboard.keyboard.internal.KeyboardIconsSet
import helium314.keyboard.keyboard.internal.KeyboardParams
import helium314.keyboard.keyboard.internal.keyboard_parser.floris.KeyLabel.rtlLabel
import helium314.keyboard.keyboard.internal.keyboard_parser.floris.PopupSet
import helium314.keyboard.latin.common.Constants.Separators
const val POPUP_KEYS_NUMBER = "popup_keys_number"
private const val POPUP_KEYS_LANGUAGE_PRIORITY = "popup_keys_language_priority"
const val POPUP_KEYS_LAYOUT = "popup_keys_layout"
private const val POPUP_KEYS_SYMBOLS = "popup_keys_symbols"
private const val POPUP_KEYS_LANGUAGE = "popup_keys_language"
const val POPUP_KEYS_LABEL_DEFAULT = "$POPUP_KEYS_NUMBER,true;$POPUP_KEYS_LANGUAGE_PRIORITY,false;$POPUP_KEYS_LAYOUT,true;$POPUP_KEYS_SYMBOLS,true;$POPUP_KEYS_LANGUAGE,false"
const val POPUP_KEYS_ORDER_DEFAULT = "$POPUP_KEYS_LANGUAGE_PRIORITY,true;$POPUP_KEYS_NUMBER,true;$POPUP_KEYS_SYMBOLS,true;$POPUP_KEYS_LAYOUT,true;$POPUP_KEYS_LANGUAGE,true"
const val POPUP_KEYS_LABEL_DEFAULT = POPUP_KEYS_NUMBER + Separators.KV + true + Separators.ENTRY + POPUP_KEYS_LANGUAGE_PRIORITY +
Separators.KV + false + Separators.ENTRY + POPUP_KEYS_LAYOUT + Separators.KV + true + Separators.ENTRY +
POPUP_KEYS_SYMBOLS + Separators.KV + true + Separators.ENTRY + POPUP_KEYS_LANGUAGE + Separators.KV + false
const val POPUP_KEYS_ORDER_DEFAULT = POPUP_KEYS_LANGUAGE_PRIORITY + Separators.KV + true + Separators.ENTRY + POPUP_KEYS_NUMBER +
Separators.KV + true + Separators.ENTRY + POPUP_KEYS_SYMBOLS + Separators.KV + true + Separators.ENTRY +
POPUP_KEYS_LAYOUT + Separators.KV + true + Separators.ENTRY + POPUP_KEYS_LANGUAGE + Separators.KV + true
private val allPopupKeyTypes = listOf(POPUP_KEYS_NUMBER, POPUP_KEYS_LAYOUT, POPUP_KEYS_SYMBOLS, POPUP_KEYS_LANGUAGE, POPUP_KEYS_LANGUAGE_PRIORITY)

View file

@ -13,6 +13,7 @@ import androidx.core.content.edit
import helium314.keyboard.keyboard.KeyboardSwitcher
import helium314.keyboard.latin.R
import helium314.keyboard.latin.RichInputMethodManager
import helium314.keyboard.latin.common.Constants.Separators
import helium314.keyboard.latin.common.LocaleUtils
import helium314.keyboard.latin.common.LocaleUtils.constructLocale
import helium314.keyboard.latin.define.DebugFlags
@ -57,8 +58,8 @@ fun getMatchingLayoutSetNameForLocale(locale: Locale): String {
fun addEnabledSubtype(prefs: SharedPreferences, newSubtype: InputMethodSubtype) {
require(initialized)
val subtypeString = newSubtype.prefString()
val oldSubtypeStrings = prefs.getString(Settings.PREF_ENABLED_SUBTYPES, Defaults.PREF_ENABLED_SUBTYPES)!!.split(SUBTYPE_SEPARATOR)
val newString = (oldSubtypeStrings + subtypeString).filter { it.isNotBlank() }.toSortedSet().joinToString(SUBTYPE_SEPARATOR)
val oldSubtypeStrings = prefs.getString(Settings.PREF_ENABLED_SUBTYPES, Defaults.PREF_ENABLED_SUBTYPES)!!.split(Separators.SETS)
val newString = (oldSubtypeStrings + subtypeString).filter { it.isNotBlank() }.toSortedSet().joinToString(Separators.SETS)
prefs.edit { putString(Settings.PREF_ENABLED_SUBTYPES, newString) }
if (newSubtype !in enabledSubtypes) {
@ -185,14 +186,14 @@ private fun InputMethodSubtype.prefString(): String {
@Suppress("deprecation") // it's debug logging, better get all information
Log.e(TAG, "unknown language, should not happen ${locale}, $languageTag, $extraValue, ${hashCode()}, $nameResId")
}
return locale().toLanguageTag() + LOCALE_LAYOUT_SEPARATOR + SubtypeLocaleUtils.getMainLayoutName(this)
return locale().toLanguageTag() + Separators.SET + SubtypeLocaleUtils.getMainLayoutName(this)
}
private fun String.toLocaleAndLayout(): Pair<Locale, String> =
substringBefore(LOCALE_LAYOUT_SEPARATOR).constructLocale() to substringAfter(LOCALE_LAYOUT_SEPARATOR)
substringBefore(Separators.SET).constructLocale() to substringAfter(Separators.SET)
private fun Pair<Locale, String>.prefString() =
first.toLanguageTag() + LOCALE_LAYOUT_SEPARATOR + second
first.toLanguageTag() + Separators.SET + second
private fun loadResourceSubtypes(resources: Resources) {
val xml = resources.getXml(R.xml.method)
@ -255,7 +256,7 @@ private fun loadAdditionalSubtypes(prefs: SharedPreferences) {
private fun loadEnabledSubtypes(context: Context) {
val prefs = context.prefs()
val subtypeStrings = prefs.getString(Settings.PREF_ENABLED_SUBTYPES, Defaults.PREF_ENABLED_SUBTYPES)!!
.split(SUBTYPE_SEPARATOR).filter { it.isNotEmpty() }.map { it.toLocaleAndLayout() }
.split(Separators.SETS).filter { it.isNotEmpty() }.map { it.toLocaleAndLayout() }
for (localeAndLayout in subtypeStrings) {
val subtypesForLocale = resourceSubtypesByLocale[localeAndLayout.first]
@ -287,7 +288,7 @@ private fun loadEnabledSubtypes(context: Context) {
private fun removeEnabledSubtype(prefs: SharedPreferences, subtypeString: String) {
val oldSubtypeString = prefs.getString(Settings.PREF_ENABLED_SUBTYPES, Defaults.PREF_ENABLED_SUBTYPES)!!
val newString = (oldSubtypeString.split(SUBTYPE_SEPARATOR) - subtypeString).joinToString(SUBTYPE_SEPARATOR)
val newString = (oldSubtypeString.split(Separators.SETS) - subtypeString).joinToString(Separators.SETS)
if (newString == oldSubtypeString)
return // already removed
prefs.edit { putString(Settings.PREF_ENABLED_SUBTYPES, newString) }
@ -310,7 +311,4 @@ private val resourceSubtypesByLocale = LinkedHashMap<Locale, MutableList<InputMe
private val additionalSubtypes = mutableListOf<InputMethodSubtype>()
private val systemLocales = mutableListOf<Locale>()
private val systemSubtypes = mutableListOf<InputMethodSubtype>()
private const val SUBTYPE_SEPARATOR = ";"
private const val LOCALE_LAYOUT_SEPARATOR = ":"
private const val TAG = "SubtypeSettings"

View file

@ -7,6 +7,7 @@ import android.view.inputmethod.InputMethodSubtype
import android.view.inputmethod.InputMethodSubtype.InputMethodSubtypeBuilder
import helium314.keyboard.latin.R
import helium314.keyboard.latin.common.Constants
import helium314.keyboard.latin.common.Constants.Separators
import helium314.keyboard.latin.common.Constants.Subtype.ExtraValue
import helium314.keyboard.latin.common.LocaleUtils.constructLocale
import helium314.keyboard.latin.common.StringUtils
@ -69,30 +70,30 @@ object SubtypeUtilsAdditional {
// todo: adjust so we can store more stuff in extra values
private fun getPrefSubtype(subtype: InputMethodSubtype): String {
val mainLayoutName = SubtypeLocaleUtils.getMainLayoutName(subtype)
val layoutExtraValue = ExtraValue.KEYBOARD_LAYOUT_SET + "=MAIN:" + mainLayoutName
val layoutExtraValue = ExtraValue.KEYBOARD_LAYOUT_SET + "=MAIN" + Separators.KV + mainLayoutName
val extraValue = StringUtils.removeFromCommaSplittableTextIfExists(
layoutExtraValue, StringUtils.removeFromCommaSplittableTextIfExists(
ExtraValue.IS_ADDITIONAL_SUBTYPE, subtype.extraValue
)
)
require(!extraValue.contains(PREF_SUBTYPE_SEPARATOR) && !extraValue.contains(LOCALE_AND_EXTRA_SEPARATOR))
require(!extraValue.contains(Separators.SETS) && !extraValue.contains(Separators.SET))
{ "extra value contains not allowed characters $extraValue" }
val basePrefSubtype = subtype.locale().toLanguageTag() + LOCALE_AND_EXTRA_SEPARATOR + mainLayoutName
val basePrefSubtype = subtype.locale().toLanguageTag() + Separators.SET + mainLayoutName
return if (extraValue.isEmpty()) basePrefSubtype
else basePrefSubtype + LOCALE_AND_EXTRA_SEPARATOR + extraValue
else basePrefSubtype + Separators.SET + extraValue
}
fun createAdditionalSubtypes(prefSubtypes: String): List<InputMethodSubtype> {
if (TextUtils.isEmpty(prefSubtypes)) {
return emptyList()
}
return prefSubtypes.split(PREF_SUBTYPE_SEPARATOR)
return prefSubtypes.split(Separators.SETS)
.mapNotNull { createSubtypeFromString(it) }
}
// use string created with getPrefSubtype
fun createSubtypeFromString(prefSubtype: String): InputMethodSubtype? {
val elems = prefSubtype.split(LOCALE_AND_EXTRA_SEPARATOR)
val elems = prefSubtype.split(Separators.SET)
if (elems.size != LENGTH_WITHOUT_EXTRA_VALUE && elems.size != LENGTH_WITH_EXTRA_VALUE) {
Log.w(TAG, "Unknown additional subtype specified: $prefSubtype")
return null
@ -118,7 +119,7 @@ object SubtypeUtilsAdditional {
val sb = StringBuilder()
for (subtype in subtypes) {
if (sb.isNotEmpty()) {
sb.append(PREF_SUBTYPE_SEPARATOR)
sb.append(Separators.SETS)
}
sb.append(getPrefSubtype(subtype))
}
@ -132,7 +133,7 @@ object SubtypeUtilsAdditional {
val sb = StringBuilder()
for (prefSubtype in prefSubtypes) {
if (sb.isNotEmpty()) {
sb.append(PREF_SUBTYPE_SEPARATOR)
sb.append(Separators.SETS)
}
sb.append(prefSubtype)
}
@ -221,8 +222,6 @@ object SubtypeUtilsAdditional {
}
private val TAG: String = SubtypeUtilsAdditional::class.java.simpleName
const val LOCALE_AND_EXTRA_SEPARATOR: String = "§"
const val PREF_SUBTYPE_SEPARATOR: String = ";"
private const val INDEX_OF_LANGUAGE_TAG: Int = 0
private const val INDEX_OF_KEYBOARD_LAYOUT: Int = 1
private const val INDEX_OF_EXTRA_VALUE: Int = 2

View file

@ -11,6 +11,7 @@ import androidx.core.view.forEach
import helium314.keyboard.keyboard.internal.KeyboardIconsSet
import helium314.keyboard.keyboard.internal.keyboard_parser.floris.KeyCode
import helium314.keyboard.latin.R
import helium314.keyboard.latin.common.Constants.Separators
import helium314.keyboard.latin.settings.Defaults
import helium314.keyboard.latin.settings.Settings
import helium314.keyboard.latin.utils.ToolbarKey.*
@ -119,17 +120,19 @@ val toolbarKeyStrings = entries.associateWithTo(EnumMap(ToolbarKey::class.java))
val defaultToolbarPref by lazy {
val default = listOf(SETTINGS, VOICE, CLIPBOARD, UNDO, REDO, SELECT_WORD, COPY, PASTE, LEFT, RIGHT)
val others = entries.filterNot { it in default || it == CLOSE_HISTORY }
default.joinToString(";") { "${it.name},true" } + ";" + others.joinToString(";") { "${it.name},false" }
default.joinToString(Separators.ENTRY) { it.name + Separators.KV + true } + Separators.ENTRY +
others.joinToString(Separators.ENTRY) { it.name + Separators.KV + false }
}
val defaultPinnedToolbarPref = entries.filterNot { it == CLOSE_HISTORY }.joinToString(";") {
"${it.name},false"
val defaultPinnedToolbarPref = entries.filterNot { it == CLOSE_HISTORY }.joinToString(Separators.ENTRY) {
it.name + Separators.KV + false
}
val defaultClipboardToolbarPref by lazy {
val default = listOf(CLEAR_CLIPBOARD, UP, DOWN, LEFT, RIGHT, UNDO, CUT, COPY, PASTE, SELECT_WORD, CLOSE_HISTORY)
val others = entries.filterNot { it in default }
default.joinToString(";") { "${it.name},true" } + ";" + others.joinToString(";") { "${it.name},false" }
default.joinToString(Separators.ENTRY) { it.name + Separators.KV + true } + Separators.ENTRY +
others.joinToString(Separators.ENTRY) { it.name + Separators.KV + false }
}
/** add missing keys, typically because a new key has been added */
@ -141,23 +144,23 @@ fun upgradeToolbarPrefs(prefs: SharedPreferences) {
private fun upgradeToolbarPref(prefs: SharedPreferences, pref: String, default: String) {
if (!prefs.contains(pref)) return
val list = prefs.getString(pref, default)!!.split(";").toMutableList()
val splitDefault = defaultToolbarPref.split(";")
val list = prefs.getString(pref, default)!!.split(Separators.ENTRY).toMutableList()
val splitDefault = defaultToolbarPref.split(Separators.ENTRY)
splitDefault.forEach { entry ->
val keyWithComma = entry.substringBefore(",") + ","
if (list.none { it.startsWith(keyWithComma) })
list.add("${keyWithComma}false")
val keyWithSeparator = entry.substringBefore(Separators.KV) + Separators.KV
if (list.none { it.startsWith(keyWithSeparator) })
list.add("${keyWithSeparator}false")
}
// likely not needed, but better prepare for possibility of key removal
list.removeAll {
try {
ToolbarKey.valueOf(it.substringBefore(","))
ToolbarKey.valueOf(it.substringBefore(Separators.KV))
false
} catch (_: IllegalArgumentException) {
true
}
}
prefs.edit { putString(pref, list.joinToString(";")) }
prefs.edit { putString(pref, list.joinToString(Separators.ENTRY)) }
}
fun getEnabledToolbarKeys(prefs: SharedPreferences) = getEnabledToolbarKeys(prefs, Settings.PREF_TOOLBAR_KEYS, defaultToolbarPref)
@ -169,19 +172,19 @@ fun getEnabledClipboardToolbarKeys(prefs: SharedPreferences) = getEnabledToolbar
fun addPinnedKey(prefs: SharedPreferences, key: ToolbarKey) {
// remove the existing version of this key and add the enabled one after the last currently enabled key
val string = prefs.getString(Settings.PREF_PINNED_TOOLBAR_KEYS, defaultPinnedToolbarPref)!!
val keys = string.split(";").toMutableList()
keys.removeAll { it.startsWith(key.name + ",") }
val keys = string.split(Separators.ENTRY).toMutableList()
keys.removeAll { it.startsWith(key.name + Separators.KV) }
val lastEnabledIndex = keys.indexOfLast { it.endsWith("true") }
keys.add(lastEnabledIndex + 1, key.name + ",true")
prefs.edit { putString(Settings.PREF_PINNED_TOOLBAR_KEYS, keys.joinToString(";")) }
keys.add(lastEnabledIndex + 1, key.name + Separators.KV + "true")
prefs.edit { putString(Settings.PREF_PINNED_TOOLBAR_KEYS, keys.joinToString(Separators.ENTRY)) }
}
fun removePinnedKey(prefs: SharedPreferences, key: ToolbarKey) {
// just set it to disabled
val string = prefs.getString(Settings.PREF_PINNED_TOOLBAR_KEYS, defaultPinnedToolbarPref)!!
val result = string.split(";").joinToString(";") {
if (it.startsWith(key.name + ","))
key.name + ",false"
val result = string.split(Separators.ENTRY).joinToString(Separators.ENTRY) {
if (it.startsWith(key.name + Separators.KV))
key.name + Separators.KV + "false"
else it
}
prefs.edit { putString(Settings.PREF_PINNED_TOOLBAR_KEYS, result) }
@ -189,8 +192,8 @@ fun removePinnedKey(prefs: SharedPreferences, key: ToolbarKey) {
private fun getEnabledToolbarKeys(prefs: SharedPreferences, pref: String, default: String): List<ToolbarKey> {
val string = prefs.getString(pref, default)!!
return string.split(";").mapNotNull {
val split = it.split(",")
return string.split(Separators.ENTRY).mapNotNull {
val split = it.split(Separators.KV)
if (split.last() == "true") {
try {
ToolbarKey.valueOf(split.first())

View file

@ -7,7 +7,6 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
@ -16,6 +15,7 @@ import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource
import helium314.keyboard.keyboard.internal.KeyboardIconsSet
import helium314.keyboard.latin.R
import helium314.keyboard.latin.common.Constants.Separators
import helium314.keyboard.latin.utils.getStringResourceOrName
import helium314.keyboard.latin.utils.prefs
import helium314.keyboard.settings.Setting
@ -34,13 +34,13 @@ fun ReorderSwitchPreference(setting: Setting, default: String) {
if (showDialog) {
val ctx = LocalContext.current
val prefs = ctx.prefs()
val items = prefs.getString(setting.key, default)!!.split(";").mapTo(ArrayList()) {
val both = it.split(",")
val items = prefs.getString(setting.key, default)!!.split(Separators.ENTRY).mapTo(ArrayList()) {
val both = it.split(Separators.KV)
KeyAndState(both.first(), both.last().toBoolean())
}
ReorderDialog(
onConfirmed = { reorderedItems ->
val value = reorderedItems.joinToString(";") { it.name + "," + it.state }
val value = reorderedItems.joinToString(Separators.ENTRY) { it.name + Separators.KV + it.state }
prefs.edit().putString(setting.key, value).apply()
keyboardNeedsReload = true
},