This commit is contained in:
Jan 2025-06-27 15:33:17 +00:00 committed by GitHub
commit cb5f1bd924
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 81 additions and 17 deletions

View file

@ -8,6 +8,8 @@ import de.jrpie.android.launcher.actions.AppAction
import de.jrpie.android.launcher.actions.Gesture import de.jrpie.android.launcher.actions.Gesture
import de.jrpie.android.launcher.actions.ShortcutAction import de.jrpie.android.launcher.actions.ShortcutAction
import de.jrpie.android.launcher.preferences.LauncherPreferences import de.jrpie.android.launcher.preferences.LauncherPreferences
import de.jrpie.android.launcher.util.countOccurrences
import de.jrpie.android.launcher.util.isSubsequent
import java.util.Locale import java.util.Locale
import kotlin.text.Regex.Companion.escape import kotlin.text.Regex.Companion.escape
@ -22,7 +24,6 @@ class AppFilter(
operator fun invoke(apps: List<AbstractDetailedAppInfo>): List<AbstractDetailedAppInfo> { operator fun invoke(apps: List<AbstractDetailedAppInfo>): List<AbstractDetailedAppInfo> {
var apps = var apps =
apps.sortedBy { app -> app.getCustomLabel(context).lowercase(Locale.ROOT) } apps.sortedBy { app -> app.getCustomLabel(context).lowercase(Locale.ROOT) }
val hidden = LauncherPreferences.apps().hidden() ?: setOf() val hidden = LauncherPreferences.apps().hidden() ?: setOf()
val favorites = LauncherPreferences.apps().favorites() ?: setOf() val favorites = LauncherPreferences.apps().favorites() ?: setOf()
val private = apps.filter { it.isPrivate() } val private = apps.filter { it.isPrivate() }
@ -62,24 +63,39 @@ class AppFilter(
if (query.isEmpty()) { if (query.isEmpty()) {
return apps return apps
} else { }
val r: MutableList<AbstractDetailedAppInfo> = ArrayList() val r: MutableSet<AbstractDetailedAppInfo> = hashSetOf()
val appsSecondary: MutableList<AbstractDetailedAppInfo> = ArrayList()
val normalizedQuery: String = normalize(query) val normalizedQuery: String = normalize(query)
val subsequentResult: MutableList<AbstractDetailedAppInfo> = mutableListOf()
val occurrences: MutableMap<AbstractDetailedAppInfo, Int> = mutableMapOf()
for (item in apps) { for (item in apps) {
val itemLabel: String = normalize(item.getCustomLabel(context)) val itemLabel: String = normalize(item.getCustomLabel(context))
if (itemLabel.startsWith(normalizedQuery)) { if (itemLabel.startsWith(normalizedQuery)) {
r.add(item) r.add(item)
} else if (itemLabel.contains(normalizedQuery)) { } else if (itemLabel.contains(normalizedQuery)) {
appsSecondary.add(item) r.add(item)
}
if (LauncherPreferences.functionality().searchFuzzy()) {
if (isSubsequent(itemLabel, normalizedQuery)) {
subsequentResult.add(item)
}
occurrences[item] = countOccurrences(itemLabel, normalizedQuery)
} }
} }
r.addAll(appsSecondary) if (LauncherPreferences.functionality().searchFuzzy() && r.size != 1) {
if (subsequentResult.isNotEmpty()) {
r.addAll(subsequentResult)
} else {
val maxOccurrences = occurrences.values.maxOrNull()
if (maxOccurrences == 0) return apps
val result = occurrences.filter { it.value == maxOccurrences }
r.addAll(result.keys)
}
}
return r.toList().sortedBy { it.getCustomLabel(context).lowercase(Locale.ROOT) }
}
return r
}
}
companion object { companion object {
enum class AppSetVisibility( enum class AppSetVisibility(

View file

@ -75,6 +75,7 @@ import eu.jonahbauer.android.preference.annotations.Preferences;
@Preference(name = "search_web", type = boolean.class, description = "false"), @Preference(name = "search_web", type = boolean.class, description = "false"),
@Preference(name = "search_auto_open_keyboard", type = boolean.class, defaultValue = "true"), @Preference(name = "search_auto_open_keyboard", type = boolean.class, defaultValue = "true"),
@Preference(name = "search_auto_close_keyboard", type = boolean.class, defaultValue = "false"), @Preference(name = "search_auto_close_keyboard", type = boolean.class, defaultValue = "false"),
@Preference(name = "search_fuzzy", type = boolean.class, defaultValue = "true"),
}), }),
@PreferenceGroup(name = "enabled_gestures", prefix = "settings_enabled_gestures_", suffix = "_key", value = { @PreferenceGroup(name = "enabled_gestures", prefix = "settings_enabled_gestures_", suffix = "_key", value = {
@Preference(name = "double_swipe", type = boolean.class, defaultValue = "true"), @Preference(name = "double_swipe", type = boolean.class, defaultValue = "true"),

View file

@ -0,0 +1,39 @@
package de.jrpie.android.launcher.util
/**
* Returns true if `search` is a subsequence of `text`.
* A subsequence means all characters in `search` appear in `text`
* in the same order, but not necessarily contiguously.
*/
fun isSubsequent(text: String, search: String): Boolean {
var i = 0
for (char in text) {
if (char != search[i]) continue
i++
if (i == search.length) {
return true
}
}
return false
}
/**
* Returns the amount of characters from `search` that occur inside `text`.
* If `text` contains the same character multiple times, it is only counted
* as often as it occurs in `search`.
*/
fun countOccurrences(text: String, search: String): Int {
val frequencies = mutableMapOf<Char, Int>()
for (char in text) {
frequencies[char] = frequencies.getOrElse(char) { 0 } + 1
}
var result = 0
for (char in search) {
val charFrequency = frequencies[char] ?: 0
if (charFrequency > 0) {
result++
frequencies[char] = charFrequency - 1
}
}
return result
}

View file

@ -309,4 +309,5 @@
<string name="list_other_list_private_space">Privater Bereich</string> <string name="list_other_list_private_space">Privater Bereich</string>
<string name="list_other_track_play_pause">Musik: Wiedergabe / Pause</string> <string name="list_other_track_play_pause">Musik: Wiedergabe / Pause</string>
<string name="settings_list_reverse_layout">Appliste umkehren</string> <string name="settings_list_reverse_layout">Appliste umkehren</string>
<string name="settings_functionality_search_fuzzy">Fuzzy-Suche verwenden</string>
</resources> </resources>

View file

@ -148,6 +148,7 @@
<string name="settings_enabled_gestures_edge_swipe_edge_width_key" translatable="false">enabled_gestures.edge_actions.edge_width</string> <string name="settings_enabled_gestures_edge_swipe_edge_width_key" translatable="false">enabled_gestures.edge_actions.edge_width</string>
<string name="settings_functionality_search_auto_launch_key" translatable="false">functionality.search_auto_launch</string> <string name="settings_functionality_search_auto_launch_key" translatable="false">functionality.search_auto_launch</string>
<string name="settings_functionality_search_web_key" translatable="false">functionality.search_web</string> <string name="settings_functionality_search_web_key" translatable="false">functionality.search_web</string>
<string name="settings_functionality_search_fuzzy_key" translatable="false">functionality.search_fuzzy</string>
<string name="settings_functionality_search_auto_open_keyboard_key" translatable="false">functionality.search_auto_keyboard</string> <string name="settings_functionality_search_auto_open_keyboard_key" translatable="false">functionality.search_auto_keyboard</string>
<string name="settings_functionality_search_auto_close_keyboard_key" translatable="false">functionality.search_auto_close_keyboard</string> <string name="settings_functionality_search_auto_close_keyboard_key" translatable="false">functionality.search_auto_close_keyboard</string>

View file

@ -456,4 +456,5 @@
<string name="content_description_navigate_next">Navigate next</string> <string name="content_description_navigate_next">Navigate next</string>
<string name="content_description_lock">Lock</string> <string name="content_description_lock">Lock</string>
<string name="content_description_settings_actions_row_button_remove">Remove binding</string> <string name="content_description_settings_actions_row_button_remove">Remove binding</string>
<string name="settings_functionality_search_fuzzy">Use fuzzy search</string>
</resources> </resources>

View file

@ -100,6 +100,11 @@
android:defaultValue="false" android:defaultValue="false"
android:summary="@string/settings_functionality_search_web_summary" android:summary="@string/settings_functionality_search_web_summary"
/> />
<SwitchPreference
android:key="@string/settings_functionality_search_fuzzy_key"
android:title="@string/settings_functionality_search_fuzzy"
android:defaultValue="true"
/>
<SwitchPreference <SwitchPreference
android:key="@string/settings_functionality_search_auto_open_keyboard_key" android:key="@string/settings_functionality_search_auto_open_keyboard_key"
android:defaultValue="true" android:defaultValue="true"