Attempt to reduce swipe sensitivity (#810)

This commit is contained in:
Benoit Marty 2023-07-10 11:54:44 +02:00
parent 39de8c1bb0
commit 40a0917c5e

View file

@ -38,6 +38,7 @@ import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
@ -45,6 +46,8 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.clipToBounds import androidx.compose.ui.draw.clipToBounds
import androidx.compose.ui.geometry.Offset import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.platform.LocalViewConfiguration
import androidx.compose.ui.platform.ViewConfiguration
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.text.style.TextOverflow
@ -137,37 +140,39 @@ fun TimelineItemEventRow(
val offset = state.offset.value val offset = state.offset.value
val swipeThresholdPx = 40.dp.toPx() val swipeThresholdPx = 40.dp.toPx()
val thresholdCrossed = abs(offset) > swipeThresholdPx val thresholdCrossed = abs(offset) > swipeThresholdPx
Box(Modifier.fillMaxWidth()) { SwipeSensitivity(3f) {
Row(modifier = Modifier.matchParentSize()) { Box(Modifier.fillMaxWidth()) {
ReplySwipeIndicator({ offset / 120 }) Row(modifier = Modifier.matchParentSize()) {
} ReplySwipeIndicator({ offset / 120 })
TimelineItemEventRowContent( }
modifier = Modifier TimelineItemEventRowContent(
.absoluteOffset { IntOffset(x = offset.roundToInt(), y = 0) } modifier = Modifier
.draggable( .absoluteOffset { IntOffset(x = offset.roundToInt(), y = 0) }
orientation = Orientation.Horizontal, .draggable(
enabled = !state.isResettingOnRelease, orientation = Orientation.Horizontal,
onDragStopped = { enabled = !state.isResettingOnRelease,
coroutineScope.launch { onDragStopped = {
if (thresholdCrossed) { coroutineScope.launch {
onSwipeToReply() if (thresholdCrossed) {
onSwipeToReply()
}
state.resetOffset()
} }
state.resetOffset() },
} state = state.draggableState,
}, ),
state = state.draggableState, event = event,
), isHighlighted = isHighlighted,
event = event, interactionSource = interactionSource,
isHighlighted = isHighlighted, onClick = onClick,
interactionSource = interactionSource, onLongClick = onLongClick,
onClick = onClick, onTimestampClicked = onTimestampClicked,
onLongClick = onLongClick, inReplyToClicked = ::inReplyToClicked,
onTimestampClicked = onTimestampClicked, onUserDataClicked = ::onUserDataClicked,
inReplyToClicked = ::inReplyToClicked, onReactionClicked = { emoji -> onReactionClick(emoji, event) },
onUserDataClicked = ::onUserDataClicked, onMoreReactionsClicked = { onMoreReactionsClick(event) },
onReactionClicked = { emoji -> onReactionClick(emoji, event) }, )
onMoreReactionsClicked = { onMoreReactionsClick(event) }, }
)
} }
} else { } else {
TimelineItemEventRowContent( TimelineItemEventRowContent(
@ -186,6 +191,29 @@ fun TimelineItemEventRow(
} }
} }
/**
* Impact ViewConfiguration.touchSlop by [sensitivityFactor].
* Inspired from https://issuetracker.google.com/u/1/issues/269627294.
* @param sensitivityFactor the factor to multiply the touchSlop by. The highest value, the more the user will
* have to drag to start the drag.
* @param content the content to display.
*/
@Composable
fun SwipeSensitivity(
sensitivityFactor: Float,
content: @Composable () -> Unit,
) {
val current = LocalViewConfiguration.current
CompositionLocalProvider(
LocalViewConfiguration provides object : ViewConfiguration by current {
override val touchSlop: Float
get() = current.touchSlop * sensitivityFactor
}
) {
content()
}
}
@Composable @Composable
private fun TimelineItemEventRowContent( private fun TimelineItemEventRowContent(
event: TimelineItem.Event, event: TimelineItem.Event,