From bf713d69672c5a8e3439f0d1a69ed8f3092a3d34 Mon Sep 17 00:00:00 2001 From: Helium314 Date: Mon, 10 Mar 2025 18:27:45 +0100 Subject: [PATCH 01/36] copy user-supplied library to final file instead of renaming apparently fixes #1251 --- .../java/helium314/keyboard/latin/settings/Defaults.kt | 3 --- .../main/java/helium314/keyboard/latin/utils/JniUtils.java | 3 +-- .../settings/preferences/LoadGestureLibPreference.kt | 7 +++++-- 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/helium314/keyboard/latin/settings/Defaults.kt b/app/src/main/java/helium314/keyboard/latin/settings/Defaults.kt index 40b2bd6c..689087f9 100644 --- a/app/src/main/java/helium314/keyboard/latin/settings/Defaults.kt +++ b/app/src/main/java/helium314/keyboard/latin/settings/Defaults.kt @@ -9,7 +9,6 @@ import helium314.keyboard.keyboard.KeyboardTheme import helium314.keyboard.latin.BuildConfig import helium314.keyboard.latin.common.Constants.Separators import helium314.keyboard.latin.common.Constants.Subtype.ExtraValue -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 @@ -152,8 +151,6 @@ object Defaults { const val PREF_EMOJI_RECENT_KEYS = "" const val PREF_LAST_SHOWN_EMOJI_CATEGORY_PAGE_ID = 0 const val PREF_PINNED_CLIPS = "" - @JvmField - val PREF_LIBRARY_CHECKSUM: String = JniUtils.expectedDefaultChecksum() const val PREF_SHOW_DEBUG_SETTINGS = false val PREF_DEBUG_MODE = BuildConfig.DEBUG const val PREF_SHOW_SUGGESTION_INFOS = false diff --git a/app/src/main/java/helium314/keyboard/latin/utils/JniUtils.java b/app/src/main/java/helium314/keyboard/latin/utils/JniUtils.java index 603e32ab..6bae92d5 100644 --- a/app/src/main/java/helium314/keyboard/latin/utils/JniUtils.java +++ b/app/src/main/java/helium314/keyboard/latin/utils/JniUtils.java @@ -13,7 +13,6 @@ import android.text.TextUtils; import helium314.keyboard.latin.App; import helium314.keyboard.latin.BuildConfig; -import helium314.keyboard.latin.settings.Defaults; import helium314.keyboard.latin.settings.Settings; import java.io.File; @@ -63,7 +62,7 @@ public final class JniUtils { // we want the default preferences, because storing the checksum in device protected storage is discouraged // see https://developer.android.com/reference/android/content/Context#createDeviceProtectedStorageContext() // if device is locked, this will throw an IllegalStateException - wantedChecksum = KtxKt.protectedPrefs(app).getString(Settings.PREF_LIBRARY_CHECKSUM, Defaults.PREF_LIBRARY_CHECKSUM); + wantedChecksum = KtxKt.protectedPrefs(app).getString(Settings.PREF_LIBRARY_CHECKSUM, expectedDefaultChecksum()); } final FileInputStream libStream = new FileInputStream(userSuppliedLibrary); final String checksum = ChecksumCalculator.INSTANCE.checksum(libStream); diff --git a/app/src/main/java/helium314/keyboard/settings/preferences/LoadGestureLibPreference.kt b/app/src/main/java/helium314/keyboard/settings/preferences/LoadGestureLibPreference.kt index 591d4a5c..5b51bdbe 100644 --- a/app/src/main/java/helium314/keyboard/settings/preferences/LoadGestureLibPreference.kt +++ b/app/src/main/java/helium314/keyboard/settings/preferences/LoadGestureLibPreference.kt @@ -35,10 +35,13 @@ fun LoadGestureLibPreference(setting: Setting) { val abi = Build.SUPPORTED_ABIS[0] val libFile = File(ctx.filesDir?.absolutePath + File.separator + JniUtils.JNI_LIB_IMPORT_FILE_NAME) fun renameToLibFileAndRestart(file: File, checksum: String) { + libFile.setWritable(true) libFile.delete() - // store checksum in default preferences (soo JniUtils) + // store checksum in default preferences (see JniUtils) prefs.edit().putString(Settings.PREF_LIBRARY_CHECKSUM, checksum).commit() - file.renameTo(libFile) + file.copyTo(libFile) + libFile.setReadOnly() + file.delete() Runtime.getRuntime().exit(0) // exit will restart the app, so library will be loaded } var tempFilePath: String? by rememberSaveable { mutableStateOf(null) } From d05a59e4edb866c52889f38f27ecb9cf70e75971 Mon Sep 17 00:00:00 2001 From: unlair <593746+unlair@users.noreply.github.com> Date: Tue, 11 Mar 2025 16:25:32 -0400 Subject: [PATCH 02/36] Track overridden subtypes when auto-switching due to HintLocales (#1410) * Track overridden subtypes when auto-switching due to HintLocales * Move hint-locale switching logic to SubtypeState --- .../helium314/keyboard/latin/LatinIME.java | 89 ++++++++++++++++--- 1 file changed, 75 insertions(+), 14 deletions(-) diff --git a/app/src/main/java/helium314/keyboard/latin/LatinIME.java b/app/src/main/java/helium314/keyboard/latin/LatinIME.java index d2e75a45..f18c530e 100644 --- a/app/src/main/java/helium314/keyboard/latin/LatinIME.java +++ b/app/src/main/java/helium314/keyboard/latin/LatinIME.java @@ -523,6 +523,11 @@ public class LatinIME extends InputMethodService implements } final class SubtypeState { + // When HintLocales causes a subtype override, we store + // the overridden subtype here in order to restore it when + // we switch to another input context that has no HintLocales. + private InputMethodSubtype mOverriddenByLocale; + private InputMethodSubtype mLastActiveSubtype; private boolean mCurrentSubtypeHasBeenUsed = true; // starting with true avoids immediate switch @@ -530,6 +535,70 @@ public class LatinIME extends InputMethodService implements mCurrentSubtypeHasBeenUsed = true; } + // TextFields can provide locale/language hints that the IME should use via 'hintLocales'. + // If a matching subtype is found, we temporarily switch to that subtype until + // we return to a context that does not provide any hints, or until the user + // explicitly changes the language/subtype in use. + public InputMethodSubtype getSubtypeForLocales(final RichInputMethodManager richImm, final Iterable locales) { + final InputMethodSubtype overriddenByLocale = mOverriddenByLocale; + if (locales == null) { + if (overriddenByLocale != null) { + // no locales provided, so switch back to + // whatever subtype was used last time. + mOverriddenByLocale = null; + + return overriddenByLocale; + } + + return null; + } + + final InputMethodSubtype currentSubtype = richImm.getCurrentSubtype().getRawSubtype(); + final Locale currentSubtypeLocale = richImm.getCurrentSubtypeLocale(); + final int minimumMatchLevel = 3; // LocaleUtils.LOCALE_LANGUAGE_MATCH_COUNTRY_DIFFER; + + // Try finding a subtype matching the hint language. + for (final Locale hintLocale : locales) { + if (LocaleUtils.INSTANCE.getMatchLevel(hintLocale, currentSubtypeLocale) >= minimumMatchLevel + || CollectionsKt.any(mSettings.getCurrent().mSecondaryLocales, + (secLocale) -> LocaleUtils.INSTANCE.getMatchLevel(hintLocale, secLocale) >= minimumMatchLevel)) { + // current locales are already a good match, and we want to avoid unnecessary layout switches. + return null; + } + + final InputMethodSubtype subtypeForHintLocale = richImm.findSubtypeForHintLocale(hintLocale); + if (subtypeForHintLocale == null) { + continue; + } + + if (subtypeForHintLocale.equals(currentSubtype)) { + // no need to switch, we already use the correct locale. + return null; + } + + if (overriddenByLocale == null) { + // auto-switching based on hint locale, so store + // whatever subtype was in use so we can switch back + // to it later when there are no hint locales. + mOverriddenByLocale = currentSubtype; + } + + return subtypeForHintLocale; + } + + return null; + } + + public void onSubtypeChanged(final InputMethodSubtype oldSubtype, + final InputMethodSubtype newSubtype) { + if (oldSubtype != mOverriddenByLocale) { + // Whenever the subtype is changed, clear tracking + // the subtype that is overridden by a HintLocale as + // we no longer have a subtype to automatically switch back to. + mOverriddenByLocale = null; + } + } + public void switchSubtype(final RichInputMethodManager richImm) { final InputMethodSubtype currentSubtype = richImm.getCurrentSubtype().getRawSubtype(); final InputMethodSubtype lastActiveSubtype = mLastActiveSubtype; @@ -858,6 +927,8 @@ public class LatinIME extends InputMethodService implements return; } InputMethodSubtype oldSubtype = mRichImm.getCurrentSubtype().getRawSubtype(); + + mSubtypeState.onSubtypeChanged(oldSubtype, subtype); StatsUtils.onSubtypeChanged(oldSubtype, subtype); mRichImm.onSubtypeChanged(subtype); mInputLogic.onSubtypeChanged(SubtypeLocaleUtils.getCombiningRulesExtraValue(subtype), @@ -876,20 +947,10 @@ public class LatinIME extends InputMethodService implements super.onStartInput(editorInfo, restarting); final List hintLocales = EditorInfoCompatUtils.getHintLocales(editorInfo); - if (hintLocales == null) { - return; - } - // Try switching to a subtype matching the hint language. - for (final Locale hintLocale : hintLocales) { - if (LocaleUtils.INSTANCE.getMatchLevel(hintLocale, mRichImm.getCurrentSubtypeLocale()) >= 3 - || CollectionsKt.any(mSettings.getCurrent().mSecondaryLocales, (secLocale) -> LocaleUtils.INSTANCE.getMatchLevel(hintLocale, secLocale) >= 3)) - return; // current locales are already a good match, and we want to avoid unnecessary layout switches - final InputMethodSubtype newSubtype = mRichImm.findSubtypeForHintLocale(hintLocale); - if (newSubtype == null) continue; - if (newSubtype.equals(mRichImm.getCurrentSubtype().getRawSubtype())) - return; // no need to switch, we already use the correct locale - mHandler.postSwitchLanguage(newSubtype); - break; + final InputMethodSubtype subtypeForLocales = mSubtypeState.getSubtypeForLocales(mRichImm, hintLocales); + if (subtypeForLocales != null) { + // found a better subtype using hint locales that we should switch to. + mHandler.postSwitchLanguage(subtypeForLocales); } } From 18a328cd2b455f6594796b0f1783252b44052bf9 Mon Sep 17 00:00:00 2001 From: Eran Leshem <1707552+eranl@users.noreply.github.com> Date: Thu, 13 Mar 2025 17:31:03 +0200 Subject: [PATCH 03/36] Show TLD popup keys (#1399) * Add option to replace period key's popup keys with the locale-specific top level domains for URL and email inputs. On by default. Also change the wide keyboard's '.com' key to use the same TLD list. Tweak TLD list order, putting default ones first, so that .com is the first TLD. * Enable TLD hint Avoid TLD popups on tablet Revert to using set for TLDs, and insert default ones first Move setting one slot up Tweak setting description Update docs * Preserve case on period key * Prevent non-TLD hints on period key --- README.md | 2 -- .../layouts/functional/functional_keys.json | 2 +- .../keyboard_parser/LocaleKeyboardInfos.kt | 21 +++++++------ .../keyboard_parser/floris/TextKeyData.kt | 31 ++++++++++++++----- .../keyboard/latin/settings/Defaults.kt | 1 + .../keyboard/latin/settings/Settings.java | 1 + .../latin/settings/SettingsValues.java | 2 ++ .../settings/screens/PreferencesScreen.kt | 7 +++++ app/src/main/res/values/strings.xml | 4 +++ layouts.md | 2 +- 10 files changed, 52 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index ae62abc0..113f49dc 100644 --- a/README.md +++ b/README.md @@ -100,8 +100,6 @@ __Planned features and improvements:__ * Add and enable emoji dictionaries by default (if available for language) * Clearer / more intuitive arrangement of settings * Maybe hide some less used settings by default (similar to color customization) -* Make use of the `.com` key in URL fields (currently only available for tablets) - * With language-dependent TLDs * [Bug fixes](https://github.com/Helium314/HeliBoard/issues?q=is%3Aissue+is%3Aopen+label%3Abug) __What will _not_ be added:__ diff --git a/app/src/main/assets/layouts/functional/functional_keys.json b/app/src/main/assets/layouts/functional/functional_keys.json index 6d28dd24..788e4479 100644 --- a/app/src/main/assets/layouts/functional/functional_keys.json +++ b/app/src/main/assets/layouts/functional/functional_keys.json @@ -15,7 +15,7 @@ { "$": "keyboard_state_selector", "emojiKeyEnabled": { "$": "keyboard_state_selector", "alphabet": { "label": "emoji" }}}, { "$": "keyboard_state_selector", "symbols": { "label": "numpad" }}, { "label": "space" }, - { "label": "period", "labelFlags": 1073741824 }, + { "label": "period" }, { "label": "action", "width": 0.15 } ] ] diff --git a/app/src/main/java/helium314/keyboard/keyboard/internal/keyboard_parser/LocaleKeyboardInfos.kt b/app/src/main/java/helium314/keyboard/keyboard/internal/keyboard_parser/LocaleKeyboardInfos.kt index 260eb957..eba17161 100644 --- a/app/src/main/java/helium314/keyboard/keyboard/internal/keyboard_parser/LocaleKeyboardInfos.kt +++ b/app/src/main/java/helium314/keyboard/keyboard/internal/keyboard_parser/LocaleKeyboardInfos.kt @@ -44,7 +44,7 @@ class LocaleKeyboardInfos(dataStream: InputStream?, locale: Locale) { "mns" -> Key.LABEL_FLAGS_FOLLOW_KEY_LETTER_RATIO else -> 0 } - val tlds = getLocaleTlds(locale) // todo: USE IT + val tlds = getLocaleTlds(locale) init { readStream(dataStream, false, true) @@ -89,12 +89,6 @@ class LocaleKeyboardInfos(dataStream: InputStream?, locale: Locale) { } } - fun addDefaultTlds(locale: Locale) { - if ((locale.language != "en" && euroLocales.matches(locale.language)) || euroCountries.matches(locale.country)) - tlds.add(".eu") - tlds.addAll(defaultTlds.splitOnWhitespace()) - } - /** Pair(extraKeysLeft, extraKeysRight) */ fun getTabletExtraKeys(elementId: Int): Pair, List> { val flags = Key.LABEL_FLAGS_FONT_DEFAULT @@ -205,7 +199,6 @@ private fun createLocaleKeyTexts(context: Context, params: KeyboardParams, popup if (locale == params.mId.locale) return@forEach lkt.addFile(getStreamForLocale(locale, context), true) } - lkt.addDefaultTlds(params.mId.locale) when (popupKeysSetting) { POPUP_KEYS_MAIN -> lkt.addFile(context.assets.open("$LOCALE_TEXTS_FOLDER/more_popups_main.txt"), false) POPUP_KEYS_MORE -> lkt.addFile(context.assets.open("$LOCALE_TEXTS_FOLDER/more_popups_more.txt"), false) @@ -227,19 +220,27 @@ private fun getStreamForLocale(locale: Locale, context: Context) = } private fun getLocaleTlds(locale: Locale): LinkedHashSet { + val tlds = getDefaultTlds(locale) val ccLower = locale.country.lowercase() - val tlds = LinkedHashSet() if (ccLower.isEmpty() || locale.language == SubtypeLocaleUtils.NO_LANGUAGE) return tlds specialCountryTlds.forEach { if (ccLower != it.first) return@forEach tlds.addAll(it.second.splitOnWhitespace()) - return tlds + return@getLocaleTlds tlds } tlds.add(".$ccLower") return tlds } +private fun getDefaultTlds(locale: Locale): LinkedHashSet { + val tlds = linkedSetOf() + tlds.addAll(defaultTlds.splitOnWhitespace()) + if ((locale.language != "en" && euroLocales.matches(locale.language)) || euroCountries.matches(locale.country)) + tlds.add(".eu") + return tlds +} + fun clearCache() = localeKeyboardInfosCache.clear() // cache the texts, so they don't need to be read over and over diff --git a/app/src/main/java/helium314/keyboard/keyboard/internal/keyboard_parser/floris/TextKeyData.kt b/app/src/main/java/helium314/keyboard/keyboard/internal/keyboard_parser/floris/TextKeyData.kt index eff71549..757ea9a5 100644 --- a/app/src/main/java/helium314/keyboard/keyboard/internal/keyboard_parser/floris/TextKeyData.kt +++ b/app/src/main/java/helium314/keyboard/keyboard/internal/keyboard_parser/floris/TextKeyData.kt @@ -24,6 +24,7 @@ import helium314.keyboard.latin.common.StringUtils import helium314.keyboard.latin.settings.Settings import helium314.keyboard.latin.spellcheck.AndroidSpellCheckerService import helium314.keyboard.latin.utils.InputTypeUtils +import helium314.keyboard.latin.utils.LayoutType import helium314.keyboard.latin.utils.Log import helium314.keyboard.latin.utils.ToolbarKey import helium314.keyboard.latin.utils.getCodeForToolbarKey @@ -482,8 +483,7 @@ sealed interface KeyData : AbstractKeyData { KeyLabel.DELETE -> "!icon/delete_key|!code/key_delete" KeyLabel.SHIFT -> "${getShiftLabel(params)}|!code/key_shift" // KeyLabel.EMOJI -> "!icon/emoji_normal_key|!code/key_emoji" - // todo (later): label and popupKeys for .com should be in localeKeyTexts, handled similar to currency key - KeyLabel.COM -> ".com" + KeyLabel.COM -> params.mLocaleKeyboardInfos.tlds.first() KeyLabel.LANGUAGE_SWITCH -> "!icon/language_switch_key|!code/key_language_switch" KeyLabel.ZWNJ -> "!icon/zwnj_key|\u200C" KeyLabel.CURRENCY -> params.mLocaleKeyboardInfos.currencyKey.first @@ -526,8 +526,11 @@ sealed interface KeyData : AbstractKeyData { return when (label) { KeyLabel.ALPHA, KeyLabel.SYMBOL_ALPHA, KeyLabel.SYMBOL -> Key.LABEL_FLAGS_PRESERVE_CASE or Key.LABEL_FLAGS_FOLLOW_FUNCTIONAL_TEXT_COLOR KeyLabel.COMMA -> Key.LABEL_FLAGS_HAS_POPUP_HINT - // essentially this only changes the appearance of the armenian period key in holo theme - KeyLabel.PERIOD -> Key.LABEL_FLAGS_HAS_POPUP_HINT and if (params.mId.isAlphabetKeyboard) params.mLocaleKeyboardInfos.labelFlags else 0 + // essentially the first term only changes the appearance of the armenian period key in holo theme + KeyLabel.PERIOD -> (Key.LABEL_FLAGS_HAS_POPUP_HINT and + if (params.mId.isAlphabetKeyboard) params.mLocaleKeyboardInfos.labelFlags else 0) or + (if (shouldShowTldPopups(params)) 0 else Key.LABEL_FLAGS_DISABLE_HINT_LABEL) or + Key.LABEL_FLAGS_PRESERVE_CASE KeyLabel.ACTION -> { Key.LABEL_FLAGS_PRESERVE_CASE or Key.LABEL_FLAGS_AUTO_X_SCALE or Key.LABEL_FLAGS_FOLLOW_KEY_LABEL_RATIO or Key.LABEL_FLAGS_FOLLOW_FUNCTIONAL_TEXT_COLOR or @@ -546,12 +549,12 @@ sealed interface KeyData : AbstractKeyData { private fun getAdditionalPopupKeys(params: KeyboardParams): PopupSet? { if (groupId == GROUP_COMMA) return SimplePopups(getCommaPopupKeys(params)) - if (groupId == GROUP_PERIOD) return SimplePopups(getPunctuationPopupKeys(params)) + if (groupId == GROUP_PERIOD) return getPeriodPopups(params) if (groupId == GROUP_ENTER) return getActionKeyPopupKeys(params) if (groupId == GROUP_NO_DEFAULT_POPUP) return null return when (label) { KeyLabel.COMMA -> SimplePopups(getCommaPopupKeys(params)) - KeyLabel.PERIOD -> SimplePopups(getPunctuationPopupKeys(params)) + KeyLabel.PERIOD -> getPeriodPopups(params) KeyLabel.ACTION -> getActionKeyPopupKeys(params) KeyLabel.SHIFT -> { if (params.mId.isAlphabetKeyboard) SimplePopups( @@ -561,13 +564,27 @@ sealed interface KeyData : AbstractKeyData { ) ) else null // why the alphabet popup keys actually? } - KeyLabel.COM -> SimplePopups(listOf(Key.POPUP_KEYS_HAS_LABELS, ".net", ".org", ".gov", ".edu")) + KeyLabel.COM -> SimplePopups( + listOf(Key.POPUP_KEYS_HAS_LABELS).plus(params.mLocaleKeyboardInfos.tlds.drop(1)) + ) + KeyLabel.ZWNJ -> SimplePopups(listOf("!icon/zwj_key|\u200D")) // only add currency popups if there are none defined on the key KeyLabel.CURRENCY -> if (popup.isEmpty()) SimplePopups(params.mLocaleKeyboardInfos.currencyKey.second) else null else -> null } } + + private fun getPeriodPopups(params: KeyboardParams): SimplePopups = + SimplePopups( + if (shouldShowTldPopups(params)) params.mLocaleKeyboardInfos.tlds + else getPunctuationPopupKeys(params) + ) + + private fun shouldShowTldPopups(params: KeyboardParams): Boolean = + (Settings.getInstance().current.mShowTldPopupKeys + && params.mId.mSubtype.layouts[LayoutType.FUNCTIONAL] != "functional_keys_tablet" + && params.mId.mMode in setOf(KeyboardId.MODE_URL, KeyboardId.MODE_EMAIL)) } /** diff --git a/app/src/main/java/helium314/keyboard/latin/settings/Defaults.kt b/app/src/main/java/helium314/keyboard/latin/settings/Defaults.kt index 689087f9..8e1261c0 100644 --- a/app/src/main/java/helium314/keyboard/latin/settings/Defaults.kt +++ b/app/src/main/java/helium314/keyboard/latin/settings/Defaults.kt @@ -122,6 +122,7 @@ object Defaults { const val PREF_POPUP_KEYS_ORDER = POPUP_KEYS_ORDER_DEFAULT const val PREF_POPUP_KEYS_LABELS_ORDER = POPUP_KEYS_LABEL_DEFAULT const val PREF_SHOW_POPUP_HINTS = false + const val PREF_SHOW_TLD_POPUP_KEYS = true const val PREF_MORE_POPUP_KEYS = "main" const val PREF_SPACE_TO_CHANGE_LANG = true const val PREF_LANGUAGE_SWIPE_DISTANCE = 5 diff --git a/app/src/main/java/helium314/keyboard/latin/settings/Settings.java b/app/src/main/java/helium314/keyboard/latin/settings/Settings.java index 1510a65b..8d9e7bef 100644 --- a/app/src/main/java/helium314/keyboard/latin/settings/Settings.java +++ b/app/src/main/java/helium314/keyboard/latin/settings/Settings.java @@ -131,6 +131,7 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang public static final String PREF_POPUP_KEYS_LABELS_ORDER = "popup_keys_labels_order"; public static final String PREF_SHOW_POPUP_HINTS = "show_popup_hints"; public static final String PREF_MORE_POPUP_KEYS = "more_popup_keys"; + public static final String PREF_SHOW_TLD_POPUP_KEYS = "show_tld_popup_keys"; public static final String PREF_SPACE_TO_CHANGE_LANG = "prefs_long_press_keyboard_to_change_lang"; public static final String PREF_LANGUAGE_SWIPE_DISTANCE = "language_swipe_distance"; diff --git a/app/src/main/java/helium314/keyboard/latin/settings/SettingsValues.java b/app/src/main/java/helium314/keyboard/latin/settings/SettingsValues.java index 8576bc1d..25c2ec15 100644 --- a/app/src/main/java/helium314/keyboard/latin/settings/SettingsValues.java +++ b/app/src/main/java/helium314/keyboard/latin/settings/SettingsValues.java @@ -65,6 +65,7 @@ public class SettingsValues { public final boolean mShowNumberRowHints; public final boolean mShowsHints; public final boolean mShowsPopupHints; + public final boolean mShowTldPopupKeys; public final boolean mSpaceForLangChange; public final boolean mShowsEmojiKey; public final boolean mVarToolbarDirection; @@ -172,6 +173,7 @@ public class SettingsValues { mShowNumberRowHints = prefs.getBoolean(Settings.PREF_SHOW_NUMBER_ROW_HINTS, Defaults.PREF_SHOW_NUMBER_ROW_HINTS); mShowsHints = prefs.getBoolean(Settings.PREF_SHOW_HINTS, Defaults.PREF_SHOW_HINTS); mShowsPopupHints = prefs.getBoolean(Settings.PREF_SHOW_POPUP_HINTS, Defaults.PREF_SHOW_POPUP_HINTS); + mShowTldPopupKeys = prefs.getBoolean(Settings.PREF_SHOW_TLD_POPUP_KEYS, Defaults.PREF_SHOW_TLD_POPUP_KEYS); mSpaceForLangChange = prefs.getBoolean(Settings.PREF_SPACE_TO_CHANGE_LANG, Defaults.PREF_SPACE_TO_CHANGE_LANG); mShowsEmojiKey = prefs.getBoolean(Settings.PREF_SHOW_EMOJI_KEY, Defaults.PREF_SHOW_EMOJI_KEY); mVarToolbarDirection = prefs.getBoolean(Settings.PREF_VARIABLE_TOOLBAR_DIRECTION, Defaults.PREF_VARIABLE_TOOLBAR_DIRECTION); diff --git a/app/src/main/java/helium314/keyboard/settings/screens/PreferencesScreen.kt b/app/src/main/java/helium314/keyboard/settings/screens/PreferencesScreen.kt index 17486bae..d7e88c84 100644 --- a/app/src/main/java/helium314/keyboard/settings/screens/PreferencesScreen.kt +++ b/app/src/main/java/helium314/keyboard/settings/screens/PreferencesScreen.kt @@ -46,6 +46,7 @@ fun PreferencesScreen( Settings.PREF_POPUP_KEYS_LABELS_ORDER else null, Settings.PREF_POPUP_KEYS_ORDER, Settings.PREF_SHOW_POPUP_HINTS, + Settings.PREF_SHOW_TLD_POPUP_KEYS, Settings.PREF_POPUP_ON, if (AudioAndHapticFeedbackManager.getInstance().hasVibrator()) Settings.PREF_VIBRATE_ON else null, @@ -89,6 +90,12 @@ fun createPreferencesSettings(context: Context) = listOf( Setting(context, Settings.PREF_POPUP_KEYS_ORDER, R.string.popup_order) { ReorderSwitchPreference(it, Defaults.PREF_POPUP_KEYS_ORDER) }, + Setting( + context, Settings.PREF_SHOW_TLD_POPUP_KEYS, R.string.show_tld_popup_keys, + R.string.show_tld_popup_keys_summary + ) { + SwitchPreference(it, Defaults.PREF_SHOW_TLD_POPUP_KEYS) { KeyboardSwitcher.getInstance().setThemeNeedsReload() } + }, Setting(context, Settings.PREF_SHOW_POPUP_HINTS, R.string.show_popup_hints, R.string.show_popup_hints_summary) { SwitchPreference(it, Defaults.PREF_SHOW_POPUP_HINTS) { KeyboardSwitcher.getInstance().setThemeNeedsReload() } }, diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 903b3cbd..e6bb1d30 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -249,6 +249,10 @@ Select hint source Select popup key order + + Show TLD popup keys + + Replace period key popups with top level domains when typing URLs and email addresses Number row Language diff --git a/layouts.md b/layouts.md index 2af0f562..b442e934 100644 --- a/layouts.md +++ b/layouts.md @@ -89,7 +89,7 @@ Usually the label is what is displayed on the key. However, there are some speci * _symbol_alpha_: toggle alpha / symbol keyboard * _numpad_: toggle numpad layout * _emoji_: switch to emoji view - * _com_: display common TLDs (.com and similar, currently not localized) + * _com_: display common TLDs (.com and similar, localized) * _language_switch_: language switch key * _action_: the action (enter) key * _delete_: delete key From d3401e5c0490d18b87a299e3d0eb3d5c5368a639 Mon Sep 17 00:00:00 2001 From: Helium314 Date: Fri, 14 Mar 2025 22:57:00 +0100 Subject: [PATCH 04/36] re-add background to app icon in about screen --- .../java/helium314/keyboard/settings/Misc.kt | 25 ++++++++++++++++++- .../settings/preferences/Preference.kt | 3 ++- .../keyboard/settings/screens/AboutScreen.kt | 2 +- 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/app/src/main/java/helium314/keyboard/settings/Misc.kt b/app/src/main/java/helium314/keyboard/settings/Misc.kt index 05925afb..d295c2eb 100644 --- a/app/src/main/java/helium314/keyboard/settings/Misc.kt +++ b/app/src/main/java/helium314/keyboard/settings/Misc.kt @@ -1,13 +1,18 @@ // SPDX-License-Identifier: GPL-3.0-only package helium314.keyboard.settings +import android.graphics.drawable.VectorDrawable +import androidx.annotation.DrawableRes +import androidx.compose.foundation.Image import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size import androidx.compose.material3.DropdownMenu import androidx.compose.material3.DropdownMenuItem +import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable @@ -17,8 +22,13 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.asImageBitmap +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.painterResource import androidx.compose.ui.unit.dp - +import androidx.core.content.ContextCompat +import androidx.core.graphics.drawable.toBitmap +import androidx.core.util.TypedValueCompat @Composable fun WithSmallTitle( @@ -31,6 +41,19 @@ fun WithSmallTitle( } } +/** Icon if resource is a vector image, (bitmap) Image otherwise */ +@Composable +fun IconOrImage(@DrawableRes resId: Int, name: String?, sizeDp: Float) { + val ctx = LocalContext.current + val drawable = ContextCompat.getDrawable(ctx, resId) + if (drawable is VectorDrawable) + Icon(painterResource(resId), name, Modifier.size(sizeDp.dp)) + else { + val px = TypedValueCompat.dpToPx(sizeDp, ctx.resources.displayMetrics).toInt() + Image(drawable!!.toBitmap(px, px).asImageBitmap(), name) + } +} + @Composable fun DropDownField( items: List, diff --git a/app/src/main/java/helium314/keyboard/settings/preferences/Preference.kt b/app/src/main/java/helium314/keyboard/settings/preferences/Preference.kt index 33cd45b6..00a30c23 100644 --- a/app/src/main/java/helium314/keyboard/settings/preferences/Preference.kt +++ b/app/src/main/java/helium314/keyboard/settings/preferences/Preference.kt @@ -29,6 +29,7 @@ import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import helium314.keyboard.latin.R +import helium314.keyboard.settings.IconOrImage import helium314.keyboard.settings.Theme import helium314.keyboard.settings.previewDark @@ -69,7 +70,7 @@ fun Preference( verticalAlignment = Alignment.CenterVertically ) { if (icon != null) - Icon(painterResource(icon), name, modifier = Modifier.size(36.dp)) + IconOrImage(icon, name, 36f) Column(modifier = Modifier.weight(1f)) { Text(text = name, style = MaterialTheme.typography.bodyLarge) if (description != null) { diff --git a/app/src/main/java/helium314/keyboard/settings/screens/AboutScreen.kt b/app/src/main/java/helium314/keyboard/settings/screens/AboutScreen.kt index 0b827952..56281034 100644 --- a/app/src/main/java/helium314/keyboard/settings/screens/AboutScreen.kt +++ b/app/src/main/java/helium314/keyboard/settings/screens/AboutScreen.kt @@ -69,7 +69,7 @@ fun createAboutSettings(context: Context) = listOf( name = it.title, description = it.description, onClick = { }, - icon = R.drawable.ic_launcher_foreground // use the bitmap trick here if we really want the colored icon + icon = R.mipmap.ic_launcher_round ) }, Setting(context, SettingsWithoutKey.VERSION, R.string.version) { From 55259b2915f1e2298beebba4f0f3c322318f25bf Mon Sep 17 00:00:00 2001 From: Helium314 Date: Fri, 14 Mar 2025 23:21:41 +0100 Subject: [PATCH 05/36] fix disappearing all_colors for dark theme on upgrade from 2.3 --- app/src/main/java/helium314/keyboard/latin/App.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/helium314/keyboard/latin/App.kt b/app/src/main/java/helium314/keyboard/latin/App.kt index 6172dac5..c2d91df5 100644 --- a/app/src/main/java/helium314/keyboard/latin/App.kt +++ b/app/src/main/java/helium314/keyboard/latin/App.kt @@ -232,7 +232,7 @@ fun checkVersionUpgrade(context: Context) { KeyboardTheme.writeUserMoreColors(prefs, themeNameNight, moreColorsNight) } if (prefs.contains("theme_dark_color_all_colors")) { - val allColorsNight = readAllColorsMap(false) + val allColorsNight = readAllColorsMap(true) prefs.edit().remove("theme_dark_color_all_colors").apply() KeyboardTheme.writeUserAllColors(prefs, themeNameNight, allColorsNight) } From ba881296410a39fe16bfe558495e0e4b97fd6449 Mon Sep 17 00:00:00 2001 From: Helium314 Date: Sat, 15 Mar 2025 09:06:10 +0100 Subject: [PATCH 06/36] make navigation transistion animation duration follow system transition animation scale --- .../keyboard/settings/SettingsNavHost.kt | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/helium314/keyboard/settings/SettingsNavHost.kt b/app/src/main/java/helium314/keyboard/settings/SettingsNavHost.kt index f3773125..761610a5 100644 --- a/app/src/main/java/helium314/keyboard/settings/SettingsNavHost.kt +++ b/app/src/main/java/helium314/keyboard/settings/SettingsNavHost.kt @@ -1,11 +1,16 @@ // SPDX-License-Identifier: GPL-3.0-only package helium314.keyboard.settings +import android.provider.Settings +import android.provider.Settings.Global +import androidx.compose.animation.core.tween import androidx.compose.animation.slideInHorizontally import androidx.compose.animation.slideOutHorizontally import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState +import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalLayoutDirection +import androidx.compose.ui.unit.IntOffset import androidx.compose.ui.unit.LayoutDirection import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable @@ -41,6 +46,10 @@ fun SettingsNavHost( val dir = if (LocalLayoutDirection.current == LayoutDirection.Ltr) 1 else -1 val target = SettingsDestination.navTarget.collectAsState() + // duration does not change when system setting changes, but that's rare enough to not care + val duration = (250 * Settings.System.getFloat(LocalContext.current.contentResolver, Global.TRANSITION_ANIMATION_SCALE, 1f)).toInt() + val animation = tween(durationMillis = duration) + fun goBack() { if (!navController.popBackStack()) onClickBack() } @@ -48,10 +57,10 @@ fun SettingsNavHost( NavHost( navController = navController, startDestination = startDestination ?: SettingsDestination.Settings, - enterTransition = { slideInHorizontally(initialOffsetX = { +it * dir }) }, - exitTransition = { slideOutHorizontally(targetOffsetX = { -it * dir }) }, - popEnterTransition = { slideInHorizontally(initialOffsetX = { -it * dir }) }, - popExitTransition = { slideOutHorizontally(targetOffsetX = { +it * dir }) } + enterTransition = { slideInHorizontally(initialOffsetX = { +it * dir }, animationSpec = animation) }, + exitTransition = { slideOutHorizontally(targetOffsetX = { -it * dir }, animationSpec = animation) }, + popEnterTransition = { slideInHorizontally(initialOffsetX = { -it * dir }, animationSpec = animation) }, + popExitTransition = { slideOutHorizontally(targetOffsetX = { +it * dir }, animationSpec = animation) } ) { composable(SettingsDestination.Settings) { MainSettingsScreen( From a6b6d1b659f70edad816a9c6fe3f279e41fb5902 Mon Sep 17 00:00:00 2001 From: Quantom2 <113715737+Quantom2@users.noreply.github.com> Date: Sat, 15 Mar 2025 15:05:05 +0200 Subject: [PATCH 07/36] Rework of UK and RU standard layout plus added extended layout (#1215) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rework of UK and RU standard layout plus added extended layout (similar to PC keyboard) as optional; - Added 'ї' as separate letter (it used much more often, just to be optional key in popups) - Added [ { } } popups to fill empty hint space (similar to PC layout) - Added ' (apostrofee) suggestion onto 'є' key (similar to oter keyboards and to PC layout) RU) Added siggestion to 'ъ' on 'х' key (similar to other keyboards, anyway there was no popups at all) - Added [ { } } popups to fill empty hint space (similar to PC layout) - Added 'э́' suggestion similar to other keyboards Both) - Improvements to multilanguage typing (now this is possible to sue UK-RU or RU-UK pair, I added letters from other language as popups) Added) - UK Extended with separate ' key (used less often than 'ї', but still used pretty often) - RU Extended, with separate 'ъ' key (similar to full desk PC layout) --- app/src/main/assets/layouts/main/russian.txt | 4 +-- .../assets/layouts/main/russian_extended.txt | 34 ++++++++++++++++++ .../main/assets/layouts/main/ukrainian.txt | 7 ++-- .../layouts/main/ukrainian_extended.txt | 35 +++++++++++++++++++ app/src/main/assets/locale_key_texts/ru.txt | 14 ++++++-- app/src/main/assets/locale_key_texts/uk.txt | 16 +++++++-- app/src/main/res/xml/method.xml | 21 +++++++++++ 7 files changed, 121 insertions(+), 10 deletions(-) create mode 100644 app/src/main/assets/layouts/main/russian_extended.txt create mode 100644 app/src/main/assets/layouts/main/ukrainian_extended.txt diff --git a/app/src/main/assets/layouts/main/russian.txt b/app/src/main/assets/layouts/main/russian.txt index 7ceb2435..7da99f64 100644 --- a/app/src/main/assets/layouts/main/russian.txt +++ b/app/src/main/assets/layouts/main/russian.txt @@ -8,7 +8,7 @@ ш щ з -х +х ъ [ { ф ы @@ -20,7 +20,7 @@ л д ж -э +э э́ ] } я ч diff --git a/app/src/main/assets/layouts/main/russian_extended.txt b/app/src/main/assets/layouts/main/russian_extended.txt new file mode 100644 index 00000000..8b3249fe --- /dev/null +++ b/app/src/main/assets/layouts/main/russian_extended.txt @@ -0,0 +1,34 @@ +й +ц +у +к +е +н +г +ш +щ +з +х [ { +ъ ] } + +ф +ы +в +а +п +р +о +л +д +ж +э э́ + +я +ч +с +м +и +т +ь +б < +ю > diff --git a/app/src/main/assets/layouts/main/ukrainian.txt b/app/src/main/assets/layouts/main/ukrainian.txt index 7e01cde3..ff1ed643 100644 --- a/app/src/main/assets/layouts/main/ukrainian.txt +++ b/app/src/main/assets/layouts/main/ukrainian.txt @@ -8,7 +8,8 @@ ш щ з -х +х [ { +ї ] } ф і @@ -20,7 +21,7 @@ л д ж -є +є ' " я ч @@ -30,4 +31,4 @@ т ь б < -ю > +ю > ґ diff --git a/app/src/main/assets/layouts/main/ukrainian_extended.txt b/app/src/main/assets/layouts/main/ukrainian_extended.txt new file mode 100644 index 00000000..7e37e93c --- /dev/null +++ b/app/src/main/assets/layouts/main/ukrainian_extended.txt @@ -0,0 +1,35 @@ +й +ц +у +к +е +н +г +ш +щ +з +х [ { +ї ] } + +ф +і +в +а +п +р +о +л +д +ж +є ' " +' " + +я +ч +с +м +и +т +ь +б < +ю > ґ diff --git a/app/src/main/assets/locale_key_texts/ru.txt b/app/src/main/assets/locale_key_texts/ru.txt index bbb9a247..59583da4 100644 --- a/app/src/main/assets/locale_key_texts/ru.txt +++ b/app/src/main/assets/locale_key_texts/ru.txt @@ -1,9 +1,19 @@ [popup_keys] -е ё -ь ъ +е ё е́ ѣ +ф ѳ +ы ы́ +а а́ +о о́ +я я́ +и и́ +ь ъ ы +ю ю́ ' ’ ‚ ‘ › ‹ " ” „ “ » « +і ы +є э э́ + [labels] alphabet: АБВ diff --git a/app/src/main/assets/locale_key_texts/uk.txt b/app/src/main/assets/locale_key_texts/uk.txt index 9ee926c9..080bf826 100644 --- a/app/src/main/assets/locale_key_texts/uk.txt +++ b/app/src/main/assets/locale_key_texts/uk.txt @@ -1,9 +1,19 @@ [popup_keys] +е е́ г ґ -ь +ф ѳ і ї -' ’ ‚ ‘ -" ” „ “ +а а́ +о о́ +я я́ +и и́ і ї +г ґ +ю ю́ +' ’ ‚ ‘ › ‹ +" ” „ “ » « + +ы і ї +э є [labels] alphabet: АБВ diff --git a/app/src/main/res/xml/method.xml b/app/src/main/res/xml/method.xml index 2733268b..213f288d 100644 --- a/app/src/main/res/xml/method.xml +++ b/app/src/main/res/xml/method.xml @@ -90,6 +90,7 @@ pt_PT: Portuguese (Portugal)/qwerty ro: Romanian/qwerty ru: Russian/russian + ru: Russian (Extended)/russian_extended ru: Russian (Student)/russian_student si_LK: Sinhala (Sri Lanka)/sinhala # This is a preliminary keyboard layout. sk: Slovak/qwerty @@ -107,6 +108,7 @@ tr: Turkish/turkish ur_PK: Urdu Pakistan uk: Ukrainian/ukrainian + uk: Ukrainian (Extended)/ukrainian_extended uz_UZ: Uzbek (Uzbekistan)/uzbek # This is a preliminary keyboard layout. vi: Vietnamese/qwerty zu: Zulu/qwerty @@ -912,6 +914,16 @@ android:imeSubtypeExtraValue="KeyboardLayoutSet=MAIN:russian,SupportTouchPositionCorrection,EmojiCapable" android:isAsciiCapable="false" /> + + Date: Sat, 15 Mar 2025 15:35:55 +0100 Subject: [PATCH 08/36] better way of determining whether a key should have action key background mostly relevant for popups fixes #1008 --- .../java/helium314/keyboard/keyboard/Key.java | 18 ++++++------------ .../keyboard/keyboard/KeyboardView.java | 2 +- .../keyboard/keyboard/MainKeyboardView.java | 2 +- .../keyboard/keyboard/PopupKeysKeyboard.java | 3 ++- .../keyboard/internal/PopupKeySpec.java | 8 +++----- 5 files changed, 13 insertions(+), 20 deletions(-) diff --git a/app/src/main/java/helium314/keyboard/keyboard/Key.java b/app/src/main/java/helium314/keyboard/keyboard/Key.java index 3d091797..c80c1eb3 100644 --- a/app/src/main/java/helium314/keyboard/keyboard/Key.java +++ b/app/src/main/java/helium314/keyboard/keyboard/Key.java @@ -24,6 +24,7 @@ import helium314.keyboard.latin.common.StringUtils; import helium314.keyboard.latin.utils.PopupKeysUtilsKt; import helium314.keyboard.latin.utils.ToolbarKey; import helium314.keyboard.latin.utils.ToolbarUtilsKt; +import kotlin.collections.ArraysKt; import java.util.Arrays; import java.util.Locale; @@ -919,7 +920,7 @@ public class Key implements Comparable { @NonNull final Drawable spacebarBackground, @NonNull final Drawable actionKeyBackground) { final Drawable background; - if (isAccentColored()) { + if (hasActionKeyBackground()) { background = actionKeyBackground; } else if (hasFunctionalBackground()) { background = functionalKeyBackground; @@ -933,17 +934,10 @@ public class Key implements Comparable { return background; } - public final boolean isAccentColored() { - if (hasActionKeyBackground()) return true; - final String iconName = getIconName(); - if (iconName == null) return false; - // todo: other way of identifying the color? - // this should be done differently, as users can set any icon now - // how is the background drawable selected? can we use the same way? - return iconName.equals(KeyboardIconsSet.NAME_NEXT_KEY) - || iconName.equals(KeyboardIconsSet.NAME_PREVIOUS_KEY) - || iconName.equals("clipboard_action_key") - || iconName.equals("emoji_action_key"); + public final boolean hasActionKeyPopups() { + if (!hasActionKeyBackground()) return false; + // only use the special action key popups for action colored keys, and only for icon popups + return ArraysKt.none(getPopupKeys(), (key) -> key.mIconName == null); } public boolean hasFunctionalBackground() { diff --git a/app/src/main/java/helium314/keyboard/keyboard/KeyboardView.java b/app/src/main/java/helium314/keyboard/keyboard/KeyboardView.java index 1c484dfb..2226e360 100644 --- a/app/src/main/java/helium314/keyboard/keyboard/KeyboardView.java +++ b/app/src/main/java/helium314/keyboard/keyboard/KeyboardView.java @@ -610,7 +610,7 @@ public class KeyboardView extends View { } private void setKeyIconColor(Key key, Drawable icon, Keyboard keyboard) { - if (key.isAccentColored()) { + if (key.hasActionKeyBackground()) { mColors.setColor(icon, ColorType.ACTION_KEY_ICON); } else if (key.isShift() && keyboard != null) { if (keyboard.mId.mElementId == KeyboardId.ELEMENT_ALPHABET_MANUAL_SHIFTED diff --git a/app/src/main/java/helium314/keyboard/keyboard/MainKeyboardView.java b/app/src/main/java/helium314/keyboard/keyboard/MainKeyboardView.java index 9239f5ea..91807cdb 100644 --- a/app/src/main/java/helium314/keyboard/keyboard/MainKeyboardView.java +++ b/app/src/main/java/helium314/keyboard/keyboard/MainKeyboardView.java @@ -505,7 +505,7 @@ public final class MainKeyboardView extends KeyboardView implements DrawingProxy mPopupKeysKeyboardCache.put(key, popupKeysKeyboard); } - final View container = key.hasActionKeyBackground() ? mPopupKeysKeyboardForActionContainer + final View container = key.hasActionKeyPopups() ? mPopupKeysKeyboardForActionContainer : mPopupKeysKeyboardContainer; final PopupKeysKeyboardView popupKeysKeyboardView = container.findViewById(R.id.popup_keys_keyboard_view); diff --git a/app/src/main/java/helium314/keyboard/keyboard/PopupKeysKeyboard.java b/app/src/main/java/helium314/keyboard/keyboard/PopupKeysKeyboard.java index 11340437..645e420b 100644 --- a/app/src/main/java/helium314/keyboard/keyboard/PopupKeysKeyboard.java +++ b/app/src/main/java/helium314/keyboard/keyboard/PopupKeysKeyboard.java @@ -328,12 +328,13 @@ public final class PopupKeysKeyboard extends Keyboard { final PopupKeysKeyboardParams params = mParams; final int popupKeyFlags = mParentKey.getPopupKeyLabelFlags(); final PopupKeySpec[] popupKeys = mParentKey.getPopupKeys(); + final int background = mParentKey.hasActionKeyPopups() ? Key.BACKGROUND_TYPE_ACTION : Key.BACKGROUND_TYPE_NORMAL; for (int n = 0; n < popupKeys.length; n++) { final PopupKeySpec popupKeySpec = popupKeys[n]; final int row = n / params.mNumColumns; final int x = params.getX(n, row); final int y = params.getY(row); - final Key key = popupKeySpec.buildKey(x, y, popupKeyFlags, params); + final Key key = popupKeySpec.buildKey(x, y, popupKeyFlags, background, params); params.markAsEdgeKey(key, row); params.onAddKey(key); diff --git a/app/src/main/java/helium314/keyboard/keyboard/internal/PopupKeySpec.java b/app/src/main/java/helium314/keyboard/keyboard/internal/PopupKeySpec.java index a1b41b79..695a660a 100644 --- a/app/src/main/java/helium314/keyboard/keyboard/internal/PopupKeySpec.java +++ b/app/src/main/java/helium314/keyboard/keyboard/internal/PopupKeySpec.java @@ -68,11 +68,9 @@ public final class PopupKeySpec { } @NonNull - public Key buildKey(final int x, final int y, final int labelFlags, - @NonNull final KeyboardParams params) { - return new Key(mLabel, mIconName, mCode, mOutputText, null /* hintLabel */, labelFlags, - Key.BACKGROUND_TYPE_NORMAL, x, y, params.mDefaultAbsoluteKeyWidth, params.mDefaultAbsoluteRowHeight, - params.mHorizontalGap, params.mVerticalGap); + public Key buildKey(final int x, final int y, final int labelFlags, final int background, @NonNull final KeyboardParams params) { + return new Key(mLabel, mIconName, mCode, mOutputText, null, labelFlags, background, x, y, + params.mDefaultAbsoluteKeyWidth, params.mDefaultAbsoluteRowHeight, params.mHorizontalGap, params.mVerticalGap); } @Override From 8298542c392aa7da6d3d59ce4db362c76c55fb03 Mon Sep 17 00:00:00 2001 From: Helium314 Date: Sat, 15 Mar 2025 15:59:49 +0100 Subject: [PATCH 09/36] add setting to switch to alphabet after typing on numpad and pressing space fixes #1224 --- .../keyboard/keyboard/internal/KeyboardState.java | 15 ++++++++++++++- .../helium314/keyboard/latin/settings/Defaults.kt | 1 + .../keyboard/latin/settings/Settings.java | 1 + .../keyboard/latin/settings/SettingsValues.java | 2 ++ .../keyboard/settings/screens/AdvancedScreen.kt | 6 ++++++ app/src/main/res/values/strings.xml | 2 ++ 6 files changed, 26 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/helium314/keyboard/keyboard/internal/KeyboardState.java b/app/src/main/java/helium314/keyboard/keyboard/internal/KeyboardState.java index 51dc98b0..07639d3f 100644 --- a/app/src/main/java/helium314/keyboard/keyboard/internal/KeyboardState.java +++ b/app/src/main/java/helium314/keyboard/keyboard/internal/KeyboardState.java @@ -80,6 +80,7 @@ public final class KeyboardState { private static final int SWITCH_STATE_SYMBOL_BEGIN = 1; private static final int SWITCH_STATE_SYMBOL = 2; private static final int SWITCH_STATE_NUMPAD = 3; + private static final int SWITCH_STATE_NUMPAD_BEGIN = 9; private static final int SWITCH_STATE_MOMENTARY_ALPHA_AND_SYMBOL = 4; private static final int SWITCH_STATE_MOMENTARY_SYMBOL_AND_MORE = 5; private static final int SWITCH_STATE_MOMENTARY_ALPHA_SHIFT = 6; @@ -403,7 +404,7 @@ public final class KeyboardState { mMode = MODE_NUMPAD; mRecapitalizeMode = RecapitalizeStatus.NOT_A_RECAPITALIZE_MODE; mSwitchActions.setNumpadKeyboard(); - mSwitchState = withSliding ? SWITCH_STATE_MOMENTARY_TO_NUMPAD : SWITCH_STATE_NUMPAD; + mSwitchState = withSliding ? SWITCH_STATE_MOMENTARY_TO_NUMPAD : SWITCH_STATE_NUMPAD_BEGIN; } public void toggleNumpad(final boolean withSliding, final int autoCapsFlags, final int recapitalizeMode, @@ -789,6 +790,17 @@ public final class KeyboardState { mPrevSymbolsKeyboardWasShifted = false; } break; + case SWITCH_STATE_NUMPAD: + // Switch back to alpha keyboard mode if user types one or more non-space/enter + // characters followed by a space/enter. + if (isSpaceOrEnter(code) && Settings.getValues().mAlphaAfterNumpadAndSpace) { + toggleNumpad(false, autoCapsFlags, recapitalizeMode, true, false); + } + break; + case SWITCH_STATE_NUMPAD_BEGIN: + if (!isSpaceOrEnter(code)) + mSwitchState = SWITCH_STATE_NUMPAD; + break; } // If the code is a letter, update keyboard shift state. @@ -833,6 +845,7 @@ public final class KeyboardState { case SWITCH_STATE_MOMENTARY_SYMBOL_AND_MORE -> "MOMENTARY-SYMBOL-MORE"; case SWITCH_STATE_MOMENTARY_ALPHA_SHIFT -> "MOMENTARY-ALPHA_SHIFT"; case SWITCH_STATE_NUMPAD -> "NUMPAD"; + case SWITCH_STATE_NUMPAD_BEGIN -> "NUMPAD-BEGIN"; case SWITCH_STATE_MOMENTARY_TO_NUMPAD -> "MOMENTARY-TO-NUMPAD"; case SWITCH_STATE_MOMENTARY_FROM_NUMPAD -> "MOMENTARY-FROM-NUMPAD"; default -> null; diff --git a/app/src/main/java/helium314/keyboard/latin/settings/Defaults.kt b/app/src/main/java/helium314/keyboard/latin/settings/Defaults.kt index 8e1261c0..1a890fa2 100644 --- a/app/src/main/java/helium314/keyboard/latin/settings/Defaults.kt +++ b/app/src/main/java/helium314/keyboard/latin/settings/Defaults.kt @@ -145,6 +145,7 @@ object Defaults { const val PREF_ABC_AFTER_EMOJI = false const val PREF_ABC_AFTER_CLIP = false const val PREF_ABC_AFTER_SYMBOL_SPACE = true + const val PREF_ABC_AFTER_NUMPAD_SPACE = false const val PREF_REMOVE_REDUNDANT_POPUPS = false const val PREF_SPACE_BAR_TEXT = "" @JvmField diff --git a/app/src/main/java/helium314/keyboard/latin/settings/Settings.java b/app/src/main/java/helium314/keyboard/latin/settings/Settings.java index 8d9e7bef..6d45548a 100644 --- a/app/src/main/java/helium314/keyboard/latin/settings/Settings.java +++ b/app/src/main/java/helium314/keyboard/latin/settings/Settings.java @@ -155,6 +155,7 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang public static final String PREF_ABC_AFTER_EMOJI = "abc_after_emoji"; public static final String PREF_ABC_AFTER_CLIP = "abc_after_clip"; public static final String PREF_ABC_AFTER_SYMBOL_SPACE = "abc_after_symbol_space"; + public static final String PREF_ABC_AFTER_NUMPAD_SPACE = "abc_after_numpad_space"; public static final String PREF_REMOVE_REDUNDANT_POPUPS = "remove_redundant_popups"; public static final String PREF_SPACE_BAR_TEXT = "space_bar_text"; diff --git a/app/src/main/java/helium314/keyboard/latin/settings/SettingsValues.java b/app/src/main/java/helium314/keyboard/latin/settings/SettingsValues.java index 25c2ec15..9a18fde2 100644 --- a/app/src/main/java/helium314/keyboard/latin/settings/SettingsValues.java +++ b/app/src/main/java/helium314/keyboard/latin/settings/SettingsValues.java @@ -114,6 +114,7 @@ public class SettingsValues { public final boolean mAlphaAfterEmojiInEmojiView; public final boolean mAlphaAfterClipHistoryEntry; public final boolean mAlphaAfterSymbolAndSpace; + public final boolean mAlphaAfterNumpadAndSpace; public final boolean mRemoveRedundantPopups; public final String mSpaceBarText; public final float mFontSizeMultiplier; @@ -268,6 +269,7 @@ public class SettingsValues { mAlphaAfterEmojiInEmojiView = prefs.getBoolean(Settings.PREF_ABC_AFTER_EMOJI, Defaults.PREF_ABC_AFTER_EMOJI); mAlphaAfterClipHistoryEntry = prefs.getBoolean(Settings.PREF_ABC_AFTER_CLIP, Defaults.PREF_ABC_AFTER_CLIP); mAlphaAfterSymbolAndSpace = prefs.getBoolean(Settings.PREF_ABC_AFTER_SYMBOL_SPACE, Defaults.PREF_ABC_AFTER_SYMBOL_SPACE); + mAlphaAfterNumpadAndSpace = prefs.getBoolean(Settings.PREF_ABC_AFTER_NUMPAD_SPACE, Defaults.PREF_ABC_AFTER_NUMPAD_SPACE); mRemoveRedundantPopups = prefs.getBoolean(Settings.PREF_REMOVE_REDUNDANT_POPUPS, Defaults.PREF_REMOVE_REDUNDANT_POPUPS); mSpaceBarText = prefs.getString(Settings.PREF_SPACE_BAR_TEXT, Defaults.PREF_SPACE_BAR_TEXT); mEmojiMaxSdk = prefs.getInt(Settings.PREF_EMOJI_MAX_SDK, Defaults.PREF_EMOJI_MAX_SDK); diff --git a/app/src/main/java/helium314/keyboard/settings/screens/AdvancedScreen.kt b/app/src/main/java/helium314/keyboard/settings/screens/AdvancedScreen.kt index 3605a422..c81f3025 100644 --- a/app/src/main/java/helium314/keyboard/settings/screens/AdvancedScreen.kt +++ b/app/src/main/java/helium314/keyboard/settings/screens/AdvancedScreen.kt @@ -66,6 +66,7 @@ fun AdvancedSettingsScreen( Settings.PREF_ENABLE_EMOJI_ALT_PHYSICAL_KEY, if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) Settings.PREF_SHOW_SETUP_WIZARD_ICON else null, Settings.PREF_ABC_AFTER_SYMBOL_SPACE, + Settings.PREF_ABC_AFTER_NUMPAD_SPACE, Settings.PREF_ABC_AFTER_EMOJI, Settings.PREF_ABC_AFTER_CLIP, Settings.PREF_CUSTOM_CURRENCY_KEY, @@ -154,6 +155,11 @@ fun createAdvancedSettings(context: Context) = listOf( { SwitchPreference(it, Defaults.PREF_ABC_AFTER_SYMBOL_SPACE) }, + Setting(context, Settings.PREF_ABC_AFTER_NUMPAD_SPACE, + R.string.switch_keyboard_after, R.string.after_numpad_and_space) + { + SwitchPreference(it, Defaults.PREF_ABC_AFTER_NUMPAD_SPACE) + }, Setting(context, Settings.PREF_ABC_AFTER_EMOJI, R.string.switch_keyboard_after, R.string.after_emoji) { SwitchPreference(it, Defaults.PREF_ABC_AFTER_EMOJI) }, diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index e6bb1d30..e063b07c 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -581,6 +581,8 @@ disposition rather than other common dispositions for Latin languages. --> Selecting clipboard history entry Pressing enter or space after other keys in symbols view + + Pressing enter or space after other keys in numpad Set image for day or night mode? From cb70553484719a088419a21f6021d3115a4cbc5f Mon Sep 17 00:00:00 2001 From: KuRa KuRd <3160786+GoRaN909@users.noreply.github.com> Date: Sun, 16 Mar 2025 16:00:23 +0300 Subject: [PATCH 10/36] Add Central Kurdish layout (#1417) --- .../assets/layouts/main/central_kurdish.txt | 31 +++++++++++++++ app/src/main/assets/locale_key_texts/ckb.txt | 39 +++++++++++++++++++ .../keyboard/latin/utils/ScriptUtils.kt | 2 +- app/src/main/res/xml/method.xml | 10 +++++ 4 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 app/src/main/assets/layouts/main/central_kurdish.txt create mode 100644 app/src/main/assets/locale_key_texts/ckb.txt diff --git a/app/src/main/assets/layouts/main/central_kurdish.txt b/app/src/main/assets/layouts/main/central_kurdish.txt new file mode 100644 index 00000000..eec1593e --- /dev/null +++ b/app/src/main/assets/layouts/main/central_kurdish.txt @@ -0,0 +1,31 @@ +ق +و +ە +ر +ت +ی +ێ +ئ +ۆ +پ + +ا +س +ش +د +ف +ھ|ه +ژ +ل +ک +گ + +ز +ع +ح +ج +چ +خ +ب +ن +م diff --git a/app/src/main/assets/locale_key_texts/ckb.txt b/app/src/main/assets/locale_key_texts/ckb.txt new file mode 100644 index 00000000..5e13897b --- /dev/null +++ b/app/src/main/assets/locale_key_texts/ckb.txt @@ -0,0 +1,39 @@ +[popup_keys] +ق ٯ +و وو +ە ة ﻪ ـہ +ر ڕ ڒ ࢪ +ت ط +ی ي ې ۍ +ێ ؽ +ئ ء ﺋ +ۆ ؤ ۏ ۊ ۋ ۉ ۇ +پ ث +ا أ إ آ ٱ +س ص +ش ض +د ۮ ڌ ﮆ +ف ڤ ڡ +ھ ھ +ژ ━|ـ +ل ڵ +ک ك ڪ +گ غ +ز ظ +ع ؏ +ب ى +punctuation !autoColumnOrder!8 \؟ ! ، ٫ ؍ : ؛ ; : | - @ _ # * ٪ & ^ +« „ “ ” +» ‚ ‘ ’ ‹ › + +[labels] +alphabet: ئ‌پ‌گ +symbol: ٣٢١؟ +comma: ، +question: ؟ + +[number_row] +١ ٢ ٣ ٤ ٥ ٦ ٧ ٨ ٩ ٠ + +[tlds] +iq krd diff --git a/app/src/main/java/helium314/keyboard/latin/utils/ScriptUtils.kt b/app/src/main/java/helium314/keyboard/latin/utils/ScriptUtils.kt index df442089..f66c76ab 100644 --- a/app/src/main/java/helium314/keyboard/latin/utils/ScriptUtils.kt +++ b/app/src/main/java/helium314/keyboard/latin/utils/ScriptUtils.kt @@ -162,7 +162,7 @@ object ScriptUtils { return SCRIPT_LATIN } return when (language) { - "ar", "ur", "fa" -> SCRIPT_ARABIC + "ar", "ckb", "ur", "fa" -> SCRIPT_ARABIC "hy" -> SCRIPT_ARMENIAN "bn" -> SCRIPT_BENGALI "sr", "mk", "ru", "uk", "mn", "be", "kk", "ky", "bg", "xdq", "cv", "mhr", "mns", "dru" -> SCRIPT_CYRILLIC diff --git a/app/src/main/res/xml/method.xml b/app/src/main/res/xml/method.xml index 213f288d..e46d5be3 100644 --- a/app/src/main/res/xml/method.xml +++ b/app/src/main/res/xml/method.xml @@ -23,6 +23,7 @@ bn_IN: Bengali (India)/bengali_inscript bn_IN: Bengali (India)/Baishakhi ca: Catalan/qwerty+ + ckb: Central Kurdish/central_kurdish cs: Czech/qwertz cv: Chuvash/chuvash da: Danish/qwerty+ @@ -289,6 +290,15 @@ android:imeSubtypeExtraValue="KeyboardLayoutSet=MAIN:qwerty+,AsciiCapable,EmojiCapable" android:isAsciiCapable="true" /> + Date: Sun, 16 Mar 2025 14:33:53 +0100 Subject: [PATCH 11/36] remove appcompat was mainly used for settings --- app/build.gradle.kts | 1 - .../keyboard/keyboard/MainKeyboardView.java | 2 +- .../keyboard/internal/KeyPreviewView.java | 10 ++++------ .../java/helium314/keyboard/latin/LatinIME.java | 2 +- .../keyboard/latin/utils/DialogUtils.kt | 2 +- .../keyboard/latin/utils/InputMethodPicker.kt | 2 +- .../keyboard/settings/screens/AboutScreen.kt | 2 +- .../res/drawable/sym_keyboard_paste_rounded.xml | 3 +-- app/src/main/res/values-v28/platform-theme.xml | 17 +++++++++++++++++ app/src/main/res/values-v31/platform-theme.xml | 8 ++------ app/src/main/res/values/platform-theme.xml | 14 ++++++++++++-- 11 files changed, 41 insertions(+), 22 deletions(-) create mode 100644 app/src/main/res/values-v28/platform-theme.xml diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 30956503..a73820c5 100755 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -97,7 +97,6 @@ android { dependencies { // androidx implementation("androidx.core:core-ktx:1.13.1") - implementation("androidx.appcompat:appcompat:1.7.0") implementation("androidx.recyclerview:recyclerview:1.3.2") implementation("androidx.autofill:autofill:1.1.0") diff --git a/app/src/main/java/helium314/keyboard/keyboard/MainKeyboardView.java b/app/src/main/java/helium314/keyboard/keyboard/MainKeyboardView.java index 91807cdb..d84998e8 100644 --- a/app/src/main/java/helium314/keyboard/keyboard/MainKeyboardView.java +++ b/app/src/main/java/helium314/keyboard/keyboard/MainKeyboardView.java @@ -18,6 +18,7 @@ import android.graphics.Paint; import android.graphics.Paint.Align; import android.graphics.Typeface; import android.util.AttributeSet; +import android.view.ContextThemeWrapper; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; @@ -25,7 +26,6 @@ import android.view.ViewGroup; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import androidx.appcompat.view.ContextThemeWrapper; import helium314.keyboard.accessibility.AccessibilityUtils; import helium314.keyboard.accessibility.MainKeyboardAccessibilityDelegate; diff --git a/app/src/main/java/helium314/keyboard/keyboard/internal/KeyPreviewView.java b/app/src/main/java/helium314/keyboard/keyboard/internal/KeyPreviewView.java index c7069ec0..64ef4bfe 100644 --- a/app/src/main/java/helium314/keyboard/keyboard/internal/KeyPreviewView.java +++ b/app/src/main/java/helium314/keyboard/keyboard/internal/KeyPreviewView.java @@ -15,8 +15,7 @@ import android.text.TextUtils; import android.util.AttributeSet; import android.util.TypedValue; import android.view.Gravity; - -import androidx.appcompat.widget.AppCompatTextView; +import android.widget.TextView; import helium314.keyboard.keyboard.Key; import helium314.keyboard.latin.R; @@ -25,10 +24,9 @@ import helium314.keyboard.latin.settings.Settings; import java.util.HashSet; -/** - * The pop up key preview view. - */ -public class KeyPreviewView extends AppCompatTextView { +/** The pop up key preview view. */ +// Android Studio complains about TextView, but we're not using tint or auto-size that should be the relevant differences +public class KeyPreviewView extends TextView { public static final int POSITION_MIDDLE = 0; public static final int POSITION_LEFT = 1; public static final int POSITION_RIGHT = 2; diff --git a/app/src/main/java/helium314/keyboard/latin/LatinIME.java b/app/src/main/java/helium314/keyboard/latin/LatinIME.java index f18c530e..5913bf70 100644 --- a/app/src/main/java/helium314/keyboard/latin/LatinIME.java +++ b/app/src/main/java/helium314/keyboard/latin/LatinIME.java @@ -7,6 +7,7 @@ package helium314.keyboard.latin; import android.annotation.SuppressLint; +import android.app.AlertDialog; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; @@ -100,7 +101,6 @@ import java.util.concurrent.TimeUnit; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.RequiresApi; -import androidx.appcompat.app.AlertDialog; import androidx.core.content.ContextCompat; /** diff --git a/app/src/main/java/helium314/keyboard/latin/utils/DialogUtils.kt b/app/src/main/java/helium314/keyboard/latin/utils/DialogUtils.kt index 470743bb..e13f2f10 100644 --- a/app/src/main/java/helium314/keyboard/latin/utils/DialogUtils.kt +++ b/app/src/main/java/helium314/keyboard/latin/utils/DialogUtils.kt @@ -1,7 +1,7 @@ package helium314.keyboard.latin.utils import android.content.Context -import androidx.appcompat.view.ContextThemeWrapper +import android.view.ContextThemeWrapper import helium314.keyboard.latin.R // todo: ideally the custom InputMethodPicker would be removed / replaced with compose dialog, then this can be removed diff --git a/app/src/main/java/helium314/keyboard/latin/utils/InputMethodPicker.kt b/app/src/main/java/helium314/keyboard/latin/utils/InputMethodPicker.kt index 33ac3d5d..3f534842 100644 --- a/app/src/main/java/helium314/keyboard/latin/utils/InputMethodPicker.kt +++ b/app/src/main/java/helium314/keyboard/latin/utils/InputMethodPicker.kt @@ -2,6 +2,7 @@ package helium314.keyboard.latin.utils +import android.app.AlertDialog import android.os.IBinder import android.text.Spannable import android.text.SpannableString @@ -10,7 +11,6 @@ import android.text.style.RelativeSizeSpan import android.view.WindowManager import android.view.inputmethod.InputMethodInfo import android.view.inputmethod.InputMethodSubtype -import androidx.appcompat.app.AlertDialog import helium314.keyboard.latin.LatinIME import helium314.keyboard.latin.R import helium314.keyboard.latin.RichInputMethodManager diff --git a/app/src/main/java/helium314/keyboard/settings/screens/AboutScreen.kt b/app/src/main/java/helium314/keyboard/settings/screens/AboutScreen.kt index 56281034..9d84985c 100644 --- a/app/src/main/java/helium314/keyboard/settings/screens/AboutScreen.kt +++ b/app/src/main/java/helium314/keyboard/settings/screens/AboutScreen.kt @@ -2,6 +2,7 @@ package helium314.keyboard.settings.screens import android.app.Activity +import android.app.AlertDialog import android.content.Context import android.content.Intent import android.text.method.LinkMovementMethod @@ -10,7 +11,6 @@ import android.widget.TextView import android.widget.Toast import androidx.activity.compose.rememberLauncherForActivityResult import androidx.activity.result.contract.ActivityResultContracts -import androidx.appcompat.app.AlertDialog import androidx.compose.material3.Surface import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue diff --git a/app/src/main/res/drawable/sym_keyboard_paste_rounded.xml b/app/src/main/res/drawable/sym_keyboard_paste_rounded.xml index 6e57a69b..051630b7 100644 --- a/app/src/main/res/drawable/sym_keyboard_paste_rounded.xml +++ b/app/src/main/res/drawable/sym_keyboard_paste_rounded.xml @@ -8,8 +8,7 @@ android:width="24dp" android:height="24dp" android:viewportWidth="960" - android:viewportHeight="960" - android:tint="?attr/colorControlNormal"> + android:viewportHeight="960"> \ No newline at end of file diff --git a/app/src/main/res/values-v28/platform-theme.xml b/app/src/main/res/values-v28/platform-theme.xml new file mode 100644 index 00000000..77a73ae9 --- /dev/null +++ b/app/src/main/res/values-v28/platform-theme.xml @@ -0,0 +1,17 @@ + + + + + + diff --git a/app/src/main/res/values-v31/platform-theme.xml b/app/src/main/res/values-v31/platform-theme.xml index 4c40353c..5014fc74 100644 --- a/app/src/main/res/values-v31/platform-theme.xml +++ b/app/src/main/res/values-v31/platform-theme.xml @@ -5,12 +5,11 @@ - - diff --git a/app/src/main/res/values/platform-theme.xml b/app/src/main/res/values/platform-theme.xml index 432d2071..2942b101 100644 --- a/app/src/main/res/values/platform-theme.xml +++ b/app/src/main/res/values/platform-theme.xml @@ -6,11 +6,21 @@ --> - + + From 9b7eaa4cf282b8b4690110a64db135cc23e16904 Mon Sep 17 00:00:00 2001 From: Helium314 Date: Sun, 16 Mar 2025 14:49:04 +0100 Subject: [PATCH 12/36] use default text button style for popup key order / hint source buttons --- .../java/helium314/keyboard/settings/dialogs/SubtypeDialog.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/helium314/keyboard/settings/dialogs/SubtypeDialog.kt b/app/src/main/java/helium314/keyboard/settings/dialogs/SubtypeDialog.kt index 7db7cadb..33d4d850 100644 --- a/app/src/main/java/helium314/keyboard/settings/dialogs/SubtypeDialog.kt +++ b/app/src/main/java/helium314/keyboard/settings/dialogs/SubtypeDialog.kt @@ -151,14 +151,14 @@ fun SubtypeDialog( } Row { TextButton(onClick = { showKeyOrderDialog = true }, Modifier.weight(1f)) - { Text(stringResource(R.string.popup_order), style = MaterialTheme.typography.bodyLarge) } + { Text(stringResource(R.string.popup_order)) } DefaultButton(currentSubtype.getExtraValueOf(ExtraValue.POPUP_ORDER) == null) { setCurrentSubtype(currentSubtype.without(ExtraValue.POPUP_ORDER)) } } Row { TextButton(onClick = { showHintOrderDialog = true }, Modifier.weight(1f)) - { Text(stringResource(R.string.hint_source), style = MaterialTheme.typography.bodyLarge) } + { Text(stringResource(R.string.hint_source)) } DefaultButton(currentSubtype.getExtraValueOf(ExtraValue.HINT_ORDER) == null) { setCurrentSubtype(currentSubtype.without(ExtraValue.HINT_ORDER)) } From a3bada8d258a8ae25e5275921971ba188a215107 Mon Sep 17 00:00:00 2001 From: Helium314 Date: Sun, 16 Mar 2025 15:01:39 +0100 Subject: [PATCH 13/36] upgrade version and translations --- app/build.gradle.kts | 4 +- app/src/main/res/values-ar/strings.xml | 12 ++-- app/src/main/res/values-be/strings.xml | 61 ++++++++++++++++++- app/src/main/res/values-bg/strings.xml | 2 + app/src/main/res/values-bn/strings.xml | 51 +++++++--------- app/src/main/res/values-ca/strings.xml | 2 + app/src/main/res/values-de/strings.xml | 3 + app/src/main/res/values-et/strings.xml | 2 + app/src/main/res/values-fr/strings.xml | 2 + app/src/main/res/values-it/strings.xml | 9 ++- app/src/main/res/values-nl/strings.xml | 2 + app/src/main/res/values-pl/strings.xml | 20 +++--- app/src/main/res/values-pt-rBR/strings.xml | 2 + app/src/main/res/values-ro/strings.xml | 31 ++++++++++ app/src/main/res/values-ru/strings.xml | 10 +-- app/src/main/res/values-zh-rCN/strings.xml | 2 + .../metadata/android/bn/full_description.txt | 2 +- 17 files changed, 165 insertions(+), 52 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index a73820c5..27915d04 100755 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -13,8 +13,8 @@ android { applicationId = "helium314.keyboard" minSdk = 21 targetSdk = 34 - versionCode = 3000 - versionName = "3.0-alpha1" + versionCode = 3001 + versionName = "3.0-alpha2" ndk { abiFilters.clear() abiFilters.addAll(listOf("armeabi-v7a", "arm64-v8a", "x86", "x86_64")) diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index 04d26849..36b7b516 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -75,16 +75,16 @@ "الرموز التعبيرية للوحة مفاتيح فعلية" "‏مفتاح Alt الفعلي يعرض لوحة الرموز التعبيرية" "التلقائية" - مرحبًا بكم في%s + مرحبًا بكم في %s مع الكتابة بالإيماءة "بدء الاستخدام" "الخطوة التالية" - قيد الإعداد%s - مكِّن%s + قيد الإعداد %s + مكِّن %s يرجى التحقق من \\%s\" في إعدادات الإدخال واللغات. سيؤدي ذلك إلى تمكين لوحة المفاتيح على جهازك.\" <xliff:g id=\"APPLICATION_NAME\" مثال=\"لوحة مفاتيح أندرويد\">%s</xliff:g> ممكّن بالفعل في إعدادات اللغات &amp؛ إعدادات الإدخال، لذا فقد تم الانتهاء من هذه الخطوة. إلى الخطوة التالية!\" "تفعيل في الإعدادات" - قم بالتبديل إلى%s + بدّل إلى %s بعد ذلك، اختر \\<<xliff:g id=\"APPLICATION_NAME\" مثال=\"لوحة مفاتيح أندرويد\">%s</xliff:g>” كطريقة إدخال النص النشط.“ "تبديل أساليب الإدخال" تهانينا ، لقد انتهيت من الإعداد! @@ -472,4 +472,8 @@ اللغات مع القواميس يمكنك العثور على المخططات ومشاركتها في %s. قسم المناقشة + نوع فرعي مخصّص + %s (Baishakhi) + أظهِر مفاتيح TLD المنبثقة + استبدل مفتاح الفترة المنبثقة مع مجالات المستوى الأعلى عند كتابة عناوين URL وعناوين البريد الإلكتروني diff --git a/app/src/main/res/values-be/strings.xml b/app/src/main/res/values-be/strings.xml index 6397a744..df4da739 100644 --- a/app/src/main/res/values-be/strings.xml +++ b/app/src/main/res/values-be/strings.xml @@ -370,5 +370,64 @@ Пераключыць лічбавую клавіятуру Дадаць самыя распаўсюджаныя варыянты (па змаўчанні) Выдаліць лішнія ўсплывальныя вокны - Прыбраць усплывальныя клавішы, якія прысутнічаюць у базавай раскладцы + Прыбраць усплывальныя клавішы, якія ўжо прысутнічаюць у базавай раскладцы + Плаваючы прадпрагляд + Бачыць прапанаванае слова падчас набору жэстамі + Раздзельная клавіятура + Вібрацыя ў рэжыме «Не турбаваць» + Уключыць падзеленую клавіятуру (альбомная) + Адлегласць падзелу (альбомная) + Перамяшчаць прадпрагляд падчас набору жэстамі + Час жыцця следа жэста + Аўтакарэкцыя спалучэнняў клавіш + Калі ўключана, спалучэнні клавіш могуць быць пашыраны з дапамогай аўтакарэкцыі + Маштаб ніжняга водступу (альбомная) + Маштаб бакавога водступу + Паказваць падказкі ў шэрагу з лічбамі + Мовы са слоўнікамі + Карыстацкі падтып + Радок эмодзі ўнізе + Радок буфера абмену ўнізе + Папярэджанне: раскладка ў дадзены момант выкарыстоўваецца + Наладзіць значкі + Сапраўды скінуць усе настроеныя значкі? + Шэраг з лічбамі + Усталяваць фонавы малюнак (альбомная) + Перавызначыць версію эмодзі + Даргінскі (Урахі) + Урахінскі (%s) + Код клавішы + Сапраўды выдаліць %s? + Усталяваць карыстацкі шрыфт з файла + Калі не ўстаноўлена, будзе выкарыстоўвацца партрэтны малюнак + Раз\'яднальнік нулявой шырыні + Вы сапраўды хочаце выдаліць усе настроеныя коды клавіш? + Дадатковыя раскладкі + Функцыянальныя клавішы (вялікі экран) + Стыль значкоў + Злучальнік нулявой шырыні + Сметніца + Недапушчальнае імя + Выдаліць + Увод + Shift + Табуляцыя + Shift (націснута) + Маштаб шрыфта клавіятуры + Маштаб шрыфта адлюстравання эмодзі + Маштаб бакавога водступу (альбомная) + Код доўгага націску + Адлегласць змахвання для пераключэння мовы + Наладзіць коды клавіш панэлі інструментаў + Карыстацкі тэкст на клавішы прабела + Прабел (раскладка лічбаў) + Пераключыць бок рэжыму адной рукой + Знайсці і падзяліцца колерамі ў %s. + Знайсці і падзяліцца раскладкамі ў %s. + абмеркавання + Caps lock + Завяршыць рэжым адной рукой + Змяніць памер у рэжыме адной рукой + Галасавы ўвод адключаны + Паказаць / схаваць панэль інструментаў diff --git a/app/src/main/res/values-bg/strings.xml b/app/src/main/res/values-bg/strings.xml index db908230..b9509430 100644 --- a/app/src/main/res/values-bg/strings.xml +++ b/app/src/main/res/values-bg/strings.xml @@ -467,4 +467,6 @@ Можете да намирате и споделяте цветове в %s. Персонализиран подтип %s (Байсахи) + Показване на TLD изскачащи клавиши + Заместване на изскачащите прозорци с клавиши за период с домейни от първо ниво при въвеждане на URL и имейл адреси diff --git a/app/src/main/res/values-bn/strings.xml b/app/src/main/res/values-bn/strings.xml index afb898f8..f6f1e06d 100644 --- a/app/src/main/res/values-bn/strings.xml +++ b/app/src/main/res/values-bn/strings.xml @@ -70,9 +70,7 @@ বহুভাষী টাইপিং অঙ্গুলিহেলন টাইপিং লাইব্রেরি অধিযোগ অঙ্গুলিহেলনের মাধ্যমে টাইপিং সক্রিয় করার জন্য স্থানীয় লাইব্রেরি সরবরাহ - \'%s\' এর জন্য লাইব্রেরি প্রয়োজন। অসামঞ্জস্যপূর্ণ লাইব্রেরি ব্যবহার অঙ্গুলিহেলন টাইপিংয়ের সময় ক্রাশ করতে পারে। -\n -\nসতর্কতা: বাহ্যিক কোডের অধিযোজন নিরাপত্তা ঝুঁকির কারণ হতে পারে। বিশ্বস্ত উৎসের লাইব্রেরি ব্যবহার করুন। + \'%s\' এর জন্য লাইব্রেরি প্রয়োজন। অসামঞ্জস্যপূর্ণ লাইব্রেরি ব্যবহার অঙ্গুলিহেলন টাইপিংয়ের সময় ক্রাশ করতে পারে। \n\nসতর্কতা: বাহ্যিক কোডের অধিযোজন নিরাপত্তা ঝুঁকির কারণ হতে পারে। বিশ্বস্ত উৎসের লাইব্রেরি ব্যবহার করুন। লাইব্রেরি অধিযোগ লাইব্রেরি বিলোপ যতিচিহ্নের পরে স্বয়ংক্রিয় স্পেস @@ -99,7 +97,7 @@ অপরিদৃষ্ট হতে পারে এমন বৈশিষ্ট্যের বর্ণনা ডিভাইস সুরক্ষিত স্টোরেজ ► পিন করে রাখা টুলবার বোতামে দীর্ঘ চাপ দিলে তা অতিরিক্ত কাজ করবে: <br> \n\t• ক্লিপবোর্ড &#65515; পেস্ট <br> \n\t• বামে/ডানে স্থানান্তর &#65515; সম্পূর্ণ বামে/ডানে স্থানান্তর <br> \n\t• উপরে/নিচে স্থানান্তর &#65515; পৃষ্ঠার উপরে/নিচে <br> \n\t• শব্দের ডানে/বামে &#65515; লাইনের শুরু/শেষ <br> \n\t• পাতার উপরে/নিচে &#65515; পাতার শুরু/শেষ <br> \n\t• অনুলিপি &#65515; কর্তন <br> \n\t• শব্দ নির্বাচন &#8596; সমস্ত নির্বাচন <br> \n\t• পূর্বাবস্থা &#8596; পুনরাবৃত্তি <br> <br> \n► পরামর্শ ফলকের টুলবারের কোনো বোতামে দীর্ঘ চাপ দিলে তা পরামর্শ ফলকে আবদ্ধ হবে। <br> <br> \n► কমা বোতামে দীর্ঘ চাপ দিলে ক্লিপবোর্ড দর্শন, ইমোজি দর্শন, একক হাত মোড, সেটিংস অথবা ভাষা পরিবর্তন বোতাম উপলব্ধ হবে:<br> \n\t• সংশ্লিষ্ট বোতাম সক্ষম থাকলে ইমোজি দর্শন বা ভাষা পরিবর্তন বোতাম দৃশ্যমান থাকবে না; <br> \n\t• কিছু লেআউটের জন্য কমা বোতাম নয়, কিন্তু একই জায়গার বোতামটি, যেমন: Dvorak লেআউটে \'q\' বোতাম। <br> <br> \n► ছদ্মবেশী মোড সক্রিয় থাকলে শব্দ শিখন বন্ধ থাকবে, এবং সাম্প্রতিকে কোনো ইমোজি যুক্ত হবে না। <br> <br> \n► ছদ্মবেশী বোতামে চাপ দিলে টুলবার উপলব্ধ হবে। <br> <br> \n► স্লাইডিং কি ইনপুট: বড়ো হাতের অক্ষর লেখার জন্য শিফট বোতাম থেকে অন্য বোতামে অভিস্পর্শ করুন: <br> \n\t• সিম্বল কিবোর্ড থেকে সিম্বল এবং সম্পর্কিত অক্ষর লেখার জন্য \'?123\' বোতামেও এটি কাজ করে।<br> <br> \n► শিফট অথবা প্রতীক বোতাম চেপে ধরে এক বা একাধিক বোতাম চাপার পর শিফট অথবা প্রতীক বোতাম ছেড়ে দিলে তা পূর্ববর্তী কিবোর্ডে নিয়ে যাবে। <br> <br> \n► পরামর্শ ফলকে কোনো পরামর্শে দীর্ঘ চাপ দিলে আরও পরামর্শ, বিলোপ করার জন্য অপসারণ বোতাম প্রদর্শিত হবে। <br> <br> \n► আরও পরামর্শ খুলতে কোনো পরামর্শ থেকে উপরে অভিস্পর্শ করুন এবং নির্দিষ্ট পরামর্শ নির্বাচনের জন্য ছেড়ে দিন। <br> <br> \n► ক্লিপবোর্ড ইতিহাসে কোনো অন্তর্ভুক্তিতে দীর্ঘ চাপ দিয়ে তা পিন করা যাবে (আনপিন না করা পর্যন্ত তা ক্লিপবোর্ডে থাকবে) \n► ক্লিপবোর্ড দর্শনে বাম পাশে অভিস্পর্শ করলে অন্তর্ভুক্তি অপসারণ হবে (যদি না সেটি পিন করা থাকে)। <br> <br> \n► লেখা সিলেক্ট করে শিফট চাপলে তা বড়ো হাতের অক্ষর, ছোটো হাতের অক্ষর এবং সব অক্ষর বড়ো হাতের হবে। <br> <br> \n► আপনি ফাইল এক্সপ্লোরারে খোলার মাধ্যমে অভিধান সংযুক্ত করতে পারেন: <br> \n\t• এটি কেবল <i>content-uris</i> এর সাথে কাজ করে, <i>file-uris</i> এর সাথে নয়। অর্থাৎ কিছু ফাইল এক্সপ্লোরারের সাথে নাও কাজ করতে পারে। <br> <br> \n► রুট উপলব্ধতাসহ ম্যানুয়াল ব্যাকআপ করা ব্যবহারকারীদের জন্য: <br> \nঅ্যান্ড্রয়েড ৭ থেকে শেয়ারড্ প্রেফারেন্স ফাইল ডিফল্ট জায়গা নয়। কারণ অ্যাপ %s ব্যবহার করছে। ডিভাইস আনলকের আগে সেটিংস খোলার জন্য এটি প্রয়োজনীয়, যেমন: বুট করার সময়। <br> \nফাইলটি /data/user_de/0/package_id/shared_prefs/ থাকে। যদিও এটা ডিভাইস এবং অ্যান্ড্রয়েড সংস্করণের উপরে নির্ভর করে। <br> <br> \n<i><b>কেবল ডিবাগ এপিকে</b></i> <br> <br> \n► পরামর্শে দীর্ঘ চাপ দিলে তার উৎস-অভিধান দেখাবে। <br> <br> \n► ডিবাগ সেটিংস উচ্চতর সেটিংসে উপলব্ধ। যদিও লগ ফাইলে অভিধান অবমুক্ত করা ছাড়া এর ব্যবহারযোগ্যতা সীমিত। <br> \n\t• রিলিজ এপিকে এর জন্য <i>সম্পর্কে</i> এর সংস্করণে কয়েকবার চাপ দিতে হবে। তাহলে <i>উচ্চতর</i>-এ ডিবাগ সেটিংস উপলব্ধ হবে। <br> \n\t• <i>পরামর্শ তথ্য প্রদর্শন</i> চালু করলে পরামর্শের উপরে কিছু ছোটো নম্বর থাকবে যা অভ্যন্তরীণ হিসাব ও উৎস অভিধান নির্দেশ করে। <br> <br> \n► অ্যাপ্লিকেশন ক্র্যাশের পরে সেটিংস খুললে আপনি ক্র্যাশ লগ চান কি না তা জিজ্ঞেস করা হবে৷ <br> <br> \n► বহুভাষী টাইপিং ব্যবহারের সময় স্পেসবার বর্তমান ভাষা নির্ধারণের জন্য একটি দৃঢ়তা মান দেখাবে। <br> <br> \n► পরামর্শের উপরে কিছু ছোটো নম্বর থাকবে যা অভ্যন্তরীণ হিসাব ও উৎস অভিধান নির্দেশ করে (নিষ্ক্রিয় করা যেতে পারে)। - সার্বীয় (ল্যাটিন) + সার্বিয়ান (ল্যাটিন) ইংরেজি (ইউকে) (%s) ইংরেজি (ইউএস) (%s) স্প্যানিশ (ইউএস) (%s) @@ -110,15 +108,15 @@ %s (প্রভাত) %s (বৈশাখী) %s (সংক্ষিপ্ত) - %s (সেবালসিক 390) - %s (সেবালসিক Final) + %s (সেবালসিক ৩৯০) + %s (সেবালসিক চূড়ান্ত) ভাষাহীন (বর্ণমালা) - বর্ণমালা (QWERTY) + বর্ণমালা (কোয়ার্টি) বর্ণমালা (QWERTZ) বর্ণমালা (AZERTY) - বর্ণমালা (Dvorak) - বর্ণমালা (Colemak) - বর্ণমালা (Colemak Mod-DH) + বর্ণমালা (ডভোরাক) + বর্ণমালা (কোলেমাক) + বর্ণমালা (কোলেমাক Mod-DH) আলফাবেট (ওয়ার্কম্যান) বর্ণমালা (PC) ইমোজি @@ -133,17 +131,17 @@ ভৌত কিবোর্ডের জন্য ইমোজি ভৌত Alt বোতামে ইমোজি প্যালেট প্রদর্শন ডিফল্ট - %s এ স্বাগত\" + %s এ স্বাগত অঙ্গুলিহেলন টাইপিংয়ের সাথে শুরু করা যাক পরবর্তী পদক্ষেপ - %s সন্নিবেশিত হচ্ছে\" - %s সক্ষম করুন\" - "ভাষা ও ইনপুট সেটিংসে \"%s\" সক্রিয় করুন। ফলে এটি আপনার ডিভাইসে চলার অনুমোদন পাবে।" - "আপনার ভাষা ও ইনপুট সেটিংসে ইতোমধ্যে %s সক্ষম করা হয়েছে; তাই এই পদক্ষেপটি সমাপ্ত হয়েছে। পরবর্তীটিতে যান!" + %s সন্নিবেশিত হচ্ছে + %s সক্ষম করুন + ভাষা ও ইনপুট সেটিংসে \"%s\" সক্রিয় করুন। ফলে এটি আপনার ডিভাইসে চলার অনুমোদন পাবে। + আপনার ভাষা ও ইনপুট সেটিংসে ইতোমধ্যে %s সক্ষম করা হয়েছে; তাই এই পদক্ষেপটি সমাপ্ত হয়েছে। পরবর্তীটিতে যান! সেটিংসে সক্ষম করুন - %s এ পরিবর্তন করুন\" - এখন সক্রিয় লিখন-ইনপুট পদ্ধতি হিসেবে \\%s\" বেছে নিন।\" + %s এ পরিবর্তন করুন + এখন সক্রিয় লিখন-ইনপুট পদ্ধতি হিসেবে \"%s\" বেছে নিন। ইনপুট পদ্ধতি পরিবর্তন "অভিনন্দন, আপনি পুরোপুরি প্রস্তুত!" এখন %s দিয়ে আপনার সব পছন্দের অ্যাপে লিখতে পারবেন। @@ -156,24 +154,17 @@ অভ্যন্তরীণ মূল অভিধান "ফাইল থেকে অভিধান সংযুক্তি" ভাষা নির্বাচন - ব্যবহারকারী-যোগকৃত অভিধান \"%1$s\" প্রতিস্থাপন করতে নিশ্চিত? -\n -\nবর্তমান অভিধান: -\n%2$s -\n -\nনতুন অভিধান: -\n%3$s + ব্যবহারকারী-যোগকৃত অভিধান \"%1$s\" প্রতিস্থাপন করতে নিশ্চিত?\n বর্তমান অভিধান: %2$s\n নতুন অভিধান: %3$s "অভিধান প্রতিস্থাপন" ব্যবহারকারী-সংযুক্ত অভিধান \"%s\" অপসারণ করতে নিশ্চিত? - "অভিধান ব্যতীত কেবল পূর্বে সন্নিবেশিত শব্দের জন্য পরামর্শ পাওয়া যাবে।<br> - আপনি %1$s অভিধান ডাউনলোড করতে পারেন, অথবা \"%2$s\" এর জন্য অভিধান সরাসরি ডাউনলোড করা যায় কি না %3$s যাচাই করতে পারেন।" + অভিধান ব্যতীত কেবল পূর্বে সন্নিবেশিত শব্দের জন্য পরামর্শ পাওয়া যাবে।<br> আপনি %1$s অভিধান ডাউনলোড করতে পারেন, অথবা \"%2$s\" এর জন্য অভিধান সরাসরি ডাউনলোড করা যায় কি না %3$s যাচাই করতে পারেন। পুনরায় প্রদর্শিত হবে না অভিধান যোগ করার জন্য নির্বাচন করুন। %s .dict ফরম্যাটে অভিধান ডাউনলোড করা যেতে পারে। ত্রুটি: এই কিবোর্ডের সাথে সামঞ্জস্যপূর্ণ স্ক্রিপ্ট নয় এখানে "ত্রুটি: নির্বাচিত ফাইলটি বৈধ অভিধান ফাইল নয়" "নির্বাচিত ফাইলটি %1$s এর জন্য, %2$s এর জন্য ফাইল প্রয়োজন। তবুও %2$s এর জন্য ব্যবহৃত হবে?" - "তবুও ব্যবহার করুন" + তবুও ব্যবহৃত হবে অভিধান ফাইল অধিযোজন করতে ত্রুটি অভিধান উপলব্ধ কোনো অভিধান উপলব্ধ নয় @@ -437,7 +428,9 @@ অভিধানসহ ভাষা আলোচনা বিভাগ সতর্কতা: লেআউট বর্তমানে ব্যবহৃত হচ্ছে - আপনি %s-তে রং খোঁজা ও শেয়ার করতে পারেন। - আপনি %s-তে লেআউট খোঁজা ও শেয়ার করতে পারেন। + আপনি %s-তে রং সন্ধান ও শেয়ার করতে পারেন। + আপনি %s-তে লেআউট সন্ধান ও শেয়ার করতে পারেন। নিজস্বীকৃত সাবটাইপ + টিএলডি পপআপ বোতাম প্রদর্শন + ইউআরএল ও ইমেইল ঠিকানা লেখার জন্য দাঁড়ি বোতাম টপ লেভেল ডোমেইন দ্বারা প্রতিস্থাপন diff --git a/app/src/main/res/values-ca/strings.xml b/app/src/main/res/values-ca/strings.xml index a2ffde55..1320d1e6 100644 --- a/app/src/main/res/values-ca/strings.xml +++ b/app/src/main/res/values-ca/strings.xml @@ -430,4 +430,6 @@ Podeu trobar i compartir colors a %s. Podeu trobar i compartir disposicions a %s. secció de discussió + Substituir les finestres emergents de la tecla punt per dominis de primer nivell en escriure URLs i adreces de correu electrònic + Mostra tecles emergents de TLD diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index e0092f3f..9af19dee 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -432,4 +432,7 @@ %s wirklich löschen? Ungültiger Name Benutzerdefinierter Subtyp + %s (Baisakhi) + Zeige TLD-Popup-Tasten + Ersetze Punkt-Tastenpopups mit Top-Level-Domains wenn URLs und Mailadressen eingegeben werden diff --git a/app/src/main/res/values-et/strings.xml b/app/src/main/res/values-et/strings.xml index 544a0a0e..ad1bf524 100644 --- a/app/src/main/res/values-et/strings.xml +++ b/app/src/main/res/values-et/strings.xml @@ -467,4 +467,6 @@ Uusi värve võid leida ja jagada %s. Sinu loodud alamtüüp %s (Baishakhi) + Näita tippdomeenide hüpikklahve + Võrgu- ja e-posti aadresside kirjutamisel asenda punktuatsiooni hüpikaknad tipptaseme domeenide omadega diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 8e797e67..2c32cf6f 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -437,4 +437,6 @@ Nouveau dictionnaire: Vous pouvez trouver et partager des couleurs dans le %s. Vous pouvez trouver et partager des dispositions dans le %s. Section de discussion + Afficher les suggestions de domaines (TLD) + Remplacer les suggestions de la touche point par des extensions de domaine (TLD) lors de la saisie d’URL ou d’adresses e-mail diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 6710cee0..af8240d3 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -304,7 +304,7 @@ Il dizionario è stato creato per la lingua %1$s, ma lo stai aggiungendo a %2$s. Confermi? Chiudi Traccia dell\'input gestuale - Tocca la lingua per aprire le impostazioni + Lingua: tap → impostazioni Salva log Holo bianco Dizionario interno principale @@ -432,4 +432,11 @@ Scorciatoie correzione Nome non valido Distanza del trascinamento per il cambio lingua + Sotto-tipo personalizzato + %s (Baishakhi) + Attenzione: il layout è in uso + Lingue con dizionari + discussione dedicata + Scopri nuovi layout o condividi quelli che hai creato nella %s. + Scopri nuove combinazioni di colori o condividi le tue nella %s. diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index 71ac1c1b..81ddbdbf 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -476,4 +476,6 @@ Je kunt lay-outs zoeken en delen in de %s. discussiesectie %s (Baishakhi) + TLD-opties weergeven + Vervang pop-ups met interpunctie door topleveldomeinen bij het typen van URL\'s en e-mailadressen diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index 8c4746aa..53ee52e1 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -94,7 +94,7 @@ "Pokaż ikonę aplikacji" "Wyświetlaj ikonę aplikacji w programie uruchamiającym" "Słowniki dodatkowe" - "Słownik dostępny" + Dostępny słownik "Brak słowników" "Ostatnia aktualizacja" "Ustawienia" @@ -174,13 +174,13 @@ Błąd podczas przywracania kopii zapasowej: %s Kolory Tło klawiszy funkcyjnych - %s (Sebeolsik 390) + %s (Sebeolsik 390) Używaj słownika osobistego do przechowywania nauczonych słów To słowo znajduje się już w słowniku: %s. Wpisz inne. Zaokrąglony Kopia Czarne - %s (Sebeolsik Final) + %s (Sebeolsik Final) Czekoladowe Na pewno usunąć słownik \"%s\" dodany przez użytkownika? Pochmurne @@ -195,7 +195,7 @@ Różowe Języki i układy Nie można odczytać pliku - stąd + tutaj Błąd: wybrany plik nie jest prawidłowym plikiem słownika chronionej pamięci urządzenia Koloruj pasek nawigacyjny @@ -360,7 +360,7 @@ Spacja - przesuwanie pionowe Spacja - przesuwanie poziome Przesuń kursor - Brak przesuwania + Brak Odwróć kierunek po wybraniu układu klawiatury od prawej do lewej Zmienny kierunek paska narzędzi %s (Probhat) @@ -392,7 +392,7 @@ Emotikony Ustaw główny i do 6 drugorzędnych symboli waluty, oddzielonych spacją Dostosuj waluty - Załaduj + Dodaj Skopiuj do schowka Ładowanie spowoduje zastąpienie bieżącego motywu Zapisz do pliku @@ -471,9 +471,11 @@ Nieprawidłowa nazwa Języki ze słownikami Ostrzeżenie: ten układ jest aktualnie używany - Motywy możesz znaleźć i udostępnić w %s . - Układy możesz znaleźć i udostępnić w %s . + Motywy możesz znaleźć i udostępnić w %s. + Układy możesz znaleźć i udostępnić w %s. sekcji dyskusji - Własny podtyp + Własny układ %s (Baishakhi) + Pokaż wyskakujące okienka TLD + Zastąp wyskakujące okienka klawisza kropki domenami najwyższego poziomu podczas wpisywania adresów URL i adresów e-mail diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index 1529f56b..d3804bc1 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -439,4 +439,6 @@ seção de discussão Subtipo customizado %s (Baishakhi) + Mostrar teclas de TLD + Substituir os pop-ups da tecla de ponto com domínios de topo ao digitar URLs e endereços de e-mail diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml index 95df5556..e6c17c2e 100644 --- a/app/src/main/res/values-ro/strings.xml +++ b/app/src/main/res/values-ro/strings.xml @@ -399,4 +399,35 @@ Introducerea vocală este dezactivată Afișează/ascunde bara de instrumente Resetezi cu adevărat toate pictogramele personalizate? + Subtip personalizat + Nume greșit + %s (Baishakhi) + Limbi cu dicționare + Tastatură împărțită + AVERTIZARE: Aspectul este utilizat în prezent + Setează imaginea de fundal (peisaj) + Dacă nu este setat, se va folosi imaginea portret + Poți găsi și împărtăși aspecte în %s. + Conectorul lățimii zero + Ștergi cu adevărat toate codurile cheie personalizate? + Distanța divizării (peisaj) + Activează tastatura divizată (peisaj) + Timp de restabilire a tastării rapide + Comenzi rapide corectare automată + Dacă este activat, comenzile rapide pot fi extinse prin corecție automată + Chiar ștergi %s? + Setează font personalizat din fișier + Suprimă tastele pop-up care sunt deja prezente pe aspectul de bază + Taste funcționale (ecran mare) + Aspecte secundare + Scală umplutură inferioară (peisaj) + Scală font la tastatură + Scală font vizualizare emoji + Coș de reciclare + Scală umplutură laterală (peisaj) + Scală umplutură laterală + Afișează indicii pe rândul cu numere + Distanța de deplasare pentru comutarea limbii + Poți găsi și împărtăși culori în %s. + secțiunea de discuții diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index f20a02d3..d94f2353 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -285,7 +285,7 @@ Holo Белая Смена обоих Вверх - Удалить пользовательский словарь \"%s\"? + Удалить пользовательский словарь «%s»? Не получается прочитать файл здесь Выберите для добавления словаря. Словари в формате .dict можно скачать %s. @@ -307,7 +307,7 @@ Всё ещё используется Выбранный файл предназначен для %1$s, но ожидался %2$s. Всё ещё используете его для %2$s? Ошибка: выбранный файл не является корректным словарем - "Без словаря вы будете получать предложения только для введенного ранее текста.<br>\n Вы можете загрузить словари %1$s или проверить, можно ли загрузить словарь для \"%2$s\" напрямую %3$s." + "Без словаря вы будете получать предложения только для введенного ранее текста.<br>\n Вы можете загрузить словари %1$s или проверить, можно ли загрузить словарь для «%2$s» напрямую %3$s." %s (экспериментальный) Символы Символы (арабские) @@ -425,7 +425,7 @@ Shift Shift (нажат) Caps lock - Голосовой ввод отключен + Голосовой ввод отключён Показать / скрыть панель инструментов Соединитель нулевой ширины Настроить коды клавиш панели инструментов @@ -435,8 +435,8 @@ Разъединитель нулевой ширины Выход из режима работы одной рукой Действительно сбросить все настроенные иконки? - Bin - Вибрировать в режиме Не беспокоить + Корзина + Вибрация в режиме «Не беспокоить» %s (Фонетика) Автокоррекция сочетаний клавиш Установить пользовательский шрифт из файла diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 158233a9..33e5840a 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -433,4 +433,6 @@ 您可以在 %s 中查找和分享颜色。 自定义子类型 %s (Baishakhi) + 输入 URL 和电子邮件地址时,用顶级域替换句点键弹出 + 显示顶级域弹出键 diff --git a/fastlane/metadata/android/bn/full_description.txt b/fastlane/metadata/android/bn/full_description.txt index cd1f98e2..4912bc37 100644 --- a/fastlane/metadata/android/bn/full_description.txt +++ b/fastlane/metadata/android/bn/full_description.txt @@ -1,4 +1,4 @@ -হেলিবোর্ড গোপনীয়তা-সচেতন ওপেন সোর্স কিবোর্ড যার উৎস অ্যান্ড্রয়েড ওপেন সোর্স প্রজেক্ট এবং ওপেনবোর্ড। বাংলা (বাংলাদেশ) ভাষার জন্য এতে ইউনিজয় লেআউট যুক্ত আছে। +হেলিবোর্ড গোপনীয়তা-সচেতন ওপেন সোর্স কিবোর্ড যার উৎস অ্যান্ড্রয়েড ওপেন সোর্স প্রজেক্ট এবং ওপেনবোর্ড। বাংলা ভাষার জন্য এতে ইউনিজয়, প্রভাত, অক্ষর, ইনস্ক্রিপ্ট, বৈশাখী লেআউট যুক্ত আছে। এটি ইন্টারনেটের অনুমতি ব্যবহার করে না, তাই ১০০% অফলাইন। সুবিধা: From 7228fa06d18442274387d39ce6f9ad1881e4e613 Mon Sep 17 00:00:00 2001 From: Helium314 Date: Sat, 22 Mar 2025 19:05:24 +0100 Subject: [PATCH 14/36] move "no limit" clipboard history retantion time to the right side sort of fixes GH-1425 (at least the unclarity about finding the setting) --- app/build.gradle.kts | 2 +- .../main/java/helium314/keyboard/latin/App.kt | 25 +++++++++++-------- .../keyboard/latin/ClipboardHistoryManager.kt | 2 +- .../settings/screens/PreferencesScreen.kt | 4 +-- 4 files changed, 18 insertions(+), 15 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 27915d04..b4d2454b 100755 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -13,7 +13,7 @@ android { applicationId = "helium314.keyboard" minSdk = 21 targetSdk = 34 - versionCode = 3001 + versionCode = 3002 versionName = "3.0-alpha2" ndk { abiFilters.clear() diff --git a/app/src/main/java/helium314/keyboard/latin/App.kt b/app/src/main/java/helium314/keyboard/latin/App.kt index c2d91df5..13f45af1 100644 --- a/app/src/main/java/helium314/keyboard/latin/App.kt +++ b/app/src/main/java/helium314/keyboard/latin/App.kt @@ -530,18 +530,21 @@ fun checkVersionUpgrade(context: Context) { prefs.edit().remove("auto_correction_confidence").putFloat(Settings.PREF_AUTO_CORRECT_THRESHOLD, value).apply() } } - if (oldVersion <= 2310) { - listOf( - Settings.PREF_ENABLED_SUBTYPES, - Settings.PREF_SELECTED_SUBTYPE, - Settings.PREF_ADDITIONAL_SUBTYPES - ).forEach { key -> - val value = prefs.getString(key, "")!! - if ("bengali," in value) { - prefs.edit().putString(key, value.replace("bengali,", "bengali_inscript,")).apply() - } + if (oldVersion <= 2310) { + listOf( + Settings.PREF_ENABLED_SUBTYPES, + Settings.PREF_SELECTED_SUBTYPE, + Settings.PREF_ADDITIONAL_SUBTYPES + ).forEach { key -> + val value = prefs.getString(key, "")!! + if ("bengali," in value) { + prefs.edit().putString(key, value.replace("bengali,", "bengali_inscript,")).apply() + } + } + } + if (oldVersion <= 3001 && prefs.getInt(Settings.PREF_CLIPBOARD_HISTORY_RETENTION_TIME, Defaults.PREF_CLIPBOARD_HISTORY_RETENTION_TIME) <= 0) { + prefs.edit().putInt(Settings.PREF_CLIPBOARD_HISTORY_RETENTION_TIME, 121).apply() } -} upgradeToolbarPrefs(prefs) LayoutUtilsCustom.onLayoutFileChanged() // just to be sure prefs.edit { putInt(Settings.PREF_VERSION_CODE, BuildConfig.VERSION_CODE) } diff --git a/app/src/main/java/helium314/keyboard/latin/ClipboardHistoryManager.kt b/app/src/main/java/helium314/keyboard/latin/ClipboardHistoryManager.kt index 3a279046..b5d62188 100644 --- a/app/src/main/java/helium314/keyboard/latin/ClipboardHistoryManager.kt +++ b/app/src/main/java/helium314/keyboard/latin/ClipboardHistoryManager.kt @@ -120,7 +120,7 @@ class ClipboardHistoryManager( private fun checkClipRetentionElapsed() { val mins = latinIME.mSettings.current.mClipboardHistoryRetentionTime - if (mins <= 0) return // No retention limit + if (mins > 120) return // No retention limit, changed from <= 0 because we want it to be larger than all other choices val maxClipRetentionTime = mins * 60 * 1000L val now = System.currentTimeMillis() historyEntries.removeAll { !it.isPinned && (now - it.timeStamp) > maxClipRetentionTime } diff --git a/app/src/main/java/helium314/keyboard/settings/screens/PreferencesScreen.kt b/app/src/main/java/helium314/keyboard/settings/screens/PreferencesScreen.kt index d7e88c84..584ae858 100644 --- a/app/src/main/java/helium314/keyboard/settings/screens/PreferencesScreen.kt +++ b/app/src/main/java/helium314/keyboard/settings/screens/PreferencesScreen.kt @@ -156,10 +156,10 @@ fun createPreferencesSettings(context: Context) = listOf( key = setting.key, default = Defaults.PREF_CLIPBOARD_HISTORY_RETENTION_TIME, description = { - if (it < 0) stringResource(R.string.settings_no_limit) + if (it > 120) stringResource(R.string.settings_no_limit) else stringResource(R.string.abbreviation_unit_minutes, it.toString()) }, - range = -1f..120f, + range = 1f..121f, ) }, Setting(context, Settings.PREF_VIBRATION_DURATION_SETTINGS, R.string.prefs_keypress_vibration_duration_settings) { setting -> From 9e91e7562b1e39140380088e57f2028b43bbf677 Mon Sep 17 00:00:00 2001 From: Helium314 Date: Sat, 22 Mar 2025 19:27:38 +0100 Subject: [PATCH 15/36] add another setting to disable always show suggestions just for web edit fields, which seem fo frequenty cause issues with this setting --- .../java/helium314/keyboard/latin/settings/Defaults.kt | 1 + .../java/helium314/keyboard/latin/settings/Settings.java | 1 + .../helium314/keyboard/latin/settings/SettingsValues.java | 6 +++++- .../keyboard/settings/screens/TextCorrectionScreen.kt | 7 +++++++ app/src/main/res/values/strings.xml | 4 ++++ 5 files changed, 18 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/helium314/keyboard/latin/settings/Defaults.kt b/app/src/main/java/helium314/keyboard/latin/settings/Defaults.kt index 1a890fa2..58ef7939 100644 --- a/app/src/main/java/helium314/keyboard/latin/settings/Defaults.kt +++ b/app/src/main/java/helium314/keyboard/latin/settings/Defaults.kt @@ -66,6 +66,7 @@ object Defaults { const val PREF_CENTER_SUGGESTION_TEXT_TO_ENTER = false const val PREF_SHOW_SUGGESTIONS = true const val PREF_ALWAYS_SHOW_SUGGESTIONS = false + const val PREF_ALWAYS_SHOW_SUGGESTIONS_EXCEPT_WEB_TEXT = true const val PREF_KEY_USE_PERSONALIZED_DICTS = true const val PREF_KEY_USE_DOUBLE_SPACE_PERIOD = true const val PREF_BLOCK_POTENTIALLY_OFFENSIVE = true diff --git a/app/src/main/java/helium314/keyboard/latin/settings/Settings.java b/app/src/main/java/helium314/keyboard/latin/settings/Settings.java index 6d45548a..bad339e5 100644 --- a/app/src/main/java/helium314/keyboard/latin/settings/Settings.java +++ b/app/src/main/java/helium314/keyboard/latin/settings/Settings.java @@ -74,6 +74,7 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang public static final String PREF_CENTER_SUGGESTION_TEXT_TO_ENTER = "center_suggestion_text_to_enter"; public static final String PREF_SHOW_SUGGESTIONS = "show_suggestions"; public static final String PREF_ALWAYS_SHOW_SUGGESTIONS = "always_show_suggestions"; + public static final String PREF_ALWAYS_SHOW_SUGGESTIONS_EXCEPT_WEB_TEXT = "always_show_suggestions_except_web_text"; public static final String PREF_KEY_USE_PERSONALIZED_DICTS = "use_personalized_dicts"; public static final String PREF_KEY_USE_DOUBLE_SPACE_PERIOD = "use_double_space_period"; public static final String PREF_BLOCK_POTENTIALLY_OFFENSIVE = "block_potentially_offensive"; diff --git a/app/src/main/java/helium314/keyboard/latin/settings/SettingsValues.java b/app/src/main/java/helium314/keyboard/latin/settings/SettingsValues.java index 9a18fde2..376c3668 100644 --- a/app/src/main/java/helium314/keyboard/latin/settings/SettingsValues.java +++ b/app/src/main/java/helium314/keyboard/latin/settings/SettingsValues.java @@ -11,6 +11,7 @@ import android.content.Context; import android.content.SharedPreferences; import android.content.res.Configuration; import android.content.res.Resources; +import android.text.InputType; import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputMethodSubtype; @@ -221,7 +222,10 @@ public class SettingsValues { mGestureFastTypingCooldown = prefs.getInt(Settings.PREF_GESTURE_FAST_TYPING_COOLDOWN, Defaults.PREF_GESTURE_FAST_TYPING_COOLDOWN); mGestureTrailFadeoutDuration = prefs.getInt(Settings.PREF_GESTURE_TRAIL_FADEOUT_DURATION, Defaults.PREF_GESTURE_TRAIL_FADEOUT_DURATION); mAccount = null; // remove? or can it be useful somewhere? - mOverrideShowingSuggestions = mInputAttributes.mMayOverrideShowingSuggestions && prefs.getBoolean(Settings.PREF_ALWAYS_SHOW_SUGGESTIONS, Defaults.PREF_ALWAYS_SHOW_SUGGESTIONS); + mOverrideShowingSuggestions = mInputAttributes.mMayOverrideShowingSuggestions + && prefs.getBoolean(Settings.PREF_ALWAYS_SHOW_SUGGESTIONS, Defaults.PREF_ALWAYS_SHOW_SUGGESTIONS) + && ((inputAttributes.mInputType & InputType.TYPE_MASK_VARIATION) != InputType.TYPE_TEXT_VARIATION_WEB_EDIT_TEXT + || !prefs.getBoolean(Settings.PREF_ALWAYS_SHOW_SUGGESTIONS_EXCEPT_WEB_TEXT, Defaults.PREF_ALWAYS_SHOW_SUGGESTIONS_EXCEPT_WEB_TEXT)); final boolean suggestionsEnabled = prefs.getBoolean(Settings.PREF_SHOW_SUGGESTIONS, Defaults.PREF_SHOW_SUGGESTIONS); mSuggestionsEnabledPerUserSettings = (mInputAttributes.mShouldShowSuggestions && suggestionsEnabled) || mOverrideShowingSuggestions; diff --git a/app/src/main/java/helium314/keyboard/settings/screens/TextCorrectionScreen.kt b/app/src/main/java/helium314/keyboard/settings/screens/TextCorrectionScreen.kt index 97d64188..f2d57048 100644 --- a/app/src/main/java/helium314/keyboard/settings/screens/TextCorrectionScreen.kt +++ b/app/src/main/java/helium314/keyboard/settings/screens/TextCorrectionScreen.kt @@ -63,6 +63,8 @@ fun TextCorrectionScreen( R.string.settings_category_suggestions, Settings.PREF_SHOW_SUGGESTIONS, if (suggestionsEnabled) Settings.PREF_ALWAYS_SHOW_SUGGESTIONS else null, + if (suggestionsEnabled && prefs.getBoolean(Settings.PREF_ALWAYS_SHOW_SUGGESTIONS, Defaults.PREF_ALWAYS_SHOW_SUGGESTIONS)) + Settings.PREF_ALWAYS_SHOW_SUGGESTIONS_EXCEPT_WEB_TEXT else null, if (suggestionsEnabled) Settings.PREF_CENTER_SUGGESTION_TEXT_TO_ENTER else null, Settings.PREF_KEY_USE_PERSONALIZED_DICTS, Settings.PREF_BIGRAM_PREDICTIONS, @@ -139,6 +141,11 @@ fun createCorrectionSettings(context: Context) = listOf( ) { SwitchPreference(it, Defaults.PREF_ALWAYS_SHOW_SUGGESTIONS) }, + Setting(context, Settings.PREF_ALWAYS_SHOW_SUGGESTIONS_EXCEPT_WEB_TEXT, + R.string.prefs_always_show_suggestions_except_web_text, R.string.prefs_always_show_suggestions_except_web_text_summary + ) { + SwitchPreference(it, Defaults.PREF_ALWAYS_SHOW_SUGGESTIONS_EXCEPT_WEB_TEXT) + }, Setting(context, Settings.PREF_KEY_USE_PERSONALIZED_DICTS, R.string.use_personalized_dicts, R.string.use_personalized_dicts_summary ) { setting -> diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index e063b07c..f683b120 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -104,6 +104,10 @@ Always show suggestions Ignore other apps’ request to disable suggestions (may cause issues) + + Don’t always show suggestions for web edit fields + + Web edit fields (mostly found in browsers) are a very common cause for issues with the always show suggestions setting Block offensive words From efaddf6c5194e0b8f7afedf58d66d83432096bb4 Mon Sep 17 00:00:00 2001 From: Helium314 Date: Sat, 22 Mar 2025 19:34:27 +0100 Subject: [PATCH 16/36] store clipboard history as strings, fixes GH-1430 --- .../keyboard/latin/ClipboardHistoryEntry.kt | 18 +----------------- .../keyboard/latin/ClipboardHistoryManager.kt | 6 +++--- 2 files changed, 4 insertions(+), 20 deletions(-) diff --git a/app/src/main/java/helium314/keyboard/latin/ClipboardHistoryEntry.kt b/app/src/main/java/helium314/keyboard/latin/ClipboardHistoryEntry.kt index bb6cf5bf..1990ee92 100644 --- a/app/src/main/java/helium314/keyboard/latin/ClipboardHistoryEntry.kt +++ b/app/src/main/java/helium314/keyboard/latin/ClipboardHistoryEntry.kt @@ -2,18 +2,12 @@ package helium314.keyboard.latin -import kotlinx.serialization.KSerializer import kotlinx.serialization.Serializable -import kotlinx.serialization.descriptors.PrimitiveKind -import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor -import kotlinx.serialization.encoding.Decoder -import kotlinx.serialization.encoding.Encoder @Serializable data class ClipboardHistoryEntry ( var timeStamp: Long, - @Serializable(with = CharSequenceStringSerializer::class) - val content: CharSequence, + val content: String, var isPinned: Boolean = false ) : Comparable { override fun compareTo(other: ClipboardHistoryEntry): Int { @@ -21,13 +15,3 @@ data class ClipboardHistoryEntry ( return if (result != 0) result else other.timeStamp.compareTo(timeStamp) } } - -class CharSequenceStringSerializer : KSerializer { - override val descriptor = PrimitiveSerialDescriptor("CharSequence", PrimitiveKind.STRING) - - override fun serialize(encoder: Encoder, value: CharSequence) { - encoder.encodeString(value.toString()) - } - - override fun deserialize(decoder: Decoder) = decoder.decodeString() -} \ No newline at end of file diff --git a/app/src/main/java/helium314/keyboard/latin/ClipboardHistoryManager.kt b/app/src/main/java/helium314/keyboard/latin/ClipboardHistoryManager.kt index b5d62188..8d41cfb7 100644 --- a/app/src/main/java/helium314/keyboard/latin/ClipboardHistoryManager.kt +++ b/app/src/main/java/helium314/keyboard/latin/ClipboardHistoryManager.kt @@ -61,7 +61,7 @@ class ClipboardHistoryManager( val content = clipItem.coerceToText(latinIME) if (TextUtils.isEmpty(content)) return - val duplicateEntryIndex = historyEntries.indexOfFirst { it.content.toString() == content.toString() } + val duplicateEntryIndex = historyEntries.indexOfFirst { it.content == content.toString() } if (duplicateEntryIndex != -1) { val existingEntry = historyEntries[duplicateEntryIndex] if (existingEntry.timeStamp == timeStamp) return // nothing to change (may occur frequently starting with API 30) @@ -74,9 +74,9 @@ class ClipboardHistoryManager( onHistoryChangeListener?.onClipboardHistoryEntryMoved(duplicateEntryIndex, newIndex) return } - if (historyEntries.any { it.content.toString() == content.toString() }) return + if (historyEntries.any { it.content == content.toString() }) return - val entry = ClipboardHistoryEntry(timeStamp, content) + val entry = ClipboardHistoryEntry(timeStamp, content.toString()) historyEntries.add(entry) sortHistoryEntries() val at = historyEntries.indexOf(entry) From 2fe0937ead59976fc17543c8db618a0ae30e8959 Mon Sep 17 00:00:00 2001 From: Helium314 Date: Sat, 22 Mar 2025 20:05:51 +0100 Subject: [PATCH 17/36] apparently people want smaller icons --- .../java/helium314/keyboard/settings/preferences/Preference.kt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/src/main/java/helium314/keyboard/settings/preferences/Preference.kt b/app/src/main/java/helium314/keyboard/settings/preferences/Preference.kt index 00a30c23..a60e6298 100644 --- a/app/src/main/java/helium314/keyboard/settings/preferences/Preference.kt +++ b/app/src/main/java/helium314/keyboard/settings/preferences/Preference.kt @@ -10,7 +10,6 @@ import androidx.compose.foundation.layout.RowScope import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.heightIn import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.Icon import androidx.compose.material3.LocalContentColor @@ -70,7 +69,7 @@ fun Preference( verticalAlignment = Alignment.CenterVertically ) { if (icon != null) - IconOrImage(icon, name, 36f) + IconOrImage(icon, name, 32f) Column(modifier = Modifier.weight(1f)) { Text(text = name, style = MaterialTheme.typography.bodyLarge) if (description != null) { From 88a7f410381024a92b2c5d092d02f096309d482c Mon Sep 17 00:00:00 2001 From: EduRGB <25287542+EduRGB@users.noreply.github.com> Date: Sat, 22 Mar 2025 20:28:56 +0100 Subject: [PATCH 18/36] Layout for shift + long press on number row (#1400) Add full-featured number row layout and set it as default; set existing layout as basic. --- .../assets/layouts/number_row/number_row.json | 44 +++++++++++++++++++ .../{number_row.txt => number_row_basic.txt} | 2 +- app/src/main/res/values/strings.xml | 2 + 3 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 app/src/main/assets/layouts/number_row/number_row.json rename app/src/main/assets/layouts/number_row/{number_row.txt => number_row_basic.txt} (85%) diff --git a/app/src/main/assets/layouts/number_row/number_row.json b/app/src/main/assets/layouts/number_row/number_row.json new file mode 100644 index 00000000..3ad11861 --- /dev/null +++ b/app/src/main/assets/layouts/number_row/number_row.json @@ -0,0 +1,44 @@ +[ + [ + { "$": "shift_state_selector", + "manualOrLocked": { "label": "!" }, + "default": { "label": "1", "popup": { "relevant": [{ "label": "¹" }, { "label": "½" }, { "label": "⅓" }, { "label": "¼" }, { "label": "⅛" }] } } + }, + { "$": "shift_state_selector", + "manualOrLocked": { "label": "@" }, + "default": { "label": "2", "popup": { "relevant": [{ "label": "²" }, { "label": "⅔" }] } } + }, + { "$": "shift_state_selector", + "manualOrLocked": { "label": "#" }, + "default": { "label": "3", "popup": { "relevant": [{ "label": "³" }, { "label": "¾" }, { "label": "⅜" }] } } + }, + { "$": "shift_state_selector", + "manualOrLocked": { "label": "$" }, + "default": { "label": "4", "popup": { "relevant": [{ "label": "⁴" }] } } + }, + { "$": "shift_state_selector", + "manualOrLocked": { "label": "%" }, + "default": { "label": "5", "popup": { "relevant": [{ "label": "⁵" }, { "label": "⅝" }] } } + }, + { "$": "shift_state_selector", + "manualOrLocked": { "label": "^" }, + "default": { "label": "6", "popup": { "relevant": [{ "label": "⁶" }] } } + }, + { "$": "shift_state_selector", + "manualOrLocked": { "label": "&" }, + "default": { "label": "7", "popup": { "relevant": [{ "label": "⁷" }, { "label": "⅞" }] } } + }, + { "$": "shift_state_selector", + "manualOrLocked": { "label": "*" }, + "default": { "label": "8", "popup": { "relevant": [{ "label": "⁸" }] } } + }, + { "$": "shift_state_selector", + "manualOrLocked": { "label": "(" }, + "default": { "label": "9", "popup": { "relevant": [{ "label": "⁹" }] } } + }, + { "$": "shift_state_selector", + "manualOrLocked": { "label": ")" }, + "default": { "label": "0", "popup": { "relevant": [{ "label": "⁰" }, { "label": "ⁿ" }, { "label": "∅" }] } } + } + ] + ] \ No newline at end of file diff --git a/app/src/main/assets/layouts/number_row/number_row.txt b/app/src/main/assets/layouts/number_row/number_row_basic.txt similarity index 85% rename from app/src/main/assets/layouts/number_row/number_row.txt rename to app/src/main/assets/layouts/number_row/number_row_basic.txt index a7fed81c..709c30a8 100644 --- a/app/src/main/assets/layouts/number_row/number_row.txt +++ b/app/src/main/assets/layouts/number_row/number_row_basic.txt @@ -7,4 +7,4 @@ 7 ⁷ ⅞ 8 ⁸ 9 ⁹ -0 ⁰ ⁿ ∅ +0 ⁰ ⁿ ∅ \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index f683b120..9873295b 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -563,6 +563,8 @@ disposition rather than other common dispositions for Latin languages. --> Numpad (landscape) Number row + + Number row (basic) Emoji bottom row From 66a07eb8d2844baca464705705a3942b6e85cad8 Mon Sep 17 00:00:00 2001 From: Helium314 Date: Wed, 26 Mar 2025 18:05:00 +0100 Subject: [PATCH 19/36] Add more settings for autospace fixes GH-1348 fixes GH-876 --- .../keyboard/latin/WordComposer.java | 4 ++++ .../keyboard/latin/inputlogic/InputLogic.java | 19 +++++++++++-------- .../keyboard/latin/settings/Defaults.kt | 4 ++++ .../keyboard/latin/settings/Settings.java | 4 ++++ .../latin/settings/SettingsValues.java | 12 ++++++++++-- .../settings/screens/TextCorrectionScreen.kt | 19 +++++++++++++++++++ app/src/main/res/values/strings.xml | 16 ++++++++++++++-- 7 files changed, 66 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/helium314/keyboard/latin/WordComposer.java b/app/src/main/java/helium314/keyboard/latin/WordComposer.java index d67f50d7..203eb205 100644 --- a/app/src/main/java/helium314/keyboard/latin/WordComposer.java +++ b/app/src/main/java/helium314/keyboard/latin/WordComposer.java @@ -474,6 +474,10 @@ public final class WordComposer { return mIsBatchMode; } + public void unsetBatchMode() { + mIsBatchMode = false; + } + public void setRejectedBatchModeSuggestion(final String rejectedSuggestion) { mRejectedBatchModeSuggestion = rejectedSuggestion; } diff --git a/app/src/main/java/helium314/keyboard/latin/inputlogic/InputLogic.java b/app/src/main/java/helium314/keyboard/latin/inputlogic/InputLogic.java index 83d00864..b98906ef 100644 --- a/app/src/main/java/helium314/keyboard/latin/inputlogic/InputLogic.java +++ b/app/src/main/java/helium314/keyboard/latin/inputlogic/InputLogic.java @@ -323,7 +323,8 @@ public final class InputLogic { // Don't allow cancellation of manual pick mLastComposedWord.deactivate(); // Space state must be updated before calling updateShiftState - mSpaceState = SpaceState.PHANTOM; + if (settingsValues.mAutospaceAfterSuggestion) + mSpaceState = SpaceState.PHANTOM; inputTransaction.requireShiftUpdate(InputTransaction.SHIFT_UPDATE_NOW); // If we're not showing the "Touch again to save", then update the suggestion strip. @@ -546,7 +547,8 @@ public final class InputLogic { || settingsValues.isUsuallyFollowedBySpace(codePointBeforeCursor)) { final boolean autoShiftHasBeenOverriden = keyboardSwitcher.getKeyboardShiftMode() != getCurrentAutoCapsState(settingsValues); - mSpaceState = SpaceState.PHANTOM; + if (settingsValues.mAutospaceBeforeGestureTyping) + mSpaceState = SpaceState.PHANTOM; if (!autoShiftHasBeenOverriden) { // When we change the space state, we need to update the shift state of the // keyboard unless it has been overridden manually. This is happening for example @@ -686,10 +688,7 @@ public final class InputLogic { if (mSuggestedWords.isPrediction()) { inputTransaction.setRequiresUpdateSuggestions(); } - // undo phantom space if it's because after punctuation - // users who want to start a sentence with a lowercase letter may not like it - if (mSpaceState == SpaceState.PHANTOM - && inputTransaction.getMSettingsValues().isUsuallyFollowedBySpace(mConnection.getCodePointBeforeCursor())) + if (mSpaceState == SpaceState.PHANTOM && inputTransaction.getMSettingsValues().mShiftRemovesAutospace) mSpaceState = SpaceState.NONE; break; case KeyCode.SETTINGS: @@ -930,6 +929,7 @@ public final class InputLogic { // handleNonSpecialCharacterEvent which has the same name as other handle* methods but is // not the same. boolean isComposingWord = mWordComposer.isComposingWord(); + mWordComposer.unsetBatchMode(); // relevant in case we continue a batch word with normal typing // if we continue directly after a sometimesWordConnector, restart suggestions for the whole word // (only with URL detection and suggestions enabled) @@ -1127,7 +1127,7 @@ public final class InputLogic { // A double quote behaves like it's usually followed by space if we're inside // a double quote. if (wasComposingWord - && settingsValues.mAutospaceAfterPunctuationEnabled + && settingsValues.mAutospaceAfterPunctuation && (settingsValues.isUsuallyFollowedBySpace(codePoint) || isInsideDoubleQuoteOrAfterDigit)) { mSpaceState = SpaceState.PHANTOM; } @@ -2168,6 +2168,7 @@ public final class InputLogic { && !(mConnection.getCodePointBeforeCursor() == Constants.CODE_PERIOD && mConnection.wordBeforeCursorMayBeEmail()) ) { mConnection.commitCodePoint(Constants.CODE_SPACE); + // todo: why not remove phantom space state? } } @@ -2202,12 +2203,14 @@ public final class InputLogic { mConnection.beginBatchEdit(); if (SpaceState.PHANTOM == mSpaceState) { insertAutomaticSpaceIfOptionsAndTextAllow(settingsValues); + mSpaceState = SpaceState.NONE; } mWordComposer.setBatchInputWord(batchInputText); setComposingTextInternal(batchInputText, 1); mConnection.endBatchEdit(); // Space state must be updated before calling updateShiftState - mSpaceState = SpaceState.PHANTOM; + if (settingsValues.mAutospaceAfterGestureTyping) + mSpaceState = SpaceState.PHANTOM; keyboardSwitcher.requestUpdatingShiftState(getCurrentAutoCapsState(settingsValues), getCurrentRecapitalizeState()); } diff --git a/app/src/main/java/helium314/keyboard/latin/settings/Defaults.kt b/app/src/main/java/helium314/keyboard/latin/settings/Defaults.kt index 58ef7939..08df4eac 100644 --- a/app/src/main/java/helium314/keyboard/latin/settings/Defaults.kt +++ b/app/src/main/java/helium314/keyboard/latin/settings/Defaults.kt @@ -92,6 +92,10 @@ object Defaults { const val PREF_SPACE_VERTICAL_SWIPE = "none" const val PREF_DELETE_SWIPE = true const val PREF_AUTOSPACE_AFTER_PUNCTUATION = false + const val PREF_AUTOSPACE_AFTER_SUGGESTION = true + const val PREF_AUTOSPACE_AFTER_GESTURE_TYPING = true + const val PREF_AUTOSPACE_BEFORE_GESTURE_TYPING = true + const val PREF_SHIFT_REMOVES_AUTOSPACE = false const val PREF_ALWAYS_INCOGNITO_MODE = false const val PREF_BIGRAM_PREDICTIONS = true const val PREF_SUGGEST_CLIPBOARD_CONTENT = true diff --git a/app/src/main/java/helium314/keyboard/latin/settings/Settings.java b/app/src/main/java/helium314/keyboard/latin/settings/Settings.java index bad339e5..08bf53b3 100644 --- a/app/src/main/java/helium314/keyboard/latin/settings/Settings.java +++ b/app/src/main/java/helium314/keyboard/latin/settings/Settings.java @@ -98,6 +98,10 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang public static final String PREF_SPACE_VERTICAL_SWIPE = "vertical_space_swipe"; public static final String PREF_DELETE_SWIPE = "delete_swipe"; public static final String PREF_AUTOSPACE_AFTER_PUNCTUATION = "autospace_after_punctuation"; + public static final String PREF_AUTOSPACE_AFTER_SUGGESTION = "autospace_after_suggestion"; + public static final String PREF_AUTOSPACE_AFTER_GESTURE_TYPING = "autospace_after_gesture_typing"; + public static final String PREF_AUTOSPACE_BEFORE_GESTURE_TYPING = "autospace_before_gesture_typing"; + public static final String PREF_SHIFT_REMOVES_AUTOSPACE = "shift_removes_autospace"; public static final String PREF_ALWAYS_INCOGNITO_MODE = "always_incognito_mode"; public static final String PREF_BIGRAM_PREDICTIONS = "next_word_prediction"; public static final String PREF_SUGGEST_CLIPBOARD_CONTENT = "suggest_clipboard_content"; diff --git a/app/src/main/java/helium314/keyboard/latin/settings/SettingsValues.java b/app/src/main/java/helium314/keyboard/latin/settings/SettingsValues.java index 376c3668..3430ae04 100644 --- a/app/src/main/java/helium314/keyboard/latin/settings/SettingsValues.java +++ b/app/src/main/java/helium314/keyboard/latin/settings/SettingsValues.java @@ -77,7 +77,11 @@ public class SettingsValues { public final int mSpaceSwipeVertical; public final int mLanguageSwipeDistance; public final boolean mDeleteSwipeEnabled; - public final boolean mAutospaceAfterPunctuationEnabled; + public final boolean mAutospaceAfterPunctuation; + public final boolean mAutospaceAfterSuggestion; + public final boolean mAutospaceAfterGestureTyping; + public final boolean mAutospaceBeforeGestureTyping; + public final boolean mShiftRemovesAutospace; public final boolean mClipboardHistoryEnabled; public final long mClipboardHistoryRetentionTime; public final boolean mOneHandedModeEnabled; @@ -236,7 +240,11 @@ public class SettingsValues { mSpaceSwipeVertical = Settings.readVerticalSpaceSwipe(prefs); mLanguageSwipeDistance = prefs.getInt(Settings.PREF_LANGUAGE_SWIPE_DISTANCE, Defaults.PREF_LANGUAGE_SWIPE_DISTANCE); mDeleteSwipeEnabled = prefs.getBoolean(Settings.PREF_DELETE_SWIPE, Defaults.PREF_DELETE_SWIPE); - mAutospaceAfterPunctuationEnabled = prefs.getBoolean(Settings.PREF_AUTOSPACE_AFTER_PUNCTUATION, Defaults.PREF_AUTOSPACE_AFTER_PUNCTUATION); + mAutospaceAfterPunctuation = prefs.getBoolean(Settings.PREF_AUTOSPACE_AFTER_PUNCTUATION, Defaults.PREF_AUTOSPACE_AFTER_PUNCTUATION); + mAutospaceAfterSuggestion = prefs.getBoolean(Settings.PREF_AUTOSPACE_AFTER_SUGGESTION, Defaults.PREF_AUTOSPACE_AFTER_SUGGESTION); + mAutospaceAfterGestureTyping = prefs.getBoolean(Settings.PREF_AUTOSPACE_AFTER_GESTURE_TYPING, Defaults.PREF_AUTOSPACE_AFTER_GESTURE_TYPING); + mAutospaceBeforeGestureTyping = prefs.getBoolean(Settings.PREF_AUTOSPACE_BEFORE_GESTURE_TYPING, Defaults.PREF_AUTOSPACE_BEFORE_GESTURE_TYPING); + mShiftRemovesAutospace = prefs.getBoolean(Settings.PREF_SHIFT_REMOVES_AUTOSPACE, Defaults.PREF_SHIFT_REMOVES_AUTOSPACE); mClipboardHistoryEnabled = prefs.getBoolean(Settings.PREF_ENABLE_CLIPBOARD_HISTORY, Defaults.PREF_ENABLE_CLIPBOARD_HISTORY); mClipboardHistoryRetentionTime = prefs.getInt(Settings.PREF_CLIPBOARD_HISTORY_RETENTION_TIME, Defaults.PREF_CLIPBOARD_HISTORY_RETENTION_TIME); diff --git a/app/src/main/java/helium314/keyboard/settings/screens/TextCorrectionScreen.kt b/app/src/main/java/helium314/keyboard/settings/screens/TextCorrectionScreen.kt index f2d57048..f322e0f0 100644 --- a/app/src/main/java/helium314/keyboard/settings/screens/TextCorrectionScreen.kt +++ b/app/src/main/java/helium314/keyboard/settings/screens/TextCorrectionScreen.kt @@ -22,6 +22,7 @@ import helium314.keyboard.latin.R import helium314.keyboard.latin.permissions.PermissionsUtil import helium314.keyboard.latin.settings.Defaults import helium314.keyboard.latin.settings.Settings +import helium314.keyboard.latin.utils.JniUtils import helium314.keyboard.latin.utils.Log import helium314.keyboard.latin.utils.getActivity import helium314.keyboard.latin.utils.prefs @@ -49,6 +50,7 @@ fun TextCorrectionScreen( Log.v("irrelevant", "stupid way to trigger recomposition on preference change") val autocorrectEnabled = prefs.getBoolean(Settings.PREF_AUTO_CORRECTION, Defaults.PREF_AUTO_CORRECTION) val suggestionsEnabled = prefs.getBoolean(Settings.PREF_SHOW_SUGGESTIONS, Defaults.PREF_SHOW_SUGGESTIONS) + val gestureEnabled = JniUtils.sHaveGestureLib && prefs.getBoolean(Settings.PREF_GESTURE_INPUT, Defaults.PREF_GESTURE_INPUT) val items = listOf( SettingsWithoutKey.EDIT_PERSONAL_DICTIONARY, R.string.settings_category_correction, @@ -58,8 +60,13 @@ fun TextCorrectionScreen( if (autocorrectEnabled) Settings.PREF_AUTOCORRECT_SHORTCUTS else null, if (autocorrectEnabled) Settings.PREF_AUTO_CORRECT_THRESHOLD else null, Settings.PREF_AUTO_CAP, + R.string.settings_category_space, Settings.PREF_KEY_USE_DOUBLE_SPACE_PERIOD, Settings.PREF_AUTOSPACE_AFTER_PUNCTUATION, + Settings.PREF_AUTOSPACE_AFTER_SUGGESTION, + if (gestureEnabled) Settings.PREF_AUTOSPACE_BEFORE_GESTURE_TYPING else null, + if (gestureEnabled) Settings.PREF_AUTOSPACE_AFTER_GESTURE_TYPING else null, + Settings.PREF_SHIFT_REMOVES_AUTOSPACE, R.string.settings_category_suggestions, Settings.PREF_SHOW_SUGGESTIONS, if (suggestionsEnabled) Settings.PREF_ALWAYS_SHOW_SUGGESTIONS else null, @@ -131,6 +138,18 @@ fun createCorrectionSettings(context: Context) = listOf( ) { SwitchPreference(it, Defaults.PREF_AUTOSPACE_AFTER_PUNCTUATION) }, + Setting(context, Settings.PREF_AUTOSPACE_AFTER_SUGGESTION, R.string.autospace_after_suggestion) { + SwitchPreference(it, Defaults.PREF_AUTOSPACE_AFTER_SUGGESTION) + }, + Setting(context, Settings.PREF_AUTOSPACE_AFTER_GESTURE_TYPING, R.string.autospace_after_gesture_typing) { + SwitchPreference(it, Defaults.PREF_AUTOSPACE_AFTER_GESTURE_TYPING) + }, + Setting(context, Settings.PREF_AUTOSPACE_BEFORE_GESTURE_TYPING, R.string.autospace_before_gesture_typing) { + SwitchPreference(it, Defaults.PREF_AUTOSPACE_BEFORE_GESTURE_TYPING) + }, + Setting(context, Settings.PREF_SHIFT_REMOVES_AUTOSPACE, R.string.shift_removes_autospace, R.string.shift_removes_autospace_summary) { + SwitchPreference(it, Defaults.PREF_SHIFT_REMOVES_AUTOSPACE) + }, Setting(context, Settings.PREF_SHOW_SUGGESTIONS, R.string.prefs_show_suggestions, R.string.prefs_show_suggestions_summary ) { diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 9873295b..aecf63b6 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -38,6 +38,8 @@ Clipboard history Corrections + + Space Suggestions @@ -209,10 +211,20 @@ Load library Delete library - + Autospace after punctuation - + Automatically insert space after punctuation when typing a new word + + Autospace after picking a suggestion + + Autospace before gesture typing a word + + Autospace after gesture typing a word + + No autospace when pressing shift + + Shift removes pending autospace Show more letters with diacritics in popup From b600431af9cdd3166e3cd547b85f63d29956f6d5 Mon Sep 17 00:00:00 2001 From: Helium314 Date: Wed, 26 Mar 2025 18:11:47 +0100 Subject: [PATCH 20/36] reduce vertical padding for preference --- .../java/helium314/keyboard/settings/preferences/Preference.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/helium314/keyboard/settings/preferences/Preference.kt b/app/src/main/java/helium314/keyboard/settings/preferences/Preference.kt index a60e6298..63fc4692 100644 --- a/app/src/main/java/helium314/keyboard/settings/preferences/Preference.kt +++ b/app/src/main/java/helium314/keyboard/settings/preferences/Preference.kt @@ -64,7 +64,7 @@ fun Preference( .fillMaxWidth() .clickable { onClick() } .heightIn(min = 44.dp) - .padding(12.dp), + .padding(vertical = 10.dp, horizontal = 12.dp), horizontalArrangement = Arrangement.spacedBy(12.dp), verticalAlignment = Alignment.CenterVertically ) { From c0b14635fdcc82bab55d4d13839ee5c0102fc0bd Mon Sep 17 00:00:00 2001 From: Helium314 Date: Wed, 26 Mar 2025 18:29:57 +0100 Subject: [PATCH 21/36] fix issue that could result in autospace being added before period --- .../helium314/keyboard/latin/inputlogic/InputLogic.java | 4 +++- .../test/java/helium314/keyboard/latin/InputLogicTest.kt | 7 +------ 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/helium314/keyboard/latin/inputlogic/InputLogic.java b/app/src/main/java/helium314/keyboard/latin/inputlogic/InputLogic.java index b98906ef..cd545d4e 100644 --- a/app/src/main/java/helium314/keyboard/latin/inputlogic/InputLogic.java +++ b/app/src/main/java/helium314/keyboard/latin/inputlogic/InputLogic.java @@ -949,7 +949,9 @@ public final class InputLogic { // TODO: remove isWordConnector() and use isUsuallyFollowedBySpace() instead. // See onStartBatchInput() to see how to do it. if (SpaceState.PHANTOM == inputTransaction.getMSpaceState() - && !settingsValues.isWordConnector(codePoint)) { + && !settingsValues.isWordConnector(codePoint) + && !settingsValues.isUsuallyFollowedBySpace(codePoint) // only relevant in rare cases + ) { if (isComposingWord) { // Sanity check throw new RuntimeException("Should not be composing here"); diff --git a/app/src/test/java/helium314/keyboard/latin/InputLogicTest.kt b/app/src/test/java/helium314/keyboard/latin/InputLogicTest.kt index 4a430ab5..e6aa8095 100644 --- a/app/src/test/java/helium314/keyboard/latin/InputLogicTest.kt +++ b/app/src/test/java/helium314/keyboard/latin/InputLogicTest.kt @@ -203,13 +203,7 @@ class InputLogicTest { assertEquals("example.net", composingText) } - // fails because - // period is not handled with handleSeparatorEvent in this case - // pickSuggestion sets phantom space state - // insertAutomaticSpaceIfOptionsAndTextAllow allows the space - // todo: fix it either in some of those functions, or by finally improving URL detection in a reasonable (and performant) way @Test fun noAutospaceInUrlFieldWhenPickingSuggestion() { - if (BuildConfig.BUILD_TYPE == "runTests") return reset() setInputType(InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_VARIATION_URI) chainInput("exam") @@ -262,6 +256,7 @@ class InputLogicTest { reset() latinIME.prefs().edit { putBoolean(Settings.PREF_URL_DETECTION, true) } latinIME.prefs().edit { putBoolean(Settings.PREF_AUTOSPACE_AFTER_PUNCTUATION, true) } + latinIME.prefs().edit { putBoolean(Settings.PREF_SHIFT_REMOVES_AUTOSPACE, true) } input("bla") input('.') functionalKeyPress(KeyCode.SHIFT) // should remove the phantom space (in addition to normal effect) From f5bc89b91d4f46bfc224a758906b38479fea132a Mon Sep 17 00:00:00 2001 From: Helium314 Date: Wed, 26 Mar 2025 19:18:13 +0100 Subject: [PATCH 22/36] make reverting autocorrect on backspace optional fixes GH-210 --- .../keyboard/latin/inputlogic/InputLogic.java | 2 +- .../helium314/keyboard/latin/settings/Defaults.kt | 1 + .../helium314/keyboard/latin/settings/Settings.java | 1 + .../keyboard/latin/settings/SettingsValues.java | 2 ++ .../settings/screens/TextCorrectionScreen.kt | 4 ++++ app/src/main/res/values/strings.xml | 2 ++ .../java/helium314/keyboard/latin/InputLogicTest.kt | 13 ++++++++++--- 7 files changed, 21 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/helium314/keyboard/latin/inputlogic/InputLogic.java b/app/src/main/java/helium314/keyboard/latin/inputlogic/InputLogic.java index cd545d4e..14d5aa3b 100644 --- a/app/src/main/java/helium314/keyboard/latin/inputlogic/InputLogic.java +++ b/app/src/main/java/helium314/keyboard/latin/inputlogic/InputLogic.java @@ -1198,7 +1198,7 @@ public final class InputLogic { } inputTransaction.setRequiresUpdateSuggestions(); } else { - if (mLastComposedWord.canRevertCommit()) { + if (mLastComposedWord.canRevertCommit() && inputTransaction.getMSettingsValues().mBackspaceRevertsAutocorrect) { final String lastComposedWord = mLastComposedWord.mTypedWord; revertCommit(inputTransaction); StatsUtils.onRevertAutoCorrect(); diff --git a/app/src/main/java/helium314/keyboard/latin/settings/Defaults.kt b/app/src/main/java/helium314/keyboard/latin/settings/Defaults.kt index 08df4eac..09c0f88d 100644 --- a/app/src/main/java/helium314/keyboard/latin/settings/Defaults.kt +++ b/app/src/main/java/helium314/keyboard/latin/settings/Defaults.kt @@ -63,6 +63,7 @@ object Defaults { const val PREF_MORE_AUTO_CORRECTION = false const val PREF_AUTO_CORRECT_THRESHOLD = 0.185f const val PREF_AUTOCORRECT_SHORTCUTS = true + const val PREF_BACKSPACE_REVERTS_AUTOCORRECT = true const val PREF_CENTER_SUGGESTION_TEXT_TO_ENTER = false const val PREF_SHOW_SUGGESTIONS = true const val PREF_ALWAYS_SHOW_SUGGESTIONS = false diff --git a/app/src/main/java/helium314/keyboard/latin/settings/Settings.java b/app/src/main/java/helium314/keyboard/latin/settings/Settings.java index 08bf53b3..55a80bd8 100644 --- a/app/src/main/java/helium314/keyboard/latin/settings/Settings.java +++ b/app/src/main/java/helium314/keyboard/latin/settings/Settings.java @@ -71,6 +71,7 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang public static final String PREF_MORE_AUTO_CORRECTION = "more_auto_correction"; public static final String PREF_AUTO_CORRECT_THRESHOLD = "auto_correct_threshold"; public static final String PREF_AUTOCORRECT_SHORTCUTS = "autocorrect_shortcuts"; + public static final String PREF_BACKSPACE_REVERTS_AUTOCORRECT = "backspace_reverts_autocorrect"; public static final String PREF_CENTER_SUGGESTION_TEXT_TO_ENTER = "center_suggestion_text_to_enter"; public static final String PREF_SHOW_SUGGESTIONS = "show_suggestions"; public static final String PREF_ALWAYS_SHOW_SUGGESTIONS = "always_show_suggestions"; diff --git a/app/src/main/java/helium314/keyboard/latin/settings/SettingsValues.java b/app/src/main/java/helium314/keyboard/latin/settings/SettingsValues.java index 3430ae04..9fe0a372 100644 --- a/app/src/main/java/helium314/keyboard/latin/settings/SettingsValues.java +++ b/app/src/main/java/helium314/keyboard/latin/settings/SettingsValues.java @@ -135,6 +135,7 @@ public class SettingsValues { public final boolean mAutoCorrectionEnabledPerUserSettings; public final boolean mAutoCorrectEnabled; public final float mAutoCorrectionThreshold; + public final boolean mBackspaceRevertsAutocorrect; public final int mScoreLimitForAutocorrect; public final boolean mAutoCorrectShortcuts; private final boolean mSuggestionsEnabledPerUserSettings; @@ -199,6 +200,7 @@ public class SettingsValues { mScoreLimitForAutocorrect = (mAutoCorrectionThreshold < 0) ? 600000 // very aggressive : (mAutoCorrectionThreshold < 0.07 ? 800000 : 950000); // aggressive or modest mAutoCorrectShortcuts = prefs.getBoolean(Settings.PREF_AUTOCORRECT_SHORTCUTS, Defaults.PREF_AUTOCORRECT_SHORTCUTS); + mBackspaceRevertsAutocorrect = prefs.getBoolean(Settings.PREF_BACKSPACE_REVERTS_AUTOCORRECT, Defaults.PREF_BACKSPACE_REVERTS_AUTOCORRECT); mBigramPredictionEnabled = prefs.getBoolean(Settings.PREF_BIGRAM_PREDICTIONS, Defaults.PREF_BIGRAM_PREDICTIONS); mSuggestClipboardContent = prefs.getBoolean(Settings.PREF_SUGGEST_CLIPBOARD_CONTENT, Defaults.PREF_SUGGEST_CLIPBOARD_CONTENT); mDoubleSpacePeriodTimeout = 1100; // ms diff --git a/app/src/main/java/helium314/keyboard/settings/screens/TextCorrectionScreen.kt b/app/src/main/java/helium314/keyboard/settings/screens/TextCorrectionScreen.kt index f322e0f0..eea74b91 100644 --- a/app/src/main/java/helium314/keyboard/settings/screens/TextCorrectionScreen.kt +++ b/app/src/main/java/helium314/keyboard/settings/screens/TextCorrectionScreen.kt @@ -59,6 +59,7 @@ fun TextCorrectionScreen( if (autocorrectEnabled) Settings.PREF_MORE_AUTO_CORRECTION else null, if (autocorrectEnabled) Settings.PREF_AUTOCORRECT_SHORTCUTS else null, if (autocorrectEnabled) Settings.PREF_AUTO_CORRECT_THRESHOLD else null, + if (autocorrectEnabled) Settings.PREF_BACKSPACE_REVERTS_AUTOCORRECT else null, Settings.PREF_AUTO_CAP, R.string.settings_category_space, Settings.PREF_KEY_USE_DOUBLE_SPACE_PERIOD, @@ -123,6 +124,9 @@ fun createCorrectionSettings(context: Context) = listOf( // todo: consider making it a slider, and maybe somehow adjust range so we can show % ListPreference(it, items, Defaults.PREF_AUTO_CORRECT_THRESHOLD) }, + Setting(context, Settings.PREF_BACKSPACE_REVERTS_AUTOCORRECT, R.string.backspace_reverts_autocorrect) { + SwitchPreference(it, Defaults.PREF_BACKSPACE_REVERTS_AUTOCORRECT) + }, Setting(context, Settings.PREF_AUTO_CAP, R.string.auto_cap, R.string.auto_cap_summary ) { diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index aecf63b6..aa277977 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -128,6 +128,8 @@ Auto-correct shortcuts When enabled shortcuts might be expanded by autocorrect + + Backspace reverts autocorrect Off diff --git a/app/src/test/java/helium314/keyboard/latin/InputLogicTest.kt b/app/src/test/java/helium314/keyboard/latin/InputLogicTest.kt index e6aa8095..e8f2a5c3 100644 --- a/app/src/test/java/helium314/keyboard/latin/InputLogicTest.kt +++ b/app/src/test/java/helium314/keyboard/latin/InputLogicTest.kt @@ -639,13 +639,20 @@ class InputLogicTest { @Test fun `revert autocorrect on delete`() { reset() + setInputType(InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_FLAG_AUTO_CORRECT) chainInput("hullo") getAutocorrectedWithSpaceAfter("hello", "hullo") + assertEquals("hello ", text) functionalKeyPress(KeyCode.DELETE) assertEquals("hullo", text) - // todo: now we want some way to disable revert on backspace, either per setting or something else - // need to avoid getting into the mLastComposedWord.canRevertCommit() part of handleBackspaceEvent + reset() + setInputType(InputType.TYPE_CLASS_TEXT or InputType.TYPE_TEXT_FLAG_AUTO_CORRECT) + latinIME.prefs().edit { putBoolean(Settings.PREF_BACKSPACE_REVERTS_AUTOCORRECT, false) } + chainInput("hullo") + getAutocorrectedWithSpaceAfter("hello", "hullo") + functionalKeyPress(KeyCode.DELETE) + assertEquals("hello", text) } @Test fun `remove glide typing word on delete`() { @@ -803,7 +810,7 @@ class InputLogicTest { val info = SuggestedWordInfo(suggestion, "", 0, 0, null, 0, 0) val typedInfo = SuggestedWordInfo(typedWord, "", 0, 0, null, 0, 0) val sw = SuggestedWords(ArrayList(listOf(typedInfo, info)), null, typedInfo, false, true, false, 0, 0) - latinIME.mInputLogic.setSuggestedWords(sw) + latinIME.mInputLogic.setSuggestedWords(sw) // this prepares for autocorrect input(' ') checkConnectionConsistency() } From 0847bac3d55f9f683270dd73cd1f5670f81890b8 Mon Sep 17 00:00:00 2001 From: Helium314 Date: Wed, 26 Mar 2025 19:56:46 +0100 Subject: [PATCH 23/36] upgrade target SDK to 35 might cause issues with hebrew and indonesian on Android 15 devices due to changed language codes --- app/build.gradle.kts | 8 ++++---- .../keyboard/internal/keyboard_parser/KeyboardParser.kt | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index b4d2454b..c5b12f2e 100755 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -6,13 +6,13 @@ plugins { } android { - compileSdk = 34 + compileSdk = 35 buildToolsVersion = "34.0.0" defaultConfig { applicationId = "helium314.keyboard" minSdk = 21 - targetSdk = 34 + targetSdk = 35 versionCode = 3002 versionName = "3.0-alpha2" ndk { @@ -96,8 +96,8 @@ android { dependencies { // androidx - implementation("androidx.core:core-ktx:1.13.1") - implementation("androidx.recyclerview:recyclerview:1.3.2") + implementation("androidx.core:core-ktx:1.15.0") + implementation("androidx.recyclerview:recyclerview:1.4.0") implementation("androidx.autofill:autofill:1.1.0") // kotlin diff --git a/app/src/main/java/helium314/keyboard/keyboard/internal/keyboard_parser/KeyboardParser.kt b/app/src/main/java/helium314/keyboard/keyboard/internal/keyboard_parser/KeyboardParser.kt index 999716ac..4cea8ac1 100644 --- a/app/src/main/java/helium314/keyboard/keyboard/internal/keyboard_parser/KeyboardParser.kt +++ b/app/src/main/java/helium314/keyboard/keyboard/internal/keyboard_parser/KeyboardParser.kt @@ -237,7 +237,7 @@ class KeyboardParser(private val params: KeyboardParams, private val context: Co { it.label == KeyLabel.PERIOD || it.groupId == KeyData.GROUP_PERIOD}, { baseKeys.last()[1].copy(newGroupId = 2, newType = baseKeys.last()[1].type ?: it.type) } ) - baseKeys.removeLast() + baseKeys.removeAt(baseKeys.lastIndex) } // add zwnj key next to space if necessary val spaceIndex = functionalKeysBottom.indexOfFirst { it.label == KeyLabel.SPACE && it.width <= 0 } // width could be 0 or -1 From f06521c8ec026f776646752082692b4088cb1976 Mon Sep 17 00:00:00 2001 From: Helium314 Date: Wed, 26 Mar 2025 20:07:47 +0100 Subject: [PATCH 24/36] make text fields follow content language direction --- app/src/main/java/helium314/keyboard/settings/Misc.kt | 4 ++++ app/src/main/java/helium314/keyboard/settings/SearchScreen.kt | 3 ++- .../keyboard/settings/dialogs/ColorThemePickerDialog.kt | 4 +++- .../helium314/keyboard/settings/dialogs/LayoutEditDialog.kt | 2 ++ .../helium314/keyboard/settings/dialogs/LayoutPickerDialog.kt | 4 +++- .../helium314/keyboard/settings/dialogs/TextInputDialog.kt | 4 +++- .../java/helium314/keyboard/settings/screens/ColorsScreen.kt | 2 ++ 7 files changed, 19 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/helium314/keyboard/settings/Misc.kt b/app/src/main/java/helium314/keyboard/settings/Misc.kt index d295c2eb..2ca4add2 100644 --- a/app/src/main/java/helium314/keyboard/settings/Misc.kt +++ b/app/src/main/java/helium314/keyboard/settings/Misc.kt @@ -25,6 +25,8 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.asImageBitmap import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.painterResource +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.style.TextDirection import androidx.compose.ui.unit.dp import androidx.core.content.ContextCompat import androidx.core.graphics.drawable.toBitmap @@ -90,3 +92,5 @@ fun DropDownField( } } } + +val contentTextDirectionStyle = TextStyle(textDirection = TextDirection.Content) diff --git a/app/src/main/java/helium314/keyboard/settings/SearchScreen.kt b/app/src/main/java/helium314/keyboard/settings/SearchScreen.kt index 7184d981..d6bf4081 100644 --- a/app/src/main/java/helium314/keyboard/settings/SearchScreen.kt +++ b/app/src/main/java/helium314/keyboard/settings/SearchScreen.kt @@ -227,7 +227,8 @@ fun ExpandableSearchField( else onSearchChange(TextFieldValue()) }) { CloseIcon(android.R.string.cancel) } }, singleLine = true, - colors = colors + colors = colors, + textStyle = contentTextDirectionStyle ) } } diff --git a/app/src/main/java/helium314/keyboard/settings/dialogs/ColorThemePickerDialog.kt b/app/src/main/java/helium314/keyboard/settings/dialogs/ColorThemePickerDialog.kt index ac97743f..6c1f8489 100644 --- a/app/src/main/java/helium314/keyboard/settings/dialogs/ColorThemePickerDialog.kt +++ b/app/src/main/java/helium314/keyboard/settings/dialogs/ColorThemePickerDialog.kt @@ -60,6 +60,7 @@ import helium314.keyboard.settings.Theme import helium314.keyboard.settings.filePicker import helium314.keyboard.settings.previewDark import helium314.keyboard.settings.screens.SaveThoseColors +import helium314.keyboard.settings.contentTextDirectionStyle import kotlinx.coroutines.launch import kotlinx.serialization.SerializationException import kotlinx.serialization.json.Json @@ -187,7 +188,8 @@ private fun AddColorRow(onDismissRequest: () -> Unit, userColors: Collection diff --git a/app/src/main/java/helium314/keyboard/settings/dialogs/LayoutPickerDialog.kt b/app/src/main/java/helium314/keyboard/settings/dialogs/LayoutPickerDialog.kt index 7355c7e4..e42631bb 100644 --- a/app/src/main/java/helium314/keyboard/settings/dialogs/LayoutPickerDialog.kt +++ b/app/src/main/java/helium314/keyboard/settings/dialogs/LayoutPickerDialog.kt @@ -50,6 +50,7 @@ import helium314.keyboard.settings.EditButton import helium314.keyboard.settings.Setting import helium314.keyboard.settings.SettingsActivity import helium314.keyboard.settings.Theme +import helium314.keyboard.settings.contentTextDirectionStyle import helium314.keyboard.settings.layoutFilePicker import helium314.keyboard.settings.layoutIntent import helium314.keyboard.settings.previewDark @@ -140,7 +141,8 @@ private fun AddLayoutRow(onNewLayout: (String) -> Unit, layoutType: LayoutType, value = textValue, onValueChange = { textValue = it }, modifier = Modifier.weight(1f), - singleLine = true + singleLine = true, + textStyle = contentTextDirectionStyle, ) EditButton(textValue.text.isNotEmpty() && LayoutUtilsCustom.getLayoutName(textValue.text, layoutType) !in userLayouts) { onNewLayout(textValue.text) diff --git a/app/src/main/java/helium314/keyboard/settings/dialogs/TextInputDialog.kt b/app/src/main/java/helium314/keyboard/settings/dialogs/TextInputDialog.kt index d23f76da..fa9b8a10 100644 --- a/app/src/main/java/helium314/keyboard/settings/dialogs/TextInputDialog.kt +++ b/app/src/main/java/helium314/keyboard/settings/dialogs/TextInputDialog.kt @@ -22,6 +22,7 @@ import androidx.compose.ui.text.input.TextFieldValue import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.window.DialogProperties import helium314.keyboard.settings.Theme +import helium314.keyboard.settings.contentTextDirectionStyle import helium314.keyboard.settings.previewDark // mostly taken from StreetComplete / SCEE @@ -76,7 +77,8 @@ fun TextInputDialog( .focusRequester(focusRequester), label = textInputLabel, keyboardOptions = KeyboardOptions(keyboardType = keyboardType), - singleLine = singleLine + singleLine = singleLine, + textStyle = contentTextDirectionStyle, ) }, properties = properties, diff --git a/app/src/main/java/helium314/keyboard/settings/screens/ColorsScreen.kt b/app/src/main/java/helium314/keyboard/settings/screens/ColorsScreen.kt index 5d2a46f1..7f14843a 100644 --- a/app/src/main/java/helium314/keyboard/settings/screens/ColorsScreen.kt +++ b/app/src/main/java/helium314/keyboard/settings/screens/ColorsScreen.kt @@ -58,6 +58,7 @@ import helium314.keyboard.settings.CloseIcon import helium314.keyboard.settings.SearchScreen import helium314.keyboard.settings.SettingsActivity import helium314.keyboard.settings.Theme +import helium314.keyboard.settings.contentTextDirectionStyle import helium314.keyboard.settings.dialogs.ColorPickerDialog import helium314.keyboard.settings.previewDark import kotlinx.serialization.Serializable @@ -137,6 +138,7 @@ fun ColorsScreen( // supportingText = { if (!nameValid) Text(stringResource(R.string.name_invalid)) } // todo: this is cutting off bottom half of the actual text... trailingIcon = { if (!nameValid) CloseIcon(R.string.name_invalid) }, singleLine = true, + textStyle = contentTextDirectionStyle, ) }, menu = listOf( From 1b1dbd4006dba0f0881f69236ecbee9b336efa32 Mon Sep 17 00:00:00 2001 From: Helium314 Date: Wed, 26 Mar 2025 20:38:06 +0100 Subject: [PATCH 25/36] upgrade robolectric version to make tests work again --- app/build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index c5b12f2e..5190c4bd 100755 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -117,7 +117,7 @@ dependencies { testImplementation(kotlin("test")) testImplementation("junit:junit:4.13.2") testImplementation("org.mockito:mockito-core:5.15.2") - testImplementation("org.robolectric:robolectric:4.12.1") + testImplementation("org.robolectric:robolectric:4.14.1") testImplementation("androidx.test:runner:1.6.2") testImplementation("androidx.test:core:1.6.1") } From b26ba76221fba2b48d86809b14457fde2029f454 Mon Sep 17 00:00:00 2001 From: Helium314 Date: Wed, 26 Mar 2025 20:57:54 +0100 Subject: [PATCH 26/36] add test related to GH-1408 --- .../keyboard/latin/StringUtilsTest.kt | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/app/src/test/java/helium314/keyboard/latin/StringUtilsTest.kt b/app/src/test/java/helium314/keyboard/latin/StringUtilsTest.kt index e2bf6adb..c7339d04 100644 --- a/app/src/test/java/helium314/keyboard/latin/StringUtilsTest.kt +++ b/app/src/test/java/helium314/keyboard/latin/StringUtilsTest.kt @@ -1,12 +1,23 @@ // SPDX-License-Identifier: GPL-3.0-only package helium314.keyboard.latin +import androidx.test.core.app.ApplicationProvider +import helium314.keyboard.ShadowInputMethodManager2 import helium314.keyboard.latin.common.StringUtils import helium314.keyboard.latin.common.getFullEmojiAtEnd +import helium314.keyboard.latin.common.nonWordCodePointAndNoSpaceBeforeCursor +import helium314.keyboard.latin.settings.SpacingAndPunctuations +import org.junit.runner.RunWith +import org.robolectric.RobolectricTestRunner +import org.robolectric.annotation.Config import kotlin.test.Test import kotlin.test.assertEquals // todo: actually this test could/should be significantly expanded... +@RunWith(RobolectricTestRunner::class) +@Config(shadows = [ + ShadowInputMethodManager2::class, +]) class StringUtilsTest { @Test fun `not inside double quotes without quotes`() { assert(!StringUtils.isInsideDoubleQuoteOrAfterDigit("hello yes")) @@ -41,6 +52,14 @@ class StringUtilsTest { assert(StringUtils.isInsideDoubleQuoteOrAfterDigit("hello \"yes\", \"h")) } + @Test fun `non-word codepoints and no space`() { + val sp = SpacingAndPunctuations(ApplicationProvider.getApplicationContext().resources, false) + assert(!nonWordCodePointAndNoSpaceBeforeCursor("this is", sp)) + assert(!nonWordCodePointAndNoSpaceBeforeCursor("this ", sp)) + assert(!nonWordCodePointAndNoSpaceBeforeCursor("th.is ", sp)) + assert(nonWordCodePointAndNoSpaceBeforeCursor("th.is", sp)) + } + @Test fun detectEmojisAtEnd() { assertEquals("", getFullEmojiAtEnd("\uD83C\uDF83 ")) assertEquals("", getFullEmojiAtEnd("a")) From a745c92e05d8c71ebb67852e508630a95c9a6a83 Mon Sep 17 00:00:00 2001 From: Helium314 Date: Wed, 26 Mar 2025 21:26:05 +0100 Subject: [PATCH 27/36] update ndk and translations --- app/build.gradle.kts | 4 ++-- app/src/main/res/values-ar/strings.xml | 5 +++-- app/src/main/res/values-bg/strings.xml | 4 ++++ app/src/main/res/values-bn/strings.xml | 4 ++++ app/src/main/res/values-ca/strings.xml | 4 ++++ app/src/main/res/values-de/strings.xml | 4 ++++ app/src/main/res/values-et/strings.xml | 4 ++++ app/src/main/res/values-fr/strings.xml | 4 ++++ app/src/main/res/values-gl/strings.xml | 12 ++++++++++++ app/src/main/res/values-it/strings.xml | 8 +++++++- app/src/main/res/values-iw/strings.xml | 8 +++++++- app/src/main/res/values-nl/strings.xml | 4 ++++ app/src/main/res/values-pl/strings.xml | 2 ++ app/src/main/res/values-pt-rBR/strings.xml | 4 ++++ app/src/main/res/values-ru/strings.xml | 8 +++++++- app/src/main/res/values-zh-rCN/strings.xml | 6 +++++- 16 files changed, 77 insertions(+), 8 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 5190c4bd..2f338a1c 100755 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -14,7 +14,7 @@ android { minSdk = 21 targetSdk = 35 versionCode = 3002 - versionName = "3.0-alpha2" + versionName = "3.0-alpha3" ndk { abiFilters.clear() abiFilters.addAll(listOf("armeabi-v7a", "arm64-v8a", "x86", "x86_64")) @@ -58,7 +58,7 @@ android { path = File("src/main/jni/Android.mk") } } - ndkVersion = "26.2.11394342" + ndkVersion = "28.0.13004108" packagingOptions { jniLibs { diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index 36b7b516..8ef08d98 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -247,10 +247,10 @@ الرموز الرموز(العربية) ارقام - لوحة ارقام + لوحة الأرقام الهاتف رموز الهاتف - لوحة رقمية (أفقي) + لوحة الأرقام (أفقي) هل تريد حقًا إزالة القاموس الذي أضافه المستخدم \"%s\"؟ خطأ: الملف المحدد ليس ملف قاموس صالح اسود @@ -476,4 +476,5 @@ %s (Baishakhi) أظهِر مفاتيح TLD المنبثقة استبدل مفتاح الفترة المنبثقة مع مجالات المستوى الأعلى عند كتابة عناوين URL وعناوين البريد الإلكتروني + الضغط على إدخال أو مساحة بعد مفاتيح أخرى في لوحة الأرقام diff --git a/app/src/main/res/values-bg/strings.xml b/app/src/main/res/values-bg/strings.xml index b9509430..19cc16c4 100644 --- a/app/src/main/res/values-bg/strings.xml +++ b/app/src/main/res/values-bg/strings.xml @@ -469,4 +469,8 @@ %s (Байсахи) Показване на TLD изскачащи клавиши Заместване на изскачащите прозорци с клавиши за период с домейни от първо ниво при въвеждане на URL и имейл адреси + Натискане на въвеждане или интервал след други клавиши в цифровата клавиатура + Не винаги показвай предложения за полета за уеб редактиране + Полетата за уеб редактиране (най-вече в браузърите) са много честа причина за проблеми с настройката за винаги показване на предложения + Числов ред (основен) diff --git a/app/src/main/res/values-bn/strings.xml b/app/src/main/res/values-bn/strings.xml index f6f1e06d..13fffa34 100644 --- a/app/src/main/res/values-bn/strings.xml +++ b/app/src/main/res/values-bn/strings.xml @@ -433,4 +433,8 @@ নিজস্বীকৃত সাবটাইপ টিএলডি পপআপ বোতাম প্রদর্শন ইউআরএল ও ইমেইল ঠিকানা লেখার জন্য দাঁড়ি বোতাম টপ লেভেল ডোমেইন দ্বারা প্রতিস্থাপন + নম্বর প্যাডে অন্য বোতামের পরে এন্টার বা স্পেস চাপ + নম্বর সারি (প্রাথমিক) + ওয়েব সম্পাদনা ফিল্ডে সর্বদা পরামর্শ প্রদর্শন করবে না + ওয়েব সম্পাদনা ফিল্ড (প্রধানত ব্রাউজারে উপলভ্য) সর্বদা পরামর্শ প্রদর্শন সেটিংসে সমস্যার একটি সাধারণ কারণ diff --git a/app/src/main/res/values-ca/strings.xml b/app/src/main/res/values-ca/strings.xml index 1320d1e6..821d7e6b 100644 --- a/app/src/main/res/values-ca/strings.xml +++ b/app/src/main/res/values-ca/strings.xml @@ -432,4 +432,8 @@ secció de discussió Substituir les finestres emergents de la tecla punt per dominis de primer nivell en escriure URLs i adreces de correu electrònic Mostra tecles emergents de TLD + Prement Intro o espai després d\'altres tecles del teclat numèric + Els camps d\'edició web (sobretot que es troben als navegadors) són una causa molt freqüent de problemes amb la configuració Mostrar sempre suggeriments + Fila de nombres (bàsic) + No mostrar sempre suggeriments per als camps d\'edició web diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 9af19dee..30385268 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -435,4 +435,8 @@ %s (Baisakhi) Zeige TLD-Popup-Tasten Ersetze Punkt-Tastenpopups mit Top-Level-Domains wenn URLs und Mailadressen eingegeben werden + Nicht immer Vorschläge für Web-Editierfelder anzeigen + Zahlenreihe (Basis) + Web-Eingabefelder (meist in Browsern) sind eine häufige Ursache für Probleme mit der Einstellung \"Immer Vorschläge anzeigen\" + Drücken der Eingabetaste oder der Leertaste nach anderen Tasten im Ziffernblock diff --git a/app/src/main/res/values-et/strings.xml b/app/src/main/res/values-et/strings.xml index ad1bf524..186a5615 100644 --- a/app/src/main/res/values-et/strings.xml +++ b/app/src/main/res/values-et/strings.xml @@ -469,4 +469,8 @@ %s (Baishakhi) Näita tippdomeenide hüpikklahve Võrgu- ja e-posti aadresside kirjutamisel asenda punktuatsiooni hüpikaknad tipptaseme domeenide omadega + Vajutades numbriklahvistikus peale muud sisestust tühiku- või sisestusklahvi + Numbririda (lihtne) + Ära alati näita sisestuse soovitusi täites veebivormide välju + Kui alati näitad sisestuse soovitusi veebivormide väljadel (nii nagu sa neid veebibrauseris näed), siis võib sellest tekkida probleeme diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 2c32cf6f..b9481974 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -439,4 +439,8 @@ Nouveau dictionnaire: Section de discussion Afficher les suggestions de domaines (TLD) Remplacer les suggestions de la touche point par des extensions de domaine (TLD) lors de la saisie d’URL ou d’adresses e-mail + Appuyer sur Entrée ou sur la barre d\'espace après d\'autres touches du pavé numérique + Les champs d\'édition Web (principalement présents dans les navigateurs) sont une cause très courante de problèmes avec le paramètre « Toujours afficher les suggestions » + Rangée numérique (standard) + Ne pas forcer l\'affichage des suggestions pour les champs de saisie web diff --git a/app/src/main/res/values-gl/strings.xml b/app/src/main/res/values-gl/strings.xml index c2fa7a99..d78aab27 100644 --- a/app/src/main/res/values-gl/strings.xml +++ b/app/src/main/res/values-gl/strings.xml @@ -434,4 +434,16 @@ zona de conversa Podes atopar e compartir disposicións na %s. %s (Baishakhi) + Subtipo personalizado + Non mostrar sempre suxestións para os campos texto nas webs + Os campos de texto nas webs (principalmente no navegador) son causa frecuente de problemas coas suxestións automáticas + Fila de números (básica) + Substitúe na emerxente da tecla do punto con dominios de alto nivel ao escribir URL e enderezos de correo + Mostrar teclas emerxentes TLD + Ao premer enter ou espazo após escribir no teclado numérico + caracter separador ancho cero + Eliminar %s? + Tes certeza de querer limpar todos os códigos personalizados? + Nome non válido + Distancia de desprazamento cambio de idioma diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index af8240d3..88405dca 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -104,7 +104,7 @@ "Scorciatoia:" "Lingua:" "Digita una parola" - "Scorciatoia facoltativa" + Scorciatoia (opzionale) "Modifica parola" Il dizionario utente è vuoto. Premi \'Aggiungi\' (+) per aggiungere manualmente una parola. "Per tutte le lingue" @@ -439,4 +439,10 @@ discussione dedicata Scopri nuovi layout o condividi quelli che hai creato nella %s. Scopri nuove combinazioni di colori o condividi le tue nella %s. + Mostra popup con TLD + Sostituisce il popup standard del tasto . (punto) con desinenze TLD internazionali durante la digitazione di URL e email + Dopo uno spazio o la pressione di ⏎ (invio) dal tastierino numerico + Non forzare i suggerimenti in tutti i campi di testo + I campi di testo Web (specie all\'interno dei browser) sono una causa ricorrente di problemi con i suggerimenti sempre attivi + Barra dei numeri (base) diff --git a/app/src/main/res/values-iw/strings.xml b/app/src/main/res/values-iw/strings.xml index 04bf34fb..d29ee520 100644 --- a/app/src/main/res/values-iw/strings.xml +++ b/app/src/main/res/values-iw/strings.xml @@ -208,7 +208,7 @@ בחירת כפתורי סרגל הכלים מרווחי קלידים צרים תרגום number row - שורת המספרים + שורת מספרים שפה שפה (עדיפות) פריסה @@ -439,4 +439,10 @@ באפשרותך למצוא ולשתף צבעים ב %s. באפשרותך למצוא ולשתף פריסות ב %s. מקטע הדיונים + הצגת חלון צץ של סיומות אינטרנט + החלפת חלון צץ של מקש נקודה ברשימת סיומות אינטרנט נפוצות בעת הקלדת כתובות אינטרנט ודוא\"ל + לאחר לחיצת Enter או רווח לאחר מקשים אחרים במקלדת המספרים + לא תמיד להציג הצעות לשדות עריכה ב-Web + שדות עריכה ב-Web (בדר\"כ יוצגו בדפדפן) הם גורם נפוץ מאד לבעיות בהגדרה \'הצגת הצעות תמיד\' + שורת המספרים (פריסת בסיס) diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index 81ddbdbf..a3e316db 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -478,4 +478,8 @@ %s (Baishakhi) TLD-opties weergeven Vervang pop-ups met interpunctie door topleveldomeinen bij het typen van URL\'s en e-mailadressen + Druk op enter of spatie na andere toetsen in het numpad + Cijferregel (basis) + Suggesties voor webbewerkingsvelden niet altijd weergeven + Webbewerkingsvelden (meestal te vinden in browsers) zijn een veel voorkomende oorzaak van problemen met de instelling Altijd suggesties weergeven diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index 53ee52e1..74cf935b 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -478,4 +478,6 @@ %s (Baishakhi) Pokaż wyskakujące okienka TLD Zastąp wyskakujące okienka klawisza kropki domenami najwyższego poziomu podczas wpisywania adresów URL i adresów e-mail + Naciśnięciu enter lub spacji po innych klawiszach w klawiaturze numerycznej + Rząd numeryczny (podstawowy) diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index d3804bc1..127df316 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -441,4 +441,8 @@ %s (Baishakhi) Mostrar teclas de TLD Substituir os pop-ups da tecla de ponto com domínios de topo ao digitar URLs e endereços de e-mail + Pressionando enter ou espaço após outras teclas no teclado de números + Linha de números (básica) + Não mostrar sugestões para campos de edição da web sempre + Campos de edição da web (encontrados normalmente em navegadores) são uma causa comum de problemas com a configuração de sempre mostrar sugestões diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index d94f2353..472bfae1 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -450,7 +450,7 @@ Переопределить версию эмодзи Если не установлено, будет использоваться портретное изображение Установить фоновое изображение (ландшафт) - Показывать подсказки в ряде с цифрами + Показывать подсказки в ряду с цифрами Расстояние смахивания для переключения языка Расстояние разделения (ландшафт) Включить разделение клавиатуры (ландшафт) @@ -466,4 +466,10 @@ Найти и поделиться раскладками в %s. обсуждения Недопустимое имя + Показать всплывающие клавиши TLD + При вводе URL и адресов электронной почты отображать домены верхнего уровня вместо всплывающих меню клавиши точки + Нажатие Enter или пробела после других клавиш на цифровой клавиатуре + Поля ввода на веб-страницах (в основном в браузерах) часто вызывают проблемы с настройкой постоянного отображения подсказок + Ряд с цифрами (основной) + Не всегда показывать подсказки для полей ввода на веб-страницах diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 33e5840a..f02abe6a 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -320,7 +320,7 @@ 切换到主键盘后… 在表情符号视图中选择表情符号 选择剪贴板历史条目 - 在符号视图中按回车键或空格键 + 在符号视图输入内容后按回车键或空格键 从文件添加词典 这将禁用未固定工具栏键的其他长按操作 添加非常常见的变体(默认) @@ -435,4 +435,8 @@ %s (Baishakhi) 输入 URL 和电子邮件地址时,用顶级域替换句点键弹出 显示顶级域弹出键 + 在数字键盘输入内容后按回车键或空格键 + 数字行(基本) + Web 编辑字段(主要存在于浏览器中)是导致“始终显示建议”设置出现问题的一个非常常见的原因 + 不要总是显示对 Web 编辑字段的建议 From 10af5def2b8c4bbb80a3be053a91dfc4874cdb8e Mon Sep 17 00:00:00 2001 From: Helium314 Date: Thu, 27 Mar 2025 21:04:42 +0100 Subject: [PATCH 28/36] deal with some very bad behavior of firefox, fixes #1139 --- .../keyboard/KeyboardActionListenerImpl.kt | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/helium314/keyboard/keyboard/KeyboardActionListenerImpl.kt b/app/src/main/java/helium314/keyboard/keyboard/KeyboardActionListenerImpl.kt index 89fdcecb..759a0c40 100644 --- a/app/src/main/java/helium314/keyboard/keyboard/KeyboardActionListenerImpl.kt +++ b/app/src/main/java/helium314/keyboard/keyboard/KeyboardActionListenerImpl.kt @@ -1,5 +1,6 @@ package helium314.keyboard.keyboard +import android.text.InputType import android.view.KeyEvent import android.view.inputmethod.InputMethodSubtype import helium314.keyboard.keyboard.internal.keyboard_parser.floris.KeyCode @@ -211,13 +212,24 @@ class KeyboardActionListenerImpl(private val latinIME: LatinIME, private val inp return true } } - if (inputLogic.moveCursorByAndReturnIfInsideComposingWord(moveSteps)) { + + // the shortcut below causes issues due to horrible handling of text fields by Firefox and forks + // issues: + // * setSelection "will cause the editor to call onUpdateSelection", see: https://developer.android.com/reference/android/view/inputmethod/InputConnection#setSelection(int,%20int) + // but Firefox is simply not doing this within the same word... WTF? + // https://github.com/Helium314/HeliBoard/issues/1139#issuecomment-2588169384 + // * inputType is NOT if variant InputType.TYPE_TEXT_VARIATION_WEB_EDIT_TEXT (variant appears to always be 0) + // so we can't even only do it for browsers (identifying by app name will break for forks) + // best "solution" is not doing this for InputType variation 0 but this applies to the majority of text fields... + val variation = InputType.TYPE_MASK_VARIATION and Settings.getValues().mInputAttributes.mInputType + if (variation != 0 && inputLogic.moveCursorByAndReturnIfInsideComposingWord(moveSteps)) { // no need to finish input and restart suggestions if we're still in the word - // this is a noticeable performance improvement + // this is a noticeable performance improvement when moving through long words val newPosition = inputLogic.mConnection.expectedSelectionStart + moveSteps inputLogic.mConnection.setSelection(newPosition, newPosition) return true } + inputLogic.finishInput() val newPosition = inputLogic.mConnection.expectedSelectionStart + moveSteps inputLogic.mConnection.setSelection(newPosition, newPosition) From a1f991088df35d85eaa17a558afe99aa94c84d4c Mon Sep 17 00:00:00 2001 From: Helium314 Date: Sat, 29 Mar 2025 07:19:17 +0100 Subject: [PATCH 29/36] reduce font size for multilibgual typing in settings --- .../java/helium314/keyboard/settings/dialogs/SubtypeDialog.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/helium314/keyboard/settings/dialogs/SubtypeDialog.kt b/app/src/main/java/helium314/keyboard/settings/dialogs/SubtypeDialog.kt index 33d4d850..5ddf7a1e 100644 --- a/app/src/main/java/helium314/keyboard/settings/dialogs/SubtypeDialog.kt +++ b/app/src/main/java/helium314/keyboard/settings/dialogs/SubtypeDialog.kt @@ -145,7 +145,7 @@ fun SubtypeDialog( val text = getSecondaryLocales(currentSubtype.extraValues).joinToString(", ") { it.localizedDisplayName(ctx) }.ifEmpty { stringResource(R.string.action_none) } - Text(text, Modifier.fillMaxWidth(), style = MaterialTheme.typography.bodyLarge) + Text(text, Modifier.fillMaxWidth()) } } } From fbfff03541a8335013180217c9f8d1b923f44f09 Mon Sep 17 00:00:00 2001 From: Helium314 Date: Sat, 29 Mar 2025 10:18:27 +0100 Subject: [PATCH 30/36] add all_colors color for key text in emoji keyboard, fixes #1058 --- .../java/helium314/keyboard/keyboard/KeyboardView.java | 7 +++++-- .../main/java/helium314/keyboard/latin/common/Colors.kt | 5 +++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/helium314/keyboard/keyboard/KeyboardView.java b/app/src/main/java/helium314/keyboard/keyboard/KeyboardView.java index 2226e360..33c7dcc8 100644 --- a/app/src/main/java/helium314/keyboard/keyboard/KeyboardView.java +++ b/app/src/main/java/helium314/keyboard/keyboard/KeyboardView.java @@ -27,6 +27,7 @@ import android.view.View; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import helium314.keyboard.keyboard.emoji.EmojiPageKeyboardView; import helium314.keyboard.keyboard.internal.KeyDrawParams; import helium314.keyboard.keyboard.internal.KeyVisualAttributes; import helium314.keyboard.keyboard.internal.keyboard_parser.floris.KeyCode; @@ -34,7 +35,7 @@ import helium314.keyboard.latin.R; import helium314.keyboard.latin.common.ColorType; import helium314.keyboard.latin.common.Colors; import helium314.keyboard.latin.common.Constants; -import helium314.keyboard.latin.common.StringUtils; +import helium314.keyboard.latin.common.StringUtilsKt; import helium314.keyboard.latin.settings.Settings; import helium314.keyboard.latin.suggestions.MoreSuggestions; import helium314.keyboard.latin.suggestions.PopupSuggestionsView; @@ -423,10 +424,12 @@ public class KeyboardView extends View { } if (key.isEnabled()) { - if (StringUtils.mightBeEmoji(label)) + if (StringUtilsKt.isEmoji(label)) paint.setColor(key.selectTextColor(params) | 0xFF000000); // ignore alpha for emojis (though actually color isn't applied anyway and we could just set white) else if (key.hasActionKeyBackground()) paint.setColor(mColors.get(ColorType.ACTION_KEY_ICON)); + else if (this instanceof EmojiPageKeyboardView) + paint.setColor(mColors.get(ColorType.EMOJI_KEY_TEXT)); else paint.setColor(key.selectTextColor(params)); // Set a drop shadow for the text if the shadow radius is positive value. diff --git a/app/src/main/java/helium314/keyboard/latin/common/Colors.kt b/app/src/main/java/helium314/keyboard/latin/common/Colors.kt index ffbc13d6..6bc71d46 100644 --- a/app/src/main/java/helium314/keyboard/latin/common/Colors.kt +++ b/app/src/main/java/helium314/keyboard/latin/common/Colors.kt @@ -277,7 +277,7 @@ class DynamicColors(context: Context, override val themeStyle: String, override AUTOFILL_BACKGROUND_CHIP, GESTURE_PREVIEW, POPUP_KEYS_BACKGROUND, MORE_SUGGESTIONS_BACKGROUND, KEY_PREVIEW -> adjustedBackground TOOL_BAR_EXPAND_KEY_BACKGROUND -> if (!isNight) accent else doubleAdjustedBackground GESTURE_TRAIL -> gesture - KEY_TEXT, SUGGESTION_AUTO_CORRECT, REMOVE_SUGGESTION_ICON, + KEY_TEXT, SUGGESTION_AUTO_CORRECT, REMOVE_SUGGESTION_ICON, EMOJI_KEY_TEXT, KEY_ICON, ONE_HANDED_MODE_BUTTON, EMOJI_CATEGORY, TOOL_BAR_KEY, FUNCTIONAL_KEY_TEXT -> keyText KEY_HINT_TEXT -> keyHintText SPACE_BAR_TEXT -> spaceBarText @@ -475,7 +475,7 @@ class DefaultColors ( GESTURE_PREVIEW, POPUP_KEYS_BACKGROUND, MORE_SUGGESTIONS_BACKGROUND, KEY_PREVIEW -> adjustedBackground TOOL_BAR_EXPAND_KEY_BACKGROUND, CLIPBOARD_SUGGESTION_BACKGROUND -> doubleAdjustedBackground GESTURE_TRAIL -> gesture - KEY_TEXT, REMOVE_SUGGESTION_ICON, FUNCTIONAL_KEY_TEXT, KEY_ICON -> keyText + KEY_TEXT, REMOVE_SUGGESTION_ICON, FUNCTIONAL_KEY_TEXT, KEY_ICON, EMOJI_KEY_TEXT -> keyText KEY_HINT_TEXT -> keyHintText SPACE_BAR_TEXT -> spaceBarText FUNCTIONAL_KEY_BACKGROUND -> functionalKey @@ -620,6 +620,7 @@ enum class ColorType { CLIPBOARD_PIN, EMOJI_CATEGORY, EMOJI_CATEGORY_SELECTED, + EMOJI_KEY_TEXT, FUNCTIONAL_KEY_TEXT, FUNCTIONAL_KEY_BACKGROUND, GESTURE_TRAIL, From 58778b1f231bd7758ff3ba39c9c55d983d2c9f67 Mon Sep 17 00:00:00 2001 From: Helium314 Date: Sat, 29 Mar 2025 10:38:43 +0100 Subject: [PATCH 31/36] add all_colors color for key preview text, fixes #1434 --- app/build.gradle.kts | 2 +- .../internal/KeyPreviewChoreographer.java | 2 +- .../internal/KeyVisualAttributes.java | 2 +- .../main/java/helium314/keyboard/latin/App.kt | 8 ++++++++ .../helium314/keyboard/latin/common/Colors.kt | 19 ++++++++++--------- 5 files changed, 21 insertions(+), 12 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 2f338a1c..12d9b8a4 100755 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -13,7 +13,7 @@ android { applicationId = "helium314.keyboard" minSdk = 21 targetSdk = 35 - versionCode = 3002 + versionCode = 3003 versionName = "3.0-alpha3" ndk { abiFilters.clear() diff --git a/app/src/main/java/helium314/keyboard/keyboard/internal/KeyPreviewChoreographer.java b/app/src/main/java/helium314/keyboard/keyboard/internal/KeyPreviewChoreographer.java index 718d1f8c..6dcfef34 100644 --- a/app/src/main/java/helium314/keyboard/keyboard/internal/KeyPreviewChoreographer.java +++ b/app/src/main/java/helium314/keyboard/keyboard/internal/KeyPreviewChoreographer.java @@ -108,7 +108,7 @@ public final class KeyPreviewChoreographer { final boolean hasPopupKeys = (key.getPopupKeys() != null); keyPreviewView.setPreviewBackground(hasPopupKeys, keyPreviewPosition); final Colors colors = Settings.getValues().mColors; - colors.setBackground(keyPreviewView, ColorType.KEY_PREVIEW); + colors.setBackground(keyPreviewView, ColorType.KEY_PREVIEW_BACKGROUND); // The key preview is placed vertically above the top edge of the parent key with an // arbitrary offset. diff --git a/app/src/main/java/helium314/keyboard/keyboard/internal/KeyVisualAttributes.java b/app/src/main/java/helium314/keyboard/keyboard/internal/KeyVisualAttributes.java index ee76f94e..2e8b172c 100644 --- a/app/src/main/java/helium314/keyboard/keyboard/internal/KeyVisualAttributes.java +++ b/app/src/main/java/helium314/keyboard/keyboard/internal/KeyVisualAttributes.java @@ -129,7 +129,7 @@ public final class KeyVisualAttributes { // when? -> hasShiftedLetterHint and isShiftedLetterActivated -> both are label flags mShiftedLetterHintActivatedColor = keyAttr.getColor( R.styleable.Keyboard_Key_keyShiftedLetterHintActivatedColor, 0); - mPreviewTextColor = colors.get(ColorType.KEY_TEXT); + mPreviewTextColor = colors.get(ColorType.KEY_PREVIEW_TEXT); mHintLabelVerticalAdjustment = ResourceUtils.getFraction(keyAttr, R.styleable.Keyboard_Key_keyHintLabelVerticalAdjustment, 0.0f); diff --git a/app/src/main/java/helium314/keyboard/latin/App.kt b/app/src/main/java/helium314/keyboard/latin/App.kt index 13f45af1..2ed0765c 100644 --- a/app/src/main/java/helium314/keyboard/latin/App.kt +++ b/app/src/main/java/helium314/keyboard/latin/App.kt @@ -545,6 +545,14 @@ fun checkVersionUpgrade(context: Context) { if (oldVersion <= 3001 && prefs.getInt(Settings.PREF_CLIPBOARD_HISTORY_RETENTION_TIME, Defaults.PREF_CLIPBOARD_HISTORY_RETENTION_TIME) <= 0) { prefs.edit().putInt(Settings.PREF_CLIPBOARD_HISTORY_RETENTION_TIME, 121).apply() } + if (oldVersion <= 3002) { + prefs.all.filterKeys { it.startsWith(Settings.PREF_USER_ALL_COLORS_PREFIX) }.forEach { + val oldValue = prefs.getString(it.key, "")!! + if ("KEY_PREVIEW" !in oldValue) return@forEach + val newValue = oldValue.replace("KEY_PREVIEW", "KEY_PREVIEW_BACKGROUND") + prefs.edit().putString(it.key, newValue).apply() + } + } upgradeToolbarPrefs(prefs) LayoutUtilsCustom.onLayoutFileChanged() // just to be sure prefs.edit { putInt(Settings.PREF_VERSION_CODE, BuildConfig.VERSION_CODE) } diff --git a/app/src/main/java/helium314/keyboard/latin/common/Colors.kt b/app/src/main/java/helium314/keyboard/latin/common/Colors.kt index 6bc71d46..15af33d8 100644 --- a/app/src/main/java/helium314/keyboard/latin/common/Colors.kt +++ b/app/src/main/java/helium314/keyboard/latin/common/Colors.kt @@ -274,10 +274,10 @@ class DynamicColors(context: Context, override val themeStyle: String, override override fun get(color: ColorType): Int = when (color) { TOOL_BAR_KEY_ENABLED_BACKGROUND, EMOJI_CATEGORY_SELECTED, ACTION_KEY_BACKGROUND, CLIPBOARD_PIN, SHIFT_KEY_ICON -> accent - AUTOFILL_BACKGROUND_CHIP, GESTURE_PREVIEW, POPUP_KEYS_BACKGROUND, MORE_SUGGESTIONS_BACKGROUND, KEY_PREVIEW -> adjustedBackground + AUTOFILL_BACKGROUND_CHIP, GESTURE_PREVIEW, POPUP_KEYS_BACKGROUND, MORE_SUGGESTIONS_BACKGROUND, KEY_PREVIEW_BACKGROUND -> adjustedBackground TOOL_BAR_EXPAND_KEY_BACKGROUND -> if (!isNight) accent else doubleAdjustedBackground GESTURE_TRAIL -> gesture - KEY_TEXT, SUGGESTION_AUTO_CORRECT, REMOVE_SUGGESTION_ICON, EMOJI_KEY_TEXT, + KEY_TEXT, SUGGESTION_AUTO_CORRECT, REMOVE_SUGGESTION_ICON, EMOJI_KEY_TEXT, KEY_PREVIEW_TEXT, KEY_ICON, ONE_HANDED_MODE_BUTTON, EMOJI_CATEGORY, TOOL_BAR_KEY, FUNCTIONAL_KEY_TEXT -> keyText KEY_HINT_TEXT -> keyHintText SPACE_BAR_TEXT -> spaceBarText @@ -327,7 +327,7 @@ class DynamicColors(context: Context, override val themeStyle: String, override EMOJI_CATEGORY_SELECTED, CLIPBOARD_PIN, SHIFT_KEY_ICON -> accentColorFilter REMOVE_SUGGESTION_ICON, EMOJI_CATEGORY, KEY_TEXT, KEY_ICON, ONE_HANDED_MODE_BUTTON, TOOL_BAR_KEY, TOOL_BAR_EXPAND_KEY -> keyTextFilter - KEY_PREVIEW -> adjustedBackgroundFilter + KEY_PREVIEW_BACKGROUND -> adjustedBackgroundFilter ACTION_KEY_ICON -> actionKeyIconColorFilter else -> colorFilter(get(color)) } @@ -336,7 +336,7 @@ class DynamicColors(context: Context, override val themeStyle: String, override if (view.background == null) view.setBackgroundColor(Color.WHITE) // set white to make the color filters work when (color) { - KEY_PREVIEW -> view.background.colorFilter = adjustedBackgroundFilter + KEY_PREVIEW_BACKGROUND -> view.background.colorFilter = adjustedBackgroundFilter FUNCTIONAL_KEY_BACKGROUND, KEY_BACKGROUND, MORE_SUGGESTIONS_WORD_BACKGROUND, SPACE_BAR_BACKGROUND, STRIP_BACKGROUND -> setColor(view.background, color) ONE_HANDED_MODE_BUTTON -> setColor(view.background, if (keyboardBackground == null) MAIN_BACKGROUND else STRIP_BACKGROUND) MORE_SUGGESTIONS_BACKGROUND -> view.background.colorFilter = backgroundFilter @@ -472,10 +472,10 @@ class DefaultColors ( TOOL_BAR_KEY_ENABLED_BACKGROUND, EMOJI_CATEGORY_SELECTED, ACTION_KEY_BACKGROUND, CLIPBOARD_PIN, SHIFT_KEY_ICON -> accent AUTOFILL_BACKGROUND_CHIP -> if (themeStyle == STYLE_MATERIAL && !hasKeyBorders) background else adjustedBackground - GESTURE_PREVIEW, POPUP_KEYS_BACKGROUND, MORE_SUGGESTIONS_BACKGROUND, KEY_PREVIEW -> adjustedBackground + GESTURE_PREVIEW, POPUP_KEYS_BACKGROUND, MORE_SUGGESTIONS_BACKGROUND, KEY_PREVIEW_BACKGROUND -> adjustedBackground TOOL_BAR_EXPAND_KEY_BACKGROUND, CLIPBOARD_SUGGESTION_BACKGROUND -> doubleAdjustedBackground GESTURE_TRAIL -> gesture - KEY_TEXT, REMOVE_SUGGESTION_ICON, FUNCTIONAL_KEY_TEXT, KEY_ICON, EMOJI_KEY_TEXT -> keyText + KEY_TEXT, REMOVE_SUGGESTION_ICON, FUNCTIONAL_KEY_TEXT, KEY_ICON, EMOJI_KEY_TEXT, KEY_PREVIEW_TEXT -> keyText KEY_HINT_TEXT -> keyHintText SPACE_BAR_TEXT -> spaceBarText FUNCTIONAL_KEY_BACKGROUND -> functionalKey @@ -524,7 +524,7 @@ class DefaultColors ( if (view.background == null) view.setBackgroundColor(Color.WHITE) // set white to make the color filters work when (color) { - KEY_PREVIEW, POPUP_KEYS_BACKGROUND -> view.background.colorFilter = adjustedBackgroundFilter + KEY_PREVIEW_BACKGROUND, POPUP_KEYS_BACKGROUND -> view.background.colorFilter = adjustedBackgroundFilter FUNCTIONAL_KEY_BACKGROUND, KEY_BACKGROUND, MORE_SUGGESTIONS_WORD_BACKGROUND, SPACE_BAR_BACKGROUND, STRIP_BACKGROUND, CLIPBOARD_SUGGESTION_BACKGROUND -> setColor(view.background, color) ONE_HANDED_MODE_BUTTON -> setColor(view.background, if (keyboardBackground == null) MAIN_BACKGROUND else STRIP_BACKGROUND) MORE_SUGGESTIONS_BACKGROUND -> view.background.colorFilter = backgroundFilter @@ -547,7 +547,7 @@ class DefaultColors ( EMOJI_CATEGORY_SELECTED, CLIPBOARD_PIN, SHIFT_KEY_ICON -> accentColorFilter KEY_TEXT, KEY_ICON -> keyTextFilter REMOVE_SUGGESTION_ICON, EMOJI_CATEGORY, ONE_HANDED_MODE_BUTTON, TOOL_BAR_KEY, TOOL_BAR_EXPAND_KEY -> suggestionTextFilter - KEY_PREVIEW -> adjustedBackgroundFilter + KEY_PREVIEW_BACKGROUND -> adjustedBackgroundFilter ACTION_KEY_ICON -> actionKeyIconColorFilter else -> colorFilter(get(color)) // create color filter (not great for performance, so the frequently used filters should be stored) } @@ -629,7 +629,8 @@ enum class ColorType { KEY_ICON, KEY_TEXT, KEY_HINT_TEXT, - KEY_PREVIEW, + KEY_PREVIEW_BACKGROUND, + KEY_PREVIEW_TEXT, MORE_SUGGESTIONS_HINT, MORE_SUGGESTIONS_BACKGROUND, MORE_SUGGESTIONS_WORD_BACKGROUND, From a3fcce26a77de0da59567adef7c939ba51c713f0 Mon Sep 17 00:00:00 2001 From: Helium314 Date: Sat, 29 Mar 2025 10:48:14 +0100 Subject: [PATCH 32/36] add all_colors color for popup key text, fixes #1297 --- .../main/java/helium314/keyboard/keyboard/KeyboardView.java | 2 ++ app/src/main/java/helium314/keyboard/latin/common/Colors.kt | 6 ++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/helium314/keyboard/keyboard/KeyboardView.java b/app/src/main/java/helium314/keyboard/keyboard/KeyboardView.java index 33c7dcc8..6fbf8238 100644 --- a/app/src/main/java/helium314/keyboard/keyboard/KeyboardView.java +++ b/app/src/main/java/helium314/keyboard/keyboard/KeyboardView.java @@ -430,6 +430,8 @@ public class KeyboardView extends View { paint.setColor(mColors.get(ColorType.ACTION_KEY_ICON)); else if (this instanceof EmojiPageKeyboardView) paint.setColor(mColors.get(ColorType.EMOJI_KEY_TEXT)); + else if (this instanceof PopupKeysKeyboardView) + paint.setColor(mColors.get(ColorType.POPUP_KEY_TEXT)); else paint.setColor(key.selectTextColor(params)); // Set a drop shadow for the text if the shadow radius is positive value. diff --git a/app/src/main/java/helium314/keyboard/latin/common/Colors.kt b/app/src/main/java/helium314/keyboard/latin/common/Colors.kt index 15af33d8..f8a57a47 100644 --- a/app/src/main/java/helium314/keyboard/latin/common/Colors.kt +++ b/app/src/main/java/helium314/keyboard/latin/common/Colors.kt @@ -277,7 +277,7 @@ class DynamicColors(context: Context, override val themeStyle: String, override AUTOFILL_BACKGROUND_CHIP, GESTURE_PREVIEW, POPUP_KEYS_BACKGROUND, MORE_SUGGESTIONS_BACKGROUND, KEY_PREVIEW_BACKGROUND -> adjustedBackground TOOL_BAR_EXPAND_KEY_BACKGROUND -> if (!isNight) accent else doubleAdjustedBackground GESTURE_TRAIL -> gesture - KEY_TEXT, SUGGESTION_AUTO_CORRECT, REMOVE_SUGGESTION_ICON, EMOJI_KEY_TEXT, KEY_PREVIEW_TEXT, + KEY_TEXT, SUGGESTION_AUTO_CORRECT, REMOVE_SUGGESTION_ICON, EMOJI_KEY_TEXT, KEY_PREVIEW_TEXT, POPUP_KEY_TEXT, KEY_ICON, ONE_HANDED_MODE_BUTTON, EMOJI_CATEGORY, TOOL_BAR_KEY, FUNCTIONAL_KEY_TEXT -> keyText KEY_HINT_TEXT -> keyHintText SPACE_BAR_TEXT -> spaceBarText @@ -475,7 +475,8 @@ class DefaultColors ( GESTURE_PREVIEW, POPUP_KEYS_BACKGROUND, MORE_SUGGESTIONS_BACKGROUND, KEY_PREVIEW_BACKGROUND -> adjustedBackground TOOL_BAR_EXPAND_KEY_BACKGROUND, CLIPBOARD_SUGGESTION_BACKGROUND -> doubleAdjustedBackground GESTURE_TRAIL -> gesture - KEY_TEXT, REMOVE_SUGGESTION_ICON, FUNCTIONAL_KEY_TEXT, KEY_ICON, EMOJI_KEY_TEXT, KEY_PREVIEW_TEXT -> keyText + KEY_TEXT, REMOVE_SUGGESTION_ICON, FUNCTIONAL_KEY_TEXT, KEY_ICON, EMOJI_KEY_TEXT, + POPUP_KEY_TEXT, KEY_PREVIEW_TEXT -> keyText KEY_HINT_TEXT -> keyHintText SPACE_BAR_TEXT -> spaceBarText FUNCTIONAL_KEY_BACKGROUND -> functionalKey @@ -635,6 +636,7 @@ enum class ColorType { MORE_SUGGESTIONS_BACKGROUND, MORE_SUGGESTIONS_WORD_BACKGROUND, POPUP_KEYS_BACKGROUND, + POPUP_KEY_TEXT, NAVIGATION_BAR, SHIFT_KEY_ICON, SPACE_BAR_BACKGROUND, From 525c4e59b6316d26b05ef2e4813524796eefbd38 Mon Sep 17 00:00:00 2001 From: Helium314 Date: Sat, 29 Mar 2025 11:47:06 +0100 Subject: [PATCH 33/36] confirm color in color picker dialog on done, fixes GH-1443 --- .../keyboard/settings/dialogs/ColorPickerDialog.kt | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/helium314/keyboard/settings/dialogs/ColorPickerDialog.kt b/app/src/main/java/helium314/keyboard/settings/dialogs/ColorPickerDialog.kt index 15e926ac..d1771b61 100644 --- a/app/src/main/java/helium314/keyboard/settings/dialogs/ColorPickerDialog.kt +++ b/app/src/main/java/helium314/keyboard/settings/dialogs/ColorPickerDialog.kt @@ -7,6 +7,7 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size +import androidx.compose.foundation.text.KeyboardActions import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.material3.Surface import androidx.compose.material3.Text @@ -24,6 +25,7 @@ import androidx.compose.ui.graphics.PaintingStyle import androidx.compose.ui.graphics.toArgb import androidx.compose.ui.platform.LocalConfiguration import androidx.compose.ui.text.TextRange +import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.text.input.TextFieldValue import androidx.compose.ui.tooling.preview.Preview @@ -109,8 +111,12 @@ fun ColorPickerDialog( ) TextField( value = textValue, - // todo: KeyboardType.Password is a crappy way of avoiding suggestions... is there really no way in compose? - keyboardOptions = KeyboardOptions(autoCorrectEnabled = false, keyboardType = KeyboardType.Password), + keyboardOptions = KeyboardOptions( + autoCorrectEnabled = false, + keyboardType = KeyboardType.Password, // todo: KeyboardType.Password is a crappy way of avoiding suggestions... is there really no way in compose? + imeAction = ImeAction.Done, + ), + keyboardActions = KeyboardActions(onDone = { onDismissRequest(); onConfirmed(controller.selectedColor.value.toArgb()) }), onValueChange = { textValue = it val androidColor = runCatching { android.graphics.Color.parseColor("#${it.text}") }.getOrNull() From 8932fc84e130e44421eaefdb7e2ffe2e077ce144 Mon Sep 17 00:00:00 2001 From: Helium314 Date: Sat, 29 Mar 2025 12:36:07 +0100 Subject: [PATCH 34/36] add timestamp keycode and setting for adjusting format, fixes GH-846 --- .../keyboard_parser/floris/KeyCode.kt | 12 ++++-- .../keyboard/latin/inputlogic/InputLogic.java | 4 ++ .../keyboard/latin/settings/Defaults.kt | 1 + .../keyboard/latin/settings/Settings.java | 1 + .../keyboard/latin/utils/Timestamp.kt | 17 +++++++++ .../preferences/TextInputPreference.kt | 37 +++++++++++++++++++ .../settings/screens/AdvancedScreen.kt | 6 +++ .../settings/screens/AppearanceScreen.kt | 24 ++---------- app/src/main/res/values/strings.xml | 2 + .../keyboard/latin/InputLogicTest.kt | 8 ++++ layouts.md | 2 +- 11 files changed, 90 insertions(+), 24 deletions(-) create mode 100644 app/src/main/java/helium314/keyboard/latin/utils/Timestamp.kt create mode 100644 app/src/main/java/helium314/keyboard/settings/preferences/TextInputPreference.kt diff --git a/app/src/main/java/helium314/keyboard/keyboard/internal/keyboard_parser/floris/KeyCode.kt b/app/src/main/java/helium314/keyboard/keyboard/internal/keyboard_parser/floris/KeyCode.kt index bf5c65f0..e4794250 100644 --- a/app/src/main/java/helium314/keyboard/keyboard/internal/keyboard_parser/floris/KeyCode.kt +++ b/app/src/main/java/helium314/keyboard/keyboard/internal/keyboard_parser/floris/KeyCode.kt @@ -167,6 +167,7 @@ object KeyCode { const val BACK = -10040 const val SELECT_LEFT = -10041 const val SELECT_RIGHT = -10042 + const val TIMESTAMP = -10043 /** to make sure a FlorisBoard code works when reading a JSON layout */ fun Int.checkAndConvertCode(): Int = if (this > 0) this else when (this) { @@ -182,7 +183,8 @@ object KeyCode { SYMBOL_ALPHA, TOGGLE_ONE_HANDED_MODE, SWITCH_ONE_HANDED_MODE, SPLIT_LAYOUT, SHIFT_ENTER, ACTION_NEXT, ACTION_PREVIOUS, NOT_SPECIFIED, CLIPBOARD_COPY_ALL, WORD_LEFT, WORD_RIGHT, PAGE_UP, PAGE_DOWN, META, TAB, ESCAPE, INSERT, SLEEP, MEDIA_PLAY, MEDIA_PAUSE, MEDIA_PLAY_PAUSE, MEDIA_NEXT, - MEDIA_PREVIOUS, VOL_UP, VOL_DOWN, MUTE, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, BACK + MEDIA_PREVIOUS, VOL_UP, VOL_DOWN, MUTE, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, BACK, + TIMESTAMP -> this // conversion @@ -194,8 +196,12 @@ object KeyCode { else -> throw IllegalStateException("key code $this not yet supported") } - // todo: three are many more keys, see near https://developer.android.com/reference/android/view/KeyEvent#KEYCODE_0 - /** convert a keyCode / codePoint to a KeyEvent.KEYCODE_, fallback to KeyEvent.KEYCODE_UNKNOWN */ + // todo: there are many more keys, see near https://developer.android.com/reference/android/view/KeyEvent#KEYCODE_0 + /** + * Convert a keyCode / codePoint to a KeyEvent.KEYCODE_. + * Fallback to KeyEvent.KEYCODE_UNKNOWN. + * To be uses for fake hardware key press. + * */ fun Int.toKeyEventCode(): Int = if (this > 0) when (this.toChar().uppercaseChar()) { '/' -> KeyEvent.KEYCODE_SLASH diff --git a/app/src/main/java/helium314/keyboard/latin/inputlogic/InputLogic.java b/app/src/main/java/helium314/keyboard/latin/inputlogic/InputLogic.java index 14d5aa3b..79464dee 100644 --- a/app/src/main/java/helium314/keyboard/latin/inputlogic/InputLogic.java +++ b/app/src/main/java/helium314/keyboard/latin/inputlogic/InputLogic.java @@ -54,6 +54,7 @@ import helium314.keyboard.latin.utils.RecapitalizeStatus; import helium314.keyboard.latin.utils.ScriptUtils; import helium314.keyboard.latin.utils.StatsUtils; import helium314.keyboard.latin.utils.TextRange; +import helium314.keyboard.latin.utils.TimestampKt; import java.util.ArrayList; import java.util.Locale; @@ -775,6 +776,9 @@ public final class InputLogic { case KeyCode.SPLIT_LAYOUT: KeyboardSwitcher.getInstance().toggleSplitKeyboardMode(); break; + case KeyCode.TIMESTAMP: + mLatinIME.onTextInput(TimestampKt.getTimestamp(mLatinIME)); + break; case KeyCode.VOICE_INPUT: // switching to shortcut IME, shift state, keyboard,... is handled by LatinIME, // {@link KeyboardSwitcher#onEvent(Event)}, or {@link #onPressKey(int,int,boolean)} and {@link #onReleaseKey(int,boolean)}. diff --git a/app/src/main/java/helium314/keyboard/latin/settings/Defaults.kt b/app/src/main/java/helium314/keyboard/latin/settings/Defaults.kt index 09c0f88d..377e1989 100644 --- a/app/src/main/java/helium314/keyboard/latin/settings/Defaults.kt +++ b/app/src/main/java/helium314/keyboard/latin/settings/Defaults.kt @@ -154,6 +154,7 @@ object Defaults { const val PREF_ABC_AFTER_NUMPAD_SPACE = false const val PREF_REMOVE_REDUNDANT_POPUPS = false const val PREF_SPACE_BAR_TEXT = "" + const val PREF_TIMESTAMP_FORMAT = "yyyy-MM-dd HH:mm:ss" @JvmField val PREF_EMOJI_MAX_SDK = Build.VERSION.SDK_INT const val PREF_EMOJI_RECENT_KEYS = "" diff --git a/app/src/main/java/helium314/keyboard/latin/settings/Settings.java b/app/src/main/java/helium314/keyboard/latin/settings/Settings.java index 55a80bd8..098b51b0 100644 --- a/app/src/main/java/helium314/keyboard/latin/settings/Settings.java +++ b/app/src/main/java/helium314/keyboard/latin/settings/Settings.java @@ -164,6 +164,7 @@ public final class Settings implements SharedPreferences.OnSharedPreferenceChang public static final String PREF_ABC_AFTER_NUMPAD_SPACE = "abc_after_numpad_space"; public static final String PREF_REMOVE_REDUNDANT_POPUPS = "remove_redundant_popups"; public static final String PREF_SPACE_BAR_TEXT = "space_bar_text"; + public static final String PREF_TIMESTAMP_FORMAT = "timestamp_format"; // Emoji public static final String PREF_EMOJI_MAX_SDK = "emoji_max_sdk"; diff --git a/app/src/main/java/helium314/keyboard/latin/utils/Timestamp.kt b/app/src/main/java/helium314/keyboard/latin/utils/Timestamp.kt new file mode 100644 index 00000000..ebe2bd0e --- /dev/null +++ b/app/src/main/java/helium314/keyboard/latin/utils/Timestamp.kt @@ -0,0 +1,17 @@ +// SPDX-License-Identifier: GPL-3.0-only +package helium314.keyboard.latin.utils + +import android.content.Context +import helium314.keyboard.latin.settings.Defaults +import helium314.keyboard.latin.settings.Settings +import java.text.SimpleDateFormat +import java.util.Calendar + +fun getTimestamp(context: Context): String { + val format = context.prefs().getString(Settings.PREF_TIMESTAMP_FORMAT, Defaults.PREF_TIMESTAMP_FORMAT) + val formatter = runCatching { SimpleDateFormat(format, Settings.getValues().mLocale) }.getOrNull() + ?: SimpleDateFormat(Defaults.PREF_TIMESTAMP_FORMAT, Settings.getValues().mLocale) + return formatter.format(Calendar.getInstance().time) +} + +fun checkTimestampFormat(format: String) = runCatching { SimpleDateFormat(format, Settings.getValues().mLocale) }.isSuccess diff --git a/app/src/main/java/helium314/keyboard/settings/preferences/TextInputPreference.kt b/app/src/main/java/helium314/keyboard/settings/preferences/TextInputPreference.kt new file mode 100644 index 00000000..3bf2ce8e --- /dev/null +++ b/app/src/main/java/helium314/keyboard/settings/preferences/TextInputPreference.kt @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: GPL-3.0-only +package helium314.keyboard.settings.preferences + +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.saveable.rememberSaveable +import androidx.compose.runtime.setValue +import androidx.compose.ui.platform.LocalContext +import helium314.keyboard.keyboard.KeyboardSwitcher +import helium314.keyboard.latin.utils.prefs +import helium314.keyboard.settings.Setting +import helium314.keyboard.settings.dialogs.TextInputDialog + +@Composable +fun TextInputPreference(setting: Setting, default: String, checkTextValid: (String) -> Boolean = { true }) { + var showDialog by rememberSaveable { mutableStateOf(false) } + val prefs = LocalContext.current.prefs() + Preference( + name = setting.title, + onClick = { showDialog = true }, + description = prefs.getString(setting.key, default)?.takeIf { it.isNotEmpty() } + ) + if (showDialog) { + TextInputDialog( + onDismissRequest = { showDialog = false }, + onConfirmed = { + prefs.edit().putString(setting.key, it).apply() + KeyboardSwitcher.getInstance().setThemeNeedsReload() + }, + initialText = prefs.getString(setting.key, default) ?: "", + title = { Text(setting.title) }, + checkTextValid = checkTextValid + ) + } +} diff --git a/app/src/main/java/helium314/keyboard/settings/screens/AdvancedScreen.kt b/app/src/main/java/helium314/keyboard/settings/screens/AdvancedScreen.kt index c81f3025..badc404d 100644 --- a/app/src/main/java/helium314/keyboard/settings/screens/AdvancedScreen.kt +++ b/app/src/main/java/helium314/keyboard/settings/screens/AdvancedScreen.kt @@ -29,6 +29,7 @@ import helium314.keyboard.latin.common.splitOnWhitespace import helium314.keyboard.latin.settings.DebugSettings import helium314.keyboard.latin.settings.Defaults import helium314.keyboard.latin.settings.Settings +import helium314.keyboard.latin.utils.checkTimestampFormat import helium314.keyboard.latin.utils.prefs import helium314.keyboard.settings.NextScreenIcon import helium314.keyboard.settings.SettingsContainer @@ -45,6 +46,7 @@ import helium314.keyboard.settings.Theme import helium314.keyboard.settings.dialogs.TextInputDialog import helium314.keyboard.settings.preferences.BackupRestorePreference import helium314.keyboard.settings.preferences.LoadGestureLibPreference +import helium314.keyboard.settings.preferences.TextInputPreference import helium314.keyboard.settings.previewDark @Composable @@ -71,6 +73,7 @@ fun AdvancedSettingsScreen( Settings.PREF_ABC_AFTER_CLIP, Settings.PREF_CUSTOM_CURRENCY_KEY, Settings.PREF_MORE_POPUP_KEYS, + Settings.PREF_TIMESTAMP_FORMAT, SettingsWithoutKey.BACKUP_RESTORE, if (BuildConfig.DEBUG || prefs.getBoolean(DebugSettings.PREF_SHOW_DEBUG_SETTINGS, Defaults.PREF_SHOW_DEBUG_SETTINGS)) SettingsWithoutKey.DEBUG_SETTINGS else null, @@ -195,6 +198,9 @@ fun createAdvancedSettings(context: Context) = listOf( Setting(context, SettingsWithoutKey.BACKUP_RESTORE, R.string.backup_restore_title) { BackupRestorePreference(it) }, + Setting(context, Settings.PREF_TIMESTAMP_FORMAT, R.string.timestamp_format_title) { + TextInputPreference(it, Defaults.PREF_TIMESTAMP_FORMAT) { checkTimestampFormat(it) } + }, Setting(context, SettingsWithoutKey.DEBUG_SETTINGS, R.string.debug_settings_title) { Preference( name = it.title, diff --git a/app/src/main/java/helium314/keyboard/settings/screens/AppearanceScreen.kt b/app/src/main/java/helium314/keyboard/settings/screens/AppearanceScreen.kt index f8a43ca2..2a53c22c 100644 --- a/app/src/main/java/helium314/keyboard/settings/screens/AppearanceScreen.kt +++ b/app/src/main/java/helium314/keyboard/settings/screens/AppearanceScreen.kt @@ -21,6 +21,7 @@ import helium314.keyboard.latin.R import helium314.keyboard.latin.settings.Defaults import helium314.keyboard.latin.settings.Settings import helium314.keyboard.latin.utils.Log +import helium314.keyboard.latin.utils.checkTimestampFormat import helium314.keyboard.latin.utils.getActivity import helium314.keyboard.latin.utils.getStringResourceOrName import helium314.keyboard.latin.utils.prefs @@ -39,6 +40,7 @@ import helium314.keyboard.settings.dialogs.TextInputDialog import helium314.keyboard.settings.initPreview import helium314.keyboard.settings.preferences.BackgroundImagePref import helium314.keyboard.settings.preferences.CustomFontPreference +import helium314.keyboard.settings.preferences.TextInputPreference import helium314.keyboard.settings.previewDark @Composable @@ -263,26 +265,8 @@ fun createAppearanceSettings(context: Context) = listOf( description = { "${(100 * it).toInt()}%" } ) { KeyboardSwitcher.getInstance().setThemeNeedsReload() } }, - Setting(context, Settings.PREF_SPACE_BAR_TEXT, R.string.prefs_space_bar_text) { setting -> - var showDialog by rememberSaveable { mutableStateOf(false) } - val prefs = LocalContext.current.prefs() - Preference( - name = setting.title, - onClick = { showDialog = true }, - description = prefs.getString(setting.key, Defaults.PREF_SPACE_BAR_TEXT)?.takeIf { it.isNotEmpty() } - ) - if (showDialog) { - TextInputDialog( - onDismissRequest = { showDialog = false }, - onConfirmed = { - prefs.edit().putString(setting.key, it).apply() - KeyboardSwitcher.getInstance().setThemeNeedsReload() - }, - initialText = prefs.getString(setting.key, Defaults.PREF_SPACE_BAR_TEXT) ?: "", - title = { Text(setting.title) }, - checkTextValid = { true } - ) - } + Setting(context, Settings.PREF_SPACE_BAR_TEXT, R.string.prefs_space_bar_text) { + TextInputPreference(it, Defaults.PREF_SPACE_BAR_TEXT) }, Setting(context, SettingsWithoutKey.CUSTOM_FONT, R.string.custom_font) { CustomFontPreference(it) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index aa277977..03e7bcff 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -196,6 +196,8 @@ Backup Restore + + Format for timestamp key Multilingual typing diff --git a/app/src/test/java/helium314/keyboard/latin/InputLogicTest.kt b/app/src/test/java/helium314/keyboard/latin/InputLogicTest.kt index e8f2a5c3..bebee923 100644 --- a/app/src/test/java/helium314/keyboard/latin/InputLogicTest.kt +++ b/app/src/test/java/helium314/keyboard/latin/InputLogicTest.kt @@ -23,6 +23,7 @@ import helium314.keyboard.latin.inputlogic.InputLogic import helium314.keyboard.latin.inputlogic.SpaceState import helium314.keyboard.latin.settings.Settings import helium314.keyboard.latin.utils.ScriptUtils +import helium314.keyboard.latin.utils.getTimestamp import helium314.keyboard.latin.utils.prefs import org.junit.runner.RunWith import org.mockito.Mockito @@ -666,6 +667,13 @@ class InputLogicTest { // need to avoid getting into the mWordComposer.isBatchMode() part of handleBackspaceEvent } + @Test fun timestamp() { + reset() + chainInput("hello") + functionalKeyPress(KeyCode.TIMESTAMP) + assertEquals("hello" + getTimestamp(latinIME), text) + } + // ------- helper functions --------- // should be called before every test, so the same state is guaranteed diff --git a/layouts.md b/layouts.md index b442e934..9464abea 100644 --- a/layouts.md +++ b/layouts.md @@ -103,7 +103,7 @@ Usually the label is what is displayed on the key. However, there are some speci * In case a label clashes with text you want to add, put a `\` in front of the text you want, e.g. `\space` will write the label `space` instead of adding a space bar. * Note that you need to escape the `\` in json files by adding a second `\`. * If you want different key label and input text, set the label to [label]|[text], e.g. `aa|bb` will show `aa`, but pressing the key will input `bb`. -You can also specify special key codes like `a|!code/key_action_previous`, but it's cleaner to use a json layout and specify the code explicitly. Note that when specifying a code in the label, and a code in a json layout, the code in the label will be ignored. +You can also specify special key codes like `a|!code/key_action_previous` or `abc|!code/-10043`, but it's cleaner to use a json layout and specify the code explicitly. Note that when specifying a code in the label, and a code in a json layout, the code in the label will be ignored. * It's also possible to specify an icon, like `!icon/previous_key|!code/key_action_previous`. * You can find available icon names in [KeyboardIconsSet](/app/src/main/java/helium314/keyboard/keyboard/internal/KeyboardIconsSet.kt). You can also use toolbar key icons using the uppercase name of the [toolbar key](/app/src/main/java/helium314/keyboard/latin/utils/ToolbarUtils.kt#L109), e.g. `!icon/redo` From ac805a9286eb58fee173b9efd2be5934873c38cc Mon Sep 17 00:00:00 2001 From: Helium314 Date: Sun, 30 Mar 2025 12:03:21 +0200 Subject: [PATCH 35/36] fix some issues with renaming color schemes fixes GH-1449 and some more unreported bugs --- .../keyboard/keyboard/KeyboardTheme.kt | 22 +++----- .../keyboard/settings/screens/ColorsScreen.kt | 56 ++++++++++--------- 2 files changed, 38 insertions(+), 40 deletions(-) diff --git a/app/src/main/java/helium314/keyboard/keyboard/KeyboardTheme.kt b/app/src/main/java/helium314/keyboard/keyboard/KeyboardTheme.kt index 9a51bafa..73d03ef0 100644 --- a/app/src/main/java/helium314/keyboard/keyboard/KeyboardTheme.kt +++ b/app/src/main/java/helium314/keyboard/keyboard/KeyboardTheme.kt @@ -405,14 +405,7 @@ private constructor(val themeId: Int, @JvmField val mStyleId: Int) { } fun getUnusedThemeName(initialName: String, prefs: SharedPreferences): String { - val existingNames = prefs.all.keys.mapNotNull { - when { - it.startsWith(Settings.PREF_USER_COLORS_PREFIX) -> it.substringAfter(Settings.PREF_USER_COLORS_PREFIX) - it.startsWith(Settings.PREF_USER_ALL_COLORS_PREFIX) -> it.substringAfter(Settings.PREF_USER_ALL_COLORS_PREFIX) - it.startsWith(Settings.PREF_USER_MORE_COLORS_PREFIX) -> it.substringAfter(Settings.PREF_USER_MORE_COLORS_PREFIX) - else -> null - } - }.toSortedSet() + val existingNames = getExistingThemeNames(prefs) if (initialName !in existingNames) return initialName var i = 1 while ("$initialName$i" in existingNames) @@ -420,11 +413,8 @@ private constructor(val themeId: Int, @JvmField val mStyleId: Int) { return "$initialName$i" } - // returns false if not renamed due to invalid name or collision - fun renameUserColors(from: String, to: String, prefs: SharedPreferences): Boolean { - if (to.isBlank()) return false // don't want that - if (to == from) return true // nothing to do - val existingNames = prefs.all.keys.mapNotNull { + private fun getExistingThemeNames(prefs: SharedPreferences) = + prefs.all.keys.mapNotNull { when { it.startsWith(Settings.PREF_USER_COLORS_PREFIX) -> it.substringAfter(Settings.PREF_USER_COLORS_PREFIX) it.startsWith(Settings.PREF_USER_ALL_COLORS_PREFIX) -> it.substringAfter(Settings.PREF_USER_ALL_COLORS_PREFIX) @@ -432,6 +422,12 @@ private constructor(val themeId: Int, @JvmField val mStyleId: Int) { else -> null } }.toSortedSet() + + // returns false if not renamed due to invalid name or collision + fun renameUserColors(from: String, to: String, prefs: SharedPreferences): Boolean { + if (to.isBlank()) return false // don't want that + if (to == from) return true // nothing to do + val existingNames = getExistingThemeNames(prefs) if (to in existingNames) return false // all good, now rename prefs.edit { diff --git a/app/src/main/java/helium314/keyboard/settings/screens/ColorsScreen.kt b/app/src/main/java/helium314/keyboard/settings/screens/ColorsScreen.kt index 7f14843a..976a1780 100644 --- a/app/src/main/java/helium314/keyboard/settings/screens/ColorsScreen.kt +++ b/app/src/main/java/helium314/keyboard/settings/screens/ColorsScreen.kt @@ -71,6 +71,14 @@ fun ColorsScreen( onClickBack: () -> Unit ) { val ctx = LocalContext.current + val prefs = ctx.prefs() + val b = (ctx.getActivity() as? SettingsActivity)?.prefChanged?.collectAsState() + if ((b?.value ?: 0) < 0) + Log.v("irrelevant", "stupid way to trigger recomposition on preference change") + + val themeName = theme ?: if (isNight) prefs.getString(Settings.PREF_THEME_COLORS_NIGHT, Defaults.PREF_THEME_COLORS_NIGHT)!! + else prefs.getString(Settings.PREF_THEME_COLORS, Defaults.PREF_THEME_COLORS)!! + var newThemeName by rememberSaveable(stateSaver = TextFieldValue.Saver) { mutableStateOf(TextFieldValue(themeName)) } // is there really no better way of only setting forceOpposite while the screen is shown (and not paused)? // lifecycle stuff is weird, there is no pause and similar when activity is paused @@ -83,21 +91,14 @@ fun ColorsScreen( val lifecycleState by lifecycleOwner.lifecycle.currentStateFlow.collectAsState() LaunchedEffect(lifecycleState) { if (lifecycleState == Lifecycle.State.RESUMED) { - (ctx.getActivity() as? SettingsActivity)?.setForceTheme(theme, isNight) + (ctx.getActivity() as? SettingsActivity)?.setForceTheme(newThemeName.text, isNight) } } - val prefs = ctx.prefs() - val b = (ctx.getActivity() as? SettingsActivity)?.prefChanged?.collectAsState() - if ((b?.value ?: 0) < 0) - Log.v("irrelevant", "stupid way to trigger recomposition on preference change") - - val themeName = theme ?: if (isNight) prefs.getString(Settings.PREF_THEME_COLORS_NIGHT, Defaults.PREF_THEME_COLORS_NIGHT)!! - else prefs.getString(Settings.PREF_THEME_COLORS, Defaults.PREF_THEME_COLORS)!! - val moreColors = KeyboardTheme.readUserMoreColors(prefs, themeName) - val userColors = KeyboardTheme.readUserColors(prefs, themeName) + val moreColors = KeyboardTheme.readUserMoreColors(prefs, newThemeName.text) + val userColors = KeyboardTheme.readUserColors(prefs, newThemeName.text) val shownColors = if (moreColors == 2) { - val allColors = KeyboardTheme.readUserAllColors(prefs, themeName) + val allColors = KeyboardTheme.readUserAllColors(prefs, newThemeName.text) ColorType.entries.map { ColorSetting(it.name, null, allColors[it] ?: it.default()) } @@ -114,12 +115,11 @@ fun ColorsScreen( fun ColorSetting.displayColor() = if (auto == true) KeyboardTheme.determineUserColor(userColors, ctx, name, isNight) else color ?: KeyboardTheme.determineUserColor(userColors, ctx, name, isNight) - var newThemeName by rememberSaveable(stateSaver = TextFieldValue.Saver) { mutableStateOf(TextFieldValue(themeName)) } var chosenColorString: String by rememberSaveable { mutableStateOf("") } val chosenColor = runCatching { Json.decodeFromString(chosenColorString) }.getOrNull() - val saveLauncher = rememberLauncherForActivityResult(ActivityResultContracts.StartActivityForResult()) { - if (it.resultCode != Activity.RESULT_OK) return@rememberLauncherForActivityResult - val uri = it.data?.data ?: return@rememberLauncherForActivityResult + val saveLauncher = rememberLauncherForActivityResult(ActivityResultContracts.StartActivityForResult()) { result -> + if (result.resultCode != Activity.RESULT_OK) return@rememberLauncherForActivityResult + val uri = result.data?.data ?: return@rememberLauncherForActivityResult ctx.getActivity()?.contentResolver?.openOutputStream(uri)?.writer()?.use { it.write(getColorString(prefs, newThemeName.text)) } } SearchScreen( @@ -130,8 +130,10 @@ fun ColorsScreen( value = nameField, onValueChange = { nameValid = KeyboardTheme.renameUserColors(newThemeName.text, it.text, prefs) - if (nameValid) + if (nameValid) { newThemeName = it + SettingsActivity.forceTheme = newThemeName.text + } nameField = it }, isError = !nameValid, @@ -195,11 +197,11 @@ fun ColorsScreen( } } if (colorSetting.auto != null) - Switch(colorSetting.auto, onCheckedChange = { - val oldUserColors = KeyboardTheme.readUserColors(prefs, themeName) - val newUserColors = (oldUserColors + ColorSetting(colorSetting.name, it, colorSetting.color)) + Switch(colorSetting.auto, onCheckedChange = { checked -> + val oldUserColors = KeyboardTheme.readUserColors(prefs, newThemeName.text) + val newUserColors = (oldUserColors + ColorSetting(colorSetting.name, checked, colorSetting.color)) .reversed().distinctBy { it.displayName } - KeyboardTheme.writeUserColors(prefs, themeName, newUserColors) + KeyboardTheme.writeUserColors(prefs, newThemeName.text, newUserColors) }) } } @@ -209,16 +211,16 @@ fun ColorsScreen( onDismissRequest = { chosenColorString = "" }, initialColor = chosenColor.displayColor(), title = chosenColor.displayName, - ) { + ) { color -> if (moreColors == 2) { - val oldColors = KeyboardTheme.readUserAllColors(prefs, themeName) - oldColors[ColorType.valueOf(chosenColor.name)] = it - KeyboardTheme.writeUserAllColors(prefs, themeName, oldColors) + val oldColors = KeyboardTheme.readUserAllColors(prefs, newThemeName.text) + oldColors[ColorType.valueOf(chosenColor.name)] = color + KeyboardTheme.writeUserAllColors(prefs, newThemeName.text, oldColors) } else { - val oldUserColors = KeyboardTheme.readUserColors(prefs, themeName) - val newUserColors = (oldUserColors + ColorSetting(chosenColor.name, false, it)) + val oldUserColors = KeyboardTheme.readUserColors(prefs, newThemeName.text) + val newUserColors = (oldUserColors + ColorSetting(chosenColor.name, false, color)) .reversed().distinctBy { it.displayName } - KeyboardTheme.writeUserColors(prefs, themeName, newUserColors) + KeyboardTheme.writeUserColors(prefs, newThemeName.text, newUserColors) } } } From 6bbce0b5ca12f4090d1849542be8e4306458d270 Mon Sep 17 00:00:00 2001 From: Helium314 Date: Sun, 30 Mar 2025 12:40:06 +0200 Subject: [PATCH 36/36] change subtype dialog to screen mostly just moved the content and adjusted necessary calls still needs some minor tweaking --- .../keyboard/settings/SearchScreen.kt | 7 +- .../keyboard/settings/SettingsNavHost.kt | 6 + .../settings/screens/LanguageScreen.kt | 24 +- .../SubtypeScreen.kt} | 243 ++++++++++-------- 4 files changed, 145 insertions(+), 135 deletions(-) rename app/src/main/java/helium314/keyboard/settings/{dialogs/SubtypeDialog.kt => screens/SubtypeScreen.kt} (70%) diff --git a/app/src/main/java/helium314/keyboard/settings/SearchScreen.kt b/app/src/main/java/helium314/keyboard/settings/SearchScreen.kt index d6bf4081..1d7608e9 100644 --- a/app/src/main/java/helium314/keyboard/settings/SearchScreen.kt +++ b/app/src/main/java/helium314/keyboard/settings/SearchScreen.kt @@ -103,6 +103,7 @@ fun SearchScreen( title: @Composable () -> Unit, filteredItems: (String) -> List, itemContent: @Composable (T) -> Unit, + icon: @Composable (() -> Unit)? = null, menu: List Unit>>? = null, content: @Composable (ColumnScope.() -> Unit)? = null, ) { @@ -137,8 +138,10 @@ fun SearchScreen( } }, actions = { - IconButton(onClick = { setShowSearch(!showSearch) }) - { SearchIcon() } + if (icon == null) + IconButton(onClick = { setShowSearch(!showSearch) }) { SearchIcon() } + else + icon() if (menu != null) Box { var showMenu by remember { mutableStateOf(false) } diff --git a/app/src/main/java/helium314/keyboard/settings/SettingsNavHost.kt b/app/src/main/java/helium314/keyboard/settings/SettingsNavHost.kt index 761610a5..7a694070 100644 --- a/app/src/main/java/helium314/keyboard/settings/SettingsNavHost.kt +++ b/app/src/main/java/helium314/keyboard/settings/SettingsNavHost.kt @@ -16,6 +16,7 @@ import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable import androidx.navigation.compose.rememberNavController import helium314.keyboard.latin.common.LocaleUtils.constructLocale +import helium314.keyboard.latin.settings.SettingsSubtype.Companion.toSettingsSubtype import helium314.keyboard.settings.screens.AboutScreen import helium314.keyboard.settings.screens.AdvancedSettingsScreen import helium314.keyboard.settings.screens.AppearanceScreen @@ -29,6 +30,7 @@ import helium314.keyboard.settings.screens.PersonalDictionariesScreen import helium314.keyboard.settings.screens.PersonalDictionaryScreen import helium314.keyboard.settings.screens.PreferencesScreen import helium314.keyboard.settings.screens.SecondaryLayoutScreen +import helium314.keyboard.settings.screens.SubtypeScreen import helium314.keyboard.settings.screens.TextCorrectionScreen import helium314.keyboard.settings.screens.ToolbarScreen import kotlinx.coroutines.CoroutineScope @@ -126,6 +128,9 @@ fun SettingsNavHost( composable(SettingsDestination.ColorsNight + "{theme}") { ColorsScreen(isNight = true, theme = it.arguments?.getString("theme"), onClickBack = ::goBack) } + composable(SettingsDestination.Subtype + "{subtype}") { + SubtypeScreen(initialSubtype = it.arguments?.getString("subtype")!!.toSettingsSubtype(), onClickBack = ::goBack) + } } if (target.value != SettingsDestination.Settings/* && target.value != navController.currentBackStackEntry?.destination?.route*/) navController.navigate(route = target.value) @@ -146,6 +151,7 @@ object SettingsDestination { const val PersonalDictionaries = "personal_dictionaries" const val PersonalDictionary = "personal_dictionary/" const val Languages = "languages" + const val Subtype = "subtype/" const val Layouts = "layouts" const val Dictionaries = "dictionaries" val navTarget = MutableStateFlow(Settings) diff --git a/app/src/main/java/helium314/keyboard/settings/screens/LanguageScreen.kt b/app/src/main/java/helium314/keyboard/settings/screens/LanguageScreen.kt index 3c715646..f4e2d5ae 100644 --- a/app/src/main/java/helium314/keyboard/settings/screens/LanguageScreen.kt +++ b/app/src/main/java/helium314/keyboard/settings/screens/LanguageScreen.kt @@ -18,7 +18,6 @@ import androidx.compose.runtime.collectAsState 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 import androidx.compose.ui.Modifier @@ -39,15 +38,14 @@ import helium314.keyboard.latin.utils.Log import helium314.keyboard.latin.utils.MissingDictionaryDialog import helium314.keyboard.latin.utils.SubtypeLocaleUtils import helium314.keyboard.latin.utils.SubtypeSettings -import helium314.keyboard.latin.utils.SubtypeUtilsAdditional import helium314.keyboard.latin.utils.displayName import helium314.keyboard.latin.utils.getActivity import helium314.keyboard.latin.utils.locale import helium314.keyboard.latin.utils.prefs import helium314.keyboard.settings.SearchScreen import helium314.keyboard.settings.SettingsActivity +import helium314.keyboard.settings.SettingsDestination import helium314.keyboard.settings.Theme -import helium314.keyboard.settings.dialogs.SubtypeDialog import helium314.keyboard.settings.initPreview import helium314.keyboard.settings.previewDark import java.util.Locale @@ -57,12 +55,11 @@ fun LanguageScreen( onClickBack: () -> Unit, ) { val ctx = LocalContext.current - var sortedSubtypes by remember { mutableStateOf(getSortedSubtypes(ctx)) } + val sortedSubtypes by remember { mutableStateOf(getSortedSubtypes(ctx)) } val prefs = ctx.prefs() val b = (LocalContext.current.getActivity() as? SettingsActivity)?.prefChanged?.collectAsState() if ((b?.value ?: 0) < 0) Log.v("irrelevant", "stupid way to trigger recomposition on preference change") - var selectedSubtype: String? by rememberSaveable { mutableStateOf(null) } val enabledSubtypes = SubtypeSettings.getEnabledSubtypes() SearchScreen( onClickBack = onClickBack, @@ -87,7 +84,9 @@ fun LanguageScreen( verticalAlignment = Alignment.CenterVertically, modifier = Modifier .fillMaxWidth() - .clickable { selectedSubtype = item.toSettingsSubtype().toPref() } + .clickable { + SettingsDestination.navigateTo(SettingsDestination.Subtype + item.toSettingsSubtype().toPref()) + } .padding(vertical = 6.dp, horizontal = 16.dp) ) { var showNoDictDialog by remember { mutableStateOf(false) } @@ -119,19 +118,6 @@ fun LanguageScreen( } } ) - if (selectedSubtype != null) { - val oldSubtype = selectedSubtype!!.toSettingsSubtype() - SubtypeDialog( - onDismissRequest = { - selectedSubtype = null - sortedSubtypes = getSortedSubtypes(ctx) - }, - onConfirmed = { - SubtypeUtilsAdditional.changeAdditionalSubtype(oldSubtype, it, ctx) - }, - initialSubtype = oldSubtype - ) - } } private fun dictsAvailable(locale: Locale, context: Context): Boolean { diff --git a/app/src/main/java/helium314/keyboard/settings/dialogs/SubtypeDialog.kt b/app/src/main/java/helium314/keyboard/settings/screens/SubtypeScreen.kt similarity index 70% rename from app/src/main/java/helium314/keyboard/settings/dialogs/SubtypeDialog.kt rename to app/src/main/java/helium314/keyboard/settings/screens/SubtypeScreen.kt index 5ddf7a1e..be938921 100644 --- a/app/src/main/java/helium314/keyboard/settings/dialogs/SubtypeDialog.kt +++ b/app/src/main/java/helium314/keyboard/settings/screens/SubtypeScreen.kt @@ -1,5 +1,4 @@ -// SPDX-License-Identifier: GPL-3.0-only -package helium314.keyboard.settings.dialogs +package helium314.keyboard.settings.screens import android.content.Context import androidx.compose.foundation.clickable @@ -14,6 +13,7 @@ import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Surface import androidx.compose.material3.Switch import androidx.compose.material3.Text import androidx.compose.material3.TextButton @@ -68,22 +68,32 @@ import helium314.keyboard.latin.utils.getStringResourceOrName import helium314.keyboard.latin.utils.mainLayoutName import helium314.keyboard.latin.utils.prefs import helium314.keyboard.settings.DefaultButton +import helium314.keyboard.settings.DeleteButton import helium314.keyboard.settings.DropDownField +import helium314.keyboard.settings.SearchScreen import helium314.keyboard.settings.SettingsActivity import helium314.keyboard.settings.Theme import helium314.keyboard.settings.WithSmallTitle +import helium314.keyboard.settings.dialogs.ConfirmationDialog +import helium314.keyboard.settings.dialogs.LayoutEditDialog +import helium314.keyboard.settings.dialogs.ListPickerDialog +import helium314.keyboard.settings.dialogs.MultiListPickerDialog +import helium314.keyboard.settings.dialogs.ReorderDialog import helium314.keyboard.settings.initPreview import helium314.keyboard.settings.layoutFilePicker import helium314.keyboard.settings.layoutIntent import helium314.keyboard.settings.previewDark -import helium314.keyboard.settings.screens.GetIcon import java.util.Locale +// todo: +// dropdowns are weird +// at very least too wide and too high +// also too wide left (anchor should be icon) +// title shows only the layout name @Composable -fun SubtypeDialog( - onDismissRequest: () -> Unit, +fun SubtypeScreen( initialSubtype: SettingsSubtype, - onConfirmed: (SettingsSubtype) -> Unit, + onClickBack: () -> Unit, ) { val ctx = LocalContext.current val prefs = ctx.prefs() @@ -92,7 +102,10 @@ fun SubtypeDialog( Log.v("irrelevant", "stupid way to trigger recomposition on preference change") var currentSubtypeString by rememberSaveable { mutableStateOf(initialSubtype.toPref()) } val currentSubtype = currentSubtypeString.toSettingsSubtype() - fun setCurrentSubtype(subtype: SettingsSubtype) { currentSubtypeString = subtype.toPref() } + fun setCurrentSubtype(subtype: SettingsSubtype) { + SubtypeUtilsAdditional.changeAdditionalSubtype(currentSubtype, subtype, ctx) + currentSubtypeString = subtype.toPref() + } LaunchedEffect(currentSubtypeString) { if (ScriptUtils.scriptSupportsUppercase(currentSubtype.locale)) return@LaunchedEffect // update the noShiftKey extra value @@ -120,120 +133,119 @@ fun SubtypeDialog( var showMorePopupsDialog by remember { mutableStateOf(false) } val scrollState = rememberScrollState() val customMainLayouts = LayoutUtilsCustom.getLayoutFiles(LayoutType.MAIN, ctx, currentSubtype.locale).map { it.name } - ThreeButtonAlertDialog( - onDismissRequest = onDismissRequest, - onConfirmed = { onConfirmed(currentSubtype) }, - neutralButtonText = if (initialSubtype.isAdditionalSubtype(prefs)) stringResource(R.string.delete) else null, - onNeutral = { - SubtypeUtilsAdditional.removeAdditionalSubtype(ctx, initialSubtype.toAdditionalSubtype()) - SubtypeSettings.removeEnabledSubtype(ctx, initialSubtype.toAdditionalSubtype()) - onDismissRequest() - }, + SearchScreen( + onClickBack = onClickBack, + icon = { if (currentSubtype.isAdditionalSubtype(prefs)) DeleteButton { + SubtypeUtilsAdditional.removeAdditionalSubtype(ctx, currentSubtype.toAdditionalSubtype()) + SubtypeSettings.removeEnabledSubtype(ctx, currentSubtype.toAdditionalSubtype()) + onClickBack() + } }, title = { - val mainLayout = initialSubtype.mainLayoutName() ?: SubtypeLocaleUtils.QWERTY - Text(SubtypeLocaleUtils.getDisplayNameInSystemLocale(mainLayout, initialSubtype.locale)) + val mainLayout = currentSubtype.mainLayoutName() ?: SubtypeLocaleUtils.QWERTY + Text(SubtypeLocaleUtils.getDisplayNameInSystemLocale(mainLayout, currentSubtype.locale)) }, - content = { - Column( - modifier = Modifier.verticalScroll(scrollState), - verticalArrangement = Arrangement.spacedBy(8.dp), - ) { - MainLayoutRow(initialSubtype, currentSubtype, customMainLayouts) { setCurrentSubtype(it) } - if (availableLocalesForScript.size > 1) { - WithSmallTitle(stringResource(R.string.secondary_locale)) { - TextButton(onClick = { showSecondaryLocaleDialog = true }) { - val text = getSecondaryLocales(currentSubtype.extraValues).joinToString(", ") { - it.localizedDisplayName(ctx) - }.ifEmpty { stringResource(R.string.action_none) } - Text(text, Modifier.fillMaxWidth()) - } + itemContent = { }, + filteredItems = { emptyList() } + ) { + Column( + modifier = Modifier.verticalScroll(scrollState).padding(horizontal = 12.dp), + verticalArrangement = Arrangement.spacedBy(8.dp), + ) { + MainLayoutRow(currentSubtype, customMainLayouts) { setCurrentSubtype(it) } + if (availableLocalesForScript.size > 1) { + WithSmallTitle(stringResource(R.string.secondary_locale)) { + TextButton(onClick = { showSecondaryLocaleDialog = true }) { + val text = getSecondaryLocales(currentSubtype.extraValues).joinToString(", ") { + it.localizedDisplayName(ctx) + }.ifEmpty { stringResource(R.string.action_none) } + Text(text, Modifier.fillMaxWidth()) } } - Row { - TextButton(onClick = { showKeyOrderDialog = true }, Modifier.weight(1f)) - { Text(stringResource(R.string.popup_order)) } - DefaultButton(currentSubtype.getExtraValueOf(ExtraValue.POPUP_ORDER) == null) { - setCurrentSubtype(currentSubtype.without(ExtraValue.POPUP_ORDER)) - } + } + Row { + TextButton(onClick = { showKeyOrderDialog = true }, Modifier.weight(1f)) + { Text(stringResource(R.string.popup_order)) } + DefaultButton(currentSubtype.getExtraValueOf(ExtraValue.POPUP_ORDER) == null) { + setCurrentSubtype(currentSubtype.without(ExtraValue.POPUP_ORDER)) } - Row { - TextButton(onClick = { showHintOrderDialog = true }, Modifier.weight(1f)) - { Text(stringResource(R.string.hint_source)) } - DefaultButton(currentSubtype.getExtraValueOf(ExtraValue.HINT_ORDER) == null) { - setCurrentSubtype(currentSubtype.without(ExtraValue.HINT_ORDER)) - } + } + Row { + TextButton(onClick = { showHintOrderDialog = true }, Modifier.weight(1f)) + { Text(stringResource(R.string.hint_source)) } + DefaultButton(currentSubtype.getExtraValueOf(ExtraValue.HINT_ORDER) == null) { + setCurrentSubtype(currentSubtype.without(ExtraValue.HINT_ORDER)) } - if (currentSubtype.locale.script() == ScriptUtils.SCRIPT_LATIN) { - WithSmallTitle(stringResource(R.string.show_popup_keys_title)) { - val explicitValue = currentSubtype.getExtraValueOf(ExtraValue.MORE_POPUPS) - val value = explicitValue ?: prefs.getString(Settings.PREF_MORE_POPUP_KEYS, Defaults.PREF_MORE_POPUP_KEYS)!! - Row { - TextButton(onClick = { showMorePopupsDialog = true }, Modifier.weight(1f)) - { Text(stringResource(morePopupKeysResId(value))) } - DefaultButton(explicitValue == null) { - setCurrentSubtype(currentSubtype.without(ExtraValue.MORE_POPUPS)) - } - } - } - } - if (hasLocalizedNumberRow(currentSubtype.locale, ctx)) { - Row(verticalAlignment = Alignment.CenterVertically) { - val checked = currentSubtype.getExtraValueOf(ExtraValue.LOCALIZED_NUMBER_ROW)?.toBoolean() - Text(stringResource(R.string.localized_number_row), Modifier.weight(1f)) - Switch( - checked = checked ?: prefs.getBoolean(Settings.PREF_LOCALIZED_NUMBER_ROW, Defaults.PREF_LOCALIZED_NUMBER_ROW), - onCheckedChange = { - setCurrentSubtype(currentSubtype.with(ExtraValue.LOCALIZED_NUMBER_ROW, it.toString())) - } - ) - DefaultButton(checked == null) { - setCurrentSubtype(currentSubtype.without(ExtraValue.LOCALIZED_NUMBER_ROW)) - } - } - } - HorizontalDivider() - Text(stringResource(R.string.settings_screen_secondary_layouts), style = MaterialTheme.typography.titleMedium) - LayoutType.entries.forEach { type -> - if (type == LayoutType.MAIN) return@forEach - WithSmallTitle(stringResource(type.displayNameId)) { - val explicitLayout = currentSubtype.layoutName(type) - val layout = explicitLayout ?: Settings.readDefaultLayoutName(type, prefs) - val defaultLayouts = LayoutUtils.getAvailableLayouts(type, ctx) - val customLayouts = LayoutUtilsCustom.getLayoutFiles(type, ctx).map { it.name } - DropDownField( - items = defaultLayouts + customLayouts, - selectedItem = layout, - onSelected = { - setCurrentSubtype(currentSubtype.withLayout(type, it)) - }, - extraButton = { DefaultButton(explicitLayout == null) { - setCurrentSubtype(currentSubtype.withoutLayout(type)) - } }, - ) { - val displayName = if (LayoutUtilsCustom.isCustomLayout(it)) LayoutUtilsCustom.getDisplayName(it) - else it.getStringResourceOrName("layout_", ctx) - var showLayoutEditDialog by remember { mutableStateOf(false) } - Row( - horizontalArrangement = Arrangement.SpaceBetween, - modifier = Modifier.fillMaxWidth() - ) { - Text(displayName, Modifier.padding(end = 8.dp)) - if (LayoutUtilsCustom.isCustomLayout(it)) - Icon(painterResource(R.drawable.ic_edit), stringResource(R.string.edit_layout), Modifier.clickable { showLayoutEditDialog = true }) - } - if (showLayoutEditDialog) - LayoutEditDialog( - onDismissRequest = { showLayoutEditDialog = false }, - layoutType = type, - initialLayoutName = it, - isNameValid = null - ) + } + if (currentSubtype.locale.script() == ScriptUtils.SCRIPT_LATIN) { + WithSmallTitle(stringResource(R.string.show_popup_keys_title)) { + val explicitValue = currentSubtype.getExtraValueOf(ExtraValue.MORE_POPUPS) + val value = explicitValue ?: prefs.getString(Settings.PREF_MORE_POPUP_KEYS, Defaults.PREF_MORE_POPUP_KEYS)!! + Row { + TextButton(onClick = { showMorePopupsDialog = true }, Modifier.weight(1f)) + { Text(stringResource(morePopupKeysResId(value))) } + DefaultButton(explicitValue == null) { + setCurrentSubtype(currentSubtype.without(ExtraValue.MORE_POPUPS)) } } } } + if (hasLocalizedNumberRow(currentSubtype.locale, ctx)) { + Row(verticalAlignment = Alignment.CenterVertically) { + val checked = currentSubtype.getExtraValueOf(ExtraValue.LOCALIZED_NUMBER_ROW)?.toBoolean() + Text(stringResource(R.string.localized_number_row), Modifier.weight(1f)) + Switch( + checked = checked ?: prefs.getBoolean(Settings.PREF_LOCALIZED_NUMBER_ROW, Defaults.PREF_LOCALIZED_NUMBER_ROW), + onCheckedChange = { + setCurrentSubtype(currentSubtype.with(ExtraValue.LOCALIZED_NUMBER_ROW, it.toString())) + } + ) + DefaultButton(checked == null) { + setCurrentSubtype(currentSubtype.without(ExtraValue.LOCALIZED_NUMBER_ROW)) + } + } + } + HorizontalDivider() + Text(stringResource(R.string.settings_screen_secondary_layouts), style = MaterialTheme.typography.titleMedium) + LayoutType.entries.forEach { type -> + if (type == LayoutType.MAIN) return@forEach + WithSmallTitle(stringResource(type.displayNameId)) { + val explicitLayout = currentSubtype.layoutName(type) + val layout = explicitLayout ?: Settings.readDefaultLayoutName(type, prefs) + val defaultLayouts = LayoutUtils.getAvailableLayouts(type, ctx) + val customLayouts = LayoutUtilsCustom.getLayoutFiles(type, ctx).map { it.name } + DropDownField( + items = defaultLayouts + customLayouts, + selectedItem = layout, + onSelected = { + setCurrentSubtype(currentSubtype.withLayout(type, it)) + }, + extraButton = { DefaultButton(explicitLayout == null) { + setCurrentSubtype(currentSubtype.withoutLayout(type)) + } }, + ) { + val displayName = if (LayoutUtilsCustom.isCustomLayout(it)) LayoutUtilsCustom.getDisplayName(it) + else it.getStringResourceOrName("layout_", ctx) + var showLayoutEditDialog by remember { mutableStateOf(false) } + Row( + horizontalArrangement = Arrangement.SpaceBetween, + modifier = Modifier.fillMaxWidth() + ) { + Text(displayName, Modifier.padding(end = 8.dp)) + if (LayoutUtilsCustom.isCustomLayout(it)) + Icon(painterResource(R.drawable.ic_edit), stringResource(R.string.edit_layout), Modifier.clickable { showLayoutEditDialog = true }) + } + if (showLayoutEditDialog) + LayoutEditDialog( + onDismissRequest = { showLayoutEditDialog = false }, + layoutType = type, + initialLayoutName = it, + isNameValid = null + ) + } + } + } } - ) + } if (showSecondaryLocaleDialog) MultiListPickerDialog( onDismissRequest = { showSecondaryLocaleDialog = false }, @@ -294,6 +306,7 @@ fun SubtypeDialog( } } + // from ReorderSwitchPreference @Composable private fun PopupOrderDialog( @@ -336,7 +349,6 @@ private fun PopupOrderDialog( @Composable private fun MainLayoutRow( - initialSubtype: SettingsSubtype, currentSubtype: SettingsSubtype, customLayouts: List, setCurrentSubtype: (SettingsSubtype) -> Unit, @@ -369,13 +381,13 @@ private fun MainLayoutRow( Text(SubtypeLocaleUtils.getDisplayNameInSystemLocale(it, currentSubtype.locale)) Row (verticalAlignment = Alignment.CenterVertically) { Icon(painterResource(R.drawable.ic_edit), stringResource(R.string.edit_layout), Modifier.clickable { showLayoutEditDialog = it to null }) - if (it in customLayouts && initialSubtype.mainLayoutName() != it) // don't allow current main layout + if (it in customLayouts && currentSubtype.mainLayoutName() != it) // don't allow current main layout // todo: this was initialSubtype, maybe needs adjustment now Icon(painterResource(R.drawable.ic_bin), stringResource(R.string.delete), Modifier.clickable { showLayoutDeleteDialog = true }) } } if (showLayoutDeleteDialog) { val others = SubtypeSettings.getAdditionalSubtypes().filter { st -> st.mainLayoutName() == it } - .any { it.toSettingsSubtype() != initialSubtype } + .any { it.toSettingsSubtype() != currentSubtype } // todo: this was initialSubtype, maybe needs adjustment now ConfirmationDialog( onDismissRequest = { showLayoutDeleteDialog = false }, confirmButtonText = stringResource(R.string.delete), @@ -442,11 +454,14 @@ private fun MainLayoutRow( private fun getAvailableSecondaryLocales(context: Context, mainLocale: Locale): List = getDictionaryLocales(context).filter { it != mainLocale && it.script() == mainLocale.script() } + @Preview @Composable private fun Preview() { initPreview(LocalContext.current) Theme(previewDark) { - SubtypeDialog({}, SettingsSubtype(Locale.ENGLISH, "")) { } + Surface { + SubtypeScreen(SettingsSubtype(Locale.ENGLISH, "")) { } + } } }