fix(ui): Draw all screens edge-to-edge under system bars

Scrolling content now slides under the transparent status and
navigation bars instead of clipping at the inset boundary. Adds
PaddingValues.plus and systemBarsAndCutoutInsets helpers, moves inset
consumption from scroll viewports into content padding on every screen,
fixes reorder auto-scroll thresholds for content padding, adds IME
handling to form screens, and removes the unused EdgeToEdgeHelper.
This commit is contained in:
darken
2026-07-24 17:53:13 +02:00
committed by Matthias Urhahn
parent 37278af34e
commit 73dc10aee9
21 changed files with 179 additions and 113 deletions
+1 -1
View File
@@ -87,7 +87,7 @@ The monitor-layer glue (`monitor/core/aap/`) described above wires this stack in
### Common Utilities
- `EdgeToEdgeHelper`: Handles Android edge-to-edge display insets
- `common/compose/InsetsExtensions.kt`: `PaddingValues.plus` operator and `systemBarsAndCutoutInsets` for laying out non-Scaffold screens edge-to-edge
## Build Configuration
@@ -5,11 +5,17 @@ import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.WindowInsetsSides
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.only
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.safeDrawing
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.windowInsetsPadding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.RoundedCornerShape
@@ -133,10 +139,12 @@ fun SupporterStatusScreen(
Scaffold(
containerColor = MaterialTheme.colorScheme.surface,
) { paddingValues ->
Box(modifier = Modifier.padding(paddingValues)) {
Box(modifier = Modifier.fillMaxSize()) {
Column(
modifier = Modifier
.fillMaxWidth()
.verticalScroll(rememberScrollState())
.padding(paddingValues)
.padding(horizontal = 24.dp),
horizontalAlignment = Alignment.CenterHorizontally,
) {
@@ -238,6 +246,7 @@ fun SupporterStatusScreen(
onClick = onNavigateUp,
modifier = Modifier
.align(Alignment.TopStart)
.windowInsetsPadding(WindowInsets.safeDrawing.only(WindowInsetsSides.Top + WindowInsetsSides.Start))
.padding(4.dp),
) {
Icon(
@@ -272,10 +281,12 @@ fun UpgradeScreen(
snackbarHost = { SnackbarHost(snackbarHostState) },
containerColor = MaterialTheme.colorScheme.surface,
) { paddingValues ->
Box(modifier = Modifier.padding(paddingValues)) {
Box(modifier = Modifier.fillMaxSize()) {
Column(
modifier = Modifier
.fillMaxWidth()
.verticalScroll(rememberScrollState())
.padding(paddingValues)
.padding(horizontal = 24.dp),
horizontalAlignment = Alignment.CenterHorizontally,
) {
@@ -402,6 +413,7 @@ fun UpgradeScreen(
onClick = onNavigateUp,
modifier = Modifier
.align(Alignment.TopStart)
.windowInsetsPadding(WindowInsets.safeDrawing.only(WindowInsetsSides.Top + WindowInsetsSides.Start))
.padding(4.dp),
) {
Icon(
@@ -8,12 +8,17 @@ import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.WindowInsetsSides
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.only
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.safeDrawing
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.widthIn
import androidx.compose.foundation.layout.windowInsetsPadding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.verticalScroll
@@ -105,7 +110,7 @@ internal fun UpgradeScreenContainer(
modifier = modifier,
containerColor = MaterialTheme.colorScheme.surface,
) { paddingValues ->
Box(modifier = Modifier.padding(paddingValues)) {
Box(modifier = Modifier.fillMaxSize()) {
Box(
modifier = Modifier
.fillMaxSize()
@@ -114,6 +119,7 @@ internal fun UpgradeScreenContainer(
) {
Column(
modifier = Modifier
.padding(paddingValues)
// widthIn BEFORE fillMaxWidth: reversed, fillMaxWidth would pin the min to
// the full screen and the 560dp cap would never take effect on wide screens.
.widthIn(max = 560.dp)
@@ -129,6 +135,7 @@ internal fun UpgradeScreenContainer(
onClick = onNavigateUp,
modifier = Modifier
.align(Alignment.TopStart)
.windowInsetsPadding(WindowInsets.safeDrawing.only(WindowInsetsSides.Top + WindowInsetsSides.Start))
.padding(4.dp),
) {
// Matches capod's app-wide back-button convention (no navigate-up string exists).
@@ -1,34 +0,0 @@
package eu.darken.capod.common
import android.app.Activity
import android.view.View
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import eu.darken.capod.common.debug.logging.logTag
class EdgeToEdgeHelper(activity: Activity) {
private val tag = logTag("EdgeToEdge", "$activity")
fun insetsPadding(
view: View,
left: Boolean = false,
top: Boolean = false,
right: Boolean = false,
bottom: Boolean = false,
) {
ViewCompat.setOnApplyWindowInsetsListener(view) { v: View, insets: WindowInsetsCompat ->
val systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars())
val displayCutout = insets.getInsets(WindowInsetsCompat.Type.displayCutout())
v.setPadding(
if (left) maxOf(systemBars.left, displayCutout.left) else v.paddingLeft,
if (top) maxOf(systemBars.top, displayCutout.top) else v.paddingTop,
if (right) maxOf(systemBars.right, displayCutout.right) else v.paddingRight,
if (bottom) maxOf(systemBars.bottom, displayCutout.bottom) else v.paddingBottom,
)
insets
}
}
}
@@ -0,0 +1,22 @@
package eu.darken.capod.common.compose
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.displayCutout
import androidx.compose.foundation.layout.systemBars
import androidx.compose.foundation.layout.union
import androidx.compose.runtime.Composable
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.LayoutDirection
operator fun PaddingValues.plus(other: PaddingValues): PaddingValues = object : PaddingValues {
override fun calculateLeftPadding(layoutDirection: LayoutDirection): Dp =
this@plus.calculateLeftPadding(layoutDirection) + other.calculateLeftPadding(layoutDirection)
override fun calculateTopPadding(): Dp = this@plus.calculateTopPadding() + other.calculateTopPadding()
override fun calculateRightPadding(layoutDirection: LayoutDirection): Dp =
this@plus.calculateRightPadding(layoutDirection) + other.calculateRightPadding(layoutDirection)
override fun calculateBottomPadding(): Dp = this@plus.calculateBottomPadding() + other.calculateBottomPadding()
}
val systemBarsAndCutoutInsets: WindowInsets
@Composable get() = WindowInsets.systemBars.union(WindowInsets.displayCutout)
@@ -127,16 +127,16 @@ fun <T> ReorderableAutoScroll(state: ReorderableState<T>) {
if (!state.isDragging) return@LaunchedEffect
while (isActive) {
val layoutInfo = state.lazyListState.layoutInfo
val viewportStart = layoutInfo.viewportStartOffset
val viewportEnd = layoutInfo.viewportEndOffset
val contentStart = layoutInfo.viewportStartOffset + layoutInfo.beforeContentPadding
val contentEnd = layoutInfo.viewportEndOffset - layoutInfo.afterContentPadding
val draggedIdx = state.draggedIndex ?: break
val draggedItem = layoutInfo.visibleItemsInfo.firstOrNull { it.index == draggedIdx }
if (draggedItem != null) {
val itemCenter = draggedItem.offset + draggedItem.size / 2 + state.dragOffsetY
val scrollSpeed = 8f
val delta = when {
itemCenter < viewportStart + scrollThresholdPx -> -scrollSpeed
itemCenter > viewportEnd - scrollThresholdPx -> scrollSpeed
itemCenter < contentStart + scrollThresholdPx -> -scrollSpeed
itemCenter > contentEnd - scrollThresholdPx -> scrollSpeed
else -> 0f
}
if (delta != 0f) state.lazyListState.scrollBy(delta)
@@ -8,7 +8,6 @@ import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.WindowInsetsSides
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
@@ -16,7 +15,6 @@ import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.only
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.systemBars
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.windowInsetsPadding
import androidx.compose.foundation.rememberScrollState
@@ -54,6 +52,7 @@ import androidx.compose.ui.unit.dp
import eu.darken.capod.R
import eu.darken.capod.common.compose.Preview2
import eu.darken.capod.common.compose.PreviewWrapper
import eu.darken.capod.common.compose.systemBarsAndCutoutInsets
import java.io.File
@Composable
@@ -68,49 +67,49 @@ fun RecorderScreen(
val context = LocalContext.current
Box(modifier = modifier.fillMaxSize()) {
Column(modifier = Modifier.fillMaxSize()) {
Column(
modifier = Modifier
.weight(1f)
.verticalScroll(rememberScrollState())
.windowInsetsPadding(systemBarsAndCutoutInsets.only(WindowInsetsSides.Top + WindowInsetsSides.Horizontal)),
) {
// Hero section
HeroSection()
Column(modifier = Modifier.padding(horizontal = 16.dp)) {
// Sensitive information card
SensitiveInfoCard(onPrivacyPolicy = onPrivacyPolicy)
Spacer(modifier = Modifier.height(12.dp))
// Session path card
SessionPathCard(path = state.logDir?.path ?: "")
Spacer(modifier = Modifier.height(16.dp))
// Log files section
LogFilesSection(
entries = state.logEntries,
compressedSize = state.compressedSize,
recordingDurationSecs = state.recordingDurationSecs,
context = context,
)
}
}
// Bottom action bar
BottomActionBar(
isWorking = state.isWorking,
onDiscard = onDiscard,
onKeep = onKeep,
onShare = onShare,
)
}
if (state.isWorking) {
LinearProgressIndicator(modifier = Modifier.fillMaxWidth())
}
Column(
modifier = Modifier
.fillMaxSize()
.windowInsetsPadding(WindowInsets.systemBars.only(WindowInsetsSides.Top + WindowInsetsSides.Horizontal))
.verticalScroll(rememberScrollState())
.padding(bottom = 80.dp),
) {
// Hero section
HeroSection()
Column(modifier = Modifier.padding(horizontal = 16.dp)) {
// Sensitive information card
SensitiveInfoCard(onPrivacyPolicy = onPrivacyPolicy)
Spacer(modifier = Modifier.height(12.dp))
// Session path card
SessionPathCard(path = state.logDir?.path ?: "")
Spacer(modifier = Modifier.height(16.dp))
// Log files section
LogFilesSection(
entries = state.logEntries,
compressedSize = state.compressedSize,
recordingDurationSecs = state.recordingDurationSecs,
context = context,
)
}
}
// Bottom action bar
BottomActionBar(
isWorking = state.isWorking,
onDiscard = onDiscard,
onKeep = onKeep,
onShare = onShare,
modifier = Modifier.align(Alignment.BottomCenter),
)
}
}
@@ -373,7 +372,9 @@ private fun BottomActionBar(
color = MaterialTheme.colorScheme.surfaceContainerHigh,
) {
Row(
modifier = Modifier.padding(12.dp),
modifier = Modifier
.windowInsetsPadding(systemBarsAndCutoutInsets.only(WindowInsetsSides.Bottom + WindowInsetsSides.Horizontal))
.padding(12.dp),
horizontalArrangement = Arrangement.spacedBy(8.dp),
) {
OutlinedButton(
@@ -415,7 +416,6 @@ private fun BottomActionBar(
}
}
}
Spacer(modifier = Modifier.windowInsetsPadding(WindowInsets.systemBars.only(WindowInsetsSides.Bottom)))
}
}
@@ -4,6 +4,7 @@ import android.content.Intent
import android.provider.Settings
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
@@ -270,7 +271,8 @@ fun DeviceSettingsScreen(
snackbarHost = { SnackbarHost(hostState = snackbarHostState) },
) { paddingValues ->
LazyColumn(
modifier = Modifier.padding(paddingValues),
modifier = Modifier.fillMaxSize(),
contentPadding = paddingValues,
) {
// Device Info
if (device != null) {
@@ -50,9 +50,9 @@ fun OnboardingScreen(
Column(
modifier = Modifier
.fillMaxSize()
.verticalScroll(rememberScrollState())
.padding(innerPadding)
.padding(horizontal = 32.dp)
.verticalScroll(rememberScrollState()),
.padding(horizontal = 32.dp),
horizontalAlignment = Alignment.CenterHorizontally,
) {
Spacer(modifier = Modifier.height(48.dp))
@@ -6,7 +6,6 @@ import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.lazy.itemsIndexed
@@ -48,6 +47,7 @@ import eu.darken.capod.R
import eu.darken.capod.common.SystemTimeSource
import eu.darken.capod.common.compose.Preview2
import eu.darken.capod.common.compose.PreviewWrapper
import eu.darken.capod.common.compose.plus
import eu.darken.capod.common.compose.preview.MockPodDataProvider
import eu.darken.capod.common.error.ErrorEventHandler
import eu.darken.capod.common.navigation.NavigationEventHandler
@@ -278,10 +278,8 @@ fun OverviewScreen(
snackbarHost = { SnackbarHost(hostState = snackbarHostState) },
) { innerPadding ->
LazyColumn(
modifier = Modifier
.fillMaxSize()
.padding(innerPadding),
contentPadding = PaddingValues(horizontal = 8.dp, vertical = 4.dp),
modifier = Modifier.fillMaxSize(),
contentPadding = innerPadding + PaddingValues(horizontal = 8.dp, vertical = 4.dp),
) {
// 1. Permission cards
items(
@@ -1,6 +1,7 @@
package eu.darken.capod.main.ui.presscontrols
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
@@ -176,7 +177,10 @@ fun PressControlsScreen(
)
},
) { paddingValues ->
LazyColumn(modifier = Modifier.padding(paddingValues)) {
LazyColumn(
modifier = Modifier.fillMaxSize(),
contentPadding = paddingValues,
) {
item("description") {
Text(
text = stringResource(R.string.press_controls_description),
@@ -1,6 +1,6 @@
package eu.darken.capod.main.ui.settings
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.twotone.ArrowBack
@@ -105,7 +105,10 @@ fun SettingsScreen(
)
},
) { innerPadding ->
LazyColumn(modifier = Modifier.padding(innerPadding)) {
LazyColumn(
modifier = Modifier.fillMaxSize(),
contentPadding = innerPadding,
) {
item {
SettingsBaseItem(
title = stringResource(R.string.settings_general_label),
@@ -1,6 +1,6 @@
package eu.darken.capod.main.ui.settings.acks
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.twotone.ArrowBack
@@ -54,7 +54,10 @@ fun AcknowledgementsScreen(
)
},
) { innerPadding ->
LazyColumn(modifier = Modifier.padding(innerPadding)) {
LazyColumn(
modifier = Modifier.fillMaxSize(),
contentPadding = innerPadding,
) {
item {
SettingsCategoryHeader(text = stringResource(R.string.general_thank_you_label))
}
@@ -1,6 +1,7 @@
package eu.darken.capod.main.ui.settings.general
import android.os.Build
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material.icons.Icons
@@ -105,7 +106,10 @@ fun GeneralSettingsScreen(
)
},
) { innerPadding ->
LazyColumn(modifier = Modifier.padding(innerPadding)) {
LazyColumn(
modifier = Modifier.fillMaxSize(),
contentPadding = innerPadding,
) {
item {
SettingsCategoryHeader(text = stringResource(R.string.settings_category_appearance_label))
}
@@ -8,6 +8,7 @@ import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
@@ -228,7 +229,10 @@ fun SupportScreen(
)
},
) { innerPadding ->
LazyColumn(modifier = Modifier.padding(innerPadding)) {
LazyColumn(
modifier = Modifier.fillMaxSize(),
contentPadding = innerPadding,
) {
item {
SettingsBaseItem(
title = stringResource(R.string.troubleshooter_title),
@@ -9,8 +9,10 @@ import androidx.compose.foundation.layout.ExperimentalLayoutApi
import androidx.compose.foundation.layout.FlowRow
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.imePadding
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
@@ -241,12 +243,14 @@ fun ContactFormScreen(
},
)
},
snackbarHost = { SnackbarHost(snackbarHostState) },
snackbarHost = { SnackbarHost(snackbarHostState, modifier = Modifier.imePadding()) },
) { innerPadding ->
Column(
modifier = Modifier
.padding(innerPadding)
.fillMaxSize()
.imePadding()
.verticalScroll(rememberScrollState())
.padding(innerPadding)
.padding(16.dp),
verticalArrangement = Arrangement.spacedBy(12.dp),
) {
@@ -22,15 +22,14 @@ import androidx.compose.foundation.layout.ExperimentalLayoutApi
import androidx.compose.foundation.layout.FlowRow
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.WindowInsetsSides
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.imePadding
import androidx.compose.foundation.layout.only
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.systemBars
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.windowInsetsPadding
import androidx.compose.foundation.rememberScrollState
@@ -77,6 +76,7 @@ import eu.darken.capod.R
import eu.darken.capod.common.compose.Preview2
import eu.darken.capod.common.compose.PreviewWrapper
import eu.darken.capod.common.compose.preview.MockPodDataProvider
import eu.darken.capod.common.compose.systemBarsAndCutoutInsets
import eu.darken.capod.pods.core.apple.PodModel
import eu.darken.capod.profiles.core.DeviceProfile
@@ -102,12 +102,13 @@ fun WidgetConfigurationScreen(
Column(
modifier = Modifier
.fillMaxSize()
.windowInsetsPadding(WindowInsets.systemBars.only(WindowInsetsSides.Top + WindowInsetsSides.Horizontal)),
.imePadding(),
) {
Column(
modifier = Modifier
.weight(1f)
.verticalScroll(rememberScrollState())
.windowInsetsPadding(systemBarsAndCutoutInsets.only(WindowInsetsSides.Top + WindowInsetsSides.Horizontal))
.padding(top = 24.dp, bottom = 16.dp),
) {
Text(
@@ -347,7 +348,7 @@ fun WidgetConfigurationScreen(
// Bottom bar
Surface(tonalElevation = 3.dp) {
Column(modifier = Modifier.windowInsetsPadding(WindowInsets.systemBars.only(WindowInsetsSides.Bottom))) {
Column(modifier = Modifier.windowInsetsPadding(systemBarsAndCutoutInsets.only(WindowInsetsSides.Bottom + WindowInsetsSides.Horizontal))) {
if (!state.isPro) {
Text(
text = stringResource(R.string.common_feature_requires_pro_msg),
@@ -4,6 +4,7 @@ import androidx.compose.foundation.Image
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
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.fillMaxSize
@@ -44,6 +45,7 @@ import eu.darken.capod.R
import eu.darken.capod.common.compose.Preview2
import eu.darken.capod.common.compose.PreviewWrapper
import eu.darken.capod.common.compose.ReorderableAutoScroll
import eu.darken.capod.common.compose.plus
import eu.darken.capod.common.compose.preview.MockPodDataProvider
import eu.darken.capod.common.compose.reorderableItemModifier
import eu.darken.capod.common.compose.rememberReorderableState
@@ -123,9 +125,8 @@ fun DeviceManagerScreen(
val showDragHandles = reorderableState.items.size >= 2
LazyColumn(
state = lazyListState,
modifier = Modifier
.fillMaxSize()
.padding(innerPadding),
modifier = Modifier.fillMaxSize(),
contentPadding = innerPadding + PaddingValues(bottom = 88.dp),
) {
itemsIndexed(
items = reorderableState.items,
@@ -8,6 +8,7 @@ import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.imePadding
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
@@ -199,8 +200,9 @@ fun DeviceProfileCreationScreen(
Column(
modifier = Modifier
.fillMaxSize()
.padding(innerPadding)
.imePadding()
.verticalScroll(rememberScrollState())
.padding(innerPadding)
.padding(16.dp),
) {
DeviceInfoCard(
@@ -76,8 +76,8 @@ fun TroubleShooterScreen(
Column(
modifier = Modifier
.fillMaxSize()
.padding(innerPadding)
.verticalScroll(rememberScrollState()),
.verticalScroll(rememberScrollState())
.padding(innerPadding),
) {
Card(
modifier = Modifier
@@ -0,0 +1,33 @@
package eu.darken.capod.common.compose
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.dp
import io.kotest.matchers.shouldBe
import org.junit.jupiter.api.Test
import testhelpers.BaseTest
class InsetsExtensionsTest : BaseTest() {
@Test
fun `plus - sums start-end padding under Ltr`() {
val a = PaddingValues(start = 4.dp, top = 8.dp, end = 12.dp, bottom = 16.dp)
val b = PaddingValues(start = 1.dp, top = 2.dp, end = 3.dp, bottom = 4.dp)
val sum = a + b
sum.calculateLeftPadding(LayoutDirection.Ltr) shouldBe 5.dp
sum.calculateRightPadding(LayoutDirection.Ltr) shouldBe 15.dp
sum.calculateTopPadding() shouldBe 10.dp
sum.calculateBottomPadding() shouldBe 20.dp
}
@Test
fun `plus - sums start-end padding under Rtl`() {
val a = PaddingValues(start = 4.dp, top = 8.dp, end = 12.dp, bottom = 16.dp)
val b = PaddingValues(start = 1.dp, top = 2.dp, end = 3.dp, bottom = 4.dp)
val sum = a + b
sum.calculateLeftPadding(LayoutDirection.Rtl) shouldBe 15.dp
sum.calculateRightPadding(LayoutDirection.Rtl) shouldBe 5.dp
sum.calculateTopPadding() shouldBe 10.dp
sum.calculateBottomPadding() shouldBe 20.dp
}
}