From e88d1d0d002430acf5641a23eb4f24377ec5e0df Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Tue, 6 Aug 2024 17:13:06 -0400 Subject: [PATCH] Adds haptic feedback to draft deletion swipe --- .../amethyst/ui/components/SwipeToDelete.kt | 16 ++++++++++- .../ui/screen/loggedIn/DraftListScreen.kt | 27 +++++++++---------- .../vitorpamplona/amethyst/ui/theme/Theme.kt | 13 +++++++++ 3 files changed, 41 insertions(+), 15 deletions(-) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/SwipeToDelete.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/SwipeToDelete.kt index 6d542110e..ef69e4800 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/SwipeToDelete.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/components/SwipeToDelete.kt @@ -32,6 +32,7 @@ import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Delete import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon +import androidx.compose.material3.MaterialTheme import androidx.compose.material3.SwipeToDismissBox import androidx.compose.material3.SwipeToDismissBoxState import androidx.compose.material3.SwipeToDismissBoxValue.EndToStart @@ -39,10 +40,13 @@ import androidx.compose.material3.SwipeToDismissBoxValue.Settled import androidx.compose.material3.SwipeToDismissBoxValue.StartToEnd import androidx.compose.material3.rememberSwipeToDismissBoxState import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color +import androidx.compose.ui.hapticfeedback.HapticFeedbackType +import androidx.compose.ui.platform.LocalHapticFeedback import androidx.compose.ui.unit.dp import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.ui.stringRes @@ -69,6 +73,7 @@ fun SwipeToDeleteContainer( } return@rememberSwipeToDismissBoxState true }, + positionalThreshold = { it * .40f }, ) SwipeToDismissBox( @@ -86,11 +91,20 @@ fun DismissBackground(dismissState: SwipeToDismissBoxState) { if (dismissState.currentValue > dismissState.targetValue) { Color(0xFFFF1744) } else { - Color.Transparent + MaterialTheme.colorScheme.surfaceVariant }, label = "DismissBackground", ) + val haptic = LocalHapticFeedback.current + LaunchedEffect(key1 = dismissState.currentValue > dismissState.targetValue) { + // doesn't run for the first time or when the list is updated. + println("AABBCC ${dismissState.progress}") + if (dismissState.progress > 0 && dismissState.progress < 1) { + haptic.performHapticFeedback(HapticFeedbackType.LongPress) + } + } + Row( modifier = Modifier diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/DraftListScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/DraftListScreen.kt index 661b62261..14b2b2f26 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/DraftListScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/DraftListScreen.kt @@ -22,7 +22,6 @@ package com.vitorpamplona.amethyst.ui.screen.loggedIn import androidx.compose.animation.animateContentSize import androidx.compose.foundation.ExperimentalFoundationApi -import androidx.compose.foundation.background import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxWidth @@ -59,6 +58,7 @@ import com.vitorpamplona.amethyst.ui.screen.SaveableFeedState import com.vitorpamplona.amethyst.ui.screen.ScrollStateKeys.DRAFTS import com.vitorpamplona.amethyst.ui.theme.DividerThickness import com.vitorpamplona.amethyst.ui.theme.FeedPadding +import com.vitorpamplona.amethyst.ui.theme.maxWidthWithBackground @Composable fun DraftListScreen( @@ -178,24 +178,23 @@ private fun DraftFeedLoaded( } } itemsIndexed(state.feed.value, key = { _, item -> item.idHex }) { _, item -> - SwipeToDeleteContainer( - modifier = - Modifier - .fillMaxWidth() - .animateContentSize(), - onStartToEnd = { accountViewModel.delete(item) }, - onEndToStart = { accountViewModel.delete(item) }, + Row( + Modifier + .fillMaxWidth() + .animateItemPlacement(), ) { - Row( - Modifier - .fillMaxWidth() - .animateItemPlacement() - .background(MaterialTheme.colorScheme.background), + SwipeToDeleteContainer( + modifier = + Modifier + .fillMaxWidth() + .animateContentSize(), + onStartToEnd = { accountViewModel.delete(item) }, + onEndToStart = { accountViewModel.delete(item) }, ) { NoteCompose( item, routeForLastRead = routeForLastRead, - modifier = Modifier.fillMaxWidth(), + modifier = MaterialTheme.colorScheme.maxWidthWithBackground, isBoostedNote = false, isHiddenFeed = state.showHidden.value, quotesLeft = 3, diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/theme/Theme.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/theme/Theme.kt index f874715a0..90d51ded1 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/theme/Theme.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/theme/Theme.kt @@ -189,6 +189,16 @@ val LightInnerPostBorderModifier = .clip(shape = QuoteBorder) .border(1.dp, LightSubtleBorder, QuoteBorder) +val DarkMaxWidthWithBackground = + Modifier + .fillMaxWidth() + .background(DarkColorPalette.background) + +val LightMaxWidthWithBackground = + Modifier + .fillMaxWidth() + .background(LightColorPalette.background) + val DarkSelectedReactionBoxModifier = Modifier .padding(horizontal = 5.dp, vertical = 5.dp) @@ -395,6 +405,9 @@ val ColorScheme.replyModifier: Modifier val ColorScheme.innerPostModifier: Modifier get() = if (isLight) LightInnerPostBorderModifier else DarkInnerPostBorderModifier +val ColorScheme.maxWidthWithBackground: Modifier + get() = if (isLight) LightMaxWidthWithBackground else DarkMaxWidthWithBackground + val ColorScheme.channelNotePictureModifier: Modifier get() = if (isLight) LightChannelNotePictureModifier else DarkChannelNotePictureModifier