summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAdam <[email protected]>2026-02-27 09:40:04 -0600
committerAdam <[email protected]>2026-02-27 09:47:56 -0600
commita94f564ff00cc16cc22503c29fa093d99844ae1a (patch)
tree0c73f71f240924735eb52258c4a8d2c6eb7736e4
parent6ef3af73dfa1c72bb2001c86d898f2edf8ea4b10 (diff)
downloadopencode-a94f564ff00cc16cc22503c29fa093d99844ae1a.tar.gz
opencode-a94f564ff00cc16cc22503c29fa093d99844ae1a.zip
fix(app): scroll issues
-rw-r--r--packages/app/src/pages/session/review-tab.tsx30
1 files changed, 24 insertions, 6 deletions
diff --git a/packages/app/src/pages/session/review-tab.tsx b/packages/app/src/pages/session/review-tab.tsx
index 7f90ff5ac..1b285407b 100644
--- a/packages/app/src/pages/session/review-tab.tsx
+++ b/packages/app/src/pages/session/review-tab.tsx
@@ -49,6 +49,7 @@ export function SessionReviewTab(props: SessionReviewTabProps) {
let scroll: HTMLDivElement | undefined
let restoreFrame: number | undefined
let userInteracted = false
+ let restored: { x: number; y: number } | undefined
const sdk = useSDK()
const layout = useLayout()
@@ -65,6 +66,11 @@ export function SessionReviewTab(props: SessionReviewTabProps) {
const handleInteraction = () => {
userInteracted = true
+
+ if (restoreFrame !== undefined) {
+ cancelAnimationFrame(restoreFrame)
+ restoreFrame = undefined
+ }
}
const doRestore = () => {
@@ -82,8 +88,11 @@ export function SessionReviewTab(props: SessionReviewTabProps) {
const targetY = Math.min(s.y, maxY)
const targetX = Math.min(s.x, maxX)
+ if (el.scrollTop === targetY && el.scrollLeft === targetX) return
+
if (el.scrollTop !== targetY) el.scrollTop = targetY
if (el.scrollLeft !== targetX) el.scrollLeft = targetX
+ restored = { x: el.scrollLeft, y: el.scrollTop }
}
const queueRestore = () => {
@@ -92,9 +101,16 @@ export function SessionReviewTab(props: SessionReviewTabProps) {
}
const handleScroll = (event: Event & { currentTarget: HTMLDivElement }) => {
- if (!layout.ready() || !userInteracted) return
-
const el = event.currentTarget
+ const prev = restored
+ if (prev && el.scrollTop === prev.y && el.scrollLeft === prev.x) {
+ restored = undefined
+ return
+ }
+
+ restored = undefined
+ handleInteraction()
+ if (!layout.ready()) return
if (el.clientHeight === 0 || el.clientWidth === 0) return
props.view().setScroll("review", {
@@ -133,10 +149,11 @@ export function SessionReviewTab(props: SessionReviewTabProps) {
onCleanup(() => {
if (restoreFrame !== undefined) cancelAnimationFrame(restoreFrame)
if (scroll) {
- scroll.removeEventListener("wheel", handleInteraction)
- scroll.removeEventListener("pointerdown", handleInteraction)
- scroll.removeEventListener("touchstart", handleInteraction)
- scroll.removeEventListener("keydown", handleInteraction)
+ scroll.removeEventListener("wheel", handleInteraction, { capture: true })
+ scroll.removeEventListener("mousewheel", handleInteraction, { capture: true })
+ scroll.removeEventListener("pointerdown", handleInteraction, { capture: true })
+ scroll.removeEventListener("touchstart", handleInteraction, { capture: true })
+ scroll.removeEventListener("keydown", handleInteraction, { capture: true })
}
})
@@ -147,6 +164,7 @@ export function SessionReviewTab(props: SessionReviewTabProps) {
scrollRef={(el) => {
scroll = el
el.addEventListener("wheel", handleInteraction, { passive: true, capture: true })
+ el.addEventListener("mousewheel", handleInteraction, { passive: true, capture: true })
el.addEventListener("pointerdown", handleInteraction, { passive: true, capture: true })
el.addEventListener("touchstart", handleInteraction, { passive: true, capture: true })
el.addEventListener("keydown", handleInteraction, { passive: true, capture: true })