Show app shortcut results as list

This commit is contained in:
MM20 2022-03-19 20:08:53 +01:00
parent 24acab4244
commit e04251d379
No known key found for this signature in database
GPG Key ID: 0B61A8F2DEAFA389
3 changed files with 106 additions and 57 deletions

View File

@ -2,6 +2,7 @@ package de.mm20.launcher2.ui.launcher.search.appshortcuts
import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.AnimatedVisibility
import androidx.compose.foundation.layout.ColumnScope import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
@ -11,7 +12,7 @@ import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel import androidx.lifecycle.viewmodel.compose.viewModel
import de.mm20.launcher2.ui.component.LauncherCard import de.mm20.launcher2.ui.component.LauncherCard
import de.mm20.launcher2.ui.launcher.search.SearchVM import de.mm20.launcher2.ui.launcher.search.SearchVM
import de.mm20.launcher2.ui.launcher.search.common.SearchResultGrid import de.mm20.launcher2.ui.launcher.search.common.list.SearchResultList
@Composable @Composable
fun ColumnScope.AppShortcutResults() { fun ColumnScope.AppShortcutResults() {
@ -22,7 +23,12 @@ fun ColumnScope.AppShortcutResults() {
LauncherCard( LauncherCard(
modifier = Modifier.padding(bottom = 8.dp) modifier = Modifier.padding(bottom = 8.dp)
) { ) {
SearchResultGrid(items = apps) SearchResultList(
items = apps,
modifier = Modifier
.fillMaxWidth()
.padding(12.dp)
)
} }
} }

View File

@ -26,14 +26,12 @@ import androidx.compose.ui.layout.boundsInWindow
import androidx.compose.ui.layout.onGloballyPositioned import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import de.mm20.launcher2.search.data.CalendarEvent import de.mm20.launcher2.search.data.*
import de.mm20.launcher2.search.data.Contact
import de.mm20.launcher2.search.data.File
import de.mm20.launcher2.search.data.Searchable
import de.mm20.launcher2.ui.component.InnerCard import de.mm20.launcher2.ui.component.InnerCard
import de.mm20.launcher2.ui.launcher.search.calendar.CalendarItem import de.mm20.launcher2.ui.launcher.search.calendar.CalendarItem
import de.mm20.launcher2.ui.launcher.search.contacts.ContactItem import de.mm20.launcher2.ui.launcher.search.contacts.ContactItem
import de.mm20.launcher2.ui.launcher.search.files.FileItem import de.mm20.launcher2.ui.launcher.search.files.FileItem
import de.mm20.launcher2.ui.launcher.search.shortcut.AppShortcutItem
import de.mm20.launcher2.ui.locals.LocalCardStyle import de.mm20.launcher2.ui.locals.LocalCardStyle
import de.mm20.launcher2.ui.locals.LocalFavoritesEnabled import de.mm20.launcher2.ui.locals.LocalFavoritesEnabled
@ -172,6 +170,22 @@ fun ListItem(modifier: Modifier = Modifier, item: Searchable) {
onBack = { showDetails = false } onBack = { showDetails = false }
) )
} }
is AppShortcut -> {
AppShortcutItem(
shortcut = item,
modifier = Modifier.combinedClickable(
enabled = !showDetails,
onClick = {
if (!viewModel.launch(context, bounds)) {
showDetails = true
}
},
onLongClick = { showDetails = true }
),
showDetails = showDetails,
onBack = { showDetails = false }
)
}
} }
} }

View File

