Просмотр исходного кода

fix(app): scroll position restoration

Adam 3 месяцев назад
Родитель
Сommit
177b01a853

+ 7 - 1
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
   }

+ 25 - 2
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)