mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
Show "add comment" tooltip below cursor if near viewport top (#21348)
* Scroll selection anchor into view when adding new comment * check if cursor is near viewport edge * Show "add comment" tooltip below cursor if near viewport top GitOrigin-RevId: 0dc2234bc03b1d88a3719ba01a4a865f218b9bfa
This commit is contained in:
parent
44b2ca1830
commit
0329a18875
3 changed files with 37 additions and 14 deletions
|
@ -15,6 +15,7 @@ import {
|
|||
import { isSplitTestEnabled } from '@/utils/splitTestUtils'
|
||||
import { v4 as uuid } from 'uuid'
|
||||
import { textSelected, textSelectedEffect } from './text-selected'
|
||||
import { isCursorNearViewportTop } from '../utils/is-cursor-near-edge'
|
||||
|
||||
export const addNewCommentRangeEffect = StateEffect.define<Range<Decoration>>()
|
||||
|
||||
|
@ -88,14 +89,15 @@ export const reviewTooltipStateField = StateField.define<{
|
|||
],
|
||||
})
|
||||
|
||||
function buildTooltip(range: SelectionRange): Tooltip | null {
|
||||
if (range.empty) {
|
||||
function buildTooltip(view: EditorView): Tooltip | null {
|
||||
if (view.state.selection.main.empty) {
|
||||
return null
|
||||
}
|
||||
|
||||
const pos = view.state.selection.main.head
|
||||
return {
|
||||
pos: range.assoc < 0 ? range.to : range.from,
|
||||
above: true,
|
||||
pos,
|
||||
above: !isCursorNearViewportTop(view, pos, 50),
|
||||
strictSide: true,
|
||||
arrow: false,
|
||||
create() {
|
||||
|
@ -113,6 +115,7 @@ const reviewTooltipTheme = EditorView.baseTheme({
|
|||
'.review-tooltip-menu-container.cm-tooltip': {
|
||||
backgroundColor: 'transparent',
|
||||
border: 'none',
|
||||
zIndex: 0,
|
||||
},
|
||||
|
||||
'&light': {
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
import { SelectionRange, StateEffect } from '@codemirror/state'
|
||||
import { ViewPlugin } from '@codemirror/view'
|
||||
import { StateEffect } from '@codemirror/state'
|
||||
import { EditorView, ViewPlugin } from '@codemirror/view'
|
||||
|
||||
export const textSelectedEffect = StateEffect.define<SelectionRange>()
|
||||
export const textSelectedEffect = StateEffect.define<EditorView>()
|
||||
|
||||
export const textSelected = ViewPlugin.define(view => {
|
||||
function mouseUpListener() {
|
||||
if (!view.state.selection.main.empty) {
|
||||
view.dispatch({
|
||||
effects: textSelectedEffect.of(view.state.selection.main),
|
||||
effects: textSelectedEffect.of(view),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ export const textSelected = ViewPlugin.define(view => {
|
|||
!view.state.selection.main.empty
|
||||
) {
|
||||
view.dispatch({
|
||||
effects: textSelectedEffect.of(view.state.selection.main),
|
||||
effects: textSelectedEffect.of(view),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,16 @@ const TOP_EDGE_THRESHOLD = 100
|
|||
const BOTTOM_EDGE_THRESHOLD = 200
|
||||
|
||||
export function isCursorNearViewportEdge(view: EditorView, pos: number) {
|
||||
return (
|
||||
isCursorNearViewportTop(view, pos) || isCursorNearViewportBottom(view, pos)
|
||||
)
|
||||
}
|
||||
|
||||
export function isCursorNearViewportTop(
|
||||
view: EditorView,
|
||||
pos: number,
|
||||
threshold = TOP_EDGE_THRESHOLD
|
||||
) {
|
||||
const cursorCoords = view.coordsAtPos(pos)
|
||||
|
||||
if (!cursorCoords) {
|
||||
|
@ -12,12 +22,22 @@ export function isCursorNearViewportEdge(view: EditorView, pos: number) {
|
|||
|
||||
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
|
||||
return Math.abs(cursorCoords.bottom - scrollInfo.top) <= threshold
|
||||
}
|
||||
|
||||
export function isCursorNearViewportBottom(
|
||||
view: EditorView,
|
||||
pos: number,
|
||||
threshold = BOTTOM_EDGE_THRESHOLD
|
||||
) {
|
||||
const cursorCoords = view.coordsAtPos(pos)
|
||||
|
||||
if (!cursorCoords) {
|
||||
return false
|
||||
}
|
||||
// check if the cursor is near the bottom of the viewport
|
||||
|
||||
const scrollInfo = view.scrollDOM.getBoundingClientRect()
|
||||
const viewportHeight = view.scrollDOM.clientHeight
|
||||
const viewportBottom = scrollInfo.top + viewportHeight
|
||||
return Math.abs(cursorCoords.bottom - viewportBottom) <= BOTTOM_EDGE_THRESHOLD
|
||||
return Math.abs(cursorCoords.bottom - viewportBottom) <= threshold
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue