Files
overleaf-cep/services/web/frontend/js/features/editor-floating-menu/components/add-comment-command.tsx
T
Malik Glossop 8ef463f8b0 Merge pull request #34357 from overleaf/mg-combine-floating-menus
Add combined floating menu for comment, tracked changes, writefull

GitOrigin-RevId: 4de5b9d3b1717fc76394f7c0edfe4d7230394c8d
2026-06-17 08:06:44 +00:00

62 lines
2.4 KiB
TypeScript

import { useCallback } from 'react'
import { EditorSelection } from '@codemirror/state'
import { EditorView } from '@codemirror/view'
import { useCodeMirrorViewContext } from '@/features/source-editor/components/codemirror-context'
import { buildAddNewCommentRangeEffect } from '@/features/source-editor/extensions/review-tooltip'
import { selectHighlightedOrNearestToken } from '@/features/source-editor/utils/select-highlighted-or-nearest-token'
import { isCursorNearViewportEdge } from '@/features/source-editor/utils/is-cursor-near-edge'
import useEventListener from '@/shared/hooks/use-event-listener'
import { usePermissionsContext } from '@/features/ide-react/context/permissions-context'
import { useReviewPanelViewActionsContext } from '@/features/review-panel/context/review-panel-view-context'
import useReviewPanelLayout from '@/features/review-panel/hooks/use-review-panel-layout'
// Headless owner of the "add comment" editor command. It is mounted whenever
// commenting is possible, independently of the floating menu's visibility, so
// the keyboard shortcut, toolbar command and floating menu button
// (which all dispatch `add-new-review-comment`) work even when the menu is hidden
const AddCommentCommand = () => {
const view = useCodeMirrorViewContext()
const permissions = usePermissionsContext()
const { setView } = useReviewPanelViewActionsContext()
const { openReviewPanel } = useReviewPanelLayout()
const addComment = useCallback(() => {
if (!permissions.comment) {
return
}
let { main } = view.state.selection
if (main.empty) {
const tokenRange = selectHighlightedOrNearestToken(view.state)
if (!tokenRange) {
return
}
main = EditorSelection.range(tokenRange.from, tokenRange.to)
}
openReviewPanel()
setView('cur_file')
const effects = isCursorNearViewportEdge(view, main.anchor)
? [
buildAddNewCommentRangeEffect(main),
EditorView.scrollIntoView(main.anchor, { y: 'center' }),
]
: [buildAddNewCommentRangeEffect(main)]
// Dispatching a new selection clears the review tooltip state, which
// dismisses the floating menu — no need to toggle menu state from here.
view.dispatch({
selection: { anchor: main.anchor, head: main.head },
effects,
})
}, [view, permissions.comment, openReviewPanel, setView])
useEventListener('add-new-review-comment', addComment)
return null
}
export default AddCommentCommand