Skip to content

fix(mobile): drop quick chat idle status gap and keyboard-dismiss jump - #7776

Merged
iscekic merged 3 commits into
mainfrom
fix/quick-chat-footer-jump
Oct 16, 2026
Merged

iscekic merged 3 commits into
mainfrom
fix/quick-chat-footer-jump

Conversation

@iscekic

@iscekic iscekic commented Oct 16, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Quick chat no longer reserves an empty status row above the composer. It shows the same working row as remote CLI and cloud agent sessions (WorkingIndicator), and only while a reply is generating.
  • Dismissing the keyboard no longer moves the transcript a second time. When the model chip hides, its row was kept with opacity-0 until the JS keyboard height reached zero, which arrives after the keyboard has landed. The row then unmounted and the transcript snapped down by the row height. The hidden row now gives its height back on the UI thread in step with the keyboard progress.
  • The shared composer carries the second fix, so session screens get it too.
  • Removed the now-unused common.generating key from every catalog.

Verification

  • apps/mobile: typecheck, lint, check:i18n, check:classes pass.
  • apps/mobile vitest: all suites pass except url-contract.test.ts, which needs a local .env that the test VM does not have.
  • New regression test in chat-composer.test.ts: the hidden row height follows keyboard progress (full, half, zero) before the JS keyboard height clears.
  • chat-screen.mounted.test.tsx: the working row renders only while working.

Visual Changes

Before: an idle chat kept an empty status row between the transcript and the composer. After the keyboard was dismissed, the transcript snapped down by the model-chip row height after the keyboard had landed.
After: an idle chat ends at the composer, and the transcript moves only with the keyboard animation.

@kilo-code-bot

kilo-code-bot Bot commented Oct 16, 2026 •

Copy link
Copy Markdown
Contributor

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Executive Summary

Incremental review of 53d776f4 found no new issues: the toolbar row now always returns a maxHeight, so a row that mounted collapsed unclamps once the chip is shown, and onLayout is guarded so a clamped layout pass cannot overwrite the natural height.

Files Reviewed (2 files)
  • apps/mobile/src/components/agents/chat-composer.tsx - no new issues; TOOLBAR_ROW_UNCLAMPED_HEIGHT plus a toolbarRowCollapsing shared value keeps the worklet always returning maxHeight, the onLayout guard preserves the natural height during interactive dismiss/reopen, and overflow: hidden clips only within the row's own bounds
  • apps/mobile/src/components/agents/chat-composer.test.ts - regression tests cover the collapse timeline and the mount-collapsed reversal; no issues
Previous Review Summaries (2 snapshots, latest commit 7e3b576)

Current summary above is authoritative. Previous snapshots are kept for context only.

Previous review (commit 7e3b576)

Status: No Issues Found | Recommendation: Merge

Executive Summary

The follow-up commit re-adds common.generating to every catalog and announces the reply start once through announceForA11y, which resolves the previous screen-reader finding with no new issues.

