diff --git a/android/app/src/main/java/com/fabledsword/thoughtsync/ui/BoardScreen.kt b/android/app/src/main/java/com/fabledsword/thoughtsync/ui/BoardScreen.kt index 7c52d62..62dfe60 100644 --- a/android/app/src/main/java/com/fabledsword/thoughtsync/ui/BoardScreen.kt +++ b/android/app/src/main/java/com/fabledsword/thoughtsync/ui/BoardScreen.kt @@ -6,11 +6,14 @@ import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.ime import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.union import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.staggeredgrid.LazyVerticalStaggeredGrid import androidx.compose.foundation.lazy.staggeredgrid.StaggeredGridCells @@ -37,6 +40,7 @@ import androidx.compose.material3.ModalDrawerSheet import androidx.compose.material3.ModalNavigationDrawer import androidx.compose.material3.NavigationDrawerItem import androidx.compose.material3.Scaffold +import androidx.compose.material3.ScaffoldDefaults import androidx.compose.material3.SnackbarDuration import androidx.compose.material3.SnackbarHost import androidx.compose.material3.SnackbarHostState @@ -138,6 +142,21 @@ fun BoardScreen( }, ) { Scaffold( + // The IME, added to what the Scaffold already insets for. `enableEdgeToEdge` + // makes the manifest's `adjustResize` a no-op on API 30+, so nothing resizes + // for the keyboard unless the app asks — and `ScaffoldDefaults.contentWindowInsets` + // is systemBars, which the IME is not part of. The Scaffold positions the FAB + // AND the snackbar host from this value, so without it both sit behind the + // keyboard whenever the search field has focus. That is not theoretical: the + // undo on a trashed search hit is exactly the control you cannot reach. + // + // `union` rather than `add` — the two are the same edge, not two stacked ones. + // Adding them would inset by the navigation bar a second time underneath a + // keyboard that already covers it. + // + // One owner for the edge, as with the search bar's missing statusBarsPadding: + // set here, the content Column gets it through `padding` and must not repeat it. + contentWindowInsets = ScaffoldDefaults.contentWindowInsets.union(WindowInsets.ime), snackbarHost = { SnackbarHost(snackbars) }, floatingActionButton = { // The + is the ONLY way in, by design: one obvious target rather