Add support for legacy app shortcuts

This commit is contained in:
MM20
2022-09-18 23:12:26 +02:00
parent b068e4d6fd
commit 5fcb6ceb2c
12 changed files with 394 additions and 152 deletions
@@ -2,13 +2,12 @@ package de.mm20.launcher2.ui.launcher.modals
import android.content.Context
import android.content.Intent
import android.content.Intent.ShortcutIconResource
import android.content.pm.LauncherApps
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import androidx.compose.foundation.lazy.grid.LazyGridItemInfo
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import de.mm20.launcher2.appshortcuts.AppShortcutRepository
import de.mm20.launcher2.badges.Badge
import de.mm20.launcher2.badges.BadgeRepository
@@ -18,13 +17,12 @@ import de.mm20.launcher2.icons.LauncherIcon
import de.mm20.launcher2.permissions.PermissionGroup
import de.mm20.launcher2.permissions.PermissionsManager
import de.mm20.launcher2.search.data.AppShortcut
import de.mm20.launcher2.search.data.LauncherApp
import de.mm20.launcher2.search.data.LauncherShortcut
import de.mm20.launcher2.search.data.LegacyShortcut
import de.mm20.launcher2.search.data.Searchable
import de.mm20.launcher2.ui.R
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.launch
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
@@ -164,6 +162,7 @@ class EditFavoritesSheetVM : ViewModel(), KoinComponent {
fun pickShortcut(section: FavoritesSheetSection) {
createShortcutTarget.value = section
}
fun cancelPickShortcut() {
createShortcutTarget.value = null
}
@@ -180,24 +179,28 @@ class EditFavoritesSheetVM : ViewModel(), KoinComponent {
fun createShortcut(context: Context, data: Intent?) {
data ?: return cancelPickShortcut()
val launcherApps = context.getSystemService(Context.LAUNCHER_APPS_SERVICE) as LauncherApps
val pinRequest = launcherApps.getPinItemRequest(data) ?: return cancelPickShortcut()
val shortcutInfo = pinRequest.shortcutInfo ?: return cancelPickShortcut()
pinRequest.accept()
val shortcut = AppShortcut(
context,
shortcutInfo,
context.packageManager.getApplicationInfo(shortcutInfo.`package`, 0)
.loadLabel(context.packageManager).toString()
)
if (createShortcutTarget.value == FavoritesSheetSection.ManuallySorted) {
manuallySorted.add(shortcut)
} else {
automaticallySorted.add(shortcut)
val shortcut = AppShortcut.fromPinRequestIntent(context, data)
if (shortcut == null) {
cancelPickShortcut()
return
}
if (!manuallySorted.any { it.key == shortcut.key }
&& !automaticallySorted.any { it.key == shortcut.key }
&& !frequentlyUsed.any { it.key == shortcut.key }
) {
if (createShortcutTarget.value == FavoritesSheetSection.ManuallySorted) {
manuallySorted.add(shortcut)
} else {
automaticallySorted.add(shortcut)
}
}
save()
buildItemList()
createShortcutTarget.value = null
}
}
@@ -4,7 +4,6 @@ package de.mm20.launcher2.ui.launcher.search.shortcut
import androidx.compose.animation.*
import androidx.compose.animation.core.*
import androidx.compose.foundation.layout.*
import androidx.compose.material.ExperimentalMaterialApi
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.*
import androidx.compose.material3.*
@@ -73,13 +72,15 @@ fun AppShortcutItem(
val textSpace by transition.animateDp(label = "textSpace") {
if (it) 4.dp else 2.dp
}
Text(
text = stringResource(R.string.shortcut_summary, shortcut.appName),
style = MaterialTheme.typography.bodySmall,
modifier = Modifier.padding(top = textSpace),
maxLines = 1,
overflow = TextOverflow.Ellipsis
)
shortcut.appName?.let {
Text(
text = stringResource(R.string.shortcut_summary, it),
style = MaterialTheme.typography.bodySmall,
modifier = Modifier.padding(top = textSpace),
maxLines = 1,
overflow = TextOverflow.Ellipsis
)
}
}
val badge by viewModel.badge.collectAsState(null)
val size by animateDpAsState(if (showDetails) 84.dp else 48.dp)
@@ -168,11 +169,14 @@ fun AppShortcutItem(
lifecycleOwner.lifecycleScope.launch {
val result = snackbarHostState.showSnackbar(
message = context.getString(R.string.msg_item_hidden, shortcut.label),
message = context.getString(
R.string.msg_item_hidden,
shortcut.label
),
actionLabel = context.getString(R.string.action_undo),
duration = SnackbarDuration.Short,
)
if(result == SnackbarResult.ActionPerformed) {
)
if (result == SnackbarResult.ActionPerformed) {
viewModel.unhide()
}
}
@@ -8,6 +8,8 @@ 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.search.data.LauncherShortcut
import de.mm20.launcher2.search.data.LegacyShortcut
import de.mm20.launcher2.ui.launcher.search.common.SearchableItemVM
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
@@ -16,12 +18,17 @@ class ShortcutItemVM(private val shortcut: AppShortcut) : SearchableItemVM(short
private val shortcutRepository: AppShortcutRepository by inject()
val canDelete = shortcut.launcherShortcut.isPinned
val canDelete = shortcut is LauncherShortcut && shortcut.launcherShortcut.isPinned
fun openAppInfo(context: Context) {
val packageName = when(shortcut) {
is LegacyShortcut -> shortcut.intent.`package` ?: return
is LauncherShortcut -> shortcut.launcherShortcut.`package`
else -> return
}
context.tryStartActivity(
Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply {
data = Uri.parse("package:${shortcut.launcherShortcut.`package`}")
data = Uri.parse("package:$packageName")
addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
}
)
@@ -29,7 +36,7 @@ class ShortcutItemVM(private val shortcut: AppShortcut) : SearchableItemVM(short
fun deleteShortcut() {
if (!canDelete) return
shortcutRepository.removePinnedShortcut(shortcut)
if (shortcut is LauncherShortcut) shortcutRepository.removePinnedShortcut(shortcut)
favoritesRepository.unpinItem(shortcut)
}
}