summaryrefslogtreecommitdiffhomepage
path: root/packages/app/src
diff options
context:
space:
mode:
authoradamelmore <[email protected]>2026-01-25 07:58:24 -0600
committeradamelmore <[email protected]>2026-01-25 10:30:10 -0600
commit2b07291e17856a2b014537542f79cc8c059487c9 (patch)
tree8fdcc4be0692245c634dc0c8f61ef8bc4a8fa169 /packages/app/src
parentd25120680dea60b4231f12b266dc733089f3e181 (diff)
downloadopencode-2b07291e17856a2b014537542f79cc8c059487c9.tar.gz
opencode-2b07291e17856a2b014537542f79cc8c059487c9.zip
fix(app): scroll to comment on click
Diffstat (limited to 'packages/app/src')
-rw-r--r--packages/app/src/components/prompt-input.tsx7
-rw-r--r--packages/app/src/pages/session.tsx42
2 files changed, 47 insertions, 2 deletions
diff --git a/packages/app/src/components/prompt-input.tsx b/packages/app/src/components/prompt-input.tsx
index ccff04efe..5ec0eb1ea 100644
--- a/packages/app/src/components/prompt-input.tsx
+++ b/packages/app/src/components/prompt-input.tsx
@@ -185,23 +185,26 @@ export const PromptInput: Component<PromptInputProps> = (props) => {
const openComment = (item: { path: string; commentID?: string; commentOrigin?: "review" | "file" }) => {
if (!item.commentID) return
- comments.setFocus({ file: item.path, id: item.commentID })
- comments.setActive({ file: item.path, id: item.commentID })
+ const focus = { file: item.path, id: item.commentID }
+ comments.setActive(focus)
view().reviewPanel.open()
if (item.commentOrigin === "review") {
tabs().open("review")
+ requestAnimationFrame(() => comments.setFocus(focus))
return
}
if (item.commentOrigin !== "file" && commentInReview(item.path)) {
tabs().open("review")
+ requestAnimationFrame(() => comments.setFocus(focus))
return
}
const tab = files.tab(item.path)
tabs().open(tab)
files.load(item.path)
+ requestAnimationFrame(() => comments.setFocus(focus))
}
const recent = createMemo(() => {
diff --git a/packages/app/src/pages/session.tsx b/packages/app/src/pages/session.tsx
index 2016870e1..5f743dcba 100644
--- a/packages/app/src/pages/session.tsx
+++ b/packages/app/src/pages/session.tsx
@@ -1860,6 +1860,7 @@ export default function Page() {
let scrollFrame: number | undefined
let pending: { x: number; y: number } | undefined
let codeScroll: HTMLElement[] = []
+ let focusToken = 0
const path = createMemo(() => file.pathFromTab(tab))
const state = createMemo(() => {
@@ -2036,9 +2037,50 @@ export default function Page() {
const target = fileComments().find((comment) => comment.id === focus.id)
if (!target) return
+ focusToken++
+ const token = focusToken
+
setOpenedComment(target.id)
setCommenting(null)
file.setSelectedLines(p, target.selection)
+
+ const scrollTo = (attempt: number) => {
+ if (token !== focusToken) return
+
+ const root = scroll
+ if (!root) {
+ if (attempt >= 120) return
+ requestAnimationFrame(() => scrollTo(attempt + 1))
+ return
+ }
+
+ const anchor = root.querySelector(`[data-comment-id="${target.id}"]`)
+ const ready =
+ anchor instanceof HTMLElement &&
+ anchor.style.pointerEvents !== "none" &&
+ anchor.style.opacity !== "0"
+
+ const shadow = getRoot()
+ const marker = shadow ? findMarker(shadow, target.selection) : undefined
+ const node = (ready ? anchor : (marker ?? wrap)) as HTMLElement | undefined
+ if (!node) {
+ if (attempt >= 120) return
+ requestAnimationFrame(() => scrollTo(attempt + 1))
+ return
+ }
+
+ const rootRect = root.getBoundingClientRect()
+ const targetRect = node.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 || marker) return
+ if (attempt >= 120) return
+ requestAnimationFrame(() => scrollTo(attempt + 1))
+ }
+
+ requestAnimationFrame(() => scrollTo(0))
requestAnimationFrame(() => comments.clearFocus())
})