From fb92d554fde7aeaacd55cd7f993dd95363ac3a66 Mon Sep 17 00:00:00 2001 From: SuperDragonXD <70206496+SuperDragonXD@users.noreply.github.com> Date: Sun, 21 Jul 2024 20:21:44 +0800 Subject: [PATCH] Update announcements to use swipe to dismiss --- .../components/AnnouncementPreference.kt | 91 +++++++++++++------ .../data/liveinfo/model/LiveInformation.kt | 2 + .../destinations/PreferencesDashboard.kt | 2 +- 3 files changed, 66 insertions(+), 29 deletions(-) diff --git a/lawnchair/src/app/lawnchair/ui/preferences/components/AnnouncementPreference.kt b/lawnchair/src/app/lawnchair/ui/preferences/components/AnnouncementPreference.kt index 1c9a0d9885..f093160546 100644 --- a/lawnchair/src/app/lawnchair/ui/preferences/components/AnnouncementPreference.kt +++ b/lawnchair/src/app/lawnchair/ui/preferences/components/AnnouncementPreference.kt @@ -7,29 +7,32 @@ import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.offset import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.width import androidx.compose.material.icons.Icons import androidx.compose.material.icons.automirrored.rounded.Launch -import androidx.compose.material.icons.rounded.Close import androidx.compose.material.icons.rounded.NewReleases import androidx.compose.material3.Icon -import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Surface +import androidx.compose.material3.SwipeToDismissBox +import androidx.compose.material3.SwipeToDismissBoxValue import androidx.compose.material3.Text +import androidx.compose.material3.rememberSwipeToDismissBoxState +import androidx.compose.material3.surfaceColorAtElevation import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember +import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.alpha import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp @@ -40,6 +43,7 @@ import app.lawnchair.ui.preferences.data.liveinfo.liveInformationManager import app.lawnchair.ui.preferences.data.liveinfo.model.Announcement import app.lawnchair.ui.util.addIf import com.android.launcher3.BuildConfig +import com.android.launcher3.R import kotlinx.collections.immutable.ImmutableList @Composable @@ -66,7 +70,7 @@ fun AnnouncementPreference( modifier = modifier, ) { announcements.forEachIndexed { index, announcement -> - var show by remember { mutableStateOf(true) } + var show by rememberSaveable { mutableStateOf(true) } AnnouncementItem(show, announcement) { show = false } if (index != announcements.lastIndex && show && (!announcement.test || BuildConfig.DEBUG)) { Spacer(modifier = Modifier.height(16.dp)) @@ -103,13 +107,60 @@ private fun AnnouncementItemContent( modifier: Modifier = Modifier, onClose: () -> Unit, ) { - Surface( - modifier = modifier - .padding(16.dp, 0.dp, 16.dp, 0.dp), - shape = MaterialTheme.shapes.large, - color = MaterialTheme.colorScheme.surfaceVariant, + val state = rememberSwipeToDismissBoxState( + confirmValueChange = { + when (it) { + SwipeToDismissBoxValue.StartToEnd -> { + onClose() + } + SwipeToDismissBoxValue.EndToStart -> return@rememberSwipeToDismissBoxState false + SwipeToDismissBoxValue.Settled -> return@rememberSwipeToDismissBoxState false + } + return@rememberSwipeToDismissBoxState true + }, + ) + + SwipeToDismissBox( + state = state, + enableDismissFromEndToStart = false, + backgroundContent = { + Surface( + modifier = modifier + .alpha( + if (state.dismissDirection != SwipeToDismissBoxValue.StartToEnd) 1f else calculateAlpha(state.progress), + ) + .fillMaxSize() + .padding(16.dp, 0.dp, 16.dp, 0.dp), + shape = MaterialTheme.shapes.large, + color = MaterialTheme.colorScheme.surfaceColorAtElevation(1.dp), + ) { + PreferenceTemplate( + {}, + description = { + Text(stringResource(R.string.accessibility_close)) + }, + ) + } + }, ) { - AnnouncementPreferenceItemContent(text = text, url = url, onClose = onClose) + Surface( + modifier = modifier + .alpha( + if (state.dismissDirection != SwipeToDismissBoxValue.StartToEnd) 1f else calculateAlpha(state.progress), + ) + .padding(16.dp, 0.dp, 16.dp, 0.dp), + shape = MaterialTheme.shapes.large, + color = MaterialTheme.colorScheme.surfaceVariant, + ) { + AnnouncementPreferenceItemContent(text = text, url = url) + } + } +} + +private fun calculateAlpha(progress: Float): Float { + return when { + progress < 0.5f -> 1f // Fully opaque until halfway + else -> 1f - (progress - 0.5f) * 2 // Fade out linearly from halfway to the end } } @@ -118,7 +169,6 @@ private fun AnnouncementPreferenceItemContent( text: String, url: String?, modifier: Modifier = Modifier, - onClose: (() -> Unit)?, ) { val context = LocalContext.current val hasLink = !url.isNullOrBlank() @@ -165,19 +215,6 @@ private fun AnnouncementPreferenceItemContent( } Spacer(modifier = Modifier.width(8.dp)) - - if (onClose != null) { - IconButton( - onClick = onClose, - modifier = Modifier.size(16.dp).offset(x = (8).dp, y = (-16).dp), - ) { - Icon( - imageVector = Icons.Rounded.Close, - tint = MaterialTheme.colorScheme.surfaceTint, - contentDescription = null, - ) - } - } } }, ) @@ -189,7 +226,6 @@ private fun InfoPreferenceWithoutLinkPreview() { AnnouncementPreferenceItemContent( text = "Very important announcement ", url = "", - onClose = null, ) } @@ -199,6 +235,5 @@ private fun InfoPreferenceWithLinkPreview() { AnnouncementPreferenceItemContent( text = "Very important announcement with a very important link", url = "https://lawnchair.app/", - onClose = null, ) } diff --git a/lawnchair/src/app/lawnchair/ui/preferences/data/liveinfo/model/LiveInformation.kt b/lawnchair/src/app/lawnchair/ui/preferences/data/liveinfo/model/LiveInformation.kt index b119399315..8d71091dba 100644 --- a/lawnchair/src/app/lawnchair/ui/preferences/data/liveinfo/model/LiveInformation.kt +++ b/lawnchair/src/app/lawnchair/ui/preferences/data/liveinfo/model/LiveInformation.kt @@ -6,6 +6,7 @@ import kotlinx.serialization.Serializable @Serializable data class LiveInformation( + private val version: Int, private val announcements: List, ) { @@ -14,6 +15,7 @@ data class LiveInformation( companion object { val default = LiveInformation( + version = 1, announcements = emptyList(), ) } diff --git a/lawnchair/src/app/lawnchair/ui/preferences/destinations/PreferencesDashboard.kt b/lawnchair/src/app/lawnchair/ui/preferences/destinations/PreferencesDashboard.kt index 40a703cbed..2f9ed747f1 100644 --- a/lawnchair/src/app/lawnchair/ui/preferences/destinations/PreferencesDashboard.kt +++ b/lawnchair/src/app/lawnchair/ui/preferences/destinations/PreferencesDashboard.kt @@ -183,7 +183,7 @@ fun PreferencesOverflowMenu( Modifier .clip(highlightShape) .background(highlightColor) - } + }, ) } val openRestoreBackup = restoreBackupOpener()