mirror of
https://github.com/d4rken-org/capod.git
synced 2026-09-14 18:26:11 -04:00
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:
@@ -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),
|
||||
|
||||
+6
-2
@@ -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,
|
||||
|
||||
+3
-1
@@ -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
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user