@@ -130,7 +130,6 @@ import androidx.compose.ui.input.key.isShiftPressed
130import androidx.compose.ui.input.key.key
130import androidx.compose.ui.input.key.key
131import androidx.compose.ui.input.key.onPreviewKeyEvent
131import androidx.compose.ui.input.key.onPreviewKeyEvent
132import androidx.compose.ui.input.key.type
132import androidx.compose.ui.input.key.type
133−import androidx.compose.ui.layout.onSizeChanged
134import androidx.compose.ui.platform.LocalContext
133import androidx.compose.ui.platform.LocalContext
135import androidx.compose.ui.platform.LocalDensity
134import androidx.compose.ui.platform.LocalDensity
136import androidx.compose.ui.platform.LocalHapticFeedback
135import androidx.compose.ui.platform.LocalHapticFeedback
@@ -1290,28 +1289,18 @@ fun ChatScreen(
1290 // (the same hazard FileViewScreen's overlay calls out). onSizeChanged only
1289 // (the same hazard FileViewScreen's overlay calls out). onSizeChanged only
1291 // fires while the banner is composed (visible), so gate the inset on
1290 // fires while the banner is composed (visible), so gate the inset on
1292 // bannerVisible and fall back to 44dp until the first measurement arrives.
1291 // bannerVisible and fall back to 44dp until the first measurement arrives.
1293− var bannerHeightPx by remember { mutableIntStateOf(0) }
1294− // Track the search bar height so the list's top padding can grow when search
1295− // is active — otherwise a scrolled-to match lands at index 0, hidden behind
1296− // the floating search bar (the "scroll-under-the-search-bar" bug).
1297− var searchbarHeightPx by remember { mutableIntStateOf(0) }
1298− val density = LocalDensity.current
1299 val topPad = if (bannerVisible) {
1292 val topPad = if (bannerVisible) {
1300− if (bannerHeightPx > 0) {
1293+ NetworkConfig.connectionBannerHeightDp.dp + 4.dp
1301− with(density) { bannerHeightPx.toDp() } + 4.dp
1305 } else {
1294 } else {
1307− } + if (searchActive && searchbarHeightPx > 0) {
1296+ } + if (searchActive) {
1308− with(density) { searchbarHeightPx.toDp() } + 4.dp
1297+ NetworkConfig.chatSearchBarHeightDp.dp + 4.dp
1309 } else {
1298 } else {
1312 ConnectionBanner(
1301 ConnectionBanner(
1313 state = connectionState,
1302 state = connectionState,
1314− modifier = Modifier.align(Alignment.TopCenter).onSizeChanged { bannerHeightPx = it.height },
1303+ modifier = Modifier.align(Alignment.TopCenter),
1315 isOnline = isOnline,
1304 isOnline = isOnline,
1316 // On a hard endpoint failure, retry by forcing an SSE reconnect (which
1305 // On a hard endpoint failure, retry by forcing an SSE reconnect (which
1317 // re-seeds from REST). refreshMessages is the right recovery path
1306 // re-seeds from REST). refreshMessages is the right recovery path
@@ -1971,8 +1960,7 @@ fun ChatScreen(
1971 tonalElevation = 3.dp,
1960 tonalElevation = 3.dp,
1972 modifier = Modifier
1961 modifier = Modifier
1973 .padding(horizontal = 12.dp, vertical = 4.dp)
1962 .padding(horizontal = 12.dp, vertical = 4.dp)
1974− .fillMaxWidth()
1963+ .fillMaxWidth(),
1975− .onSizeChanged { searchbarHeightPx = it.height },
1977 // Focus the search field when the bar appears (from the overflow menu's
1965 // Focus the search field when the bar appears (from the overflow menu's
1978 // "Find in conversation" or Ctrl+F), so the user can start typing
1966 // "Find in conversation" or Ctrl+F), so the user can start typing