Skip to content

Commit

Permalink
Merge branch 'main' into clipboard-clear
Browse files Browse the repository at this point in the history
  • Loading branch information
codokie authored Apr 6, 2024
2 parents d42efc0 + 38126d2 commit 489ade7
Show file tree
Hide file tree
Showing 26 changed files with 270 additions and 111 deletions.
2 changes: 2 additions & 0 deletions .github/FUNDING.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@

liberapay: Helium314
11 changes: 7 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ Does not use internet permission, and thus is 100% offline.
<ul>
<li>build your own, or get them <a href="https://codeberg.org/Helium314/aosp-dictionaries#dictionaries">here</a>, or in the <a href="https://codeberg.org/Helium314/aosp-dictionaries#experimental-dictionaries">experimental</a> section (quality may vary)</li>
<li>additional dictionaries for emojis or scientific symbols can be used to provide suggestions (similar to "emoji search")</li>
<li>note that for Korean layouts, suggestions only work using [this dictionary](https://github.com/openboard-team/openboard/commit/83fca9533c03b9fecc009fc632577226bbd6301f), the tools in the dictionary repository are not able to create working dictionaries</li>
<li>note that for Korean layouts, suggestions only work using <a href="https://github.com/openboard-team/openboard/commit/83fca9533c03b9fecc009fc632577226bbd6301f">this dictionary</a>, the tools in the dictionary repository are not able to create working dictionaries</li>
</ul>
<li>Customize keyboard themes (style, colors and background image)</li>
<ul>
Expand Down Expand Up @@ -55,6 +55,7 @@ Does not use internet permission, and thus is 100% offline.
* __Glide typing is not working after loading a library__: Possibly the download was corrupted, or you downloaded the wrong file. If you get a "_unknown file_" confirmation popup, it is likely you are not using the correct file (or you might be using a different version of the library). In rare cases, there might be crashes when the file is not in internal storage, or some [Samsung-specific problems](https://stackoverflow.com/a/75286899).
* __German layout with / without umlauts__: _German (Germany)_ layout has umlauts, _German_ layout doesn't
* __Spell checker is not checking all languages in multilingual typing__: Make sure you actually enabled HeliBoard spell checker. Usually it can be found in System Settings -> System -> Languages -> Advanced -> Spell Checker, but this may depend on Android version.
* __Words added to Gboard dictionary are not suggested__: Gboard uses its own dictionary instead of the system's personal dictionary. See [here](https://github.com/Helium314/HeliBoard/issues/500#issuecomment-2032292161) for how to export the words.
* __What is the _nouserlib_ version?__: The normal version (_release_) allows the user to provide a library for glide typing. Running code that isn't supplied with the app is _dynamic code loading_, which is a security risk. Android Studio warns about this:
> Dynamically loading code from locations other than the application's library directory or the Android platform's built-in library directories is dangerous, as there is an increased risk that the code could have been tampered with. Applications should use loadLibrary when possible, which provides increased assurance that libraries are loaded from one of these safer locations. Application developers should use the features of their development environment to place application native libraries into the lib directory of their compiled APKs.
Expand All @@ -76,14 +77,16 @@ Features that may go unnoticed, and further potentially useful information
* Swipe up from a suggestion to open more suggestions, and release on the suggestion to select it.
* Long-press an entry in the clipboard history to pin it (keep it in clipboard until you unpin).
* Swipe left in clipboard view to remove an entry (except when it's pinned)
* Select text and press shift to switch between uppercase, lowercase and capitalize words
* You can add dictionaries by opening the file
* This only works with _content-uris_ and not with _file-uris_, meaning that it may not work with some file explorers.
* _When using debug mode / debug APK_
* _Debug mode / debug APK_
* Long-press a suggestion in the suggestion strip twice to show the source dictionary.
* When using debug APK, you can find Debug Settings within the Advanced Preferences, though the usefulness is limited except for dumping dictionaries into the log.
* When using debug APK, you can find _Debug Settings_ within the _Advanced Preferences_, though the usefulness is limited except for dumping dictionaries into the log.
* For a release APK, you need to tap the version in _About_ several times, then you can find debug settings in _Advanced Preferences_.
* When enabling _Show suggestion infos_, suggestions will have some tiny numbers on top showing some internal score and source dictionary.
* In the event of an application crash, you will be prompted whether you want the crash logs when you open the Settings.
* When using multilingual typing, space bar will show an confidence value used for determining the currently used language.
* Suggestions will have some tiny numbers on top showing some internal score and source dictionary (can be disabled)
* For users doing manual backups with root access: Starting at Android 7, some files and the main shared preferences file are not in the default location, because the app is using [device protected storage](https://developer.android.com/reference/android/content/Context#createDeviceProtectedStorageContext()). This is necessary so the settings and layout files can be read before the device is unlocked, e.g. at boot. The files are usually located in `/data/user_de/0/<package_id>/`, though the location may depend on the device and Android version.

# Contributing ❤
Expand Down
6 changes: 5 additions & 1 deletion app/src/main/assets/layouts/bengali_probhat.json
Original file line number Diff line number Diff line change
Expand Up @@ -122,11 +122,15 @@
},
{ "$": "shift_state_selector",
"manualOrLocked": { "label": "" },
"default": { "label": "." }
"default": { "label": "" }
},
{ "$": "shift_state_selector",
"manualOrLocked": { "label": "" },
"default": { "label": "" }
}
],
[
{ "label": "," },
{ "label": "." }
]
]
33 changes: 33 additions & 0 deletions app/src/main/assets/layouts/russian_student.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
я
ш
е
р
т
ы
y
и
о
п
э

а
с
д
ф
г
ч
й
к
л
ж
щ

з
х
ц
в
б
н
м
ь
ю
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ import helium314.keyboard.latin.common.DefaultColors
import helium314.keyboard.latin.common.DynamicColors
import helium314.keyboard.latin.settings.Settings
import helium314.keyboard.latin.utils.DeviceProtectedUtils
import helium314.keyboard.latin.utils.Log
import helium314.keyboard.latin.utils.ResourceUtils

class KeyboardTheme // Note: The themeId should be aligned with "themeId" attribute of Keyboard style in values/themes-<style>.xml.
Expand Down Expand Up @@ -92,9 +91,7 @@ private constructor(val themeId: Int, @JvmField val mStyleId: Int) {
STYLE_ROUNDED -> if (borders) THEME_ID_ROUNDED_BASE_BORDER else THEME_ID_ROUNDED_BASE
else -> if (borders) THEME_ID_LXX_BASE_BORDER else THEME_ID_LXX_BASE
}
val theme = KEYBOARD_THEMES.firstOrNull { it.themeId == matchingId } ?: KEYBOARD_THEMES[DEFAULT_THEME_ID]
Log.d("KeyboardTheme", "Selected theme ${theme.themeId} and style ${theme.mStyleId} from $style (borders: $borders)")
return theme
return KEYBOARD_THEMES.firstOrNull { it.themeId == matchingId } ?: KEYBOARD_THEMES[DEFAULT_THEME_ID]
}

