Display undo snackbar after hiding an item

This commit is contained in:
MM20 2022-05-21 19:29:29 +02:00
parent b784ab5aa5
commit 2c41d05ed3
No known key found for this signature in database
GPG Key ID: 0B61A8F2DEAFA389
8 changed files with 129 additions and 10 deletions

View File

@ -7,14 +7,14 @@ import android.os.Bundle
import androidx.activity.compose.setContent import androidx.activity.compose.setContent
import androidx.activity.viewModels import androidx.activity.viewModels
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.*
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.material3.SnackbarHost
import androidx.compose.foundation.layout.imePadding import androidx.compose.material3.SnackbarHostState
import androidx.compose.foundation.layout.systemBarsPadding
import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.livedata.observeAsState import androidx.compose.runtime.livedata.observeAsState
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Size import androidx.compose.ui.geometry.Size
@ -38,6 +38,7 @@ import de.mm20.launcher2.ui.launcher.modals.EditFavoritesView
import de.mm20.launcher2.ui.launcher.modals.HiddenItemsSheet import de.mm20.launcher2.ui.launcher.modals.HiddenItemsSheet
import de.mm20.launcher2.ui.launcher.transitions.HomeTransitionManager import de.mm20.launcher2.ui.launcher.transitions.HomeTransitionManager
import de.mm20.launcher2.ui.launcher.transitions.LocalHomeTransitionManager import de.mm20.launcher2.ui.launcher.transitions.LocalHomeTransitionManager
import de.mm20.launcher2.ui.locals.LocalSnackbarHostState
import de.mm20.launcher2.ui.locals.LocalWindowSize import de.mm20.launcher2.ui.locals.LocalWindowSize
import de.mm20.launcher2.ui.theme.LauncherTheme import de.mm20.launcher2.ui.theme.LauncherTheme
import org.koin.android.ext.android.inject import org.koin.android.ext.android.inject
@ -61,9 +62,11 @@ class LauncherActivity : BaseActivity() {
viewModel.setDarkMode(resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK == Configuration.UI_MODE_NIGHT_YES) viewModel.setDarkMode(resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK == Configuration.UI_MODE_NIGHT_YES)
setContent { setContent {
val snackbarHostState = remember { SnackbarHostState() }
CompositionLocalProvider( CompositionLocalProvider(
LocalHomeTransitionManager provides homeTransitionManager, LocalHomeTransitionManager provides homeTransitionManager,
LocalWindowSize provides windowSize LocalWindowSize provides windowSize,
LocalSnackbarHostState provides snackbarHostState
) { ) {
LauncherTheme { LauncherTheme {
ProvideSettings { ProvideSettings {
@ -111,6 +114,10 @@ class LauncherActivity : BaseActivity() {
} }
else -> {} else -> {}
} }
SnackbarHost(
snackbarHostState,
modifier = Modifier.navigationBarsPadding().imePadding()
)
} }
val showHiddenItems by viewModel.isHiddenItemsShown.observeAsState(false) val showHiddenItems by viewModel.isHiddenItemsShown.observeAsState(false)
if (showHiddenItems) { if (showHiddenItems) {

View File

@ -8,16 +8,19 @@ 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.*
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.SnackbarResult
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.* import androidx.compose.runtime.*
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
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalLifecycleOwner
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.core.app.NotificationCompat import androidx.core.app.NotificationCompat
import androidx.lifecycle.lifecycleScope
import coil.compose.rememberImagePainter import coil.compose.rememberImagePainter
import com.google.accompanist.flowlayout.FlowRow import com.google.accompanist.flowlayout.FlowRow
import de.mm20.launcher2.search.data.Application import de.mm20.launcher2.search.data.Application
@ -27,6 +30,7 @@ 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
import de.mm20.launcher2.ui.locals.LocalGridIconSize import de.mm20.launcher2.ui.locals.LocalGridIconSize
import de.mm20.launcher2.ui.locals.LocalSnackbarHostState
import de.mm20.launcher2.ui.modifier.scale import de.mm20.launcher2.ui.modifier.scale
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlin.math.min import kotlin.math.min
@ -42,6 +46,9 @@ fun AppItem(
) { ) {
val viewModel = remember { AppItemVM(app) } val viewModel = remember { AppItemVM(app) }
val context = LocalContext.current val context = LocalContext.current
val lifecycleOwner = LocalLifecycleOwner.current
val snackbarHostState = LocalSnackbarHostState.current
val scope = rememberCoroutineScope() val scope = rememberCoroutineScope()
Column( Column(
modifier = modifier modifier = modifier
@ -275,6 +282,16 @@ fun AppItem(
action = { action = {
viewModel.hide() viewModel.hide()
onBack() onBack()
lifecycleOwner.lifecycleScope.launch {
val result = snackbarHostState.showSnackbar(
message = context.getString(R.string.msg_item_hidden, app.label),
actionLabel = context.getString(R.string.action_undo),
)
if(result == SnackbarResult.ActionPerformed) {
viewModel.unhide()
}
}
}) })
} }

View File

@ -11,6 +11,7 @@ import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.* import androidx.compose.material.icons.rounded.*
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.SnackbarResult
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState import androidx.compose.runtime.collectAsState
@ -23,8 +24,10 @@ import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.geometry.Rect import androidx.compose.ui.geometry.Rect
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalLifecycleOwner
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.lifecycle.lifecycleScope
import de.mm20.launcher2.search.data.CalendarEvent import de.mm20.launcher2.search.data.CalendarEvent
import de.mm20.launcher2.ui.R import de.mm20.launcher2.ui.R
import de.mm20.launcher2.ui.animation.animateTextStyleAsState import de.mm20.launcher2.ui.animation.animateTextStyleAsState
@ -33,6 +36,8 @@ import de.mm20.launcher2.ui.component.Toolbar
import de.mm20.launcher2.ui.component.ToolbarAction 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.locals.LocalFavoritesEnabled import de.mm20.launcher2.ui.locals.LocalFavoritesEnabled
import de.mm20.launcher2.ui.locals.LocalSnackbarHostState
import kotlinx.coroutines.launch
@Composable @Composable
fun CalendarItem( fun CalendarItem(
@ -44,6 +49,9 @@ fun CalendarItem(
val context = LocalContext.current val context = LocalContext.current
val viewModel = remember(calendar.key) { CalendarItemVM(calendar) } val viewModel = remember(calendar.key) { CalendarItemVM(calendar) }
val lifecycleOwner = LocalLifecycleOwner.current
val snackbarHostState = LocalSnackbarHostState.current
Row( Row(
modifier = modifier modifier = modifier
.drawBehind { .drawBehind {
@ -190,6 +198,16 @@ fun CalendarItem(
action = { action = {
viewModel.hide() viewModel.hide()
onBack() onBack()
lifecycleOwner.lifecycleScope.launch {
val result = snackbarHostState.showSnackbar(
message = context.getString(R.string.msg_item_hidden, calendar.label),
actionLabel = context.getString(R.string.action_undo),
)
if(result == SnackbarResult.ActionPerformed) {
viewModel.unhide()
}
}
}) })
} }
toolbarActions.add(hideAction) toolbarActions.add(hideAction)

View File

@ -16,6 +16,7 @@ import androidx.compose.material.icons.rounded.StarOutline
import androidx.compose.material.icons.rounded.Visibility import androidx.compose.material.icons.rounded.Visibility
import androidx.compose.material.icons.rounded.VisibilityOff import androidx.compose.material.icons.rounded.VisibilityOff
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.SnackbarResult
import androidx.compose.runtime.* import androidx.compose.runtime.*
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
@ -24,8 +25,12 @@ 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.res.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
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.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
@ -33,6 +38,8 @@ 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.LocalCardStyle
import de.mm20.launcher2.ui.locals.LocalFavoritesEnabled import de.mm20.launcher2.ui.locals.LocalFavoritesEnabled
import de.mm20.launcher2.ui.locals.LocalSnackbarHostState
import kotlinx.coroutines.launch
@OptIn(ExperimentalMaterialApi::class, androidx.compose.foundation.ExperimentalFoundationApi::class) @OptIn(ExperimentalMaterialApi::class, androidx.compose.foundation.ExperimentalFoundationApi::class)
@Composable @Composable
@ -44,6 +51,9 @@ fun ListItem(modifier: Modifier = Modifier, item: Searchable) {
val isPinned by viewModel.isPinned.collectAsState(false) val isPinned by viewModel.isPinned.collectAsState(false)
val isHidden by viewModel.isHidden.collectAsState(false) val isHidden by viewModel.isHidden.collectAsState(false)
val lifecycleOwner = LocalLifecycleOwner.current
val snackbarHostState = LocalSnackbarHostState.current
val dismissState = rememberDismissState( val dismissState = rememberDismissState(
confirmStateChange = { confirmStateChange = {
when (it) { when (it) {
@ -54,7 +64,19 @@ fun ListItem(modifier: Modifier = Modifier, item: Searchable) {
} }
DismissValue.DismissedToStart -> { DismissValue.DismissedToStart -> {
if (isHidden) viewModel.unhide() if (isHidden) viewModel.unhide()
else viewModel.hide() 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 it == DismissValue.DismissedToStart

View File

@ -12,6 +12,7 @@ import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.* import androidx.compose.material.icons.rounded.*
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.SnackbarResult
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState import androidx.compose.runtime.collectAsState
@ -22,10 +23,12 @@ 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
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalLifecycleOwner
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.ExperimentalUnitApi import androidx.compose.ui.unit.ExperimentalUnitApi
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.lifecycle.lifecycleScope
import de.mm20.launcher2.search.data.Contact import de.mm20.launcher2.search.data.Contact
import de.mm20.launcher2.ui.R import de.mm20.launcher2.ui.R
import de.mm20.launcher2.ui.animation.animateTextStyleAsState import de.mm20.launcher2.ui.animation.animateTextStyleAsState
@ -36,7 +39,9 @@ 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
import de.mm20.launcher2.ui.locals.LocalGridIconSize import de.mm20.launcher2.ui.locals.LocalGridIconSize
import de.mm20.launcher2.ui.locals.LocalSnackbarHostState
import de.mm20.launcher2.ui.modifier.scale import de.mm20.launcher2.ui.modifier.scale
import kotlinx.coroutines.launch
@OptIn(ExperimentalUnitApi::class) @OptIn(ExperimentalUnitApi::class)
@Composable @Composable
@ -49,6 +54,9 @@ fun ContactItem(
val context = LocalContext.current val context = LocalContext.current
val viewModel = remember(contact) { ContactItemVM(contact) } val viewModel = remember(contact) { ContactItemVM(contact) }
val lifecycleOwner = LocalLifecycleOwner.current
val snackbarHostState = LocalSnackbarHostState.current
val transition = updateTransition(showDetails, label = "ContactItem") val transition = updateTransition(showDetails, label = "ContactItem")
Column( Column(
@ -257,6 +265,16 @@ fun ContactItem(
action = { action = {
viewModel.hide() viewModel.hide()
onBack() onBack()
lifecycleOwner.lifecycleScope.launch {
val result = snackbarHostState.showSnackbar(
message = context.getString(R.string.msg_item_hidden, contact.label),
actionLabel = context.getString(R.string.action_undo),
)
if(result == SnackbarResult.ActionPerformed) {
viewModel.unhide()
}
}
}) })
} }
toolbarActions.add(hideAction) toolbarActions.add(hideAction)

View File

@ -8,20 +8,19 @@ import androidx.compose.animation.core.updateTransition
import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.*
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.* import androidx.compose.material.icons.rounded.*
import androidx.compose.material3.AlertDialog import androidx.compose.material3.*
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
import androidx.compose.runtime.* import androidx.compose.runtime.*
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
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
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalLifecycleOwner
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.ExperimentalUnitApi import androidx.compose.ui.unit.ExperimentalUnitApi
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.lifecycle.lifecycleScope
import de.mm20.launcher2.search.data.File import de.mm20.launcher2.search.data.File
import de.mm20.launcher2.ui.R import de.mm20.launcher2.ui.R
import de.mm20.launcher2.ui.animation.animateTextStyleAsState import de.mm20.launcher2.ui.animation.animateTextStyleAsState
@ -33,7 +32,9 @@ 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
import de.mm20.launcher2.ui.locals.LocalGridIconSize import de.mm20.launcher2.ui.locals.LocalGridIconSize
import de.mm20.launcher2.ui.locals.LocalSnackbarHostState
import de.mm20.launcher2.ui.modifier.scale import de.mm20.launcher2.ui.modifier.scale
import kotlinx.coroutines.launch
import java.text.DecimalFormat import java.text.DecimalFormat
import kotlin.math.roundToInt import kotlin.math.roundToInt
@ -48,6 +49,9 @@ fun FileItem(
val context = LocalContext.current val context = LocalContext.current
val viewModel = remember(file.key) { FileItemVM(file) } val viewModel = remember(file.key) { FileItemVM(file) }
val lifecycleOwner = LocalLifecycleOwner.current
val snackbarHostState = LocalSnackbarHostState.current
val transition = updateTransition(showDetails, label = "ContactItem") val transition = updateTransition(showDetails, label = "ContactItem")
Column( Column(
@ -235,6 +239,17 @@ fun FileItem(
action = { action = {
viewModel.hide() viewModel.hide()
onBack() onBack()
lifecycleOwner.lifecycleScope.launch {
val result = snackbarHostState.showSnackbar(
message = context.getString(R.string.msg_item_hidden, file.label),
actionLabel = context.getString(R.string.action_undo),
)
if(result == SnackbarResult.ActionPerformed) {
viewModel.unhide()
}
}
}) })
} }
toolbarActions.add(hideAction) toolbarActions.add(hideAction)

View File

@ -8,6 +8,7 @@ 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.*
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.SnackbarResult
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState import androidx.compose.runtime.collectAsState
@ -17,9 +18,11 @@ 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
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalLifecycleOwner
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.lifecycle.lifecycleScope
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.animation.animateTextStyleAsState import de.mm20.launcher2.ui.animation.animateTextStyleAsState
@ -31,7 +34,9 @@ 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
import de.mm20.launcher2.ui.locals.LocalGridIconSize import de.mm20.launcher2.ui.locals.LocalGridIconSize
import de.mm20.launcher2.ui.locals.LocalSnackbarHostState
import de.mm20.launcher2.ui.modifier.scale import de.mm20.launcher2.ui.modifier.scale
import kotlinx.coroutines.launch
import kotlin.math.pow import kotlin.math.pow
import kotlin.math.roundToInt import kotlin.math.roundToInt
@ -46,6 +51,9 @@ fun AppShortcutItem(
val viewModel = remember { ShortcutItemVM(shortcut) } val viewModel = remember { ShortcutItemVM(shortcut) }
val context = LocalContext.current val context = LocalContext.current
val lifecycleOwner = LocalLifecycleOwner.current
val snackbarHostState = LocalSnackbarHostState.current
val transition = updateTransition(showDetails, label = "AppShortcutItem") val transition = updateTransition(showDetails, label = "AppShortcutItem")
Column( Column(
@ -143,6 +151,17 @@ fun AppShortcutItem(
action = { action = {
viewModel.hide() viewModel.hide()
onBack() onBack()
lifecycleOwner.lifecycleScope.launch {
val result = snackbarHostState.showSnackbar(
message = context.getString(R.string.msg_item_hidden, shortcut.label),
actionLabel = context.getString(R.string.action_undo),
)
if(result == SnackbarResult.ActionPerformed) {
viewModel.unhide()
}
}
}) })
} }
toolbarActions.add(hideAction) toolbarActions.add(hideAction)

View File

@ -1,6 +1,7 @@
package de.mm20.launcher2.ui.locals package de.mm20.launcher2.ui.locals
import android.appwidget.AppWidgetHost import android.appwidget.AppWidgetHost
import androidx.compose.material3.SnackbarHostState
import androidx.compose.runtime.compositionLocalOf import androidx.compose.runtime.compositionLocalOf
import androidx.compose.ui.geometry.Size import androidx.compose.ui.geometry.Size
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
@ -22,6 +23,8 @@ val LocalGridColumns = compositionLocalOf { 5 }
val LocalGridIconSize = compositionLocalOf { 48.dp } val LocalGridIconSize = compositionLocalOf { 48.dp }
val LocalSnackbarHostState = compositionLocalOf { SnackbarHostState() }
/** /**
* Workaround a bug in Jetpack Compose which incorrectly places popups * Workaround a bug in Jetpack Compose which incorrectly places popups
* that are nested inside other popups. * that are nested inside other popups.