Skip to content

feat(mobile): show a full-page skeleton on session open and stabilize older-page scroll - #6347

Open
iscekic wants to merge 1 commit into
mainfrom
kwf/req-20260918-133438-a545
Open

iscekic wants to merge 1 commit into
mainfrom
kwf/req-20260918-133438-a545

Conversation

@iscekic

@iscekic iscekic commented Sep 19, 2026

Copy link
Copy Markdown
Collaborator

Changelog for users

  • Opening a session shows the full-page message skeleton instead of reusing the last visit's messages.
  • No top spinner appears during an open; the skeleton is the only loader.
  • Loading older messages by scrolling up keeps the message under your finger in place.
  • Condensed tool-call rows keep their position when an older page loads; no row duplicates or disappears.
  • Timestamp dividers stay on the message that opens each burst, so they no longer move when older messages load.
  • Fast flings through a long transcript render rows further ahead, so fewer blank gaps appear.
  • Auto-follow still pins the view to the newest message while the agent streams at the bottom.

Changelog for maintainers

  • The session manager no longer reads or writes a persisted transcript snapshot; the encrypted-KV transcript cache and its tests are removed. Existing transcript blobs are no longer read and clear on sign-out or a schema bump.
  • SessionTranscriptItem drops the type: 'time' variant. Markers move to an optional timeMarker on message and tool-run items, and keys no longer use time:<id>.
  • condenseTranscriptToolRuns takes an optional part-to-key map so a run reuses the key its row was already mounted under; without the map the output is unchanged.
  • getSessionTranscriptItemType returns separate recycling buckets for user, assistant, and failed-assistant message rows.
  • useSessionListAutoScroll requires newestItemKey and auto-scrolls only when the newest key changes; shouldScheduleSessionAutoScroll gained newestKeyChanged (default true).
  • SessionMessageList raises the draw distance from 1000 to 2000 and memoizes the pagination header.
  • Riskiest area: the carried-key reuse in condenseTranscriptToolRuns; the marker folding also changes the item shape consumers read.

E2E proof

[e1] session open: full-page skeleton, no stale data, older-page hold, image states (android emulator-5554) — e2e-mobile-app/e1-open-slow-state.png

/home/igor_kilocode_ai/.local/share/kwf/sections/kwf-fix-proof-9189579-3-ad00/e2e-backend/backend.log
    '    "code": "invalid_format",\n' +
    '    "format": "datetime",\n' +
    '    "pattern": "/^(?:(?:\\\\d\\\\d[2468][048]|\\\\d\\\\d[13579][26]|\\\\d\\\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\\\d|3[01])|(?:0[469]|11)-(?:
    '    "path": [\n' +
    '      "needsInputSince"\n' +
    '    ],\n' +
    '    "message": "Invalid ISO datetime"\n' +
    '  }\n' +
    ']'
}
 ✓ src/lib/glanceable-delivery.test.ts (81 tests) 1601ms
 Test Files  16 passed (16)
      Tests  312 passed (312)
   Start at  19:24:33
   Duration  18.89s (transform 46.91s, setup 972ms, import 136.51s, tests 4.48s, environment 2ms)
No projects matched the filters in "/home/igor_kilocode_ai/.local/share/kwf/wt/kwf-fix-proof-9189579-3-ad00"
No projects matched the filters in "/home/igor_kilocode_ai/.local/share/kwf/wt/kwf-fix-proof-9189579-3-ad00"
No projects matched the filters in "/home/igor_kilocode_ai/.local/share/kwf/wt/kwf-fix-proof-9189579-3-ad00"
No projects matched the filters in "/home/igor_kilocode_ai/.local/share/kwf/wt/kwf-fix-proof-9189579-3-ad00"
No projects matched the filters in "/home/igor_kilocode_ai/.local/share/kwf/wt/kwf-fix-proof-9189579-3-ad00"
No projects matched the filters in "/home/igor_kilocode_ai/.local/share/kwf/wt/kwf-fix-proof-9189579-3-ad00"
No projects matched the filters in "/home/igor_kilocode_ai/.local/share/kwf/wt/kwf-fix-proof-9189579-3-ad00"
No projects matched the filters in "/home/igor_kilocode_ai/.local/share/kwf/wt/kwf-fix-proof-9189579-3-ad00"
No projects matched the filters in "/home/igor_kilocode_ai/.local/share/kwf/wt/kwf-fix-proof-9189579-3-ad00"

