Dont show "add comment" tooltip when text is selected via search (#23341)

* Dont show "add comment" tooltip when text is selected via search

* remove the tooltip if selection changes

* handle empty selection

* use tr.effects.some for mouseUp check

* avoid creating new create function each time

* use useEventListener

GitOrigin-RevId: 18d96fe6fdefcd55f88849cf880f804d4c963f4d
This commit is contained in:
Domagoj Kriskovic
2025-02-04 14:40:48 +01:00
committed by Copybot
parent 1ab971a2da
commit 6ee3ff63e4
2 changed files with 65 additions and 49 deletions

View File

@@ -1,8 +1,6 @@
import {
CSSProperties,
Dispatch,
FC,
SetStateAction,
useCallback,
useEffect,
useMemo,
@@ -35,6 +33,7 @@ import { useModalsContext } from '@/features/ide-react/context/modals-context'
import { numberOfChangesInSelection } from '../utils/changes-in-selection'
import { useEditorManagerContext } from '@/features/ide-react/context/editor-manager-context'
import classNames from 'classnames'
import useEventListener from '@/shared/hooks/use-event-listener'
const TRACK_CHANGES_ON_WIDGET_HEIGHT = 25
const CM_LINE_RIGHT_PADDING = 2
@@ -45,6 +44,8 @@ const ReviewTooltipMenu: FC = () => {
const view = useCodeMirrorViewContext()
const isViewer = useViewerPermissions()
const [show, setShow] = useState(true)
const { setView } = useReviewPanelViewActionsContext()
const { setReviewPanelOpen } = useLayoutContext()
const tooltipState = state.field(reviewTooltipStateField, false)?.tooltip
const previousTooltipState = usePreviousValue(tooltipState)
@@ -55,37 +56,6 @@ const ReviewTooltipMenu: FC = () => {
}
}, [tooltipState, previousTooltipState])
if (isViewer || !show || !tooltipState) {
return null
}
const tooltipView = getTooltip(view, tooltipState)
if (!tooltipView) {
return null
}
return ReactDOM.createPortal(
<ReviewTooltipMenuContent setShow={setShow} />,
tooltipView.dom
)
}
const ReviewTooltipMenuContent: FC<{
setShow: Dispatch<SetStateAction<boolean>>
}> = ({ setShow }) => {
const { t } = useTranslation()
const view = useCodeMirrorViewContext()
const state = useCodeMirrorStateContext()
const { setReviewPanelOpen, reviewPanelOpen } = useLayoutContext()
const { setView } = useReviewPanelViewActionsContext()
const ranges = useRangesContext()
const { acceptChanges, rejectChanges } = useRangesActionsContext()
const { showGenericConfirmModal } = useModalsContext()
const { wantTrackChanges } = useEditorManagerContext()
const [tooltipStyle, setTooltipStyle] = useState<CSSProperties | undefined>()
const [visible, setVisible] = useState(false)
const addComment = useCallback(() => {
setReviewPanelOpen(true)
setView('cur_file')
@@ -102,12 +72,37 @@ const ReviewTooltipMenuContent: FC<{
setShow(false)
}, [setReviewPanelOpen, setView, setShow, view, state.selection.main])
useEffect(() => {
window.addEventListener('add-new-review-comment', addComment)
return () => {
window.removeEventListener('add-new-review-comment', addComment)
}
}, [addComment])
useEventListener('add-new-review-comment', addComment)
if (isViewer || !show || !tooltipState) {
return null
}
const tooltipView = getTooltip(view, tooltipState)
if (!tooltipView) {
return null
}
return ReactDOM.createPortal(
<ReviewTooltipMenuContent onAddComment={addComment} />,
tooltipView.dom
)
}
const ReviewTooltipMenuContent: FC<{ onAddComment: () => void }> = ({
onAddComment,
}) => {
const { t } = useTranslation()
const view = useCodeMirrorViewContext()
const state = useCodeMirrorStateContext()
const { reviewPanelOpen } = useLayoutContext()
const ranges = useRangesContext()
const { acceptChanges, rejectChanges } = useRangesActionsContext()
const { showGenericConfirmModal } = useModalsContext()
const { wantTrackChanges } = useEditorManagerContext()
const [tooltipStyle, setTooltipStyle] = useState<CSSProperties | undefined>()
const [visible, setVisible] = useState(false)
const changeIdsInSelection = useMemo(() => {
return (ranges?.changes ?? [])
@@ -219,7 +214,7 @@ const ReviewTooltipMenuContent: FC<{
>
<button
className="review-tooltip-menu-button review-tooltip-add-comment-button"
onClick={addComment}
onClick={onAddComment}
>
<MaterialIcon type="chat" />
{t('add_comment')}

View File

@@ -13,6 +13,7 @@ import {
Range,
SelectionRange,
EditorState,
Transaction,
} from '@codemirror/state'
import { isSplitTestEnabled } from '@/utils/splitTestUtils'
import { v4 as uuid } from 'uuid'
@@ -119,14 +120,29 @@ export const reviewTooltipStateField = StateField.define<{
}
}
const isMouseDown = tr.state.field(mouseDownStateField)
if (!isMouseDown && !tr.state.selection.main.empty) {
tooltip = buildTooltip(tr.state)
} else if (tooltip && tr.state.selection.main.empty) {
tooltip = null
if (tr.state.selection.main.empty) {
return { tooltip: null, addCommentRanges }
}
return { tooltip, addCommentRanges }
if (
!tr.effects.some(effect => effect.is(mouseUpEffect)) &&
tr.annotation(Transaction.userEvent) !== 'select' &&
tr.annotation(Transaction.userEvent) !== 'select.pointer'
) {
if (tr.selection) {
// selection was changed, remove the tooltip
return { tooltip: null, addCommentRanges }
}
// for any other update, we keep the tooltip because it could be created in previous transaction
// and we are still waiting for "mouse up" event to show it
return { tooltip, addCommentRanges }
}
const isMouseDown = tr.state.field(mouseDownStateField)
// if "isMouseDown" is true, tooltip will be created but still hidden
// the reason why we cant just create the tooltip on mouse up is because transaction.userEvent is empty at that point
return { tooltip: buildTooltip(tr.state, isMouseDown), addCommentRanges }
},
provide: field => [
@@ -135,7 +151,7 @@ export const reviewTooltipStateField = StateField.define<{
],
})
function buildTooltip(state: EditorState): Tooltip | null {
function buildTooltip(state: EditorState, hidden: boolean): Tooltip | null {
const lineAtFrom = state.doc.lineAt(state.selection.main.from)
const lineAtTo = state.doc.lineAt(state.selection.main.to)
const multiLineSelection = lineAtFrom.number !== lineAtTo.number
@@ -151,19 +167,24 @@ function buildTooltip(state: EditorState): Tooltip | null {
return {
pos,
above: state.selection.main.head !== state.selection.main.to,
create: createReviewTooltipView,
create: hidden
? createHiddenReviewTooltipView
: createVisibleReviewTooltipView,
}
}
const createReviewTooltipView = (): TooltipView => {
const createReviewTooltipView = (hidden: boolean): TooltipView => {
const dom = document.createElement('div')
dom.className = 'review-tooltip-menu-container'
dom.style.display = hidden ? 'none' : 'block'
return {
dom,
overlap: true,
offset: { x: 0, y: 8 },
}
}
const createHiddenReviewTooltipView = () => createReviewTooltipView(true)
const createVisibleReviewTooltipView = () => createReviewTooltipView(false)
/**
* Styles for the tooltip