Remove list result swipe actions
This commit is contained in:
parent
965e9fed02
commit
30bd85db8a
@ -1,33 +1,19 @@
|
|||||||
package de.mm20.launcher2.ui.launcher.search.common.list
|
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.combinedClickable
|
||||||
import androidx.compose.foundation.layout.Box
|
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.material.DismissDirection
|
||||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
import androidx.compose.material.DismissValue
|
||||||
import androidx.compose.material.*
|
import androidx.compose.material.ExperimentalMaterialApi
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.rememberDismissState
|
||||||
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.material3.SnackbarResult
|
import androidx.compose.material3.SnackbarResult
|
||||||
import androidx.compose.runtime.*
|
import androidx.compose.runtime.*
|
||||||
import androidx.compose.ui.Alignment
|
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.scale
|
|
||||||
import androidx.compose.ui.geometry.Rect
|
import androidx.compose.ui.geometry.Rect
|
||||||
import androidx.compose.ui.layout.boundsInWindow
|
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.platform.LocalLifecycleOwner
|
import androidx.compose.ui.platform.LocalLifecycleOwner
|
||||||
import androidx.compose.ui.res.stringResource
|
|
||||||
import androidx.compose.ui.unit.dp
|
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import de.mm20.launcher2.search.data.*
|
import de.mm20.launcher2.search.data.*
|
||||||
import de.mm20.launcher2.ui.R
|
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.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.launcher.search.shortcut.AppShortcutItem
|
||||||
import de.mm20.launcher2.ui.locals.LocalCardStyle
|
|
||||||
import de.mm20.launcher2.ui.locals.LocalFavoritesEnabled
|
import de.mm20.launcher2.ui.locals.LocalFavoritesEnabled
|
||||||
import de.mm20.launcher2.ui.locals.LocalSnackbarHostState
|
import de.mm20.launcher2.ui.locals.LocalSnackbarHostState
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
@ -48,167 +33,72 @@ fun ListItem(modifier: Modifier = Modifier, item: Searchable) {
|
|||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
|
|
||||||
val viewModel = remember(item.key) { ListItemVM(item) }
|
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
|
var bounds by remember { mutableStateOf(Rect.Zero) }
|
||||||
val snackbarHostState = LocalSnackbarHostState.current
|
InnerCard(
|
||||||
|
modifier = modifier
|
||||||
val dismissState = rememberDismissState(
|
.onGloballyPositioned {
|
||||||
confirmStateChange = {
|
bounds = it.boundsInWindow()
|
||||||
when (it) {
|
},
|
||||||
DismissValue.Default -> {}
|
raised = showDetails
|
||||||
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) }
|
when (item) {
|
||||||
InnerCard(
|
is Contact -> {
|
||||||
modifier = Modifier
|
ContactItem(
|
||||||
.fillMaxWidth()
|
modifier = Modifier.combinedClickable(
|
||||||
.onGloballyPositioned {
|
enabled = !showDetails,
|
||||||
bounds = it.boundsInWindow()
|
onClick = { showDetails = true },
|
||||||
},
|
onLongClick = { showDetails = true }
|
||||||
raised = showDetails
|
),
|
||||||
) {
|
contact = item,
|
||||||
when (item) {
|
showDetails = showDetails,
|
||||||
is Contact -> {
|
onBack = { showDetails = false }
|
||||||
ContactItem(
|
)
|
||||||
modifier = Modifier.combinedClickable(
|
}
|
||||||
enabled = !showDetails,
|
is File -> {
|
||||||
onClick = { showDetails = true },
|
FileItem(
|
||||||
onLongClick = { showDetails = true }
|
modifier = Modifier.combinedClickable(
|
||||||
),
|
enabled = !showDetails,
|
||||||
contact = item,
|
onClick = {
|
||||||
showDetails = showDetails,
|
if (!viewModel.launch(context, bounds)) {
|
||||||
onBack = { showDetails = false }
|
showDetails = true
|
||||||
)
|
}
|
||||||
}
|
},
|
||||||
is File -> {
|
onLongClick = { showDetails = true }
|
||||||
FileItem(
|
),
|
||||||
modifier = Modifier.combinedClickable(
|
file = item,
|
||||||
enabled = !showDetails,
|
showDetails = showDetails,
|
||||||
onClick = {
|
onBack = { showDetails = false }
|
||||||
if (!viewModel.launch(context, bounds)) {
|
)
|
||||||
showDetails = true
|
}
|
||||||
}
|
is CalendarEvent -> {
|
||||||
},
|
CalendarItem(
|
||||||
onLongClick = { showDetails = true }
|
modifier = Modifier.combinedClickable(
|
||||||
),
|
enabled = !showDetails,
|
||||||
file = item,
|
onClick = { showDetails = true },
|
||||||
showDetails = showDetails,
|
onLongClick = { showDetails = true }
|
||||||
onBack = { showDetails = false }
|
),
|
||||||
)
|
calendar = item,
|
||||||
}
|
showDetails = showDetails,
|
||||||
is CalendarEvent -> {
|
onBack = { showDetails = false }
|
||||||
CalendarItem(
|
)
|
||||||
modifier = Modifier.combinedClickable(
|
}
|
||||||
enabled = !showDetails,
|
is AppShortcut -> {
|
||||||
onClick = { showDetails = true },
|
AppShortcutItem(
|
||||||
onLongClick = { showDetails = true }
|
shortcut = item,
|
||||||
),
|
modifier = Modifier.combinedClickable(
|
||||||
calendar = item,
|
enabled = !showDetails,
|
||||||
showDetails = showDetails,
|
onClick = {
|
||||||
onBack = { showDetails = false }
|
if (!viewModel.launch(context, bounds)) {
|
||||||
)
|
showDetails = true
|
||||||
}
|
}
|
||||||
is AppShortcut -> {
|
},
|
||||||
AppShortcutItem(
|
onLongClick = { showDetails = true }
|
||||||
shortcut = item,
|
),
|
||||||
modifier = Modifier.combinedClickable(
|
showDetails = showDetails,
|
||||||
enabled = !showDetails,
|
onBack = { showDetails = false }
|
||||||
onClick = {
|
)
|
||||||
if (!viewModel.launch(context, bounds)) {
|
|
||||||
showDetails = true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onLongClick = { showDetails = true }
|
|
||||||
),
|
|
||||||
showDetails = showDetails,
|
|
||||||
onBack = { showDetails = false }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user