diff --git a/appshortcuts/src/main/java/de/mm20/launcher2/appshortcuts/AppShortcutRepository.kt b/appshortcuts/src/main/java/de/mm20/launcher2/appshortcuts/AppShortcutRepository.kt index 7f61be3e..753ca0c0 100644 --- a/appshortcuts/src/main/java/de/mm20/launcher2/appshortcuts/AppShortcutRepository.kt +++ b/appshortcuts/src/main/java/de/mm20/launcher2/appshortcuts/AppShortcutRepository.kt @@ -5,9 +5,9 @@ import android.content.pm.LauncherActivityInfo import android.content.pm.LauncherApps import android.content.pm.PackageManager import android.os.Process +import android.util.Log import androidx.core.content.getSystemService 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 @@ -28,6 +28,8 @@ interface AppShortcutRepository { ): List fun search(query: String): Flow> + + fun removePinnedShortcut(shortcut: AppShortcut) } internal class AppShortcutRepositoryImpl( @@ -127,6 +129,27 @@ internal class AppShortcutRepositoryImpl( } } + override fun removePinnedShortcut(shortcut: AppShortcut) { + val launcherApps = context.getSystemService(Context.LAUNCHER_APPS_SERVICE) as LauncherApps + if (!launcherApps.hasShortcutHostPermission()) return + val pinnedShortcutsQuery = LauncherApps.ShortcutQuery().apply { + setQueryFlags(LauncherApps.ShortcutQuery.FLAG_MATCH_PINNED) + } + val userHandle = shortcut.launcherShortcut.userHandle + val allPinned = launcherApps.getShortcuts(pinnedShortcutsQuery, userHandle) + + if (allPinned == null) { + Log.e("MM20", "Could not remove shortcut ${shortcut.key}: shortcut query returned null") + return + } + + launcherApps.pinShortcuts( + shortcut.launcherShortcut.`package`, + allPinned.filter { it.id != shortcut.launcherShortcut.id }.map { it.id }, + userHandle + ) + } + private fun matches(label: String, query: String): Boolean { val labelLatin = label.normalize() diff --git a/ui/src/main/java/de/mm20/launcher2/ui/launcher/search/shortcut/ShortcutItem.kt b/ui/src/main/java/de/mm20/launcher2/ui/launcher/search/shortcut/ShortcutItem.kt index 7e985de8..76bdd3dd 100644 --- a/ui/src/main/java/de/mm20/launcher2/ui/launcher/search/shortcut/ShortcutItem.kt +++ b/ui/src/main/java/de/mm20/launcher2/ui/launcher/search/shortcut/ShortcutItem.kt @@ -141,6 +141,14 @@ fun AppShortcutItem( action = { edit = true } )) + if (viewModel.canDelete) { + toolbarActions.add(DefaultToolbarAction( + label = stringResource(R.string.menu_delete), + icon = Icons.Rounded.Delete, + action = { viewModel.deleteShortcut() } + )) + } + val isHidden by viewModel.isHidden.collectAsState(false) val hideAction = if (isHidden) { DefaultToolbarAction( diff --git a/ui/src/main/java/de/mm20/launcher2/ui/launcher/search/shortcut/ShortcutItemVM.kt b/ui/src/main/java/de/mm20/launcher2/ui/launcher/search/shortcut/ShortcutItemVM.kt index dd02d551..c6404a67 100644 --- a/ui/src/main/java/de/mm20/launcher2/ui/launcher/search/shortcut/ShortcutItemVM.kt +++ b/ui/src/main/java/de/mm20/launcher2/ui/launcher/search/shortcut/ShortcutItemVM.kt @@ -4,11 +4,20 @@ import android.content.Context import android.content.Intent import android.net.Uri import android.provider.Settings +import android.util.Log +import de.mm20.launcher2.appshortcuts.AppShortcutRepository import de.mm20.launcher2.ktx.tryStartActivity import de.mm20.launcher2.search.data.AppShortcut import de.mm20.launcher2.ui.launcher.search.common.SearchableItemVM +import org.koin.core.component.KoinComponent +import org.koin.core.component.inject + +class ShortcutItemVM(private val shortcut: AppShortcut) : SearchableItemVM(shortcut), KoinComponent { + + private val shortcutRepository: AppShortcutRepository by inject() + + val canDelete = shortcut.launcherShortcut.isPinned -class ShortcutItemVM(private val shortcut: AppShortcut) : SearchableItemVM(shortcut) { fun openAppInfo(context: Context) { context.tryStartActivity( Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply { @@ -17,4 +26,8 @@ class ShortcutItemVM(private val shortcut: AppShortcut) : SearchableItemVM(short } ) } + + fun deleteShortcut() { + shortcutRepository.removePinnedShortcut(shortcut) + } } \ No newline at end of file