diff --git a/src/apps/mobile/android/app/src/androidTest/kotlin/com/openbitfun/mobile/app/MobileScreenTest.kt b/src/apps/mobile/android/app/src/androidTest/kotlin/com/openbitfun/mobile/app/MobileScreenTest.kt index 6e7179024f..f57f70aa37 100644 --- a/src/apps/mobile/android/app/src/androidTest/kotlin/com/openbitfun/mobile/app/MobileScreenTest.kt +++ b/src/apps/mobile/android/app/src/androidTest/kotlin/com/openbitfun/mobile/app/MobileScreenTest.kt @@ -120,10 +120,9 @@ class MobileScreenTest { /** * The settings page closes by its own button. * - * The sheet has no drag handle — the source draws none, and the page centres - * its title where one would sit — so this button is the only way out that does - * not depend on guessing where a downward drag will be read as a dismissal - * rather than as a scroll. Losing it would strand the page. + * The page's body is one long scroll and the sheet does not take a pull-down, + * so a downward drag never dismisses it and this button is the exit that is + * always there. Losing it would strand the page. */ @Test fun theSettingsPageClosesByItsOwnButton() { diff --git a/src/apps/mobile/android/app/src/main/kotlin/com/openbitfun/mobile/app/ui/common/AdaptiveModalSurface.kt b/src/apps/mobile/android/app/src/main/kotlin/com/openbitfun/mobile/app/ui/common/AdaptiveModalSurface.kt index 34c02a8464..f55ed7b6a4 100644 --- a/src/apps/mobile/android/app/src/main/kotlin/com/openbitfun/mobile/app/ui/common/AdaptiveModalSurface.kt +++ b/src/apps/mobile/android/app/src/main/kotlin/com/openbitfun/mobile/app/ui/common/AdaptiveModalSurface.kt @@ -47,6 +47,12 @@ import com.openbitfun.mobile.core.feature.layout.SettingsPlacementMode * placement uses a full-window Dialog so back handling, focus containment and * accessibility isolation remain native while the surface docks to the * physical trailing region selected by the shared policy. + * + * @param draggable whether the compact sheet follows a pull-down. A page whose + * body is itself a scroll should say no: the same pull-down then means both + * "scroll the body" and "drag the sheet away", so a gesture the user meant as + * scrolling can move the surface or dismiss the page. Such a page still closes + * through its own close button, the back action, and a tap on the scrim. */ @OptIn(ExperimentalMaterial3Api::class) @Composable @@ -56,6 +62,7 @@ internal fun AdaptiveModalSurface( onDismissRequest: () -> Unit, edgeToEdgeContent: Boolean = false, fitContent: Boolean = false, + draggable: Boolean = true, content: @Composable (Modifier) -> Unit, ) { if (!visible) return @@ -137,6 +144,7 @@ internal fun AdaptiveModalSurface( topEnd = MobileDesignGeometry.SheetTopRadius, ), dragHandle = null, + sheetGesturesEnabled = draggable, contentWindowInsets = { if (edgeToEdgeContent) WindowInsets(0) else BottomSheetDefaults.windowInsets }, ) { val modifier = if (fitContent) { diff --git a/src/apps/mobile/android/app/src/main/kotlin/com/openbitfun/mobile/app/ui/shell/MobileScreen.kt b/src/apps/mobile/android/app/src/main/kotlin/com/openbitfun/mobile/app/ui/shell/MobileScreen.kt index d540ae59b7..4cdde6ed04 100644 --- a/src/apps/mobile/android/app/src/main/kotlin/com/openbitfun/mobile/app/ui/shell/MobileScreen.kt +++ b/src/apps/mobile/android/app/src/main/kotlin/com/openbitfun/mobile/app/ui/shell/MobileScreen.kt @@ -678,6 +678,10 @@ internal fun MobileScreen(onAccountRestored: (Boolean) -> Unit = {}) { visible = shell.showSettings, placement = settingsPlacement, onDismissRequest = shell::dismissSettings, + // The settings body is one long scroll, so a pull-down has to scroll it + // rather than drag the page away. The page closes through its own close + // button, the back action, and a tap on the scrim. + draggable = false, content = settingsContent, ) AdaptiveModalSurface(