Title: Add a "jump to latest" (scroll-to-bottom) button to the chat transcript · Issue #46 · modelstudioai/openwork · GitHub
Open Graph Title: Add a "jump to latest" (scroll-to-bottom) button to the chat transcript · Issue #46 · modelstudioai/openwork
X Title: Add a "jump to latest" (scroll-to-bottom) button to the chat transcript · Issue #46 · modelstudioai/openwork
Description: Problem or Motivation Every comparable AI desktop chat surface — Claude Code Desktop, ChatGPT desktop, Codex desktop — shows a floating "jump to latest" / scroll-to-bottom affordance when you scroll up through a long conversation, so you...
Open Graph Description: Problem or Motivation Every comparable AI desktop chat surface — Claude Code Desktop, ChatGPT desktop, Codex desktop — shows a floating "jump to latest" / scroll-to-bottom affordance when you scrol...
X Description: Problem or Motivation Every comparable AI desktop chat surface — Claude Code Desktop, ChatGPT desktop, Codex desktop — shows a floating "jump to latest" / scroll-to-bottom affordance when...
Opengraph URL: https://github.com/modelstudioai/openwork/issues/46
X: @github
Domain: github.com
{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"Add a \"jump to latest\" (scroll-to-bottom) button to the chat transcript","articleBody":"## Problem or Motivation\n\nEvery comparable AI desktop chat surface — Claude Code Desktop, ChatGPT desktop, Codex desktop — shows a floating **\"jump to latest\" / scroll-to-bottom** affordance when you scroll up through a long conversation, so you can return to the newest message in one click. OpenWork has no such control.\n\nToday OpenWork's transcript (`ChatDisplay`) already tracks scroll position for sticky-bottom auto-scroll (`handleScroll` computes `distanceFromBottom`, un-sticks when you scroll up, re-sticks at the bottom), but there is **no visible way to jump back to the latest message**: once you scroll up to read history you must manually drag all the way back down, and during active streaming that means fighting the growing content. The state needed to drive the button already exists — only the UI was missing.\n\n## Proposed Solution\n\nRender a small floating circular button (a down-chevron) centered near the bottom of the transcript, shown **only when the user has scrolled well away from the bottom** (200px hysteresis so it doesn't flicker near the end). Clicking it:\n\n- re-enables sticky-bottom auto-scroll (`isStickToBottomRef = true`),\n- smooth-scrolls the transcript to the latest message,\n- hides itself again once back at the bottom.\n\nIt fades in/out with the existing `motion`/`AnimatePresence` primitives already used throughout `ChatDisplay`, and hides on session switch.\n\n**Frontend-only.** No backend / qwen-code change. The button reads/derives from existing renderer scroll state (`scrollViewportRef`, `distanceFromBottom`, `messagesEndRef.scrollIntoView`). One new i18n key `chat.scrollToBottom` (accessible label / tooltip) is added to all six locales.\n\n## Feasibility\n\n- **Classification: pure frontend — candidate.** The scroll geometry, the sticky-bottom ref, and the scroll anchor all already live in `apps/electron/src/renderer/components/app-shell/ChatDisplay.tsx`. Adding a button that flips visibility on `distanceFromBottom` and calls `scrollIntoView` requires no main-process or backend involvement.\n- Confirmed genuinely missing: the `ChevronDown` import in `ChatDisplay` is used only for a details expander, not for scrolling; there is no floating jump control anywhere in the transcript.\n\n## Acceptance Criteria (what the CDP assertion checks)\n\nA new e2e CDP assertion (`e2e/assertions/scroll-to-bottom.assert.ts`) drives the real built app end-to-end:\n\n1. **Seeds** a 40-message session on disk (backend-independent — a plain `session.jsonl` under the isolated profile) and opens it from the sidebar.\n2. The transcript renders and **overflows** the viewport (proof the real conversation loaded).\n3. On open the transcript is at the bottom and the button is **hidden**.\n4. Scrolling to the top makes the button **appear**.\n5. Clicking the button returns the transcript to the bottom (`distanceFromBottom \u003c 40`) and the button **disappears**.\n\nThis required a small, reusable harness addition: an optional `seed(profileDirs)` hook (`e2e/app.ts` + `e2e/runner.ts`) that lets an assertion pre-seed on-disk session state before the app launches — unblocking this and future transcript-dependent assertions.\n\nPart of the autonomous desktop-feature loop (`loop-bot`).","author":{"url":"https://github.com/DragonnZhang","@type":"Person","name":"DragonnZhang"},"datePublished":"2026-07-02T13:41:25.000Z","interactionStatistic":{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":0},"url":"https://github.com/46/openwork/issues/46"}
| route-pattern | /_view_fragments/issues/show/:user_id/:repository/:id/issue_layout(.:format) |
| route-controller | voltron_issues_fragments |
| route-action | issue_layout |
| fetch-nonce | v2:a02b7c3e-da41-c52f-9f03-a44d2df8e260 |
| current-catalog-service-hash | 81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114 |
| request-id | C46C:1ECA58:567373:740530:6A529AB1 |
| html-safe-nonce | d4bdaed6aa23bd8f1bbfb792ace916f9a1e2e67d81b5ea7b91c4d5f0e75b3d33 |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJDNDZDOjFFQ0E1ODo1NjczNzM6NzQwNTMwOjZBNTI5QUIxIiwidmlzaXRvcl9pZCI6IjIzNDI4NDcwMzkzNDQ4NzIxNyIsInJlZ2lvbl9lZGdlIjoiaWFkIiwicmVnaW9uX3JlbmRlciI6ImlhZCJ9 |
| visitor-hmac | 4d9f810c3c0efa032445dd6f63001c5bba439aff730de2a8855002d4c3f293cb |
| hovercard-subject-tag | issue:4794968690 |
| github-keyboard-shortcuts | repository,issues,copilot |
| google-site-verification | Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I |
| octolytics-url | https://collector.github.com/github/collect |
| analytics-location | / |
| fb:app_id | 1401488693436528 |
| apple-itunes-app | app-id=1477376905, app-argument=https://github.com/_view_fragments/issues/show/modelstudioai/openwork/46/issue_layout |
| twitter:image | https://opengraph.githubassets.com/dbb3b77b54995e7c1c81951f614a6853c6d95ba5e5a258df7b318b44b2f6759a/modelstudioai/openwork/issues/46 |
| twitter:card | summary_large_image |
| og:image | https://opengraph.githubassets.com/dbb3b77b54995e7c1c81951f614a6853c6d95ba5e5a258df7b318b44b2f6759a/modelstudioai/openwork/issues/46 |
| og:image:alt | Problem or Motivation Every comparable AI desktop chat surface — Claude Code Desktop, ChatGPT desktop, Codex desktop — shows a floating "jump to latest" / scroll-to-bottom affordance when you scrol... |
| og:image:width | 1200 |
| og:image:height | 600 |
| og:site_name | GitHub |
| og:type | object |
| og:author:username | DragonnZhang |
| hostname | github.com |
| expected-hostname | github.com |
| None | b9a586c06a05a7a86fc7e3f4dbd03e42f6869085879aa184aa6369456dbd50fb |
| turbo-cache-control | no-preview |
| go-import | github.com/modelstudioai/openwork git https://github.com/modelstudioai/openwork.git |
| octolytics-dimension-user_id | 283556804 |
| octolytics-dimension-user_login | modelstudioai |
| octolytics-dimension-repository_id | 1256697754 |
| octolytics-dimension-repository_nwo | modelstudioai/openwork |
| octolytics-dimension-repository_public | true |
| octolytics-dimension-repository_is_fork | false |
| octolytics-dimension-repository_network_root_id | 1256697754 |
| octolytics-dimension-repository_network_root_nwo | modelstudioai/openwork |
| turbo-body-classes | logged-out env-production page-responsive |
| disable-turbo | false |
| browser-stats-url | https://api.github.com/_private/browser/stats |
| browser-errors-url | https://api.github.com/_private/browser/errors |
| release | 07a982c1d40157c619b364352b704c3ce66bb332 |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width