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
This commit is contained in:
Eran Leshem 2025-03-13 17:31:03 +02:00 committed by GitHub
parent d05a59e4ed
commit 18a328cd2b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 52 additions and 21 deletions

View file

@ -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:__

View file

@ -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 }
]
]

View file

@ -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<KeyData>, List<KeyData>> {
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<String> {
val tlds = getDefaultTlds(locale)
val ccLower = locale.country.lowercase()
val tlds = LinkedHashSet<String>()
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<String> {
val tlds = linkedSetOf<String>()
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

View file

@ -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<AbstractKeyData>? {
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))
}
/**

View file

@ -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

View file

@ -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";

View file

@ -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);

View file

@ -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() }
},

View file

@ -249,6 +249,10 @@
<string name="hint_source">Select hint source</string>
<!-- Title of the setting to set popup key order -->
<string name="popup_order">Select popup key order</string>
<!-- Title of the setting to show TLD popup keys -->
<string name="show_tld_popup_keys">Show TLD popup keys</string>
<!-- Description of the setting to show TLD popup keys -->
<string name="show_tld_popup_keys_summary">Replace period key popups with top level domains when typing URLs and email addresses</string>
<!-- Names of the popup key classes -->
<string name="popup_keys_number" tools:keep="@string/popup_keys_number">Number row</string>
<string name="popup_keys_language" tools:keep="@string/popup_keys_language">Language</string>

View file

@ -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