Refresh shortcuts after removing one
This commit is contained in:
parent
44d4555966
commit
bc86a22086
@ -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
|
||||||
|
|||||||
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user