Sort chinese apps by their pinyin transliteration

Close #61
This commit is contained in:
MM20 2022-06-12 15:48:43 +02:00
parent a064e800b6
commit b436f75f17
No known key found for this signature in database
GPG Key ID: 0B61A8F2DEAFA389
7 changed files with 40 additions and 24 deletions

View File

@ -45,8 +45,6 @@ dependencies {
implementation(libs.commons.text)
implementation(libs.tinypinyin)
implementation(project(":search"))
implementation(project(":base"))
implementation(project(":preferences"))

View File

@ -5,15 +5,13 @@ import android.content.Context
import android.content.Intent
import android.content.pm.LauncherActivityInfo
import android.content.pm.LauncherApps
import android.content.pm.PackageInstaller
import android.content.pm.ShortcutInfo
import android.os.Handler
import android.os.Looper
import android.os.Process
import android.os.UserHandle
import android.util.Log
import com.github.promeg.pinyinhelper.Pinyin
import de.mm20.launcher2.search.data.AppInstallation
import de.mm20.launcher2.ktx.normalize
import de.mm20.launcher2.search.data.Application
import de.mm20.launcher2.search.data.LauncherApp
import kotlinx.coroutines.Dispatchers
@ -170,14 +168,10 @@ internal class AppRepositoryImpl(
}
private fun matches(label: String, query: String): Boolean {
val labelLatin = romanize(label)
val normalizedLabel = label.normalize()
val fuzzyScore = FuzzyScore(Locale.getDefault())
return fuzzyScore.fuzzyScore(label, query) >= query.length * 1.5 ||
fuzzyScore.fuzzyScore(labelLatin, query) >= query.length * 1.5
}
private fun romanize(label: String): String {
return Pinyin.toPinyin(label, "").lowercase(Locale.getDefault())
fuzzyScore.fuzzyScore(normalizedLabel, query.normalize()) >= query.length * 1.5
}
private fun getActivityByComponentName(componentName: ComponentName?): Application? {

View File

@ -42,7 +42,6 @@ dependencies {
implementation(libs.koin.android)
implementation(libs.commons.text)
implementation(libs.tinypinyin)
implementation(project(":search"))
implementation(project(":permissions"))

View File

@ -6,7 +6,8 @@ import android.content.pm.LauncherApps
import android.content.pm.PackageManager
import android.os.Process
import androidx.core.content.getSystemService
import com.github.promeg.pinyinhelper.Pinyin
import de.mm20.launcher2.ktx.normalize
import de.mm20.launcher2.ktx.romanize
import de.mm20.launcher2.permissions.PermissionGroup
import de.mm20.launcher2.permissions.PermissionsManager
import de.mm20.launcher2.preferences.LauncherDataStore
@ -128,13 +129,9 @@ internal class AppShortcutRepositoryImpl(
private fun matches(label: String, query: String): Boolean {
val labelLatin = romanize(label)
val labelLatin = label.normalize()
val fuzzyScore = FuzzyScore(Locale.getDefault())
return fuzzyScore.fuzzyScore(label, query) >= query.length * 1.5 ||
fuzzyScore.fuzzyScore(labelLatin, query) >= query.length * 1.5
}
private fun romanize(label: String): String {
return Pinyin.toPinyin(label, "").lowercase(Locale.getDefault())
fuzzyScore.fuzzyScore(labelLatin, query.normalize()) >= query.length * 1.5
}
}

View File

@ -38,6 +38,7 @@ dependencies {
implementation(libs.bundles.kotlin)
implementation(libs.androidx.core)
implementation(libs.tinypinyin)
implementation(libs.androidx.appcompat)
implementation(libs.bundles.androidx.lifecycle)

View File

@ -1,7 +1,25 @@
package de.mm20.launcher2.ktx
import com.github.promeg.pinyinhelper.Pinyin
import java.net.URLDecoder
import java.util.*
fun String.decodeUrl(charset: String): String? {
return URLDecoder.decode(this, charset)
}
/**
* Normalize a string to lowercase ASCII
* TODO: Only supports Chinese/Pinyin at the moment
*/
fun String.normalize(): String {
return this.romanize().lowercase(Locale.getDefault())
}
/**
* Romanize a string, transliterate non-latin characters into latin
* TODO: Only supports Chinese/Pinyin at the moment
*/
fun String.romanize(): String {
return Pinyin.toPinyin(this, "")
}

View File

@ -1,13 +1,12 @@
package de.mm20.launcher2.search.data
import android.content.ActivityNotFoundException
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.widget.Toast
import de.mm20.launcher2.icons.LauncherIcon
import de.mm20.launcher2.ktx.romanize
import de.mm20.launcher2.ktx.tryStartActivity
import de.mm20.launcher2.preferences.Settings
import de.mm20.launcher2.preferences.Settings.IconSettings.LegacyIconBackground
import de.mm20.launcher2.search.R
import java.text.Collator
@ -26,16 +25,26 @@ abstract class Searchable : Comparable<Searchable> {
return if (context.tryStartActivity(intent, options)) {
true
} else {
Toast.makeText(context, context.getString(R.string.error_activity_not_found, label), Toast.LENGTH_SHORT).show()
Toast.makeText(
context,
context.getString(R.string.error_activity_not_found, label),
Toast.LENGTH_SHORT
).show()
false
}
}
open suspend fun loadIcon(context: Context, size: Int, legacyIconBackground: LegacyIconBackground): LauncherIcon? = null
open suspend fun loadIcon(
context: Context,
size: Int,
legacyIconBackground: LegacyIconBackground
): LauncherIcon? = null
abstract fun getPlaceholderIcon(context: Context): LauncherIcon
override fun compareTo(other: Searchable): Int {
return Collator.getInstance().apply { strength = Collator.SECONDARY }.compare(label, other.label)
return Collator.getInstance().apply { strength = Collator.SECONDARY }
.compare(label.romanize(), other.label.romanize())
}
override fun equals(other: Any?): Boolean {