[e1] session open: full-page skeleton, no stale data, older-page hold, image states (android emulator-5554) — prior/e1-open-slow-state.png

[e1] session open: full-page skeleton, no stale data, no top spinner, older-page hold, image states (android emulator-5554) — e2e-mobile-app/e1-open-loading.png

[e1] session open: full-page skeleton, no stale data, no top spinner, older-page -> pass :: Stalled open (<internal>, e1-stall3.log) of an already-rendered session shows only text="New session - 2026-09-19T19:30:50.181Z" and text="Message" with 66 empty placeholder nodes, no message rows and no ProgressBar (e1-open-loading.txt); the same open settles to text="This is taking longer than expected. You can close this and check again." + text="Retry" (e1-open-slow.txt); Retry then loads 'Reply with exactly this and nothing else:', 'Preparation complete', 'View image demo' (e1loaded2-scene.log); the 127.0.0.1:1 reply shows 'Image unavailable, retry loading' / 'Image unavailable&#10;demo' / 'Retry' (e1imgfail2-scene.log); older-page scroll keeps anchoring with no dup
/home/igor_kilocode_ai/.local/share/kwf/sections/kwf-fix-proof-9189579-3-ad00/e2e-mobile-app/e1-open-loading.txt
                                          </com.horcrux.svg.SvgView>
                                        </android.widget.Button>
                                      </android.view.ViewGroup>
                                    </android.view.ViewGroup>
                                  </android.view.ViewGroup>
<redacted>
                                </android.view.ViewGroup>
                              </android.view.ViewGroup>
                            </android.widget.ScrollView>
                          </android.view.ViewGroup>
                        </android.view.ViewGroup>
                      </android.view.ViewGroup>
<redacted>
                    </android.view.ViewGroup>
                  </android.view.ViewGroup>
                </android.view.ViewGroup>
              </android.widget.FrameLayout>
            </android.widget.FrameLayout>
          </android.widget.FrameLayout>
        </android.widget.LinearLayout>
      </android.widget.FrameLayout>
    </android.widget.LinearLayout>
  </android.widget.FrameLayout>
</hierarchy>
/home/igor_kilocode_ai/.local/share/kwf/sections/kwf-fix-proof-9189579-3-ad00/e2e-mobile-app/e1-stall3.log
<internal>[99785] for 240s
<internal>
/home/igor_kilocode_ai/.local/share/kwf/sections/kwf-fix-proof-9189579-3-ad00/e2e-mobile-app/e1-open-slow.txt
                                          </com.horcrux.svg.SvgView>
                                        </android.widget.Button>
                                      </android.view.ViewGroup>
                                    </android.view.ViewGroup>
                                  </android.view.ViewGroup>
<redacted>
                                </android.view.ViewGroup>
                              </android.view.ViewGroup>
                            </android.widget.ScrollView>
                          </android.view.ViewGroup>
                        </android.view.ViewGroup>
                      </android.view.ViewGroup>
<redacted>
                    </android.view.ViewGroup>
                  </android.view.ViewGroup>
                </android.view.ViewGroup>
              </android.widget.FrameLayout>
            </android.widget.FrameLayout>
          </android.widget.FrameLayout>
        </android.widget.LinearLayout>
      </android.widget.FrameLayout>
    </android.widget.LinearLayout>
  </android.widget.FrameLayout>
