Refresh shortcuts after removing one

This commit is contained in:
MM20 2022-08-05 13:30:53 +02:00
parent 44d4555966
commit bc86a22086
No known key found for this signature in database
GPG Key ID: 0B61A8F2DEAFA389
2 changed files with 99 additions and 44 deletions

View File

@ -4,7 +4,11 @@ import android.content.Context
import android.content.pm.LauncherActivityInfo
import android.content.pm.LauncherApps
import android.content.pm.PackageManager
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 androidx.core.content.getSystemService
import de.mm20.launcher2.ktx.normalize
@ -12,11 +16,11 @@ import de.mm20.launcher2.permissions.PermissionGroup
import de.mm20.launcher2.permissions.PermissionsManager
import de.mm20.launcher2.preferences.LauncherDataStore
import de.mm20.launcher2.search.data.AppShortcut
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.channelFlow
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.Job
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.*
import kotlinx.coroutines.withContext
import org.apache.commons.text.similarity.FuzzyScore
import java.util.*
@ -38,6 +42,8 @@ internal class AppShortcutRepositoryImpl(
private val dataStore: LauncherDataStore,
) : AppShortcutRepository {
private val scope = CoroutineScope(Dispatchers.Default + Job())
override suspend fun getShortcutsForActivity(
launcherActivityInfo: LauncherActivityInfo,
count: Int,
@ -84,51 +90,99 @@ internal class AppShortcutRepositoryImpl(
return@collectLatest
}
val launcherApps =
context.getSystemService<LauncherApps>() ?: return@collectLatest send(
emptyList()
)
val shortcutQuery = LauncherApps.ShortcutQuery()
shortcutQuery.setQueryFlags(
LauncherApps.ShortcutQuery.FLAG_MATCH_PINNED or
LauncherApps.ShortcutQuery.FLAG_MATCH_DYNAMIC or
LauncherApps.ShortcutQuery.FLAG_MATCH_MANIFEST or
LauncherApps.ShortcutQuery.FLAG_MATCH_CACHED or
LauncherApps.ShortcutQuery.FLAG_MATCH_PINNED_BY_ANY_LAUNCHER
)
val shortcuts = launcherApps.getShortcuts(shortcutQuery, Process.myUserHandle())
?.filter {
if (it.longLabel != null) {
return@filter matches(it.longLabel.toString(), query)
}
if (it.shortLabel != null) {
return@filter matches(it.shortLabel.toString(), query)
}
return@filter false
} ?: emptyList()
val pm = context.packageManager
send(
shortcuts.mapNotNull {
val label = try {
pm.getApplicationInfo(it.`package`, 0).loadLabel(pm).toString()
} catch (e: PackageManager.NameNotFoundException) {
""
}
AppShortcut(
context,
it,
label
shortcutChangeEmitter.collectLatest {
val launcherApps =
context.getSystemService<LauncherApps>() ?: return@collectLatest send(
emptyList()
)
}.sorted()
)
val shortcutQuery = LauncherApps.ShortcutQuery()
shortcutQuery.setQueryFlags(
LauncherApps.ShortcutQuery.FLAG_MATCH_PINNED or
LauncherApps.ShortcutQuery.FLAG_MATCH_DYNAMIC or
LauncherApps.ShortcutQuery.FLAG_MATCH_MANIFEST or
LauncherApps.ShortcutQuery.FLAG_MATCH_CACHED or
LauncherApps.ShortcutQuery.FLAG_MATCH_PINNED_BY_ANY_LAUNCHER
)
val shortcuts = launcherApps.getShortcuts(shortcutQuery, Process.myUserHandle())
?.filter {
if (it.longLabel != null) {
return@filter matches(it.longLabel.toString(), query)
}
if (it.shortLabel != null) {
return@filter matches(it.shortLabel.toString(), query)
}
return@filter false
} ?: emptyList()
val pm = context.packageManager
send(
shortcuts.mapNotNull {
val label = try {
pm.getApplicationInfo(it.`package`, 0).loadLabel(pm).toString()
} catch (e: PackageManager.NameNotFoundException) {
""
}
AppShortcut(
context,
it,
label
)
}.sorted()
)
}
}
}
}
private val shortcutChangeEmitter = callbackFlow {
send(Unit)
val launcherApps = context.getSystemService(Context.LAUNCHER_APPS_SERVICE) as LauncherApps
val callback = object : LauncherApps.Callback() {
override fun onPackageRemoved(packageName: String?, user: UserHandle?) {
}
override fun onPackageAdded(packageName: String?, user: UserHandle?) {
}
override fun onPackageChanged(packageName: String?, user: UserHandle?) {
}
override fun onPackagesAvailable(
packageNames: Array<out String>?,
user: UserHandle?,
replacing: Boolean
) {
}
override fun onPackagesUnavailable(
packageNames: Array<out String>?,
user: UserHandle?,
replacing: Boolean
) {
}
override fun onShortcutsChanged(
packageName: String,
shortcuts: MutableList<ShortcutInfo>,
user: UserHandle
) {
super.onShortcutsChanged(packageName, shortcuts, user)
trySend(Unit)
}
}
launcherApps.registerCallback(callback, Handler(Looper.getMainLooper()))
awaitClose {
launcherApps.unregisterCallback(callback)
}
}.shareIn(scope, SharingStarted.WhileSubscribed(500), 1)
override fun removePinnedShortcut(shortcut: AppShortcut) {
val launcherApps = context.getSystemService(Context.LAUNCHER_APPS_SERVICE) as LauncherApps
if (!launcherApps.hasShortcutHostPermission()) return

View File

@ -29,5 +29,6 @@ class ShortcutItemVM(private val shortcut: AppShortcut) : SearchableItemVM(short
fun deleteShortcut() {
shortcutRepository.removePinnedShortcut(shortcut)
favoritesRepository.unpinItem(shortcut)
}
}