Skip to content

feat(assistant): keep reading position with jump-to-latest - #314

Open
gac0812 wants to merge 5 commits into
1024XEngineer:mainfrom
gac0812:feat/continuous-voice-focus
Open

feat(assistant): keep reading position with jump-to-latest#314
gac0812 wants to merge 5 commits into
1024XEngineer:mainfrom
gac0812:feat/continuous-voice-focus

Conversation

@gac0812

@gac0812 gac0812 commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Summary

Closes #313

Test plan

  • 免提多聊几轮,对白超出一屏后可以上滑看到更早的用户句和助手句
  • 停在较上面时,助手还在说话或新一句追加,滚动位置保持,不被拉回底部
  • 此时出现「查看最新」,可看到最新一句摘要;点击后跳到最新,入口消失
  • 滑回底部附近后,入口不再出现,新内容再次自动贴底
  • 只有一两句、一屏装得下时,气泡仍靠在声纹球上方

Verification

cd frontend
npx jest --runInBand tests/unit/features/assistant/presentation/usePinnedTranscriptScroll.test.ts tests/unit/features/assistant/presentation/VoiceCallScreen.test.tsx

本地结果:Test Suites: 2 passedTests: 42 passed

覆盖要点:

  • contentFitsViewport / isPinnedToBottom:未测量视口、刚好一屏、越过 80px 阈值
  • 上滑阅读时不 scrollToEnd,并标记未读最新;jumpToLatest 后贴回底部
  • 自己滑回底部会清掉「查看最新」
  • iOS / Android:拖动中不跟随,停在底部后恢复贴底;上滑后出新内容出现「查看最新」,点击后消失

设计对照

对比图待用户提供。请发改前/改后各一张(上滑看历史时出现「查看最新」、以及点了之后回到最新),再挂到本 PR 附件。

Replace the status-list hands-free screen with a GPT Voice-style layout: chat bubbles above a voiceprint orb, and keep the current call readable while scrolling up.
Keep the live transcript still during a scroll gesture, then snap back to the latest message when the user stops interacting.
Leave follow-latest / jump-to-latest scroll behavior for a separate change so this PR only ships the bubble layout.
Leave the transcript still while scrolling up, and show a jump-to-latest chip so new turns stay reachable.
@codecov

codecov Bot commented Aug 20, 2026

Copy link
Copy Markdown

@fennoai fennoai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

审查了连续对话消息模型、钉底滚动状态机、全屏通话页及入口集成。整体的离底后保留阅读位置与“查看最新”路径清晰,但 Web 的空闲判定没有做防抖,会在仍在滚动时提前恢复自动贴底。

本地 git diff --check 通过;工作区未提供可执行的前端依赖,因此未能运行 Jest/typecheck。

View job run

Comment thread frontend/src/features/assistant/presentation/usePinnedTranscriptScroll.ts Outdated
@gac0812
gac0812 marked this pull request as draft August 20, 2026 04:17
Native drag and momentum handlers already debounce follow-latest; the extra web onScroll timer is out of scope for the mobile change.
@gac0812
gac0812 marked this pull request as ready for review August 20, 2026 09:24

@fennoai fennoai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed the fixed range from 612955df0cd65f54006952918c98159a609a4799 to 05423188b7eaa99521c0826a692280c9a7a186bf, covering the continuous conversation message flow, mobile transcript pinning, jump-to-latest behavior, and the new voice-call UI. The message/rendering contracts are coherent overall, but the scroll state has a race that can leave users without the promised latest-message entry.

Verification: git diff --check passes. The requested Jest suites could not run because frontend/node_modules is absent and the configured jest-expo preset is unavailable in the mounted workspace.

const atBottom = isPinnedToBottom({
contentHeight: contentSize.height,
offsetY: contentOffset.y,
viewportHeight: layoutMeasurement.height,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P2] Mark latest content unseen during an active drag

When a user begins dragging while still at the bottom, interactingRef.current becomes true but followingRef.current remains true until the first scroll event moves past the threshold. If a new transcript message arrives during that drag, this branch returns without setting hasUnseenLatest; after the user then scrolls upward, no later content-size event may occur, so the promised “查看最新” chip never appears even though newer content is now off-screen. Treat an active drag that subsequently leaves the bottom as unread content, or defer/re-evaluate the content update when the drag’s scroll position is known.

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.

feat(ui): 长对话回看时保持阅读位置

1 participant