Skip to content

Commit 2af689a

Browse files
authored
fix(mobile): keep the settings pull-down in the body, not the sheet (#3324)
The settings page is a modal sheet whose body is one long verticalScroll. The sheet also followed a pull-down, so a single gesture meant both "scroll the body" and "drag the page away": on the emulator the same pull-down moves the sheet 305 px and dismisses the page instead of scrolling the list. AdaptiveModalSurface now takes `draggable` (default true, so every other sheet keeps its current behaviour) and forwards it to Material's `sheetGesturesEnabled`. Settings opts out; its close button, the back action, and a tap on the scrim still close the page.
1 parent 2321151 commit 2af689a

3 files changed

Lines changed: 15 additions & 4 deletions

File tree

‎src/apps/mobile/android/app/src/androidTest/kotlin/com/openbitfun/mobile/app/MobileScreenTest.kt‎

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -120,10 +120,9 @@ class MobileScreenTest {
120120
/**
121121
* The settings page closes by its own button.
122122
*
123-
* The sheet has no drag handle — the source draws none, and the page centres
124-
* its title where one would sit — so this button is the only way out that does
125-
* not depend on guessing where a downward drag will be read as a dismissal
126-
* rather than as a scroll. Losing it would strand the page.
123+
* The page's body is one long scroll and the sheet does not take a pull-down,
124+
* so a downward drag never dismisses it and this button is the exit that is
125+
* always there. Losing it would strand the page.
127126
*/
128127
@Test
129128
fun theSettingsPageClosesByItsOwnButton() {

‎src/apps/mobile/android/app/src/main/kotlin/com/openbitfun/mobile/app/ui/common/AdaptiveModalSurface.kt‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,12 @@ import com.openbitfun.mobile.core.feature.layout.SettingsPlacementMode
4747
* placement uses a full-window Dialog so back handling, focus containment and
4848
* accessibility isolation remain native while the surface docks to the
4949
* physical trailing region selected by the shared policy.
50+
*
51+
* @param draggable whether the compact sheet follows a pull-down. A page whose
52+
* body is itself a scroll should say no: the same pull-down then means both
53+
* "scroll the body" and "drag the sheet away", so a gesture the user meant as
54+
* scrolling can move the surface or dismiss the page. Such a page still closes
55+
* through its own close button, the back action, and a tap on the scrim.
5056
*/
5157
@OptIn(ExperimentalMaterial3Api::class)
5258
@Composable
@@ -56,6 +62,7 @@ internal fun AdaptiveModalSurface(
5662
onDismissRequest: () -> Unit,
5763
edgeToEdgeContent: Boolean = false,
5864
fitContent: Boolean = false,
65+
draggable: Boolean = true,
5966
content: @Composable (Modifier) -> Unit,
6067
) {
6168
if (!visible) return
@@ -137,6 +144,7 @@ internal fun AdaptiveModalSurface(
137144
topEnd = MobileDesignGeometry.SheetTopRadius,
138145
),
139146
dragHandle = null,
147+
sheetGesturesEnabled = draggable,
140148
contentWindowInsets = { if (edgeToEdgeContent) WindowInsets(0) else BottomSheetDefaults.windowInsets },
141149
) {
142150
val modifier = if (fitContent) {

‎src/apps/mobile/android/app/src/main/kotlin/com/openbitfun/mobile/app/ui/shell/MobileScreen.kt‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -678,6 +678,10 @@ internal fun MobileScreen(onAccountRestored: (Boolean) -> Unit = {}) {
678678
visible = shell.showSettings,
679679
placement = settingsPlacement,
680680
onDismissRequest = shell::dismissSettings,
681+
// The settings body is one long scroll, so a pull-down has to scroll it
682+
// rather than drag the page away. The page closes through its own close
683+
// button, the back action, and a tap on the scrim.
684+
draggable = false,
681685
content = settingsContent,
682686
)
683687
AdaptiveModalSurface(

0 commit comments

Comments
 (0)