fix(ui): resolve double-resizing overlap bug with dynamic keyboard insets padding
This commit is contained in:
parent
43ca73c04a
commit
cbcbd4f76b
2 changed files with 23 additions and 8 deletions
|
|
@ -21,10 +21,13 @@ import androidx.compose.foundation.layout.Column
|
|||
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.asPaddingValues
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.heightIn
|
||||
import androidx.compose.foundation.layout.ime
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.width
|
||||
|
|
@ -128,6 +131,13 @@ fun EmptyHero(userName: String, onPick: (String) -> Unit, modifier: Modifier = M
|
|||
val dateLine = remember {
|
||||
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(
|
||||
modifier = modifier
|
||||
.fillMaxSize()
|
||||
|
|
@ -145,7 +155,7 @@ fun EmptyHero(userName: String, onPick: (String) -> Unit, modifier: Modifier = M
|
|||
Text(dateLine, color = cs.onSurfaceVariant.copy(alpha = 0.7f), fontSize = 13.sp)
|
||||
Spacer(Modifier.height(32.dp))
|
||||
SuggestionPills(onPick)
|
||||
Spacer(Modifier.height(142.dp)) // Clear the floating bottom dock
|
||||
Spacer(Modifier.height(bottomSpacerHeight)) // Dynamically expands to push layout out of the floating bottom dock
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,12 +4,15 @@ import androidx.compose.foundation.layout.Arrangement
|
|||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
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.fillMaxWidth
|
||||
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.Spacer
|
||||
import androidx.compose.foundation.layout.statusBarsPadding
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
|
|
@ -80,23 +83,25 @@ fun ChatScreen(userName: String = "Bruno") {
|
|||
|
||||
MeshBackground {
|
||||
Box(Modifier.fillMaxSize()) {
|
||||
val imeBottom = WindowInsets.ime.asPaddingValues().calculateBottomPadding()
|
||||
|
||||
// 1. Scrollable Chat Content
|
||||
// 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.
|
||||
if (messages.isEmpty()) {
|
||||
EmptyHero(
|
||||
userName = userName,
|
||||
onPick = { haptics.tick(); send(it) },
|
||||
modifier = Modifier.imePadding() // Viewport shrinks so the scrollable Column adapts without warping
|
||||
modifier = Modifier.fillMaxSize()
|
||||
)
|
||||
} else {
|
||||
val bottomPadding = remember(imeBottom) { 152.dp + imeBottom }
|
||||
LazyColumn(
|
||||
state = listState,
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.imePadding(), // Adjusts viewport height so scrollable content stops exactly above the keyboard
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
contentPadding = PaddingValues(
|
||||
top = 92.dp, // Leaves luxurious room for the floating KaizenHeader + status bars
|
||||
bottom = 152.dp, // Leaves luxurious room for the floating ModePills + ChatInput + bottom margins
|
||||
bottom = bottomPadding, // Dynamically expands as the keyboard rises to keep messages clear of the floating dock
|
||||
start = 16.dp,
|
||||
end = 16.dp
|
||||
),
|
||||
|
|
@ -118,7 +123,7 @@ fun ChatScreen(userName: String = "Bruno") {
|
|||
modifier = Modifier
|
||||
.align(Alignment.BottomCenter)
|
||||
.navigationBarsPadding()
|
||||
.imePadding()
|
||||
.imePadding() // Only the bottom controls float up, perfectly placing them above the keyboard
|
||||
) {
|
||||
ModePillsRow(selected = selectedMode, onSelect = { selectedMode = it; haptics.tick() })
|
||||
Spacer(Modifier.height(10.dp))
|
||||
|
|
|
|||
Loading…
Reference in a new issue