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,86 +39,105 @@ 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,
) )
} }
val toolbarActions = mutableListOf<ToolbarAction>()
if (LocalFavoritesEnabled.current) { AnimatedVisibility(showDetails) {
val isPinned by viewModel.isPinned.collectAsState(false)
val favAction = if (isPinned) {
DefaultToolbarAction(
label = stringResource(R.string.menu_favorites_unpin),
icon = Icons.Rounded.Star,
action = {
viewModel.unpin()
}
)
} else {
DefaultToolbarAction(
label = stringResource(R.string.menu_favorites_pin),
icon = Icons.Rounded.StarOutline,
action = {
viewModel.pin()
})
}
toolbarActions.add(favAction)
}
toolbarActions.add( val toolbarActions = mutableListOf<ToolbarAction>()
DefaultToolbarAction(
label = stringResource(R.string.menu_app_info),
icon = Icons.Rounded.Info
) {
viewModel.openAppInfo(context)
})
Toolbar( if (LocalFavoritesEnabled.current) {
leftActions = listOf( val isPinned by viewModel.isPinned.collectAsState(false)
DefaultToolbarAction( val favAction = if (isPinned) {
label = stringResource(id = R.string.menu_back), DefaultToolbarAction(
icon = Icons.Rounded.ArrowBack label = stringResource(R.string.menu_favorites_unpin),
) { icon = Icons.Rounded.Star,
onBack() action = {
viewModel.unpin()
}
)
} else {
DefaultToolbarAction(
label = stringResource(R.string.menu_favorites_pin),
icon = Icons.Rounded.StarOutline,
action = {
viewModel.pin()
})
} }
), toolbarActions.add(favAction)
rightActions = toolbarActions }
)
toolbarActions.add(
DefaultToolbarAction(
label = stringResource(R.string.menu_app_info),
icon = Icons.Rounded.Info
) {
viewModel.openAppInfo(context)
})
Toolbar(
leftActions = listOf(
DefaultToolbarAction(
label = stringResource(id = R.string.menu_back),
icon = Icons.Rounded.ArrowBack
) {
onBack()
}
),
rightActions = toolbarActions
)
}
} }
} }
@ -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 {