Explorar o código

Merge pull request #16268 from overleaf/ii-ide-page-prototype-review-panel-layout-to-left

[web] Review panel popovers

GitOrigin-RevId: 4424abab97b197013063679bd8efcac001f458ad
ilkin-overleaf %!s(int64=2) %!d(string=hai) anos
pai
achega
fbed0cb943

+ 4 - 0
services/web/frontend/js/features/ide-react/context/review-panel/hooks/use-review-panel-state.ts

@@ -7,6 +7,7 @@ import useSocketListener from '@/features/ide-react/hooks/use-socket-listener'
 import useAsync from '@/shared/hooks/use-async'
 import useAsync from '@/shared/hooks/use-async'
 import useAbortController from '@/shared/hooks/use-abort-controller'
 import useAbortController from '@/shared/hooks/use-abort-controller'
 import useScopeEventEmitter from '@/shared/hooks/use-scope-event-emitter'
 import useScopeEventEmitter from '@/shared/hooks/use-scope-event-emitter'
+import useLayoutToLeft from '@/features/ide-react/context/review-panel/hooks/useLayoutToLeft'
 import { sendMB } from '../../../../../infrastructure/event-tracking'
 import { sendMB } from '../../../../../infrastructure/event-tracking'
 import {
 import {
   dispatchReviewPanelLayout as handleLayoutChange,
   dispatchReviewPanelLayout as handleLayoutChange,
@@ -147,6 +148,7 @@ function useReviewPanelState(): ReviewPanelStateReactIde {
   const { showGenericMessageModal } = useModalsContext()
   const { showGenericMessageModal } = useModalsContext()
   const addCommentEmitter = useScopeEventEmitter('comment:start_adding')
   const addCommentEmitter = useScopeEventEmitter('comment:start_adding')
 
 
+  const layoutToLeft = useLayoutToLeft('.ide-react-editor-panel')
   const [subView, setSubView] =
   const [subView, setSubView] =
     useState<ReviewPanel.Value<'subView'>>('cur_file')
     useState<ReviewPanel.Value<'subView'>>('cur_file')
   const [isOverviewLoading, setIsOverviewLoading] =
   const [isOverviewLoading, setIsOverviewLoading] =
@@ -1523,6 +1525,7 @@ function useReviewPanelState(): ReviewPanelStateReactIde {
       formattedProjectMembers,
       formattedProjectMembers,
       layoutSuspended,
       layoutSuspended,
       unsavedComment,
       unsavedComment,
+      layoutToLeft,
     }),
     }),
     [
     [
       collapsed,
       collapsed,
@@ -1550,6 +1553,7 @@ function useReviewPanelState(): ReviewPanelStateReactIde {
       formattedProjectMembers,
       formattedProjectMembers,
       layoutSuspended,
       layoutSuspended,
       unsavedComment,
       unsavedComment,
+      layoutToLeft,
     ]
     ]
   )
   )
 
 

+ 32 - 0
services/web/frontend/js/features/ide-react/context/review-panel/hooks/useLayoutToLeft.tsx

@@ -0,0 +1,32 @@
+import { useState, useEffect } from 'react'
+
+function useLayoutToLeft(querySelector: string) {
+  const [layoutToLeft, setLayoutToLeft] = useState(false)
+
+  useEffect(() => {
+    if (!('ResizeObserver' in window)) return
+
+    const target = document.querySelector(querySelector)
+
+    if (!target) return
+
+    const handleResize = () => {
+      const docWidth = document.documentElement.clientWidth
+      const { right: rightEdge } = target.getBoundingClientRect()
+      setLayoutToLeft(docWidth - rightEdge < 225)
+    }
+
+    handleResize()
+
+    const observer = new ResizeObserver(handleResize)
+    observer.observe(target)
+
+    return () => {
+      observer.disconnect()
+    }
+  }, [querySelector])
+
+  return layoutToLeft
+}
+
+export default useLayoutToLeft

+ 0 - 1
services/web/frontend/js/features/ide-react/scope-adapters/review-panel-context-adapter.ts

@@ -2,6 +2,5 @@ import { ReactScopeValueStore } from '@/features/ide-react/scope-value-store/rea
 
 
 export default function populateReviewPanelScope(store: ReactScopeValueStore) {
 export default function populateReviewPanelScope(store: ReactScopeValueStore) {
   store.set('users', {})
   store.set('users', {})
-  store.set('reviewPanel.layoutToLeft', false)
   store.set('addNewComment', () => {})
   store.set('addNewComment', () => {})
 }
 }

+ 2 - 2
services/web/frontend/js/features/source-editor/components/review-panel/entries/entry-container.tsx

@@ -1,7 +1,7 @@
 import classNames from 'classnames'
 import classNames from 'classnames'
 import { createPortal } from 'react-dom'
 import { createPortal } from 'react-dom'
