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.LauncherActivityInfo
import android.content.pm.LauncherApps import android.content.pm.LauncherApps
import android.content.pm.PackageManager 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.Process
import android.os.UserHandle
import android.util.Log import android.util.Log
import androidx.core.content.getSystemService import androidx.core.content.getSystemService
import de.mm20.launcher2.ktx.normalize 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.permissions.PermissionsManager
import de.mm20.launcher2.preferences.LauncherDataStore import de.mm20.launcher2.preferences.LauncherDataStore
import de.mm20.launcher2.search.data.AppShortcut import de.mm20.launcher2.search.data.AppShortcut
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.Job
import kotlinx.coroutines.flow.channelFlow import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.flow.*
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import org.apache.commons.text.similarity.FuzzyScore import org.apache.commons.text.similarity.FuzzyScore
import java.util.* import java.util.*
@ -38,6 +42,8 @@ internal class AppShortcutRepositoryImpl(
private val dataStore: LauncherDataStore, private val dataStore: LauncherDataStore,
) : AppShortcutRepository { ) : AppShortcutRepository {
private val scope = CoroutineScope(Dispatchers.Default + Job())
override suspend fun getShortcutsForActivity( override suspend fun getShortcutsForActivity(
launcherActivityInfo: LauncherActivityInfo, launcherActivityInfo: LauncherActivityInfo,
count: Int, count: Int,
@ -84,51 +90,99 @@ internal class AppShortcutRepositoryImpl(
return@collectLatest return@collectLatest
} }
val launcherApps = shortcutChangeEmitter.collectLatest {
context.getSystemService<LauncherApps>() ?: return@collectLatest send( val launcherApps =
emptyList() 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
) )
}.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) { override fun removePinnedShortcut(shortcut: AppShortcut) {
val launcherApps = context.getSystemService(Context.LAUNCHER_APPS_SERVICE) as LauncherApps val launcherApps = context.getSystemService(Context.LAUNCHER_APPS_SERVICE) as LauncherApps
if (!launcherApps.hasShortcutHostPermission()) return if (!launcherApps.hasShortcutHostPermission()) return

View File

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