Merge branch 'main' of git.arirex.me:iris/ai-app

This commit is contained in:
iris committed 2026-09-01 01:20:46 -04:00
commit 6d12388063
2 files changed
+30 -13

No files matched your search

@@ -21,6 +21,7 @@ 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.isImeVisible
import androidx.compose.foundation.layout.navigationBars
import androidx.compose.foundation.layout.padding
@@ -1220,19 +1221,20 @@ fun SessionScreen(settings: ServerSettings, summary: SessionSummary, onBack: ()
// message -- and then the keyboard's, per frame of its animation. This modifier
// is the whole of what the keyboard re-measures: the box's own size never
// changes, so nothing above it is touched.
.padding(
bottom =
with(LocalDensity.current) { composerHeight.toDp() } +
// Not the `imePadding()` modifier: it trusts the same animated
// value `imeVisible` exists to correct, so it is exactly as prone
// to sticking open. Coerced to zero the moment the platform says
// the keyboard is gone, whatever the animation still claims.
if (imeVisible) {
with(LocalDensity.current) { imeInsets.getBottom(this).toDp() }
} else {
0.dp
}
)
.padding(bottom = with(LocalDensity.current) { composerHeight.toDp() })
// The keyboard's room, and only while the platform says there is a keyboard --
// dropping the modifier is what coerces the stuck-open animated value to zero,
// the same guard the composer's translation applies below. It has to stay a
// *modifier* rather than a padding computed here: `imePadding` reads the inset
// in the layout phase, so a keyboard frame re-measures this box and nothing
// else, while reading `imeInsets` in this composable body subscribes the whole
// of `SessionScreen` to a value that changes every frame of the animation.
// That cost 16 full recompositions of this screen per keyboard open, against
// one, and it made the transcript's position depend on a recomposition landing
// inside the frame that the inset changed -- which the composer's does not,
// since its translation is re-read in that frame's draw phase. When the
// recomposition misses, the transcript trails the composer up the screen.
.then(if (imeVisible) Modifier.imePadding() else Modifier)
) {
Box(Modifier.fillMaxSize()) {
TranscriptList(