diff options
| author | Adam <[email protected]> | 2026-01-04 04:53:55 -0600 |
|---|---|---|
| committer | Adam <[email protected]> | 2026-01-04 04:53:55 -0600 |
| commit | 177b01a8531c0918323f4b02984f1def304a74b2 (patch) | |
| tree | c21719e6cff5647a4ee0af86d62a2c7b191c13b7 | |
| parent | c9f907caecad1cc1cc5434c6636281571778d250 (diff) | |
| download | opencode-177b01a8531c0918323f4b02984f1def304a74b2.tar.gz opencode-177b01a8531c0918323f4b02984f1def304a74b2.zip | |
fix(app): scroll position restoration
| -rw-r--r-- | packages/app/src/components/session/session-context-tab.tsx | 8 | ||||
| -rw-r--r-- | packages/app/src/pages/session.tsx | 27 |
2 files changed, 32 insertions, 3 deletions
diff --git a/packages/app/src/components/session/session-context-tab.tsx b/packages/app/src/components/session/session-context-tab.tsx index b157eb228..a975f9fa5 100644 --- a/packages/app/src/components/session/session-context-tab.tsx +++ b/packages/app/src/components/session/session-context-tab.tsx @@ -305,13 +305,19 @@ export function SessionContextTab(props: SessionContextTabProps) { let frame: number | undefined let pending: { x: number; y: number } | undefined - const restoreScroll = () => { + const restoreScroll = (retries = 0) => { const el = scroll if (!el) return const s = props.view()?.scroll("context") if (!s) return + // Wait for content to be scrollable - content may not have rendered yet + if (el.scrollHeight <= el.clientHeight && retries < 10) { + requestAnimationFrame(() => restoreScroll(retries + 1)) + return + } + if (el.scrollTop !== s.y) el.scrollTop = s.y if (el.scrollLeft !== s.x) el.scrollLeft = s.x } diff --git a/packages/app/src/pages/session.tsx b/packages/app/src/pages/session.tsx index 221831605..4011ea890 100644 --- a/packages/app/src/pages/session.tsx +++ b/packages/app/src/pages/session.tsx @@ -74,13 +74,19 @@ function SessionReviewTab(props: SessionReviewTabProps) { let frame: number | undefined let pending: { x: number; y: number } | undefined - const restoreScroll = () => { + const restoreScroll = (retries = 0) => { const el = scroll if (!el) return const s = props.view().scroll("review") if (!s) return + // Wait for content to be scrollable - content may not have rendered yet + if (el.scrollHeight <= el.clientHeight && retries < 10) { + requestAnimationFrame(() => restoreScroll(retries + 1)) + return + } + if (el.scrollTop !== s.y) el.scrollTop = s.y if (el.scrollLeft !== s.x) el.scrollLeft = s.x } @@ -1031,13 +1037,19 @@ export default function Page() { return `L${sel.startLine}-${sel.endLine}` }) - const restoreScroll = () => { + const restoreScroll = (retries = 0) => { const el = scroll if (!el) return const s = view()?.scroll(tab) if (!s) return + // Wait for content to be scrollable - content may not have rendered yet + if (el.scrollHeight <= el.clientHeight && retries < 10) { + requestAnimationFrame(() => restoreScroll(retries + 1)) + return + } + if (el.scrollTop !== s.y) el.scrollTop = s.y if (el.scrollLeft !== s.x) el.scrollLeft = s.x } @@ -1082,6 +1094,17 @@ export default function Page() { ), ) + createEffect( + on( + () => tabs().active() === tab, + (active) => { + if (!active) return + if (!state()?.loaded) return + requestAnimationFrame(restoreScroll) + }, + ), + ) + onCleanup(() => { if (scrollFrame === undefined) return cancelAnimationFrame(scrollFrame) |
