From 91231834dc15bc8862232e2754f717be628368d2 Mon Sep 17 00:00:00 2001 From: AskaEth Date: Tue, 26 May 2026 13:01:43 +0800 Subject: [PATCH] fix: prevent IME from hiding latest messages in chat Changed chat layout from Box overlay to Column flow so imePadding() applies to the whole container instead of just the input bar. Messages area now shrinks with the keyboard, keeping latest messages visible. Co-Authored-By: Claude Opus 4.7 --- .../yeij/cyrene/ui/screens/chat/ChatScreen.kt | 95 +++++++++---------- 1 file changed, 45 insertions(+), 50 deletions(-) diff --git a/app/src/main/java/top/yeij/cyrene/ui/screens/chat/ChatScreen.kt b/app/src/main/java/top/yeij/cyrene/ui/screens/chat/ChatScreen.kt index 9f3ac46..e36242d 100644 --- a/app/src/main/java/top/yeij/cyrene/ui/screens/chat/ChatScreen.kt +++ b/app/src/main/java/top/yeij/cyrene/ui/screens/chat/ChatScreen.kt @@ -162,72 +162,67 @@ fun ChatScreen( else -> CyreneStatus.OFFLINE } - // Input area overlaid at bottom, with IME padding so only input moves up - Box( + // Single column layout: everything flows together and IME shrinks the whole view + Column( modifier = Modifier .fillMaxSize() - .statusBarsPadding(), + .statusBarsPadding() + .imePadding(), ) { - Column(modifier = Modifier.fillMaxSize()) { - // Top status bar - Row( - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 16.dp, vertical = 8.dp), - verticalAlignment = Alignment.CenterVertically, - ) { - StatusIndicator(status = status) - } + // Top status bar + Row( + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 16.dp, vertical = 8.dp), + verticalAlignment = Alignment.CenterVertically, + ) { + StatusIndicator(status = status) + } - // Messages area (fills space above input area) - PullToRefreshBox( - isRefreshing = isRefreshing, - onRefresh = { viewModel.refreshMessages() }, - modifier = Modifier - .weight(1f) - .padding(bottom = 96.dp), // Reserve space for floating input bar - ) { - if (messages.isEmpty() && !isStreaming) { - Box( - modifier = Modifier.fillMaxSize(), - contentAlignment = Alignment.Center, - ) { - Text( - text = "开始和昔涟对话吧", - style = MaterialTheme.typography.bodyLarge, - color = MaterialTheme.colorScheme.onSurfaceVariant, + // Messages area (fills remaining space, shrinks with IME) + PullToRefreshBox( + isRefreshing = isRefreshing, + onRefresh = { viewModel.refreshMessages() }, + modifier = Modifier.weight(1f), + ) { + if (messages.isEmpty() && !isStreaming) { + Box( + modifier = Modifier.fillMaxSize(), + contentAlignment = Alignment.Center, + ) { + Text( + text = "开始和昔涟对话吧", + style = MaterialTheme.typography.bodyLarge, + color = MaterialTheme.colorScheme.onSurfaceVariant, + ) + } + } else { + LazyColumn( + modifier = Modifier.fillMaxSize(), + state = listState, + reverseLayout = true, + ) { + itemsIndexed(messages, key = { _, msg -> msg.id }) { index, message -> + AnimatedChatBubble( + message = message, + animIndex = index.coerceAtMost(20), ) } - } else { - LazyColumn( - modifier = Modifier.fillMaxSize(), - state = listState, - reverseLayout = true, - ) { - itemsIndexed(messages, key = { _, msg -> msg.id }) { index, message -> - AnimatedChatBubble( - message = message, - animIndex = index.coerceAtMost(20), - ) - } - if (isStreaming) { - item(key = "typing_indicator") { - TypingIndicator() - } + if (isStreaming) { + item(key = "typing_indicator") { + TypingIndicator() } } } } } - // Input area at bottom, moved up by IME + // Input area at bottom, in flow (not overlaid) Column( modifier = Modifier - .align(Alignment.BottomCenter) .fillMaxWidth() .background(MaterialTheme.colorScheme.surface) - .navigationBarsPadding() - .imePadding(), + .navigationBarsPadding(), ) { // "昔涟正在输入..." indicator if (isStreaming) {