mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
Merge pull request #20583 from overleaf/dk-review-gotoposition
Goto position when clicking on review entry in Overview tab GitOrigin-RevId: 17c9cefed339537afa994778ffbc01cfb294bf46
This commit is contained in:
parent
e253b48bc0
commit
2801b3baad
6 changed files with 52 additions and 20 deletions
|
@ -15,11 +15,12 @@ import { ThreadId } from '../../../../../types/review-panel/review-panel'
|
|||
import { Decoration } from '@codemirror/view'
|
||||
|
||||
export const ReviewPanelAddComment: FC<{
|
||||
docId: string
|
||||
from: number
|
||||
to: number
|
||||
value: Decoration
|
||||
top: number | undefined
|
||||
}> = ({ from, to, value, top }) => {
|
||||
}> = ({ from, to, value, top, docId }) => {
|
||||
const { t } = useTranslation()
|
||||
const view = useCodeMirrorViewContext()
|
||||
const state = useCodeMirrorStateContext()
|
||||
|
@ -113,6 +114,7 @@ export const ReviewPanelAddComment: FC<{
|
|||
|
||||
return (
|
||||
<ReviewPanelEntry
|
||||
docId={docId}
|
||||
top={top}
|
||||
position={from}
|
||||
op={{
|
||||
|
|
|
@ -21,7 +21,9 @@ export const ReviewPanelChange = memo<{
|
|||
aggregate?: Change<DeleteOperation>
|
||||
top?: number
|
||||
editable?: boolean
|
||||
}>(({ change, aggregate, top, editable = true }) => {
|
||||
docId: string
|
||||
hoverRanges?: boolean
|
||||
}>(({ change, aggregate, top, docId, hoverRanges, editable = true }) => {
|
||||
const { t } = useTranslation()
|
||||
const { acceptChanges, rejectChanges } = useRangesActionsContext()
|
||||
const permissions = usePermissionsContext()
|
||||
|
@ -42,6 +44,8 @@ export const ReviewPanelChange = memo<{
|
|||
top={top}
|
||||
op={change.op}
|
||||
position={change.op.p}
|
||||
docId={docId}
|
||||
hoverRanges={hoverRanges}
|
||||
>
|
||||
<div className="review-panel-entry-indicator">
|
||||
<MaterialIcon type="edit" className="review-panel-entry-icon" />
|
||||
|
|
|
@ -8,8 +8,10 @@ import { ReviewPanelCommentContent } from './review-panel-comment-content'
|
|||
|
||||
export const ReviewPanelComment = memo<{
|
||||
comment: Change<CommentOperation>
|
||||
docId: string
|
||||
top?: number
|
||||
}>(({ comment, top }) => {
|
||||
hoverRanges?: boolean
|
||||
}>(({ comment, top, docId, hoverRanges }) => {
|
||||
const threads = useThreadsContext()
|
||||
|
||||
const thread = threads?.[comment.op.t]
|
||||
|
@ -22,9 +24,11 @@ export const ReviewPanelComment = memo<{
|
|||
className={classnames('review-panel-entry-comment', {
|
||||
'review-panel-entry-loaded': !!threads?.[comment.op.t],
|
||||
})}
|
||||
docId={docId}
|
||||
top={top}
|
||||
op={comment.op}
|
||||
position={comment.op.p}
|
||||
hoverRanges={hoverRanges}
|
||||
>
|
||||
<div className="review-panel-entry-indicator">
|
||||
<MaterialIcon type="comment" className="review-panel-entry-icon" />
|
||||
|
|
|
@ -251,6 +251,7 @@ const ReviewPanelCurrentFile: FC = () => {
|
|||
const { id, from, to, value, top } = entry
|
||||
return (
|
||||
<ReviewPanelAddComment
|
||||
docId={ranges!.docId}
|
||||
key={id}
|
||||
from={from}
|
||||
to={to}
|
||||
|
@ -264,6 +265,7 @@ const ReviewPanelCurrentFile: FC = () => {
|
|||
change =>
|
||||
positions.has(change.id) && (
|
||||
<ReviewPanelChange
|
||||
docId={ranges!.docId}
|
||||
key={change.id}
|
||||
change={change}
|
||||
top={positions.get(change.id)}
|
||||
|
@ -276,6 +278,7 @@ const ReviewPanelCurrentFile: FC = () => {
|
|||
comment =>
|
||||
positions.has(comment.id) && (
|
||||
<ReviewPanelComment
|
||||
docId={ranges!.docId}
|
||||
key={comment.id}
|
||||
comment={comment}
|
||||
top={positions.get(comment.id)}
|
||||
|
|
|
@ -5,44 +5,56 @@ import {
|
|||
useCodeMirrorViewContext,
|
||||
} from '@/features/source-editor/components/codemirror-editor'
|
||||
import { isSelectionWithinOp } from '../utils/is-selection-within-op'
|
||||
import { EditorSelection } from '@codemirror/state'
|
||||
import { EditorView } from '@codemirror/view'
|
||||
import classNames from 'classnames'
|
||||
import { highlightRanges } from '@/features/source-editor/extensions/ranges'
|
||||
import { useEditorManagerContext } from '@/features/ide-react/context/editor-manager-context'
|
||||
|
||||
export const ReviewPanelEntry: FC<{
|
||||
position: number
|
||||
op: AnyOperation
|
||||
docId: string
|
||||
top?: number
|
||||
className?: string
|
||||
selectLineOnFocus?: boolean
|
||||
}> = ({ children, position, top, op, className, selectLineOnFocus = true }) => {
|
||||
hoverRanges?: boolean
|
||||
}> = ({
|
||||
children,
|
||||
position,
|
||||
top,
|
||||
op,
|
||||
className,
|
||||
selectLineOnFocus = true,
|
||||
docId,
|
||||
hoverRanges = true,
|
||||
}) => {
|
||||
const state = useCodeMirrorStateContext()
|
||||
const view = useCodeMirrorViewContext()
|
||||
const { openDocId } = useEditorManagerContext()
|
||||
const [focused, setFocused] = useState(false)
|
||||
|
||||
const highlighted = isSelectionWithinOp(op, state.selection.main)
|
||||
|
||||
const focusHandler = useCallback(() => {
|
||||
setTimeout(() => {
|
||||
// without setTimeout, error "EditorView.update are not allowed while an update is in progress" can occur
|
||||
// this can be avoided by using onClick rather than onFocus but it will then not pick up <Tab> or <Shift+Tab> events for focusing entries
|
||||
if (selectLineOnFocus) {
|
||||
view.dispatch({
|
||||
selection: EditorSelection.cursor(position),
|
||||
effects: EditorView.scrollIntoView(position, { y: 'center' }),
|
||||
})
|
||||
}
|
||||
}, 0)
|
||||
if (selectLineOnFocus) {
|
||||
openDocId(docId, { gotoOffset: position, keepCurrentView: true })
|
||||
}
|
||||
setFocused(true)
|
||||
}, [view, position, selectLineOnFocus])
|
||||
}, [selectLineOnFocus, docId, openDocId, position])
|
||||
|
||||
return (
|
||||
<div
|
||||
onFocus={focusHandler}
|
||||
onBlur={() => setFocused(false)}
|
||||
onMouseEnter={() => view.dispatch(highlightRanges(op))}
|
||||
onMouseLeave={() => view.dispatch(highlightRanges())}
|
||||
onMouseEnter={() => {
|
||||
if (hoverRanges) {
|
||||
view.dispatch(highlightRanges(op))
|
||||
}
|
||||
}}
|
||||
onMouseLeave={() => {
|
||||
if (hoverRanges) {
|
||||
view.dispatch(highlightRanges())
|
||||
}
|
||||
}}
|
||||
role="button"
|
||||
tabIndex={position + 1}
|
||||
className={classNames(
|
||||
|
|
|
@ -82,11 +82,18 @@ export const ReviewPanelOverviewFile: FC<{
|
|||
change={change}
|
||||
aggregate={aggregates.get(change.id)}
|
||||
editable={false}
|
||||
docId={doc.doc.id}
|
||||
hoverRanges={false}
|
||||
/>
|
||||
))}
|
||||
|
||||
{unresolvedComments.map(comment => (
|
||||
<ReviewPanelComment key={comment.id} comment={comment} />
|
||||
<ReviewPanelComment
|
||||
key={comment.id}
|
||||
comment={comment}
|
||||
docId={doc.doc.id}
|
||||
hoverRanges={false}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
|
|
Loading…
Reference in a new issue