summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAdam <[email protected]>2026-01-04 04:53:55 -0600
committerAdam <[email protected]>2026-01-04 04:53:55 -0600
commit177b01a8531c0918323f4b02984f1def304a74b2 (patch)
treec21719e6cff5647a4ee0af86d62a2c7b191c13b7
parentc9f907caecad1cc1cc5434c6636281571778d250 (diff)
downloadopencode-177b01a8531c0918323f4b02984f1def304a74b2.tar.gz
opencode-177b01a8531c0918323f4b02984f1def304a74b2.zip
fix(app): scroll position restoration
-rw-r--r--packages/app/src/components/session/session-context-tab.tsx8
-rw-r--r--packages/app/src/pages/session.tsx27
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)