</hierarchy>
/home/igor_kilocode_ai/.local/share/kwf/sections/kwf-fix-proof-9189579-3-ad00/e2e-mobile-app/e1loaded2-scene.log
android.widget.TextView 1% tappable [857,195][894,232]
android.widget.Button Copy link tappable [943,163][1044,264]
android.view.ViewGroup Assistant message tappable [0,305][1080,481]
android.view.ViewGroup html tappable [37,305][1043,472]
android.view.ViewGroup body tappable [37,305][1043,472]
android.widget.Button View image demo tappable [37,305][1043,461]
android.view.ViewGroup Reply with exactly this and nothing else:, User message tappable [0,481][1080,1208]
android.view.ViewGroup html tappable [250,513][1011,1176]
android.view.ViewGroup body tappable [250,513][1011,1176]
android.view.ViewGroup p tappable [250,518][1011,1170]
android.widget.TextView Reply with exactly this and nothing else: tappable [250,518][1012,581]
android.widget.Button Image unavailable, retry loading tappable [250,590][1011,1161]
android.widget.TextView Image unavailable&#10;demo tappable [332,838][845,912]
android.widget.TextView Retry tappable [917,856][983,893]
android.widget.Button Preparation complete tappable [40,1229][1042,1330]
android.widget.TextView Preparation complete tappable [188,1256][506,1302]
android.view.ViewGroup Assistant message tappable [0,1351][1080,2143]
android.view.ViewGroup html tappable [37,1360][1043,2134]
android.view.ViewGroup body tappable [37,1360][1043,2134]
android.widget.Button View image demo tappable [37,1369][1043,2123]
android.widget.Button Add attachment tappable [28,2214][101,2288]
android.widget.EditText Message tappable [126,2191][800,2311]
android.widget.Button Start voice input tappable [835,2205][926,2297]
android.widget.Button Send message [926,2188][1052,2314]
/home/igor_kilocode_ai/.local/share/kwf/sections/kwf-fix-proof-9189579-3-ad00/e2e-mobile-app/e1imgfail2-scene.log
android.widget.TextView 1% tappable [857,195][894,232]
android.widget.Button Copy link tappable [943,163][1044,264]
android.view.ViewGroup Assistant message tappable [0,305][1080,481]
android.view.ViewGroup html tappable [37,305][1043,472]
android.view.ViewGroup body tappable [37,305][1043,472]
android.widget.Button View image demo tappable [37,305][1043,461]
android.view.ViewGroup Reply with exactly this and nothing else:, User message tappable [0,481][1080,1208]
android.view.ViewGroup html tappable [250,513][1011,1176]
android.view.ViewGroup body tappable [250,513][1011,1176]
android.view.ViewGroup p tappable [250,518][1011,1170]
android.widget.TextView Reply with exactly this and nothing else: tappable [250,518][1012,581]
android.widget.Button Image unavailable, retry loading tappable [250,590][1011,1161]
android.widget.TextView Image unavailable&#10;demo tappable [332,838][845,912]
android.widget.TextView Retry tappable [917,856][983,893]
android.widget.Button Preparation complete tappable [40,1229][1042,1330]
android.widget.TextView Preparation complete tappable [188,1256][506,1302]
android.view.ViewGroup Assistant message tappable [0,1351][1080,2143]
android.view.ViewGroup html tappable [37,1360][1043,2134]
android.view.ViewGroup body tappable [37,1360][1043,2134]
android.widget.Button View image demo tappable [37,1369][1043,2123]
android.widget.Button Add attachment tappable [28,2214][101,2288]
android.widget.EditText Message tappable [126,2191][800,2311]
android.widget.Button Start voice input tappable [835,2205][926,2297]
android.widget.Button Send message [926,2188][1052,2314]
/home/igor_kilocode_ai/.local/share/kwf/sections/kwf-fix-proof-9189579-3-ad00/e2e-mobile-app/e1-scrollafter-scene.log
SCENE e1-scrollafter OK
android.widget.LinearLayout com.kilocode.kiloapp:id/action_bar_root tappable [0,0][1080,2400]
android.widget.FrameLayout android:id/content tappable [0,0][1080,2400]
android.widget.Button Go back tappable [0,163][101,265]
android.widget.Button Rename session: 60-message pagination fixture tappable [111,149][627,279]
android.view.View 60-message pagination fixture tappable [111,149][627,279]
android.widget.Button Context 40 of 1,000,000 tokens, 0% used, cost 3 cents. Tap to view context details. tappable [654,156][925,272]
android.widget.TextView 0% tappable [776,195][813,232]
android.widget.TextView $0.03 tappable [822,195][894,232]
android.widget.Button Copy link tappable [943,163][1044,265]
android.view.ViewGroup Assistant message 16 of 60., Padded so fifty messages overflow the chat viewport.&#10;Short one-liners stay on-screen, and the near-top autoload then pulls the older page immedi
android.widget.TextView Padded so fifty messages overflow the chat viewport.&#10;Short one-liners stay on-screen, and the near-top autoload then pulls the older page immediately.&#10;Marker line A for
android.view.ViewGroup User message 17 of 60., Padded so fifty messages overflow the chat viewport.&#10;Short one-liners stay on-screen, and the near-top autoload then pulls the older page immediately
android.widget.TextView User message 17 of 60. tappable [250,906][1011,969]
android.widget.TextView Padded so fifty messages overflow the chat viewport.&#10;Short one-liners stay on-screen, and the near-top autoload then pulls the older page immediately.&#10;Marker line A for
android.view.ViewGroup Assistant message 18 of 60., Padded so fifty messages overflow the chat viewport.&#10;Short one-liners stay on-screen, and the near-top autoload then pulls the older page immedi
/home/igor_kilocode_ai/.local/share/kwf/sections/kwf-fix-proof-9189579-3-ad00/e2e-mobile-app/e1-scrolloldest-scene.log
SCENE e1-scrolloldest OK
android.widget.LinearLayout com.kilocode.kiloapp:id/action_bar_root tappable [0,0][1080,2400]
android.widget.FrameLayout android:id/content tappable [0,0][1080,2400]
android.widget.Button Go back tappable [0,163][101,265]
android.widget.Button Rename session: 60-message pagination fixture tappable [111,149][627,279]
android.view.View 60-message pagination fixture tappable [111,149][627,279]
android.widget.Button Context 40 of 1,000,000 tokens, 0% used, cost 3 cents. Tap to view context details. tappable [654,156][925,272]
android.widget.TextView 0% tappable [776,195][813,232]
android.widget.TextView $0.03 tappable [822,195][894,232]
android.widget.Button Copy link tappable [943,163][1044,265]
android.widget.TextView NOV 16, 2023, 2:00 AM tappable [336,346][744,385]
android.view.ViewGroup User message 1 of 60., Padded so fifty messages overflow the chat viewport.&#10;Short one-liners stay on-screen, and the near-top autoload then pulls the older page immediately.
android.widget.TextView User message 1 of 60. tappable [250,441][1011,504]
android.widget.TextView Padded so fifty messages overflow the chat viewport.&#10;Short one-liners stay on-screen, and the near-top autoload then pulls the older page immediately.&#10;Marker line A for
android.view.ViewGroup Assistant message 2 of 60., Padded so fifty messages overflow the chat viewport.&#10;Short one-liners stay on-screen, and the near-top autoload then pulls the older page immedia
android.widget.TextView Assistant message 2 of 60. tappable [37,1385][1045,1448]
android.widget.TextView Padded so fifty messages overflow the chat viewport.&#10;Short one-liners stay on-screen, and the near-top autoload then pulls the older page immediately.&#10;Marker line A for
/home/igor_kilocode_ai/.local/share/kwf/sections/kwf-fix-proof-9189579-3-ad00/e2e-mobile-app/e1-cheap-model.log
kilo/deepseek/deepseek-v4-flash-0731:free
/home/igor_kilocode_ai/.local/share/kwf/sections/kwf-fix-proof-9189579-3-ad00/e2e-mobile-app/e1-cloud-enter.log
WAIT OK services cloud-agent-next 2s
WAIT OK services nextjs 1s
session.sh: cloud ses_f44d99d5effe0GjtkER4XrklsC repo=iscekic/panon-deking
session.sh: link delivered on emulator-5554
hierarchy: /tmp/kilo-e2e-attach.i7ggns (219 elements)
{"op":"cloud-enter","result":"ok","sid":"ses_f44d99d5effe0GjtkER4XrklsC","device":"emulator-5554","stages":"create,enter,attach"}
## Open findings (not fixed here) - [e11] condensed older-page prepend: needs:seed:deep-link into a session titled 'Condensed history' with 'Condense tool calls' enabled in General settings and a long tool-heavy transcript whose page boundary splits a tool run; scrolling to the start loads the older page and the viewport holds its pos - [e11] $KILO_WORKFLOW/e2e/appium.sh script /home/igor_kilocode_ai/.local/share/kwf/sections/req-20260918-133438-a545/e2e-mobile-app/repro-e11.json --out /home/igor_kilocode_ai/.local/share/kwf/sections/req-20260918-133438-a545/e2e-mobile-app/repro-e11 - [e11] spot check: no verdict: spot: no verdict — the frame got no usable verdict after one solo re-judge (evidence: /home/igor_kilocode_ai/.local/share/kwf/sections/req-20260918-133438-a545/e2e-mobile-app/e11-state.png) - not fully verified: some optional checks did not run - the '## E2E proof' section is empty