fun getThemeActionAndEmojiKeyLabelFlags(themeId: Int): Int {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ class ClipboardHistoryView @JvmOverloads constructor(
// even when state is activated, the not activated color is set
// in suggestionStripView the same thing works correctly, wtf?
// need to properly fix it (and maybe undo the inverted isActivated) when adding a toggle key
listOf(ToolbarKey.LEFT, ToolbarKey.RIGHT, ToolbarKey.COPY, ToolbarKey.CUT, ToolbarKey.CLEAR_CLIPBOARD, ToolbarKey.SELECT_WORD, ToolbarKey.SELECT_ALL)
listOf(ToolbarKey.LEFT, ToolbarKey.RIGHT, ToolbarKey.COPY, ToolbarKey.CUT, ToolbarKey.CLEAR_CLIPBOARD, ToolbarKey.SELECT_WORD, ToolbarKey.SELECT_ALL, ToolbarKey.CLOSE_HISTORY)
.forEach { toolbarKeys.add(createToolbarKey(context, keyboardAttr, it)) }
keyboardAttr.recycle()
}
Expand Down Expand Up @@ -236,8 +236,6 @@ class ClipboardHistoryView @JvmOverloads constructor(
keyboardActionListener?.onCodeInput(code, Constants.NOT_A_COORDINATE, Constants.NOT_A_COORDINATE, false)
return
}
if (tag == ToolbarKey.CLEAR_CLIPBOARD)
clipboardHistoryManager?.clearHistory()
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ class AdvancedSettingsFragment : SubScreenFragment() {
requireContext().assets.list("layouts")?.firstOrNull { it.startsWith("$layout.") }
?.let { requireContext().assets.open("layouts" + File.separator + it).reader().readText() }
}
val displayName = layout.getStringResourceOrName("layout", requireContext())
val displayName = layout.getStringResourceOrName("layout_", requireContext())
editCustomLayout(customLayoutName ?: "$CUSTOM_LAYOUT_PREFIX$layout.txt", requireContext(), originalLayout, displayName)
}

