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
This commit is contained in:
Domagoj Kriskovic 2024-10-25 15:04:55 +02:00 committed by Copybot
parent 4bcc7c9602
commit db23262611
2 changed files with 34 additions and 4 deletions

View file

@ -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])

View file

@ -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
}