e1-image-loaded

e1-image-failure

e1-image-loaded

e1-image-failure

e1-image-loaded

e1-image-failure

e1-open-loading-skeleton

e1-usage

e1-open-slow-state

e1-open-loading

@iscekic
iscekic marked this pull request as draft September 19, 2026 06:26
Comment thread apps/mobile/src/components/agents/session-detail-content.tsx
Comment thread apps/mobile/src/components/agents/session-message-list.tsx Outdated
@kilo-code-bot

kilo-code-bot Bot commented Sep 19, 2026

Copy link
Copy Markdown
Contributor

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Executive Summary

The incremental delta resolves the carried-key duplicate, the marker-wrapper remount, and the unused userId option, and adds regression tests; the rewritten key-reuse logic is collision-safe on inspection.

Files Reviewed (10 files)
  • apps/mobile/src/components/agents/mobile-session-manager.ts
  • apps/mobile/src/components/agents/session-detail-content.test.ts
  • apps/mobile/src/components/agents/session-detail-content.tsx
  • apps/mobile/src/components/agents/session-detail-queue.test.ts
  • apps/mobile/src/components/agents/session-provider.test.tsx
  • apps/mobile/src/components/agents/session-provider.tsx
  • apps/mobile/src/components/agents/session-transcript.test.ts
  • apps/mobile/src/components/agents/session-transcript.ts
  • apps/mobile/src/lib/glanceable/approve-front-agent.ts
  • dev/seed/app/paged-history.ts
