feat: enhance swipe-back functionality in OtherProfileScreen and SwipeBackContainer

This commit is contained in:
2026-03-03 20:47:32 +05:00
parent ddb6207bb5
commit 2501296d70
3 changed files with 14 additions and 8 deletions

View File

@@ -895,7 +895,8 @@ fun MainScreen(
isVisible = isThemeVisible, isVisible = isThemeVisible,
onBack = { navStack = navStack.filterNot { it is Screen.Theme } }, onBack = { navStack = navStack.filterNot { it is Screen.Theme } },
isDarkTheme = isDarkTheme, isDarkTheme = isDarkTheme,
layer = 2 layer = 2,
deferToChildren = true
) { ) {
ThemeScreen( ThemeScreen(
isDarkTheme = isDarkTheme, isDarkTheme = isDarkTheme,

View File

@@ -88,6 +88,7 @@ fun SwipeBackContainer(
layer: Int = 1, layer: Int = 1,
swipeEnabled: Boolean = true, swipeEnabled: Boolean = true,
propagateBackgroundProgress: Boolean = true, propagateBackgroundProgress: Boolean = true,
deferToChildren: Boolean = false,
content: @Composable () -> Unit content: @Composable () -> Unit
) { ) {
// 🚀 Lazy composition: skip ALL setup until the screen is opened for the first time. // 🚀 Lazy composition: skip ALL setup until the screen is opened for the first time.
@@ -243,7 +244,7 @@ fun SwipeBackContainer(
alpha = currentAlpha alpha = currentAlpha
} }
.background(if (isDarkTheme) Color(0xFF1B1B1B) else Color.White) .background(if (isDarkTheme) Color(0xFF1B1B1B) else Color.White)
.pointerInput(swipeEnabled, isAnimatingIn, isAnimatingOut) { .pointerInput(swipeEnabled, isAnimatingIn, isAnimatingOut, deferToChildren) {
if (!swipeEnabled || isAnimatingIn || isAnimatingOut) return@pointerInput if (!swipeEnabled || isAnimatingIn || isAnimatingOut) return@pointerInput
val velocityTracker = VelocityTracker() val velocityTracker = VelocityTracker()
@@ -268,12 +269,14 @@ fun SwipeBackContainer(
var totalDragY = 0f var totalDragY = 0f
var passedSlop = false var passedSlop = false
// Pre-slop: use Main pass so children (e.g. LazyRow) // deferToChildren=true: pre-slop uses Main pass so children
// process first — if they consume, we back off. // (e.g. LazyRow) process first — if they consume, we back off.
// Post-claim: use Initial pass to intercept before children. // deferToChildren=false (default): always use Initial pass
// to intercept before children (original behavior).
// Post-claim: always Initial to block children.
while (true) { while (true) {
val pass = val pass =
if (startedSwipe) if (startedSwipe || !deferToChildren)
PointerEventPass.Initial PointerEventPass.Initial
else PointerEventPass.Main else PointerEventPass.Main
val event = awaitPointerEvent(pass) val event = awaitPointerEvent(pass)

View File

@@ -199,15 +199,17 @@ fun OtherProfileScreen(
} }
} }
// Pager swipe → update tab // Pager swipe → update tab + control swipe-back
LaunchedEffect(pagerState) { LaunchedEffect(pagerState) {
snapshotFlow { pagerState.currentPage }.collect { page -> snapshotFlow { pagerState.currentPage }.collect { page ->
selectedTab = OtherProfileTab.entries[page] selectedTab = OtherProfileTab.entries[page]
// Swipe-back only on first tab (Media); on other tabs pager handles swipe
onSwipeBackEnabledChanged(page == 0 && !showImageViewer)
} }
} }
LaunchedEffect(showImageViewer) { LaunchedEffect(showImageViewer) {
onSwipeBackEnabledChanged(!showImageViewer) onSwipeBackEnabledChanged(!showImageViewer && pagerState.currentPage == 0)
} }
val backgroundColor = if (isDarkTheme) Color(0xFF1A1A1A) else Color(0xFFFFFFFF) val backgroundColor = if (isDarkTheme) Color(0xFF1A1A1A) else Color(0xFFFFFFFF)