Просмотр исходного кода

Merge pull request #20583 from overleaf/dk-review-gotoposition

Goto position when clicking on review entry in Overview tab

GitOrigin-RevId: 17c9cefed339537afa994778ffbc01cfb294bf46
David 2 лет назад
Родитель
Сommit
2801b3baad

+ 3 - 1
services/web/frontend/js/features/review-panel-new/components/review-panel-add-comment.tsx

@@ -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={{

+ 5 - 1
services/web/frontend/js/features/review-panel-new/components/review-panel-change.tsx

@@ -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" />

+ 5 - 1
services/web/frontend/js/features/review-panel-new/components/review-panel-comment.tsx

@@ -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" />

+ 3 - 0
services/web/frontend/js/features/review-panel-new/components/review-panel-current-file.tsx

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

+ 28 - 16
services/web/frontend/js/features/review-panel-new/components/review-panel-entry.tsx

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

+ 8 - 1
services/web/frontend/js/features/review-panel-new/components/review-panel-overview-file.tsx

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