Previous Review Summaries (2 snapshots, latest commit 99beb74)

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

Previous review (commit 99beb74)

Status: 3 Issues Found | Recommendation: Address before merge

Overview

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

WARNING

File Line Issue
apps/mobile/src/components/agents/session-transcript.ts 347 Carried-key reuse can emit two rows with the same key, when a run adopts a message id that the message later re-emits and a later item re-adds it

SUGGESTION

File Line Issue
apps/mobile/src/components/agents/session-detail-content.tsx 1346 The marker wrapper changes the row root element type, remounting the boundary row subtree on the prepend path this change stabilizes
apps/mobile/src/components/agents/mobile-session-manager.ts 171 userId is now a required-but-unused option; the rewritten comment claims it still scopes construction
Files Reviewed (15 files)
  • apps/mobile/src/components/agents/mobile-session-manager.ts - 1 suggestion
  • apps/mobile/src/components/agents/mobile-session-manager.test.ts - no new issues
  • apps/mobile/src/components/agents/session-detail-content.tsx - 1 suggestion
  • apps/mobile/src/components/agents/session-detail-content.test.ts - no new issues
  • apps/mobile/src/components/agents/session-detail-queue.test.ts - no new issues
  • apps/mobile/src/components/agents/session-message-list.tsx - no new issues
  • apps/mobile/src/components/agents/session-message-list.mounted.test.tsx - no new issues
  • apps/mobile/src/components/agents/session-transcript.ts - 1 warning
  • apps/mobile/src/components/agents/session-transcript.test.ts - no new issues
  • apps/mobile/src/components/agents/use-session-auto-scroll-state.ts - no new issues
  • apps/mobile/src/components/agents/use-session-auto-scroll-state.test.ts - no new issues
  • apps/mobile/src/components/agents/use-session-list-auto-scroll.ts - no new issues
  • apps/mobile/src/lib/persist/session-transcript-cache.ts (deleted) - no new issues
  • apps/mobile/src/lib/persist/session-transcript-cache.test.ts (deleted) - no new issues
  • dev/seed/app/condensed-history.ts - no new issues