@ -2,15 +2,20 @@ package de.mm20.launcher2.ui.launcher.search.shortcut
import androidx.compose.animation.* import androidx.compose.animation.*
import androidx.compose.animation.core.snap import androidx.compose.animation.core.*
import androidx.compose.animation.core.tween
import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.*
import androidx.compose.material.ExperimentalMaterialApi import androidx.compose.material.ExperimentalMaterialApi
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.* import androidx.compose.material.icons.rounded.ArrowBack
import androidx.compose.material.icons.rounded.Info
import androidx.compose.material.icons.rounded.Star
import androidx.compose.material.icons.rounded.StarOutline
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.* import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Rect import androidx.compose.ui.geometry.Rect
import androidx.compose.ui.graphics.TransformOrigin import androidx.compose.ui.graphics.TransformOrigin
@ -20,7 +25,11 @@ import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import de.mm20.launcher2.search.data.AppShortcut import de.mm20.launcher2.search.data.AppShortcut
import de.mm20.launcher2.ui.R import de.mm20.launcher2.ui.R
import de.mm20.launcher2.ui.component.* import de.mm20.launcher2.ui.animation.animateTextStyleAsState
import de.mm20.launcher2.ui.component.DefaultToolbarAction
import de.mm20.launcher2.ui.component.ShapedLauncherIcon
import de.mm20.launcher2.ui.component.Toolbar
import de.mm20.launcher2.ui.component.ToolbarAction
import de.mm20.launcher2.ui.ktx.toDp import de.mm20.launcher2.ui.ktx.toDp
import de.mm20.launcher2.ui.ktx.toPixels import de.mm20.launcher2.ui.ktx.toPixels
import de.mm20.launcher2.ui.locals.LocalFavoritesEnabled import de.mm20.launcher2.ui.locals.LocalFavoritesEnabled
@ -30,44 +39,62 @@ import kotlin.math.roundToInt
@OptIn(ExperimentalMaterialApi::class) @OptIn(ExperimentalMaterialApi::class)
@Composable @Composable
fun AppItem( fun AppShortcutItem(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
shortcut: AppShortcut, shortcut: AppShortcut,
showDetails: Boolean = false,
onBack: () -> Unit onBack: () -> Unit
) { ) {
val viewModel = remember { ShortcutItemVM(shortcut) } val viewModel = remember { ShortcutItemVM(shortcut) }
val context = LocalContext.current val context = LocalContext.current
val scope = rememberCoroutineScope()
val transition = updateTransition(showDetails, label = "AppShortcutItem")
Column( Column(
modifier = modifier modifier = modifier
) { ) {
Row { Row {
val topPadding by transition.animateDp(label = "topPadding") {
if (it) 16.dp else 14.dp
}
Column( Column(
modifier = Modifier modifier = Modifier
.weight(1f) .weight(1f)
.padding(16.dp) .padding(start = 16.dp, top = topPadding, bottom = 16.dp, end = 16.dp)
) { ) {
Text(text = shortcut.label, style = MaterialTheme.typography.titleMedium) val titleStyle by animateTextStyleAsState(if (showDetails) MaterialTheme.typography.titleMedium else MaterialTheme.typography.titleSmall)
Text(text = shortcut.label, style = titleStyle, maxLines = 1, overflow = TextOverflow.Ellipsis)
val textSpace by transition.animateDp(label = "textSpace") {
if (it) 4.dp else 0.dp
}
Text( Text(
text = stringResource(R.string.shortcut_summary, shortcut.appName), text = stringResource(R.string.shortcut_summary, shortcut.appName),
style = MaterialTheme.typography.bodySmall, style = MaterialTheme.typography.bodySmall,
modifier = Modifier.padding(top = 4.dp), modifier = Modifier.padding(top = textSpace),
maxLines = 1, maxLines = 1,
overflow = TextOverflow.Ellipsis overflow = TextOverflow.Ellipsis
) )
} }
val badge by viewModel.badge.collectAsState(null) val badge by viewModel.badge.collectAsState(null)
val size by animateDpAsState(if (showDetails) 84.dp else 48.dp)
val iconSize = 84.dp.toPixels().toInt() val iconSize = 84.dp.toPixels().toInt()
val icon by remember(shortcut.key) { viewModel.getIcon(iconSize) }.collectAsState(null) val icon by remember(shortcut.key) { viewModel.getIcon(iconSize) }.collectAsState(null)
val padding by transition.animateDp(label = "iconPadding") {
if (it) 16.dp else 8.dp
}
ShapedLauncherIcon( ShapedLauncherIcon(
size = 84.dp, size = size,
modifier = Modifier modifier = Modifier
.padding(16.dp), .padding(padding),
badge = badge, badge = badge,
icon = icon, icon = icon,
) )
} }
AnimatedVisibility(showDetails) {
val toolbarActions = mutableListOf<ToolbarAction>() val toolbarActions = mutableListOf<ToolbarAction>()
if (LocalFavoritesEnabled.current) { if (LocalFavoritesEnabled.current) {
@ -112,6 +139,7 @@ fun AppItem(
) )
} }
} }
}
@OptIn(ExperimentalAnimationApi::class) @OptIn(ExperimentalAnimationApi::class)
@Composable @Composable
@ -137,7 +165,7 @@ fun ShortcutItemGridPopup(
} }
) { targetState -> ) { targetState ->
if (targetState) { if (targetState) {
AppItem( AppShortcutItem(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
.scale( .scale(
@ -149,6 +177,7 @@ fun ShortcutItemGridPopup(
y = -16.dp * (1 - animationProgress), y = -16.dp * (1 - animationProgress),
), ),
shortcut = shortcut, shortcut = shortcut,
showDetails = true,
onBack = onDismiss onBack = onDismiss
) )
} else { } else {