From 751563bc29a7a82754e45f8188a6ad04ea2db945 Mon Sep 17 00:00:00 2001 From: WhiredPlanck Date: Sun, 19 May 2024 20:39:03 +0800 Subject: [PATCH] refactor: refactors to picker dialog Enhance the UX --- .../trime/data/sound/SoundEffectManager.kt | 2 +- .../java/com/osfans/trime/data/theme/Theme.kt | 5 +- .../osfans/trime/data/theme/ThemeManager.kt | 13 ++- .../osfans/trime/ime/text/TextInputManager.kt | 14 +-- .../ui/components/CoroutineChoiceDialog.kt | 85 ------------------- .../trime/ui/fragments/KeyboardFragment.kt | 4 +- .../trime/ui/fragments/ThemeColorFragment.kt | 8 +- .../java/com/osfans/trime/ui/main/Pickers.kt | 82 ------------------ .../osfans/trime/ui/main/PrefMainActivity.kt | 2 +- .../ui/main/settings/ColorPickerDialog.kt | 42 +++++++++ .../settings/KeySoundEffectPickerDialog.kt | 38 +++++++++ .../ui/main/settings/ThemePickerDialog.kt | 44 ++++++++++ .../java/com/osfans/trime/util/DialogUtils.kt | 2 +- app/src/main/res/values-zh-rCN/strings.xml | 5 +- app/src/main/res/values-zh-rTW/strings.xml | 5 +- app/src/main/res/values/strings.xml | 5 +- app/src/main/res/xml/keyboard_preference.xml | 2 +- 17 files changed, 166 insertions(+), 192 deletions(-) delete mode 100644 app/src/main/java/com/osfans/trime/ui/components/CoroutineChoiceDialog.kt delete mode 100644 app/src/main/java/com/osfans/trime/ui/main/Pickers.kt create mode 100644 app/src/main/java/com/osfans/trime/ui/main/settings/ColorPickerDialog.kt create mode 100644 app/src/main/java/com/osfans/trime/ui/main/settings/KeySoundEffectPickerDialog.kt create mode 100644 app/src/main/java/com/osfans/trime/ui/main/settings/ThemePickerDialog.kt diff --git a/app/src/main/java/com/osfans/trime/data/sound/SoundEffectManager.kt b/app/src/main/java/com/osfans/trime/data/sound/SoundEffectManager.kt index a14fe0b0a9..087e6d498b 100644 --- a/app/src/main/java/com/osfans/trime/data/sound/SoundEffectManager.kt +++ b/app/src/main/java/com/osfans/trime/data/sound/SoundEffectManager.kt @@ -52,7 +52,7 @@ object SoundEffectManager { private fun getSound(name: String) = userSounds.find { it.name == name } - private val userSounds: MutableList = listSounds() + private val userSounds: MutableList get() = listSounds() @JvmStatic fun switchSound(name: String) { diff --git a/app/src/main/java/com/osfans/trime/data/theme/Theme.kt b/app/src/main/java/com/osfans/trime/data/theme/Theme.kt index c2b5fe4383..28a4611445 100644 --- a/app/src/main/java/com/osfans/trime/data/theme/Theme.kt +++ b/app/src/main/java/com/osfans/trime/data/theme/Theme.kt @@ -35,7 +35,8 @@ class Theme(name: String) { private const val DEFAULT_THEME_NAME = "trime" private fun deploy(active: String): Config? { - val nameWithExtension = "$active.yaml" + val ext = if (active == DEFAULT_THEME_NAME) ".yaml" else ".trime.yaml" + val nameWithExtension = "$active$ext" val isDeployed: Boolean measureTimeMillis { isDeployed = Rime.deployRimeConfigFile(nameWithExtension, VERSION_KEY) @@ -46,7 +47,7 @@ class Theme(name: String) { Timber.w("Failed to deploy theme file '$nameWithExtension'") } } - return Config.create(active) + return Config.create(nameWithExtension.removeSuffix(".yaml")) } } diff --git a/app/src/main/java/com/osfans/trime/data/theme/ThemeManager.kt b/app/src/main/java/com/osfans/trime/data/theme/ThemeManager.kt index 29a6f2b6e5..c1b96a9d2c 100644 --- a/app/src/main/java/com/osfans/trime/data/theme/ThemeManager.kt +++ b/app/src/main/java/com/osfans/trime/data/theme/ThemeManager.kt @@ -29,15 +29,22 @@ object ThemeManager { DataManager.addOnChangedListener(onDataDirChange) } + private val suffixRegex = Regex("(.*?)(\\.trime\\.yaml$|\\.yaml$)") + private fun listThemes(path: File): MutableList { return path.listFiles { _, name -> name.endsWith("trime.yaml") } - ?.map { f -> f.nameWithoutExtension } + ?.mapNotNull { f -> + suffixRegex.matchEntire(f.name)?.let { result -> + val basename = if (result.groups[2]?.value == ".trime.yaml") result.groupValues[1] else f.nameWithoutExtension + basename + } + } ?.toMutableList() ?: mutableListOf() } - private val sharedThemes: MutableList = listThemes(DataManager.sharedDataDir) + private val sharedThemes: MutableList get() = listThemes(DataManager.sharedDataDir) - private val userThemes: MutableList = listThemes(DataManager.userDataDir) + private val userThemes: MutableList get() = listThemes(DataManager.userDataDir) fun getAllThemes(): List { if (DataManager.sharedDataDir.absolutePath == DataManager.userDataDir.absolutePath) { diff --git a/app/src/main/java/com/osfans/trime/ime/text/TextInputManager.kt b/app/src/main/java/com/osfans/trime/ime/text/TextInputManager.kt index fb372b72fe..920b0f2b42 100644 --- a/app/src/main/java/com/osfans/trime/ime/text/TextInputManager.kt +++ b/app/src/main/java/com/osfans/trime/ime/text/TextInputManager.kt @@ -31,9 +31,9 @@ import com.osfans.trime.ime.keyboard.Keyboard import com.osfans.trime.ime.keyboard.KeyboardSwitcher import com.osfans.trime.ime.keyboard.KeyboardView import com.osfans.trime.ime.symbol.SymbolBoardType -import com.osfans.trime.ui.main.buildColorPickerDialog -import com.osfans.trime.ui.main.buildSoundEffectPickerDialog -import com.osfans.trime.ui.main.buildThemePickerDialog +import com.osfans.trime.ui.main.settings.ColorPickerDialog +import com.osfans.trime.ui.main.settings.KeySoundEffectPickerDialog +import com.osfans.trime.ui.main.settings.ThemePickerDialog import com.osfans.trime.util.ShortcutUtils import com.osfans.trime.util.startsWithAsciiChar import kotlinx.coroutines.Job @@ -368,22 +368,22 @@ class TextInputManager( KeyEvent.KEYCODE_SETTINGS -> { // Settings trime.lifecycleScope.launch { when (event.option) { - "theme" -> trime.inputView?.showDialog(buildThemePickerDialog(themedContext, trime.lifecycleScope)) - "color" -> trime.inputView?.showDialog(buildColorPickerDialog(themedContext, trime.lifecycleScope)) + "theme" -> trime.inputView?.showDialog(ThemePickerDialog.build(trime.lifecycleScope, themedContext)) + "color" -> trime.inputView?.showDialog(ColorPickerDialog.build(trime.lifecycleScope, themedContext)) "schema" -> rime.launchOnReady { api -> trime.lifecycleScope.launch { trime.inputView?.showDialog(AvailableSchemaPickerDialog.build(api, trime.lifecycleScope, themedContext)) } } - "sound" -> trime.inputView?.showDialog(buildSoundEffectPickerDialog(themedContext)) + "sound" -> trime.inputView?.showDialog(KeySoundEffectPickerDialog.build(trime.lifecycleScope, themedContext)) else -> ShortcutUtils.launchMainActivity(trime) } } } KeyEvent.KEYCODE_PROG_RED -> trime.lifecycleScope.launch { - trime.inputView?.showDialog(buildColorPickerDialog(themedContext, trime.lifecycleScope)) + trime.inputView?.showDialog(ColorPickerDialog.build(trime.lifecycleScope, themedContext)) } KeyEvent.KEYCODE_MENU -> { rime.launchOnReady { api -> diff --git a/app/src/main/java/com/osfans/trime/ui/components/CoroutineChoiceDialog.kt b/app/src/main/java/com/osfans/trime/ui/components/CoroutineChoiceDialog.kt deleted file mode 100644 index d2240d1259..0000000000 --- a/app/src/main/java/com/osfans/trime/ui/components/CoroutineChoiceDialog.kt +++ /dev/null @@ -1,85 +0,0 @@ -// SPDX-FileCopyrightText: 2015 - 2024 Rime community -// -// SPDX-License-Identifier: GPL-3.0-or-later - -package com.osfans.trime.ui.components - -import android.app.AlertDialog -import android.content.Context -import androidx.lifecycle.LifecycleCoroutineScope -import kotlinx.coroutines.CoroutineDispatcher -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext - -class CoroutineChoiceDialog( - context: Context, - private val scope: LifecycleCoroutineScope, -) { - private val builder = AlertDialog.Builder(context) - var items: Array = arrayOf() - var checkedItem: Int = -1 - var checkedItems: BooleanArray = booleanArrayOf() - var title: String = "" - var emptyMessage: String = "" - var initDispatcher: CoroutineDispatcher = Dispatchers.Main - var postiveDispatcher: CoroutineDispatcher = Dispatchers.Main - - private lateinit var onInitListener: ActionListener - private lateinit var onPositiveListener: ActionListener - - fun interface ActionListener { - fun onAction() - } - - fun onInit(listener: ActionListener): CoroutineChoiceDialog { - onInitListener = listener - return this - } - - fun onOKButton(listener: ActionListener): CoroutineChoiceDialog { - onPositiveListener = listener - return this - } - - private suspend fun init() = - withContext(initDispatcher) { - onInitListener.onAction() - } - - private suspend fun positive() = - withContext(postiveDispatcher) { - onPositiveListener.onAction() - } - - private fun build() { - with(builder) { - setNegativeButton(android.R.string.cancel, null) - if (title.isNotEmpty()) setTitle(title) - if (items.isNotEmpty()) { - if (checkedItems.isNotEmpty()) { - setMultiChoiceItems(items, checkedItems) { _, id, isChecked -> - checkedItems[id] = isChecked - } - } else if (checkedItem > -1) { - setSingleChoiceItems(items, checkedItem) { _, id -> - checkedItem = id - } - } - setPositiveButton(android.R.string.ok) { _, _ -> - scope.launch { - positive() - } - } - } else { - setMessage(emptyMessage) - } - } - } - - suspend fun create(): AlertDialog { - init() - build() - return builder.create() - } -} diff --git a/app/src/main/java/com/osfans/trime/ui/fragments/KeyboardFragment.kt b/app/src/main/java/com/osfans/trime/ui/fragments/KeyboardFragment.kt index 1ef9156fd7..68634280a9 100644 --- a/app/src/main/java/com/osfans/trime/ui/fragments/KeyboardFragment.kt +++ b/app/src/main/java/com/osfans/trime/ui/fragments/KeyboardFragment.kt @@ -16,7 +16,7 @@ import com.osfans.trime.data.base.DataManager import com.osfans.trime.ime.core.TrimeInputMethodService import com.osfans.trime.ui.components.PaddingPreferenceFragment import com.osfans.trime.ui.main.MainViewModel -import com.osfans.trime.ui.main.buildSoundEffectPickerDialog +import com.osfans.trime.ui.main.settings.KeySoundEffectPickerDialog import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext @@ -33,7 +33,7 @@ class KeyboardFragment : addPreferencesFromResource(R.xml.keyboard_preference) findPreference("keyboard__key_sound_package") ?.setOnPreferenceClickListener { - lifecycleScope.launch { buildSoundEffectPickerDialog(requireContext()).show() } + lifecycleScope.launch { KeySoundEffectPickerDialog.build(lifecycleScope, requireContext()).show() } true } } diff --git a/app/src/main/java/com/osfans/trime/ui/fragments/ThemeColorFragment.kt b/app/src/main/java/com/osfans/trime/ui/fragments/ThemeColorFragment.kt index 54a2412313..a85f73538b 100644 --- a/app/src/main/java/com/osfans/trime/ui/fragments/ThemeColorFragment.kt +++ b/app/src/main/java/com/osfans/trime/ui/fragments/ThemeColorFragment.kt @@ -12,8 +12,8 @@ import androidx.preference.get import com.osfans.trime.R import com.osfans.trime.ui.components.PaddingPreferenceFragment import com.osfans.trime.ui.main.MainViewModel -import com.osfans.trime.ui.main.buildColorPickerDialog -import com.osfans.trime.ui.main.buildThemePickerDialog +import com.osfans.trime.ui.main.settings.ColorPickerDialog +import com.osfans.trime.ui.main.settings.ThemePickerDialog import kotlinx.coroutines.launch class ThemeColorFragment : PaddingPreferenceFragment() { @@ -26,11 +26,11 @@ class ThemeColorFragment : PaddingPreferenceFragment() { addPreferencesFromResource(R.xml.theme_color_preference) with(preferenceScreen) { get("theme_selected_theme")?.setOnPreferenceClickListener { - lifecycleScope.launch { buildThemePickerDialog(context, lifecycleScope).show() } + lifecycleScope.launch { ThemePickerDialog.build(lifecycleScope, context).show() } true } get("theme_selected_color")?.setOnPreferenceClickListener { - lifecycleScope.launch { buildColorPickerDialog(context, lifecycleScope).show() } + lifecycleScope.launch { ColorPickerDialog.build(lifecycleScope, context).show() } true } } diff --git a/app/src/main/java/com/osfans/trime/ui/main/Pickers.kt b/app/src/main/java/com/osfans/trime/ui/main/Pickers.kt deleted file mode 100644 index a4298d0275..0000000000 --- a/app/src/main/java/com/osfans/trime/ui/main/Pickers.kt +++ /dev/null @@ -1,82 +0,0 @@ -// SPDX-FileCopyrightText: 2015 - 2024 Rime community -// -// SPDX-License-Identifier: GPL-3.0-or-later - -package com.osfans.trime.ui.main - -import android.app.AlertDialog -import android.content.Context -import androidx.lifecycle.LifecycleCoroutineScope -import com.osfans.trime.R -import com.osfans.trime.data.AppPrefs -import com.osfans.trime.data.sound.SoundEffect -import com.osfans.trime.data.sound.SoundEffectManager -import com.osfans.trime.data.theme.ColorManager -import com.osfans.trime.data.theme.ThemeManager -import com.osfans.trime.ui.components.CoroutineChoiceDialog -import kotlinx.coroutines.Dispatchers - -suspend fun buildThemePickerDialog( - context: Context, - scope: LifecycleCoroutineScope, -): AlertDialog { - return CoroutineChoiceDialog(context, scope).apply { - title = context.getString(R.string.looks__selected_theme_title) - initDispatcher = Dispatchers.IO - onInit { - items = - ThemeManager.getAllThemes() - .map { it.substringBeforeLast('.') } - .toTypedArray() - val current = - AppPrefs.defaultInstance().theme.selectedTheme - .substringBeforeLast('.') - checkedItem = items.indexOf(current) - } - postiveDispatcher = Dispatchers.Default - onOKButton { - with(items[checkedItem].toString()) { - ThemeManager.setNormalTheme(if (this == "trime") this else "$this.trime") - } - } - }.create() -} - -suspend fun buildColorPickerDialog( - context: Context, - scope: LifecycleCoroutineScope, -): AlertDialog { - return CoroutineChoiceDialog(context, scope).apply { - title = context.getString(R.string.looks__selected_color_title) - initDispatcher = Dispatchers.Default - val all by lazy { ColorManager.presetColorSchemes } - onInit { - items = all.map { it.value["name"]!! }.toTypedArray() - val current = ColorManager.selectedColor - val schemeIds = all.keys - checkedItem = schemeIds.indexOf(current).takeIf { it > -1 } ?: 1 - } - postiveDispatcher = Dispatchers.Default - onOKButton { - val schemeIds = all.keys.toList() - ColorManager.setColorScheme(schemeIds[checkedItem]) - } - }.create() -} - -fun buildSoundEffectPickerDialog(context: Context): AlertDialog { - val all = SoundEffectManager.getAllSoundEffects().mapNotNull(SoundEffect::name) - val current = SoundEffectManager.getActiveSoundEffect().getOrNull()?.name ?: "" - var checked = all.indexOf(current) - return AlertDialog.Builder(context) - .setTitle(R.string.keyboard__key_sound_package_title) - .setSingleChoiceItems( - all.toTypedArray(), - checked, - ) { _, id -> checked = id } - .setPositiveButton(android.R.string.ok) { _, _ -> - SoundEffectManager.switchSound(all[checked]) - } - .setNegativeButton(android.R.string.cancel, null) - .create() -} diff --git a/app/src/main/java/com/osfans/trime/ui/main/PrefMainActivity.kt b/app/src/main/java/com/osfans/trime/ui/main/PrefMainActivity.kt index 1a3ac6cfa8..aec3a7219a 100644 --- a/app/src/main/java/com/osfans/trime/ui/main/PrefMainActivity.kt +++ b/app/src/main/java/com/osfans/trime/ui/main/PrefMainActivity.kt @@ -4,6 +4,7 @@ package com.osfans.trime.ui.main +import android.app.AlertDialog import android.content.Intent import android.os.Build import android.os.Bundle @@ -13,7 +14,6 @@ import android.view.MenuItem import android.view.ViewGroup import androidx.activity.enableEdgeToEdge import androidx.activity.viewModels -import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatDelegate import androidx.core.view.ViewCompat diff --git a/app/src/main/java/com/osfans/trime/ui/main/settings/ColorPickerDialog.kt b/app/src/main/java/com/osfans/trime/ui/main/settings/ColorPickerDialog.kt new file mode 100644 index 0000000000..562db29980 --- /dev/null +++ b/app/src/main/java/com/osfans/trime/ui/main/settings/ColorPickerDialog.kt @@ -0,0 +1,42 @@ +package com.osfans.trime.ui.main.settings + +import android.app.AlertDialog +import android.content.Context +import androidx.lifecycle.LifecycleCoroutineScope +import com.osfans.trime.R +import com.osfans.trime.data.theme.ColorManager +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext + +object ColorPickerDialog { + suspend fun build( + scope: LifecycleCoroutineScope, + context: Context, + ): AlertDialog { + val all = withContext(Dispatchers.Default) { ColorManager.presetColorSchemes } + val allIds = all.keys + val allNames = all.values.mapNotNull { it["name"] } + val currentId = ColorManager.selectedColor + val currentIndex = all.keys.indexOfFirst { it == currentId } + return AlertDialog.Builder(context).apply { + setTitle(R.string.looks__selected_color_title) + if (all.isEmpty()) { + setMessage(R.string.no_color_to_select) + } else { + setSingleChoiceItems( + allNames.toTypedArray(), + currentIndex, + ) { dialog, which -> + scope.launch { + if (which != currentIndex) { + ColorManager.setColorScheme(allIds.elementAt(which)) + } + dialog.dismiss() + } + } + } + setNegativeButton(android.R.string.cancel, null) + }.create() + } +} diff --git a/app/src/main/java/com/osfans/trime/ui/main/settings/KeySoundEffectPickerDialog.kt b/app/src/main/java/com/osfans/trime/ui/main/settings/KeySoundEffectPickerDialog.kt new file mode 100644 index 0000000000..7ab6aeb69e --- /dev/null +++ b/app/src/main/java/com/osfans/trime/ui/main/settings/KeySoundEffectPickerDialog.kt @@ -0,0 +1,38 @@ +package com.osfans.trime.ui.main.settings + +import android.app.AlertDialog +import android.content.Context +import androidx.lifecycle.LifecycleCoroutineScope +import com.osfans.trime.R +import com.osfans.trime.data.sound.SoundEffectManager +import kotlinx.coroutines.launch + +object KeySoundEffectPickerDialog { + fun build( + scope: LifecycleCoroutineScope, + context: Context, + ): AlertDialog { + val all = SoundEffectManager.getAllSoundEffects().mapNotNull { it.name } + val current = SoundEffectManager.getActiveSoundEffect().getOrNull()?.name ?: "" + val currentIndex = all.indexOfFirst { it == current } + return AlertDialog.Builder(context).apply { + setTitle(R.string.keyboard__key_sound_effect_title) + if (all.isEmpty()) { + setMessage(R.string.no_effect_to_select) + } else { + setSingleChoiceItems( + all.toTypedArray(), + currentIndex, + ) { dialog, which -> + scope.launch { + if (which != currentIndex) { + SoundEffectManager.switchSound(all[which]) + } + dialog.dismiss() + } + } + } + setNegativeButton(android.R.string.cancel, null) + }.create() + } +} diff --git a/app/src/main/java/com/osfans/trime/ui/main/settings/ThemePickerDialog.kt b/app/src/main/java/com/osfans/trime/ui/main/settings/ThemePickerDialog.kt new file mode 100644 index 0000000000..fe13735888 --- /dev/null +++ b/app/src/main/java/com/osfans/trime/ui/main/settings/ThemePickerDialog.kt @@ -0,0 +1,44 @@ +package com.osfans.trime.ui.main.settings + +import android.app.AlertDialog +import android.content.Context +import androidx.lifecycle.LifecycleCoroutineScope +import com.osfans.trime.R +import com.osfans.trime.data.AppPrefs +import com.osfans.trime.data.theme.ThemeManager +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext + +object ThemePickerDialog { + suspend fun build( + scope: LifecycleCoroutineScope, + context: Context, + ): AlertDialog { + val all = + withContext(Dispatchers.IO) { + ThemeManager.getAllThemes() + } + val current = + AppPrefs.defaultInstance().theme.selectedTheme + .substringBeforeLast('.') + val currentIndex = all.indexOfFirst { it == current } + return AlertDialog.Builder(context).apply { + setTitle(R.string.looks__selected_theme_title) + if (all.isEmpty()) { + setMessage(R.string.no_theme_to_select) + } else { + setSingleChoiceItems( + all.toTypedArray(), + currentIndex, + ) { dialog, which -> + scope.launch { + ThemeManager.setNormalTheme(all[which]) + dialog.dismiss() + } + } + } + setNegativeButton(android.R.string.cancel, null) + }.create() + } +} diff --git a/app/src/main/java/com/osfans/trime/util/DialogUtils.kt b/app/src/main/java/com/osfans/trime/util/DialogUtils.kt index af59360851..ed40dbd1d7 100644 --- a/app/src/main/java/com/osfans/trime/util/DialogUtils.kt +++ b/app/src/main/java/com/osfans/trime/util/DialogUtils.kt @@ -4,11 +4,11 @@ package com.osfans.trime.util +import android.app.AlertDialog import android.content.ClipData import android.content.Context import android.view.ViewGroup.MarginLayoutParams import androidx.annotation.StringRes -import androidx.appcompat.app.AlertDialog import androidx.lifecycle.LifecycleCoroutineScope import com.blankj.utilcode.util.ToastUtils import com.osfans.trime.R diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index c7b5211446..d451a81a53 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -138,7 +138,7 @@ SPDX-License-Identifier: GPL-3.0-or-later 已授予存储权限 已拒绝授权存储权限,部署或读取方案和配置功能或不可用 同文输入法需要允许显示在其他应用上方以能显示应用外悬浮窗或对话框,点击“确定”以授权。 - 按键音效包 + 按键音效 正在应用音效... 草稿箱历史记录上限 草稿箱过滤规则 @@ -278,6 +278,9 @@ SPDX-License-Identifier: GPL-3.0-or-later 方案 选择当前方案或启用更多方案 导航栏背景 + 当前没有主题可选择。 + 当前没有配色方案可选择。 + 当前没有按键音效可选择。 无背景 跟随键盘背景色 diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 585ac1fee0..f47df9a839 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -141,7 +141,7 @@ SPDX-License-Identifier: GPL-3.0-or-later 已授予儲存許可權 已拒絕授權儲存許可權,部署或讀取方案和配置功能或不可用 同文輸入法需要允許顯示在其他應用上方以能顯示應用外懸浮窗或對話方塊,點選“確定”以授權。 - 按鍵音效包 + 按鍵音效 正在應用音效... 草稿箱歷史記錄上限 草稿箱過濾規則 @@ -279,6 +279,9 @@ SPDX-License-Identifier: GPL-3.0-or-later 方案 選擇當前方案或啓用更多方案 導航欄背景 + 當前沒有主題可選擇。 + 當前沒有配色方案可選擇。 + 當前沒有按鍵音效可選擇。 無背景 跟隨鍵盤背景色 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index aa33798c60..ed65bf0fa7 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -145,7 +145,7 @@ SPDX-License-Identifier: GPL-3.0-or-later External storage permission is granted External storage permission was denied, deployment or reading schemas and config may not be available Trime needs alert window permission to show up popup window or dialog, tap OK to grant the permission. - Key Sound Package + Key Sound Effect Loading sound... Draft History Limit Draft Filter @@ -280,6 +280,9 @@ SPDX-License-Identifier: GPL-3.0-or-later Schemata Select current schema or enable more schemata Navigation bar background + Currently there is no theme to select. + Currently there is no color scheme to select. + Currently there is no key sound effect to select. No background Follow keyboard color diff --git a/app/src/main/res/xml/keyboard_preference.xml b/app/src/main/res/xml/keyboard_preference.xml index f06c27b89a..0236d415cf 100644 --- a/app/src/main/res/xml/keyboard_preference.xml +++ b/app/src/main/res/xml/keyboard_preference.xml @@ -192,7 +192,7 @@ SPDX-License-Identifier: GPL-3.0-or-later app:iconSpaceReserved="false" />