Fix these issues in Kilo Cloud

Previous review (commit 0698e3d)

Status: 2 Issues Found | Recommendation: Address before merge

Overview

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

WARNING

File Line Issue
apps/mobile/src/components/agents/session-detail-content.tsx 896 Carried part→key map is collected on every transcript change even when condensing is off, allocating an unused O(parts) map per streaming update

SUGGESTION

File Line Issue
apps/mobile/src/components/agents/session-message-list.tsx 246 The new listHeaderComponent memo is defeated by the inline onLoadOlderMessages prop, so the header element is still recreated on every streaming render
Files Reviewed (15 files)
  • apps/mobile/src/components/agents/mobile-session-manager.ts - no new issues
  • apps/mobile/src/components/agents/mobile-session-manager.test.ts - no new issues
  • apps/mobile/src/components/agents/session-detail-content.tsx - 1 warning
  • apps/mobile/src/components/agents/session-detail-content.test.ts - no new issues
  • apps/mobile/src/components/agents/session-detail-queue.test.ts - no new issues
  • apps/mobile/src/components/agents/session-message-list.tsx - 1 suggestion
  • apps/mobile/src/components/agents/session-message-list.mounted.test.tsx - no new issues
  • apps/mobile/src/components/agents/session-transcript.ts - no new issues
  • apps/mobile/src/components/agents/session-transcript.test.ts - no new issues
  • apps/mobile/src/components/agents/use-session-auto-scroll-state.ts - no new issues
  • apps/mobile/src/components/agents/use-session-auto-scroll-state.test.ts - no new issues
  • apps/mobile/src/components/agents/use-session-list-auto-scroll.ts - no new issues
  • apps/mobile/src/lib/persist/session-transcript-cache.ts (deleted) - no new issues
  • apps/mobile/src/lib/persist/session-transcript-cache.test.ts (deleted) - no new issues
  • dev/seed/app/condensed-history.ts - no new issues

Fix these issues in Kilo Cloud


Reviewed by deepseek-v4.1-flash · Input: 0 · Output: 0 · Cached: 0

Review guidance: REVIEW.md from base branch main

iscekic added a commit that referenced this pull request Sep 19, 2026
@iscekic
iscekic force-pushed the kwf/req-20260918-133438-a545 branch from 4e301d8 to 99beb74 Compare September 19, 2026 08:38
@iscekic
iscekic marked this pull request as ready for review September 19, 2026 08:58
Comment thread apps/mobile/src/components/agents/session-transcript.ts Outdated
Comment thread apps/mobile/src/components/agents/session-detail-content.tsx Outdated
Comment thread apps/mobile/src/components/agents/mobile-session-manager.ts Outdated
@iscekic
iscekic marked this pull request as draft September 19, 2026 09:19
iscekic added a commit that referenced this pull request Sep 19, 2026
@iscekic
iscekic force-pushed the kwf/req-20260918-133438-a545 branch from 99beb74 to 9189579 Compare September 19, 2026 11:39
@iscekic
iscekic marked this pull request as ready for review September 19, 2026 11:48
@iscekic iscekic added the human-ready The PR is ready for human review. label Sep 19, 2026
@iscekic iscekic self-assigned this Sep 19, 2026
@iscekic
iscekic force-pushed the kwf/req-20260918-133438-a545 branch from 9189579 to 602302b Compare September 20, 2026 18:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

human-ready The PR is ready for human review.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant