diff --git a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/WidgetColumn.kt b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/WidgetColumn.kt
index ebc921df..abfc6681 100644
--- a/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/WidgetColumn.kt
+++ b/app/ui/src/main/java/de/mm20/launcher2/ui/launcher/widgets/WidgetColumn.kt
@@ -1,6 +1,5 @@
package de.mm20.launcher2.ui.launcher.widgets
-import android.appwidget.AppWidgetHost
import androidx.compose.animation.graphics.res.animatedVectorResource
import androidx.compose.animation.graphics.res.rememberAnimatedVectorPainter
import androidx.compose.animation.graphics.vector.AnimatedImageVector
@@ -11,6 +10,8 @@ import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.ExtendedFloatingActionButton
import androidx.compose.material3.Icon
+import androidx.compose.material3.SnackbarDuration
+import androidx.compose.material3.SnackbarResult
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
@@ -27,7 +28,6 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.onPlaced
import androidx.compose.ui.layout.positionInParent
import androidx.compose.ui.platform.LocalContext
-import androidx.compose.ui.platform.LocalLifecycleOwner
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.semantics.contentDescription
@@ -35,17 +35,15 @@ import androidx.compose.ui.semantics.role
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.dp
-import androidx.lifecycle.Lifecycle
-import androidx.lifecycle.repeatOnLifecycle
+import androidx.lifecycle.compose.LocalLifecycleOwner
+import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.viewmodel.compose.viewModel
-import de.mm20.launcher2.crashreporter.CrashReporter
import de.mm20.launcher2.ui.R
import de.mm20.launcher2.ui.base.LocalAppWidgetHost
import de.mm20.launcher2.ui.ktx.animateTo
-import de.mm20.launcher2.ui.launcher.sheets.LocalBottomSheetManager
import de.mm20.launcher2.ui.launcher.sheets.WidgetPickerSheet
+import de.mm20.launcher2.ui.locals.LocalSnackbarHostState
import de.mm20.launcher2.widgets.AppWidget
-import kotlinx.coroutines.awaitCancellation
import kotlinx.coroutines.launch
@Composable
@@ -55,13 +53,14 @@ fun WidgetColumn(
onEditModeChange: (Boolean) -> Unit,
) {
+ val context = LocalContext.current
+ val lifecycleOwner = LocalLifecycleOwner.current
val viewModel: WidgetsVM = viewModel()
- val bottomSheetManager = LocalBottomSheetManager.current
+ val snackbarHostState = LocalSnackbarHostState.current
var addNewWidget by rememberSaveable { mutableStateOf(false) }
-
Column(
modifier = modifier
) {
@@ -90,10 +89,21 @@ fun WidgetColumn(
viewModel.addWidget(widget, i + offset)
},
onWidgetRemove = {
- if (widget is AppWidget) {
- widgetHost.deleteAppWidgetId(widget.config.widgetId)
+ lifecycleOwner.lifecycleScope.launch {
+ viewModel.removeWidget(widget)
+ val result = snackbarHostState.showSnackbar(
+ message = context.getString(R.string.widget_removed),
+ actionLabel = context.getString(R.string.action_undo),
+ duration = SnackbarDuration.Short,
+ )
+ if (result == SnackbarResult.ActionPerformed) {
+ viewModel.addWidget(widget, i)
+ } else {
+ if (widget is AppWidget) {
+ widgetHost.deleteAppWidgetId(widget.config.widgetId)
+ }
+ }
}
- viewModel.removeWidget(widget)
},
onWidgetUpdate = {
viewModel.updateWidget(it)
diff --git a/core/i18n/src/main/res/values/strings.xml b/core/i18n/src/main/res/values/strings.xml
index c4eb4d17..e234596c 100644
--- a/core/i18n/src/main/res/values/strings.xml
+++ b/core/i18n/src/main/res/values/strings.xml
@@ -229,6 +229,7 @@
Note
Unknown app widget
Add widget
+ Widget removed
Write a noteā¦
New note