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

fix(app): scroll to comment on click

adamelmore 3 недель назад
Родитель
Сommit
2b07291e17

+ 5 - 2
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(() => {

+ 42 - 0
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())
                     })
 

+ 2 - 2
packages/ui/src/components/session-review.tsx

@@ -238,7 +238,7 @@ export const SessionReview = (props: SessionReviewProps) => {
 
       const target = ready ? anchor : anchors.get(focus.file)
       if (!target) {
-        if (attempt >= 24) return
+        if (attempt >= 120) return
         requestAnimationFrame(() => scrollTo(attempt + 1))
         return
       }
@@ -250,7 +250,7 @@ export const SessionReview = (props: SessionReviewProps) => {
       root.scrollTop = Math.max(0, next)
 
       if (ready) return
-      if (attempt >= 24) return
+      if (attempt >= 120) return
       requestAnimationFrame(() => scrollTo(attempt + 1))
     }