+import { useReviewPanelValueContext } from '@/features/source-editor/context/review-panel/review-panel-context'
 import { Coordinates } from '../hooks/use-indicator-hover'
 import { Coordinates } from '../hooks/use-indicator-hover'
-import useScopeValue from '@/shared/hooks/use-scope-value'
 
 
 function EntryContainer({
 function EntryContainer({
   id,
   id,
@@ -11,7 +11,7 @@ function EntryContainer({
 }: React.ComponentProps<'div'> & {
 }: React.ComponentProps<'div'> & {
   hoverCoords?: Coordinates | null
   hoverCoords?: Coordinates | null
 }) {
 }) {
-  const [layoutToLeft] = useScopeValue<boolean>('reviewPanel.layoutToLeft')
+  const { layoutToLeft } = useReviewPanelValueContext()
 
 
   const container = (
   const container = (
     <div
     <div

+ 2 - 2
services/web/frontend/js/features/source-editor/components/review-panel/review-panel.tsx

@@ -18,7 +18,7 @@ type ReviewPanelViewProps = {
 }
 }
 
 
 function ReviewPanelView({ parentDomNode }: ReviewPanelViewProps) {
 function ReviewPanelView({ parentDomNode }: ReviewPanelViewProps) {
-  const { subView, loadingThreads } = useReviewPanelValueContext()
+  const { subView, loadingThreads, layoutToLeft } = useReviewPanelValueContext()
   const { reviewPanelOpen, miniReviewPanelVisible } = useLayoutContext()
   const { reviewPanelOpen, miniReviewPanelVisible } = useLayoutContext()
   const { isReactIde } = useIdeContext()
   const { isReactIde } = useIdeContext()
 
 
@@ -45,7 +45,7 @@ function ReviewPanelView({ parentDomNode }: ReviewPanelViewProps) {
           'rp-state-overview': subView === 'overview',
           'rp-state-overview': subView === 'overview',
           'rp-size-mini': miniReviewPanelVisible,
           'rp-size-mini': miniReviewPanelVisible,
           'rp-size-expanded': reviewPanelOpen,
           'rp-size-expanded': reviewPanelOpen,
-          // 'rp-layout-left': reviewPanel.layoutToLeft,
+          'rp-layout-left': layoutToLeft,
           'rp-loading-threads': loadingThreads,
           'rp-loading-threads': loadingThreads,
         })}
         })}
       >
       >

+ 5 - 0
services/web/frontend/js/features/source-editor/context/review-panel/hooks/use-angular-review-panel-state.ts

@@ -1,5 +1,6 @@
 import { useState, useMemo, useCallback } from 'react'
 import { useState, useMemo, useCallback } from 'react'
 import useScopeValue from '../../../../../shared/hooks/use-scope-value'
 import useScopeValue from '../../../../../shared/hooks/use-scope-value'
+import useLayoutToLeft from '@/features/ide-react/context/review-panel/hooks/useLayoutToLeft'
 import { sendMB } from '../../../../../infrastructure/event-tracking'
 import { sendMB } from '../../../../../infrastructure/event-tracking'
 import { ReviewPanelState } from '../types/review-panel-state'
 import { ReviewPanelState } from '../types/review-panel-state'
 import * as ReviewPanel from '../types/review-panel-state'
 import * as ReviewPanel from '../types/review-panel-state'
@@ -131,6 +132,8 @@ function useAngularReviewPanelState(): ReviewPanelState {
       'bulkRejectActions'
       'bulkRejectActions'
     )
     )
 
 
+  const layoutToLeft = useLayoutToLeft('#editor')
+
   const handleSetSubview = useCallback(
   const handleSetSubview = useCallback(
     (subView: SubView) => {
     (subView: SubView) => {
       setSubView(subView)
       setSubView(subView)
@@ -180,6 +183,7 @@ function useAngularReviewPanelState(): ReviewPanelState {
       formattedProjectMembers,
       formattedProjectMembers,
       layoutSuspended,
       layoutSuspended,
       unsavedComment,
       unsavedComment,
+      layoutToLeft,
     }),
     }),
     [
     [
       collapsed,
       collapsed,
@@ -207,6 +211,7 @@ function useAngularReviewPanelState(): ReviewPanelState {
       formattedProjectMembers,
       formattedProjectMembers,
       layoutSuspended,
       layoutSuspended,
       unsavedComment,
       unsavedComment,
+      layoutToLeft,
     ]
     ]
   )
   )
 
 

+ 1 - 0
services/web/frontend/js/features/source-editor/context/review-panel/types/review-panel-state.ts

@@ -48,6 +48,7 @@ export interface ReviewPanelState {
     >
     >
     layoutSuspended: boolean
     layoutSuspended: boolean
     unsavedComment: string
     unsavedComment: string
+    layoutToLeft: boolean
   }
   }
   updaterFns: {
   updaterFns: {
     handleSetSubview: (subView: SubView) => void
     handleSetSubview: (subView: SubView) => void