fix(ui): remove redundant bottom dock imePadding and restore constant bottom clear margins
This commit is contained in:
parent
cbcbd4f76b
commit
e13f6798db
2 changed files with 6 additions and 20 deletions
|
|
@ -21,13 +21,10 @@ import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.FlowRow
|
import androidx.compose.foundation.layout.FlowRow
|
||||||
import androidx.compose.foundation.layout.Row
|
import androidx.compose.foundation.layout.Row
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
import androidx.compose.foundation.layout.WindowInsets
|
|
||||||
import androidx.compose.foundation.layout.asPaddingValues
|
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.foundation.layout.heightIn
|
import androidx.compose.foundation.layout.heightIn
|
||||||
import androidx.compose.foundation.layout.ime
|
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.layout.size
|
import androidx.compose.foundation.layout.size
|
||||||
import androidx.compose.foundation.layout.width
|
import androidx.compose.foundation.layout.width
|
||||||
|
|
@ -131,12 +128,6 @@ fun EmptyHero(userName: String, onPick: (String) -> Unit, modifier: Modifier = M
|
||||||
val dateLine = remember {
|
val dateLine = remember {
|
||||||
now.format(DateTimeFormatter.ofPattern("EEE, d. MMMM · HH:mm", Locale.GERMAN))
|
now.format(DateTimeFormatter.ofPattern("EEE, d. MMMM · HH:mm", Locale.GERMAN))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Query soft-keyboard height dynamically to dynamically expand the bottom spacer.
|
|
||||||
// This allows suggestion pills to push upwards cleanly above the keyboard & floating input,
|
|
||||||
// completely preventing any overlaps without squeezing the greeting, date, or Kaizen orb.
|
|
||||||
val imeBottom = WindowInsets.ime.asPaddingValues().calculateBottomPadding()
|
|
||||||
val bottomSpacerHeight = remember(imeBottom) { 142.dp + imeBottom }
|
|
||||||
|
|
||||||
Column(
|
Column(
|
||||||
modifier = modifier
|
modifier = modifier
|
||||||
|
|
@ -155,7 +146,7 @@ fun EmptyHero(userName: String, onPick: (String) -> Unit, modifier: Modifier = M
|
||||||
Text(dateLine, color = cs.onSurfaceVariant.copy(alpha = 0.7f), fontSize = 13.sp)
|
Text(dateLine, color = cs.onSurfaceVariant.copy(alpha = 0.7f), fontSize = 13.sp)
|
||||||
Spacer(Modifier.height(32.dp))
|
Spacer(Modifier.height(32.dp))
|
||||||
SuggestionPills(onPick)
|
SuggestionPills(onPick)
|
||||||
Spacer(Modifier.height(bottomSpacerHeight)) // Dynamically expands to push layout out of the floating bottom dock
|
Spacer(Modifier.height(142.dp)) // Clear the floating bottom dock
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,13 +5,9 @@ import androidx.compose.foundation.layout.Box
|
||||||
import androidx.compose.foundation.layout.Column
|
import androidx.compose.foundation.layout.Column
|
||||||
import androidx.compose.foundation.layout.PaddingValues
|
import androidx.compose.foundation.layout.PaddingValues
|
||||||
import androidx.compose.foundation.layout.Spacer
|
import androidx.compose.foundation.layout.Spacer
|
||||||
import androidx.compose.foundation.layout.WindowInsets
|
|
||||||
import androidx.compose.foundation.layout.asPaddingValues
|
|
||||||
import androidx.compose.foundation.layout.fillMaxSize
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
import androidx.compose.foundation.layout.fillMaxWidth
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
import androidx.compose.foundation.layout.height
|
import androidx.compose.foundation.layout.height
|
||||||
import androidx.compose.foundation.layout.ime
|
|
||||||
import androidx.compose.foundation.layout.imePadding
|
|
||||||
import androidx.compose.foundation.layout.navigationBarsPadding
|
import androidx.compose.foundation.layout.navigationBarsPadding
|
||||||
import androidx.compose.foundation.layout.statusBarsPadding
|
import androidx.compose.foundation.layout.statusBarsPadding
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
|
|
@ -83,11 +79,10 @@ fun ChatScreen(userName: String = "Bruno") {
|
||||||
|
|
||||||
MeshBackground {
|
MeshBackground {
|
||||||
Box(Modifier.fillMaxSize()) {
|
Box(Modifier.fillMaxSize()) {
|
||||||
val imeBottom = WindowInsets.ime.asPaddingValues().calculateBottomPadding()
|
|
||||||
|
|
||||||
// 1. Scrollable Chat Content
|
// 1. Scrollable Chat Content
|
||||||
// Stretches to the full screen, allowing bubbles to scroll cleanly behind the floating glass panels.
|
// Stretches to the full screen, allowing bubbles to scroll cleanly behind the floating glass panels.
|
||||||
// No root imePadding() here to prevent double-resizing/pushing bugs on standard Android windows.
|
// Since the OS physically resizes the window when the keyboard opens, the Box container shrinks natively,
|
||||||
|
// placing the bottom dock exactly on top of the keyboard. We use constant Paddings to clear the docks.
|
||||||
if (messages.isEmpty()) {
|
if (messages.isEmpty()) {
|
||||||
EmptyHero(
|
EmptyHero(
|
||||||
userName = userName,
|
userName = userName,
|
||||||
|
|
@ -95,13 +90,12 @@ fun ChatScreen(userName: String = "Bruno") {
|
||||||
modifier = Modifier.fillMaxSize()
|
modifier = Modifier.fillMaxSize()
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
val bottomPadding = remember(imeBottom) { 152.dp + imeBottom }
|
|
||||||
LazyColumn(
|
LazyColumn(
|
||||||
state = listState,
|
state = listState,
|
||||||
modifier = Modifier.fillMaxSize(),
|
modifier = Modifier.fillMaxSize(),
|
||||||
contentPadding = PaddingValues(
|
contentPadding = PaddingValues(
|
||||||
top = 92.dp, // Leaves luxurious room for the floating KaizenHeader + status bars
|
top = 92.dp, // Leaves luxurious room for the floating KaizenHeader + status bars
|
||||||
bottom = bottomPadding, // Dynamically expands as the keyboard rises to keep messages clear of the floating dock
|
bottom = 152.dp, // Leaves luxurious room for the floating ModePills + ChatInput + bottom margins
|
||||||
start = 16.dp,
|
start = 16.dp,
|
||||||
end = 16.dp
|
end = 16.dp
|
||||||
),
|
),
|
||||||
|
|
@ -119,11 +113,12 @@ fun ChatScreen(userName: String = "Bruno") {
|
||||||
)
|
)
|
||||||
|
|
||||||
// 3. Floating Bottom Control Dock
|
// 3. Floating Bottom Control Dock
|
||||||
|
// Positioned at the bottom of the window. When the keyboard is active, the OS resizes the window
|
||||||
|
// and this dock naturally sits exactly on top of the keyboard without any double-padding.
|
||||||
Column(
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.align(Alignment.BottomCenter)
|
.align(Alignment.BottomCenter)
|
||||||
.navigationBarsPadding()
|
.navigationBarsPadding()
|
||||||
.imePadding() // Only the bottom controls float up, perfectly placing them above the keyboard
|
|
||||||
) {
|
) {
|
||||||
ModePillsRow(selected = selectedMode, onSelect = { selectedMode = it; haptics.tick() })
|
ModePillsRow(selected = selectedMode, onSelect = { selectedMode = it; haptics.tick() })
|
||||||
Spacer(Modifier.height(10.dp))
|
Spacer(Modifier.height(10.dp))
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue