diff --git a/ui/src/main/java/de/mm20/launcher2/ui/launcher/search/common/list/ListItem.kt b/ui/src/main/java/de/mm20/launcher2/ui/launcher/search/common/list/ListItem.kt index afce4b41..1fd4ec44 100644 --- a/ui/src/main/java/de/mm20/launcher2/ui/launcher/search/common/list/ListItem.kt +++ b/ui/src/main/java/de/mm20/launcher2/ui/launcher/search/common/list/ListItem.kt @@ -1,33 +1,19 @@ package de.mm20.launcher2.ui.launcher.search.common.list -import androidx.compose.animation.animateColorAsState -import androidx.compose.animation.core.animateFloatAsState -import androidx.compose.foundation.background import androidx.compose.foundation.combinedClickable -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.* -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.rounded.Star -import androidx.compose.material.icons.rounded.StarOutline -import androidx.compose.material.icons.rounded.Visibility -import androidx.compose.material.icons.rounded.VisibilityOff -import androidx.compose.material3.MaterialTheme +import androidx.compose.material.DismissDirection +import androidx.compose.material.DismissValue +import androidx.compose.material.ExperimentalMaterialApi +import androidx.compose.material.rememberDismissState import androidx.compose.material3.SnackbarResult import androidx.compose.runtime.* -import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.scale import androidx.compose.ui.geometry.Rect import androidx.compose.ui.layout.boundsInWindow import androidx.compose.ui.layout.onGloballyPositioned import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalLifecycleOwner -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.unit.dp import androidx.lifecycle.lifecycleScope import de.mm20.launcher2.search.data.* import de.mm20.launcher2.ui.R @@ -36,7 +22,6 @@ 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.files.FileItem import de.mm20.launcher2.ui.launcher.search.shortcut.AppShortcutItem -import de.mm20.launcher2.ui.locals.LocalCardStyle import de.mm20.launcher2.ui.locals.LocalFavoritesEnabled import de.mm20.launcher2.ui.locals.LocalSnackbarHostState import kotlinx.coroutines.launch @@ -48,167 +33,72 @@ fun ListItem(modifier: Modifier = Modifier, item: Searchable) { val context = LocalContext.current val viewModel = remember(item.key) { ListItemVM(item) } - val isPinned by viewModel.isPinned.collectAsState(false) - val isHidden by viewModel.isHidden.collectAsState(false) - val lifecycleOwner = LocalLifecycleOwner.current - val snackbarHostState = LocalSnackbarHostState.current - - val dismissState = rememberDismissState( - confirmStateChange = { - when (it) { - DismissValue.Default -> {} - DismissValue.DismissedToEnd -> { - if (isPinned) viewModel.unpin() - else viewModel.pin() - } - DismissValue.DismissedToStart -> { - if (isHidden) viewModel.unhide() - else { - viewModel.hide() - lifecycleOwner.lifecycleScope.launch { - val result = snackbarHostState.showSnackbar( - message = context.getString(R.string.msg_item_hidden, item.label), - actionLabel = context.getString(R.string.action_undo), - - ) - if(result == SnackbarResult.ActionPerformed) { - viewModel.unhide() - } - } - } - } - } - it == DismissValue.DismissedToStart - } - ) - - val swipeDirections = when { - showDetails -> emptySet() - LocalFavoritesEnabled.current -> setOf( - DismissDirection.StartToEnd, - DismissDirection.EndToStart - ) - else -> setOf(DismissDirection.EndToStart) - } - - SwipeToDismiss( - modifier = modifier, - state = dismissState, - directions = swipeDirections, - background = { - Surface( - modifier = Modifier.fillMaxSize(), - color = MaterialTheme.colorScheme.surfaceVariant, - shape = RoundedCornerShape(LocalCardStyle.current.radius.dp) - ) { - Box( - modifier = Modifier - .fillMaxWidth() - .background( - MaterialTheme.colorScheme.primaryContainer.copy( - alpha = (dismissState.progress.fraction * 2f).coerceAtMost( - 1f - ) - ) - ), - contentAlignment = if (dismissState.dismissDirection == DismissDirection.EndToStart) Alignment.CenterEnd else Alignment.CenterStart - ) { - val overThreshold = - dismissState.progress.fraction >= 0.5f && dismissState.dismissDirection != null - val iconScale by animateFloatAsState( - if (overThreshold) 1.25f else 1f - ) - val iconColor by animateColorAsState( - if (overThreshold) MaterialTheme.colorScheme.onPrimaryContainer else MaterialTheme.colorScheme.onSurface - ) - val pinIcon = if (isPinned) Icons.Rounded.StarOutline else Icons.Rounded.Star - val hideIcon = - if (isHidden) Icons.Rounded.Visibility else Icons.Rounded.VisibilityOff - Icon( - modifier = Modifier - .padding(16.dp) - .scale(iconScale), - imageVector = if (dismissState.dismissDirection == DismissDirection.EndToStart) { - hideIcon - } else { - pinIcon - }, - tint = iconColor, - contentDescription = null - ) - } - } - } + var bounds by remember { mutableStateOf(Rect.Zero) } + InnerCard( + modifier = modifier + .onGloballyPositioned { + bounds = it.boundsInWindow() + }, + raised = showDetails ) { - var bounds by remember { mutableStateOf(Rect.Zero) } - InnerCard( - modifier = Modifier - .fillMaxWidth() - .onGloballyPositioned { - bounds = it.boundsInWindow() - }, - raised = showDetails - ) { - when (item) { - is Contact -> { - ContactItem( - modifier = Modifier.combinedClickable( - enabled = !showDetails, - onClick = { showDetails = true }, - onLongClick = { showDetails = true } - ), - contact = item, - showDetails = showDetails, - onBack = { showDetails = false } - ) - } - is File -> { - FileItem( - modifier = Modifier.combinedClickable( - enabled = !showDetails, - onClick = { - if (!viewModel.launch(context, bounds)) { - showDetails = true - } - }, - onLongClick = { showDetails = true } - ), - file = item, - showDetails = showDetails, - onBack = { showDetails = false } - ) - } - is CalendarEvent -> { - CalendarItem( - modifier = Modifier.combinedClickable( - enabled = !showDetails, - onClick = { showDetails = true }, - onLongClick = { showDetails = true } - ), - calendar = item, - showDetails = showDetails, - 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 } - ) - } + when (item) { + is Contact -> { + ContactItem( + modifier = Modifier.combinedClickable( + enabled = !showDetails, + onClick = { showDetails = true }, + onLongClick = { showDetails = true } + ), + contact = item, + showDetails = showDetails, + onBack = { showDetails = false } + ) + } + is File -> { + FileItem( + modifier = Modifier.combinedClickable( + enabled = !showDetails, + onClick = { + if (!viewModel.launch(context, bounds)) { + showDetails = true + } + }, + onLongClick = { showDetails = true } + ), + file = item, + showDetails = showDetails, + onBack = { showDetails = false } + ) + } + is CalendarEvent -> { + CalendarItem( + modifier = Modifier.combinedClickable( + enabled = !showDetails, + onClick = { showDetails = true }, + onLongClick = { showDetails = true } + ), + calendar = item, + showDetails = showDetails, + 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 } + ) } } - } } \ No newline at end of file