fix(app): scroll jacking
This commit is contained in:
@@ -16,7 +16,18 @@ import { useFileComponent } from "../context/file"
|
|||||||
import { useI18n } from "../context/i18n"
|
import { useI18n } from "../context/i18n"
|
||||||
import { getDirectory, getFilename } from "@opencode-ai/util/path"
|
import { getDirectory, getFilename } from "@opencode-ai/util/path"
|
||||||
import { checksum } from "@opencode-ai/util/encode"
|
import { checksum } from "@opencode-ai/util/encode"
|
||||||
import { createEffect, createMemo, createSignal, For, Match, onCleanup, Show, Switch, type JSX } from "solid-js"
|
import {
|
||||||
|
createEffect,
|
||||||
|
createMemo,
|
||||||
|
createSignal,
|
||||||
|
For,
|
||||||
|
Match,
|
||||||
|
onCleanup,
|
||||||
|
Show,
|
||||||
|
Switch,
|
||||||
|
untrack,
|
||||||
|
type JSX,
|
||||||
|
} from "solid-js"
|
||||||
import { createStore } from "solid-js/store"
|
import { createStore } from "solid-js/store"
|
||||||
import { type FileContent, type FileDiff } from "@opencode-ai/sdk/v2"
|
import { type FileContent, type FileDiff } from "@opencode-ai/sdk/v2"
|
||||||
import { PreloadMultiFileDiffResult } from "@pierre/diffs/ssr"
|
import { PreloadMultiFileDiffResult } from "@pierre/diffs/ssr"
|
||||||
@@ -442,50 +453,52 @@ export const SessionReview = (props: SessionReviewProps) => {
|
|||||||
const focus = props.focusedComment
|
const focus = props.focusedComment
|
||||||
if (!focus) return
|
if (!focus) return
|
||||||
|
|
||||||
focusToken++
|
untrack(() => {
|
||||||
const token = focusToken
|
focusToken++
|
||||||
|
const token = focusToken
|
||||||
|
|
||||||
setOpened(focus)
|
setOpened(focus)
|
||||||
|
|
||||||
const comment = (props.comments ?? []).find((c) => c.file === focus.file && c.id === focus.id)
|
const comment = (props.comments ?? []).find((c) => c.file === focus.file && c.id === focus.id)
|
||||||
if (comment) setSelection({ file: comment.file, range: cloneSelectedLineRange(comment.selection) })
|
if (comment) setSelection({ file: comment.file, range: cloneSelectedLineRange(comment.selection) })
|
||||||
|
|
||||||
const current = open()
|
const current = open()
|
||||||
if (!current.includes(focus.file)) {
|
if (!current.includes(focus.file)) {
|
||||||
handleChange([...current, focus.file])
|
handleChange([...current, focus.file])
|
||||||
}
|
|
||||||
|
|
||||||
const scrollTo = (attempt: number) => {
|
|
||||||
if (token !== focusToken) return
|
|
||||||
|
|
||||||
const root = scroll
|
|
||||||
if (!root) return
|
|
||||||
|
|
||||||
const wrapper = anchors.get(focus.file)
|
|
||||||
const anchor = wrapper?.querySelector(`[data-comment-id="${focus.id}"]`)
|
|
||||||
const ready = anchor instanceof HTMLElement
|
|
||||||
|
|
||||||
const target = ready ? anchor : wrapper
|
|
||||||
if (!target) {
|
|
||||||
if (attempt >= 120) return
|
|
||||||
requestAnimationFrame(() => scrollTo(attempt + 1))
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const rootRect = root.getBoundingClientRect()
|
const scrollTo = (attempt: number) => {
|
||||||
const targetRect = target.getBoundingClientRect()
|
if (token !== focusToken) return
|
||||||
const offset = targetRect.top - rootRect.top
|
|
||||||
const next = root.scrollTop + offset - rootRect.height / 2 + targetRect.height / 2
|
|
||||||
root.scrollTop = Math.max(0, next)
|
|
||||||
|
|
||||||
if (ready) return
|
const root = scroll
|
||||||
if (attempt >= 120) return
|
if (!root) return
|
||||||
requestAnimationFrame(() => scrollTo(attempt + 1))
|
|
||||||
}
|
|
||||||
|
|
||||||
requestAnimationFrame(() => scrollTo(0))
|
const wrapper = anchors.get(focus.file)
|
||||||
|
const anchor = wrapper?.querySelector(`[data-comment-id="${focus.id}"]`)
|
||||||
|
const ready = anchor instanceof HTMLElement
|
||||||
|
|
||||||
requestAnimationFrame(() => props.onFocusedCommentChange?.(null))
|
const target = ready ? anchor : wrapper
|
||||||
|
if (!target) {
|
||||||
|
if (attempt >= 120) return
|
||||||
|
requestAnimationFrame(() => scrollTo(attempt + 1))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const rootRect = root.getBoundingClientRect()
|
||||||
|
const targetRect = target.getBoundingClientRect()
|
||||||
|
const offset = targetRect.top - rootRect.top
|
||||||
|
const next = root.scrollTop + offset - rootRect.height / 2 + targetRect.height / 2
|
||||||
|
root.scrollTop = Math.max(0, next)
|
||||||
|
|
||||||
|
if (ready) return
|
||||||
|
if (attempt >= 120) return
|
||||||
|
requestAnimationFrame(() => scrollTo(attempt + 1))
|
||||||
|
}
|
||||||
|
|
||||||
|
requestAnimationFrame(() => scrollTo(0))
|
||||||
|
|
||||||
|
requestAnimationFrame(() => props.onFocusedCommentChange?.(null))
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
const handleReviewKeyDown = (event: KeyboardEvent) => {
|
const handleReviewKeyDown = (event: KeyboardEvent) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user