From fe853f7b65ffe189b8ad465119c9b63e314e7f22 Mon Sep 17 00:00:00 2001 From: Jeffrey Starke Date: Mon, 28 Apr 2025 17:00:23 -0400 Subject: [PATCH] Add missing long press haptic feedback to composables. As recommended by https://developer.android.com/develop/ui/compose/touch-input/pointer-input/tap-and-press > As a best practice, you should include haptic feedback when the user long-presses elements. --- .../settings/app/chats/folders/ChatFoldersFragment.kt | 8 +++++++- .../backup/InternalBackupPlaygroundFragment.kt | 4 ++++ .../src/main/java/org/signal/core/ui/compose/Rows.kt | 10 +++++++++- 3 files changed, 20 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/chats/folders/ChatFoldersFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/chats/folders/ChatFoldersFragment.kt index 209e945b9d..1e807639e0 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/chats/folders/ChatFoldersFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/chats/folders/ChatFoldersFragment.kt @@ -30,8 +30,10 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.draw.shadow import androidx.compose.ui.graphics.ColorFilter import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.hapticfeedback.HapticFeedbackType import androidx.compose.ui.platform.LocalConfiguration import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.platform.LocalHapticFeedback import androidx.compose.ui.res.dimensionResource import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.pluralStringResource @@ -285,6 +287,7 @@ fun FolderRow( showDragHandle: Boolean = false ) { val menuController = remember { DropdownMenus.MenuController() } + val haptics = LocalHapticFeedback.current Row( verticalAlignment = Alignment.CenterVertically, @@ -292,7 +295,10 @@ fun FolderRow( modifier .combinedClickable( onClick = onClick, - onLongClick = { menuController.show() } + onLongClick = { + haptics.performHapticFeedback(HapticFeedbackType.LongPress) + menuController.show() + } ) .fillMaxWidth() .defaultMinSize(minHeight = dimensionResource(id = R.dimen.chat_folder_row_height)) diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/internal/backup/InternalBackupPlaygroundFragment.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/internal/backup/InternalBackupPlaygroundFragment.kt index 61417487d6..69d47b4f93 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/internal/backup/InternalBackupPlaygroundFragment.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/internal/backup/InternalBackupPlaygroundFragment.kt @@ -55,7 +55,9 @@ import androidx.compose.runtime.setValue 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.LocalContext +import androidx.compose.ui.platform.LocalHapticFeedback import androidx.compose.ui.res.painterResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.input.ImeAction @@ -604,6 +606,7 @@ fun MediaList( } } + val haptics = LocalHapticFeedback.current var selectionState by remember { mutableStateOf(MediaMultiSelectState()) } Box(modifier = Modifier.fillMaxSize()) { @@ -620,6 +623,7 @@ fun MediaList( selectionState = selectionState.copy(selected = if (selectionState.selected.contains(attachment.id)) selectionState.selected - attachment.id else selectionState.selected + attachment.id) } }, onLongClick = { + haptics.performHapticFeedback(HapticFeedbackType.LongPress) selectionState = if (selectionState.selecting) MediaMultiSelectState() else MediaMultiSelectState(selecting = true, selected = setOf(attachment.id)) }) .padding(horizontal = 16.dp, vertical = 8.dp) diff --git a/core-ui/src/main/java/org/signal/core/ui/compose/Rows.kt b/core-ui/src/main/java/org/signal/core/ui/compose/Rows.kt index 97de16b5ae..31c87c526f 100644 --- a/core-ui/src/main/java/org/signal/core/ui/compose/Rows.kt +++ b/core-ui/src/main/java/org/signal/core/ui/compose/Rows.kt @@ -39,6 +39,8 @@ import androidx.compose.ui.draw.alpha import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.painter.Painter import androidx.compose.ui.graphics.vector.ImageVector +import androidx.compose.ui.hapticfeedback.HapticFeedbackType +import androidx.compose.ui.platform.LocalHapticFeedback import androidx.compose.ui.res.dimensionResource import androidx.compose.ui.res.painterResource import androidx.compose.ui.text.TextStyle @@ -300,13 +302,19 @@ object Rows { onLongClick: (() -> Unit)? = null, enabled: Boolean = true ) { + val haptics = LocalHapticFeedback.current Row( modifier = modifier .fillMaxWidth() .combinedClickable( enabled = enabled && (onClick != null || onLongClick != null), onClick = onClick ?: {}, - onLongClick = onLongClick ?: {} + onLongClick = { + if (onLongClick != null) { + haptics.performHapticFeedback(HapticFeedbackType.LongPress) + onLongClick() + } + } ) .padding(defaultPadding()), verticalAlignment = CenterVertically