Expand Down Expand Up @@ -459,9 +459,10 @@ class AdvancedSettingsFragment : SubScreenFragment() {
originalName.replace(fileName, fileName.constructLocale().toLanguageTag())
}
originalName.startsWith("layouts") -> {
// replace file name after switch to language tag
// but only if it's not a symbols layout
// replace file name after switch to language tag, but only if it's not a layout
val localeString = originalName.substringAfter(".").substringBefore(".")
if (localeString in listOf(LAYOUT_SYMBOLS, LAYOUT_SYMBOLS_SHIFTED, LAYOUT_SYMBOLS_ARABIC, LAYOUT_NUMBER, LAYOUT_NUMPAD, LAYOUT_NUMPAD_LANDSCAPE, LAYOUT_PHONE, LAYOUT_PHONE_SYMBOLS))
return originalName // it's a layout!
val locale = localeString.constructLocale()
if (locale.toLanguageTag() != "und")
originalName.replace(localeString, locale.toLanguageTag())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -375,12 +375,12 @@ class LanguageSettingsDialog(
private fun setupPopupSettings() {
binding.popupOrder.setOnClickListener {
val popupKeyTypesDefault = prefs.getString(Settings.PREF_POPUP_KEYS_ORDER, POPUP_KEYS_ORDER_DEFAULT)!!
reorderPopupKeysDialog(context, Settings.PREF_POPUP_KEYS_ORDER + "_" + mainLocale.toLanguageTag(), popupKeyTypesDefault, R.string.popup_order)
reorderDialog(context, Settings.PREF_POPUP_KEYS_ORDER + "_" + mainLocale.toLanguageTag(), popupKeyTypesDefault, R.string.popup_order)
KeyboardLayoutSet.onKeyboardThemeChanged()
}
binding.popupLabelPriority.setOnClickListener {
val popupKeyTypesDefault = prefs.getString(Settings.PREF_POPUP_KEYS_LABELS_ORDER, POPUP_KEYS_LABEL_DEFAULT)!!
reorderPopupKeysDialog(context, Settings.PREF_POPUP_KEYS_LABELS_ORDER + "_" + mainLocale.toLanguageTag(), popupKeyTypesDefault, R.string.hint_source)
reorderDialog(context, Settings.PREF_POPUP_KEYS_LABELS_ORDER + "_" + mainLocale.toLanguageTag(), popupKeyTypesDefault, R.string.hint_source)
KeyboardLayoutSet.onKeyboardThemeChanged()
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import helium314.keyboard.latin.AudioAndHapticFeedbackManager;
import helium314.keyboard.latin.R;
import helium314.keyboard.latin.RichInputMethodManager;
import helium314.keyboard.latin.utils.DialogUtilsKt;
import helium314.keyboard.latin.utils.PopupKeysUtilsKt;
import helium314.keyboard.latin.utils.SubtypeSettingsKt;
import helium314.keyboard.latin.utils.SubtypeUtilsKt;
Expand Down Expand Up @@ -59,15 +60,18 @@ public void onCreate(final Bundle icicle) {
setLocalizedNumberRowVisibility();
findPreference(Settings.PREF_POPUP_KEYS_LABELS_ORDER).setVisible(getSharedPreferences().getBoolean(Settings.PREF_SHOW_HINTS, false));
findPreference(Settings.PREF_POPUP_KEYS_ORDER).setOnPreferenceClickListener((pref) -> {
PopupKeysUtilsKt.reorderPopupKeysDialog(requireContext(), Settings.PREF_POPUP_KEYS_ORDER, PopupKeysUtilsKt.POPUP_KEYS_ORDER_DEFAULT, R.string.popup_order);
DialogUtilsKt.reorderDialog(requireContext(), Settings.PREF_POPUP_KEYS_ORDER,
PopupKeysUtilsKt.POPUP_KEYS_ORDER_DEFAULT, R.string.popup_order, (x) -> null);
return true;
});
findPreference(Settings.PREF_POPUP_KEYS_LABELS_ORDER).setOnPreferenceClickListener((pref) -> {
PopupKeysUtilsKt.reorderPopupKeysDialog(requireContext(), Settings.PREF_POPUP_KEYS_LABELS_ORDER, PopupKeysUtilsKt.POPUP_KEYS_LABEL_DEFAULT, R.string.hint_source);
DialogUtilsKt.reorderDialog(requireContext(), Settings.PREF_POPUP_KEYS_LABELS_ORDER,
PopupKeysUtilsKt.POPUP_KEYS_LABEL_DEFAULT, R.string.hint_source, (x) -> null);
return true;
});
findPreference(Settings.PREF_TOOLBAR_KEYS).setOnPreferenceClickListener((pref) -> {
PopupKeysUtilsKt.reorderPopupKeysDialog(requireContext(), Settings.PREF_TOOLBAR_KEYS, ToolbarUtilsKt.getDefaultToolbarPref(), R.string.toolbar_keys);
DialogUtilsKt.reorderDialog(requireContext(), Settings.PREF_TOOLBAR_KEYS, ToolbarUtilsKt.getDefaultToolbarPref(),
R.string.toolbar_keys, (name) -> ToolbarUtilsKt.getToolbarIconByName(name, requireContext()));
return true;
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -625,7 +625,7 @@ public static Colors getColorsForCurrentTheme(final Context context, final Share
boolean isNight = ResourceUtils.isNight(context.getResources());
if (ColorsSettingsFragment.Companion.getForceOppositeTheme()) isNight = !isNight;
final String themeColors = (isNight && readDayNightPref(prefs, context.getResources()))
? prefs.getString(Settings.PREF_THEME_COLORS_NIGHT, KeyboardTheme.THEME_DARKER)
? prefs.getString(Settings.PREF_THEME_COLORS_NIGHT, KeyboardTheme.THEME_DARK)
: prefs.getString(Settings.PREF_THEME_COLORS, KeyboardTheme.THEME_LIGHT);
final String themeStyle = prefs.getString(Settings.PREF_THEME_STYLE, KeyboardTheme.STYLE_MATERIAL);

Expand Down
97 changes: 97 additions & 0 deletions app/src/main/java/helium314/keyboard/latin/utils/DialogUtils.kt
Original file line number Diff line number Diff line change
@@ -1,9 +1,24 @@
package helium314.keyboard.latin.utils

import android.content.Context
import android.graphics.drawable.Drawable
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.Switch
import android.widget.TextView
import androidx.annotation.StringRes
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.view.ContextThemeWrapper
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.ItemTouchHelper
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView
import helium314.keyboard.latin.R
import java.util.Collections

fun getPlatformDialogThemeContext(context: Context): Context {
// Because {@link AlertDialog.Builder.create()} doesn't honor the specified theme with
Expand Down Expand Up @@ -32,3 +47,85 @@ fun infoDialog(context: Context, message: String) {
.setNegativeButton(android.R.string.ok, null)
.show()
}

/**
* Show a dialog that allows re-ordering and dis/enabling items (currently toolbar keys and popup keys).
* The items are stored in a string pref in [key]. Each item contains a name and true/false, comma-separated.
* Items are semicolon-separated, see e.g. [POPUP_KEYS_LABEL_DEFAULT] for an example.
*/
// this should probably be a class
fun reorderDialog(
context: Context,
key: String,
defaultSetting: String,
@StringRes dialogTitleId: Int,
getIcon: (String) -> Drawable? = { null }
) {
val prefs = DeviceProtectedUtils.getSharedPreferences(context)
val orderedItems = prefs.getString(key, defaultSetting)!!.split(";").mapTo(ArrayList()) {
val both = it.split(",")
both.first() to both.last().toBoolean()
}
val rv = RecyclerView(context)
val bgColor = ContextCompat.getColor(context, R.color.sliding_items_background)
val padding = ResourceUtils.toPx(8, context.resources)
rv.setPadding(3 * padding, padding, padding, padding)
rv.layoutManager = LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)

val callback = object : DiffUtil.ItemCallback<Pair<String, Boolean>>() {
override fun areItemsTheSame(p0: Pair<String, Boolean>, p1: Pair<String, Boolean>) = p0 == p1
override fun areContentsTheSame(p0: Pair<String, Boolean>, p1: Pair<String, Boolean>) = p0 == p1
}

val adapter = object : ListAdapter<Pair<String, Boolean>, RecyclerView.ViewHolder>(callback) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val b = LayoutInflater.from(context).inflate(R.layout.reorder_dialog_item, rv, false)
b.setBackgroundColor(bgColor)
return object : RecyclerView.ViewHolder(b) { }
}
override fun onBindViewHolder(viewHolder: RecyclerView.ViewHolder, position: Int) {
val (text, wasChecked) = orderedItems[position]
val displayText = text.lowercase().getStringResourceOrName("", context)
viewHolder.itemView.findViewById<TextView>(R.id.reorder_item_name)?.text = displayText
val switch = viewHolder.itemView.findViewById<Switch>(R.id.reorder_item_switch)
switch?.setOnCheckedChangeListener(null)
switch?.isChecked = wasChecked
switch?.setOnCheckedChangeListener { _, isChecked ->
val pos = orderedItems.indexOfFirst { it.first == text }
orderedItems[pos] = text to isChecked
}
val icon = getIcon(text)
viewHolder.itemView.findViewById<ImageView>(R.id.reorder_item_icon)?.let {
it.visibility = if (icon == null) View.GONE else View.VISIBLE
it.setImageDrawable(icon)
}
}
}
rv.adapter = adapter

ItemTouchHelper(object : ItemTouchHelper.SimpleCallback(ItemTouchHelper.UP or ItemTouchHelper.DOWN, 0) {
override fun onMove(rv: RecyclerView, viewHolder: RecyclerView.ViewHolder, target: RecyclerView.ViewHolder): Boolean {
val pos1 = viewHolder.absoluteAdapterPosition
val pos2 = target.absoluteAdapterPosition
Collections.swap(orderedItems, pos1, pos2)
adapter.notifyItemMoved(pos1, pos2)
return true
}
override fun onSwiped(rv: RecyclerView.ViewHolder, direction: Int) { }
}).attachToRecyclerView(rv)

adapter.submitList(orderedItems)

AlertDialog.Builder(context)
.setTitle(dialogTitleId)
.setPositiveButton(android.R.string.ok) { _, _ ->
val value = orderedItems.joinToString(";") { it.first + "," + it.second }
prefs.edit().putString(key, value).apply()
}
.setNegativeButton(android.R.string.cancel, null)
.setNeutralButton(R.string.button_default) { _, _ ->
prefs.edit().remove(key).apply()
}
.setView(rv)
.show()
}
Loading

0 comments on commit 489ade7

Please sign in to comment.