Files Reviewed (89 files)
  • apps/mobile/src/components/chat/chat-composer-area.tsx - prior "silent generating status" finding is resolved: it now announces common.generating once when status becomes working, while the working row stays plain text so its elapsed-time tick does not re-announce; the added effect has no subscriptions/timers, so no leak or cleanup gap
  • apps/mobile/src/components/chat/chat-screen.mounted.test.tsx - asserts one announcement while working and none while idle; no issues
  • 87 apps/mobile/src/i18n/locales/*.json - common.generating re-added to en.json and every catalog; key parity holds, no duplicate-copy collision, and no remaining untranslated key

Previous review (commit 6c6b54f)

Status: 1 Issue Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 0
SUGGESTION 1
Issue Details (click to expand)

SUGGESTION

File Line Issue
apps/mobile/src/components/chat/chat-composer-area.tsx 101 Replacing AccessibleStatus with WorkingIndicator drops the screen-reader announcement of the generating status
Files Reviewed (8 files + 87 locale catalogs)
  • apps/mobile/src/components/agents/chat-composer.tsx - keyboard-driven collapse of the model-chip row; verified against useReanimatedKeyboardAnimation progress semantics and hook-order rules
  • apps/mobile/src/components/chat/chat-composer-area.tsx - 1 issue
  • apps/mobile/src/components/chat/chat-screen.tsx
  • apps/mobile/src/components/agents/chat-composer.test.ts
  • apps/mobile/src/components/agents/chat-composer-attachment-send.test.ts
  • apps/mobile/src/components/agents/chat-composer-send-once.mounted.test.tsx
  • apps/mobile/src/components/agents/chat-composer-typing-render.mounted.test.tsx
  • apps/mobile/src/components/chat/chat-screen.mounted.test.tsx
  • 87 apps/mobile/src/i18n/locales/*.json - one common.generating key deletion each; no remaining references found

Notes: no memory leak introduced (the only interval, in WorkingIndicator, is pre-existing and cleaned up; no new listeners). The removed common.generating key has no remaining references in apps/mobile, packages/app-shared, or apps/web. Review is based on static reading only; the diff could not be executed.

Fix these issues in Kilo Cloud


Reviewed by deepseek-v4.1-flash · Input: 53.7K · Output: 12.5K · Cached: 573.7K

Review guidance: REVIEW.md from base branch main

@iscekic

iscekic commented Oct 16, 2026

Copy link
Copy Markdown
Collaborator Author

bot: iOS simulator proof for quick chat (iPhone 17, iOS 26.5, CI native artifact, Metro and backend on an isolated VM, fake account)

Proof A: idle gap

Generating Idle, keyboard up
Generating Idle
  • While a reply generates, the working row ("Considering next steps · 3 sec") shows right above the composer.
  • When idle, there is no reserved row. Pixel scan: the last transcript line ends at y≈461pt and the composer starts at y≈485pt. That is the list's normal bottom padding, not the 40pt status row.

Proof B: keyboard-dismiss jump

I recorded focus composer → tap the empty space above the composer → wait, then sampled it at 30 fps. Transcript offset per frame comes from row-profile cross-correlation (points, compared with the previous frame):

frame 161 162 163 164 165 166 167 168 169 170 171 172 173 174–191
Δ transcript 0 49 -8 43 43 25 14 7 5 1 1 0 1 0
keyboard area changing – yes yes yes yes yes yes yes yes yes yes yes yes no

The transcript only moves while the keyboard animates (frames 162–173, about 0.4 s). Once the keyboard settles, the whole frame stays identical for all 18 remaining frames (0.6 s), and there is no shift afterwards. The original bug video had a +38px snap 8 frames after the keyboard settled; nothing like it appears here.

Frame strip (frames 160, 165, 169, 173, 174, 182, 191):

Dismiss frame strip

@iscekic

iscekic commented Oct 16, 2026

Copy link
Copy Markdown
Collaborator Author

bot: Follow-up iOS proof for the keyboard-dismiss jump, now with the model chip row visible (head 53d776f, iPhone 17 simulator, iOS 26.5, same isolated VM stack and fake account).

The earlier Proof B comment is superseded. That run never showed the chip row: the row was stuck at zero height, which 53d776f fixes. With nothing to collapse, it could not show the jump fix.

Composer focused, keyboard up, chip visible

Chip visible while focused

The "Aion 3.5" chip is fully visible above the input (AX rect 88×28pt at y=444, input at y=485). Refocusing after a dismiss brings it back at full height. Tapping it opens the "Select model" sheet with the current model selected.

Dismiss: focus → tap above the composer → about 3 s more recording

These are 30 fps frames. Δ transcript is the row-profile cross-correlation shift (pt) against the previous frame. "Chip" is template-matched at its focused position.

frame 168 169 170 171 172 173 174 175 176 177 178 179 180 181–295
Δ transcript 0 -56 -11 44 43 25 14 7 4 2 1 1 1 0
keyboard/composer area changing no yes yes yes yes yes yes yes yes yes yes yes yes no
chip visible gone gone gone gone gone gone gone gone gone gone gone gone gone
  • The chip row goes away in the first frame of the keyboard animation, not after it.
  • The keyboard lands at frame 180. Frames 181–295 (3.8 s) show zero transcript shift, and the whole body is unchanged (max pixel difference 2/255, which is codec noise).
  • To prove the recorder was still capturing live frames, I changed the status-bar clock at frames 255 and 276 (2.5 s and 3.2 s after landing). Nothing below the status bar changed.
  • In the original bug video, the transcript snapped +38px 8 frames after the keyboard settled. Nothing like that happens here.

Frame strip (168, 170, 172, 174, 177, 180, 181, 295):

Dismiss frame strip with chip

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants