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

Scroll selection anchor into view when adding new comment (#21328)

* Scroll selection anchor into view when adding new comment

* check if cursor is near viewport edge

GitOrigin-RevId: 57d4195f7ce1513a56249365b45b3959b4ea813f
Domagoj Kriskovic 1 год назад
Родитель
Сommit
db23262611

+ 11 - 4
services/web/frontend/js/features/review-panel-new/components/review-tooltip-menu.tsx

@@ -18,7 +18,7 @@ import {
   buildAddNewCommentRangeEffect,
   reviewTooltipStateField,
 } from '@/features/source-editor/extensions/review-tooltip'
-import { getTooltip } from '@codemirror/view'
+import { EditorView, getTooltip } from '@codemirror/view'
 import useViewerPermissions from '@/shared/hooks/use-viewer-permissions'
 import usePreviousValue from '@/shared/hooks/use-previous-value'
 import { useLayoutContext } from '@/shared/context/layout-context'
@@ -28,6 +28,7 @@ import {
   useRangesContext,
 } from '../context/ranges-context'
 import { isInsertOperation } from '@/utils/operations'
+import { isCursorNearViewportEdge } from '@/features/source-editor/utils/is-cursor-near-edge'
 
 const ReviewTooltipMenu: FC = () => {
   const state = useCodeMirrorStateContext()
@@ -75,9 +76,15 @@ const ReviewTooltipMenuContent: FC<{
     setReviewPanelOpen(true)
     setView('cur_file')
 
-    view.dispatch({
-      effects: buildAddNewCommentRangeEffect(state.selection.main),
-    })
+    const commentPos = state.selection.main.anchor
+    const effects = isCursorNearViewportEdge(view, commentPos)
+      ? [
+          buildAddNewCommentRangeEffect(state.selection.main),
+          EditorView.scrollIntoView(commentPos, { y: 'center' }),
+        ]
+      : [buildAddNewCommentRangeEffect(state.selection.main)]
+
+    view.dispatch({ effects })
     setShow(false)
   }, [setReviewPanelOpen, setView, setShow, view, state.selection.main])
 

+ 23 - 0
services/web/frontend/js/features/source-editor/utils/is-cursor-near-edge.ts

@@ -0,0 +1,23 @@
+import { EditorView } from '@codemirror/view'
+
+const TOP_EDGE_THRESHOLD = 100
+const BOTTOM_EDGE_THRESHOLD = 200
+
+export function isCursorNearViewportEdge(view: EditorView, pos: number) {
+  const cursorCoords = view.coordsAtPos(pos)
+
+  if (!cursorCoords) {
+    return false
+  }
+
+  const scrollInfo = view.scrollDOM.getBoundingClientRect()
+
+  // check if the cursor is near the top of the viewport
+  if (Math.abs(cursorCoords.bottom - scrollInfo.top) <= TOP_EDGE_THRESHOLD) {
+    return true
+  }
+  // check if the cursor is near the bottom of the viewport
+  const viewportHeight = view.scrollDOM.clientHeight
+  const viewportBottom = scrollInfo.top + viewportHeight
+  return Math.abs(cursorCoords.bottom - viewportBottom) <= BOTTOM_EDGE_THRESHOLD
+}