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

Merge pull request #27384 from overleaf/dp-drag-file-tree-outline

Allow file tree and outline to be expandable and collapsible by dragging

GitOrigin-RevId: e25f0d263b1446537cdb42ef52fe1c486e855773
David 1 год назад
Родитель
Сommit
075e18c7c8

+ 14 - 0
services/web/frontend/js/features/ide-react/context/file-tree-open-context.tsx

@@ -32,6 +32,8 @@ const FileTreeOpenContext = createContext<
       handleFileTreeDelete: (entity: FileTreeFindResult) => void
       handleFileTreeDelete: (entity: FileTreeFindResult) => void
       fileTreeExpanded: boolean
       fileTreeExpanded: boolean
       toggleFileTreeExpanded: () => void
       toggleFileTreeExpanded: () => void
+      expandFileTree: () => void
+      collapseFileTree: () => void
     }
     }
   | undefined
   | undefined
 >(undefined)
 >(undefined)
@@ -59,6 +61,14 @@ export const FileTreeOpenProvider: FC<React.PropsWithChildren> = ({
     setFileTreeExpanded(prev => !prev)
     setFileTreeExpanded(prev => !prev)
   }, [])
   }, [])
 
 
+  const expandFileTree = useCallback(() => {
+    setFileTreeExpanded(true)
+  }, [])
+
+  const collapseFileTree = useCallback(() => {
+    setFileTreeExpanded(false)
+  }, [])
+
   const handleFileTreeInit = useCallback(() => {
   const handleFileTreeInit = useCallback(() => {
     setFileTreeReady(true)
     setFileTreeReady(true)
   }, [])
   }, [])
@@ -144,6 +154,8 @@ export const FileTreeOpenProvider: FC<React.PropsWithChildren> = ({
       handleFileTreeDelete,
       handleFileTreeDelete,
       fileTreeExpanded,
       fileTreeExpanded,
       toggleFileTreeExpanded,
       toggleFileTreeExpanded,
+      expandFileTree,
+      collapseFileTree,
     }
     }
   }, [
   }, [
     handleFileTreeDelete,
     handleFileTreeDelete,
@@ -153,6 +165,8 @@ export const FileTreeOpenProvider: FC<React.PropsWithChildren> = ({
     selectedEntityCount,
     selectedEntityCount,
     fileTreeExpanded,
     fileTreeExpanded,
     toggleFileTreeExpanded,
     toggleFileTreeExpanded,
+    expandFileTree,
+    collapseFileTree,
   ])
   ])
 
 
   return (
   return (

+ 27 - 7
services/web/frontend/js/features/ide-react/context/outline-context.tsx

@@ -38,6 +38,8 @@ const OutlineContext = createContext<
       canShowOutline: boolean
       canShowOutline: boolean
       outlineExpanded: boolean
       outlineExpanded: boolean
       toggleOutlineExpanded: () => void
       toggleOutlineExpanded: () => void
+      expandOutline: () => void
+      collapseOutline: () => void
     }
     }
   | undefined
   | undefined
 >(undefined)
 >(undefined)
@@ -133,15 +135,29 @@ export const OutlineProvider: FC<React.PropsWithChildren> = ({ children }) => {
 
 
   const canShowOutline = isTexFile && !binaryFileOpened
   const canShowOutline = isTexFile && !binaryFileOpened
 
 
-  const toggleOutlineExpanded = useCallback(() => {
+  const expandOutline = useCallback(() => {
+    if (canShowOutline) {
+      localStorage.setItem(storageKey, true)
+      eventTracking.sendMB('outline-expand')
+      setOutlineExpanded(true)
+    }
+  }, [canShowOutline, storageKey])
+
+  const collapseOutline = useCallback(() => {
     if (canShowOutline) {
     if (canShowOutline) {
-      localStorage.setItem(storageKey, !outlineExpanded)
-      eventTracking.sendMB(
-        outlineExpanded ? 'outline-collapse' : 'outline-expand'
-      )
-      setOutlineExpanded(!outlineExpanded)
+      localStorage.setItem(storageKey, false)
+      eventTracking.sendMB('outline-collapse')
+      setOutlineExpanded(false)
+    }
+  }, [canShowOutline, storageKey])
+
+  const toggleOutlineExpanded = useCallback(() => {
+    if (outlineExpanded) {
+      collapseOutline()
+    } else {
+      expandOutline()
     }
     }
-  }, [canShowOutline, outlineExpanded, storageKey])
+  }, [collapseOutline, expandOutline, outlineExpanded])
 
 
   const value = useMemo(
   const value = useMemo(
     () => ({
     () => ({
@@ -152,6 +168,8 @@ export const OutlineProvider: FC<React.PropsWithChildren> = ({ children }) => {
       canShowOutline,
       canShowOutline,
       outlineExpanded,
       outlineExpanded,
       toggleOutlineExpanded,
       toggleOutlineExpanded,
+      expandOutline,
+      collapseOutline,
     }),
     }),
     [
     [
       flatOutline,
       flatOutline,
@@ -160,6 +178,8 @@ export const OutlineProvider: FC<React.PropsWithChildren> = ({ children }) => {
       canShowOutline,
       canShowOutline,
       outlineExpanded,
       outlineExpanded,
       toggleOutlineExpanded,
       toggleOutlineExpanded,
+      expandOutline,
+      collapseOutline,
     ]
     ]
   )
   )
 
 

+ 9 - 2
services/web/frontend/js/features/ide-react/hooks/use-outline-pane.ts

@@ -4,11 +4,18 @@ import { useRef } from 'react'
 import { ImperativePanelHandle } from 'react-resizable-panels'
 import { ImperativePanelHandle } from 'react-resizable-panels'
 
 
 export const useOutlinePane = () => {
 export const useOutlinePane = () => {
-  const { canShowOutline, outlineExpanded } = useOutlineContext()
+  const { canShowOutline, outlineExpanded, expandOutline, collapseOutline } =
+    useOutlineContext()
   const outlinePanelRef = useRef<ImperativePanelHandle>(null)
   const outlinePanelRef = useRef<ImperativePanelHandle>(null)
   const outlineEnabled = canShowOutline && outlineExpanded
   const outlineEnabled = canShowOutline && outlineExpanded
 
 
   useCollapsiblePanel(outlineEnabled, outlinePanelRef)
   useCollapsiblePanel(outlineEnabled, outlinePanelRef)
 
 
-  return { outlineEnabled, outlinePanelRef }
+  return {
+    outlineEnabled,
+    canShowOutline,
+    outlinePanelRef,
+    expandOutline,
+    collapseOutline,
+  }
 }
 }

+ 15 - 3
services/web/frontend/js/features/ide-redesign/components/file-tree/file-tree-outline-panel.tsx

@@ -7,8 +7,14 @@ import useCollapsibleFileTree from '../../hooks/use-collapsible-file-tree'
 import classNames from 'classnames'
 import classNames from 'classnames'
 
 
 function FileTreeOutlinePanel() {
 function FileTreeOutlinePanel() {
-  const { outlineEnabled, outlinePanelRef } = useOutlinePane()
-  const { fileTreeExpanded, fileTreePanelRef } = useCollapsibleFileTree()
+  const { canShowOutline, outlinePanelRef, expandOutline, collapseOutline } =
+    useOutlinePane()
+  const {
+    fileTreeExpanded,
+    fileTreePanelRef,
+    expandFileTree,
+    collapseFileTree,
+  } = useCollapsibleFileTree()
 
 
   return (
   return (
     <PanelGroup
     <PanelGroup
@@ -25,12 +31,15 @@ function FileTreeOutlinePanel() {
         order={1}
         order={1}
         collapsible
         collapsible
         ref={fileTreePanelRef}
         ref={fileTreePanelRef}
+        onExpand={expandFileTree}
+        onCollapse={collapseFileTree}
+        minSize={10}
       >
       >
         <FileTree />
         <FileTree />
       </Panel>
       </Panel>
       <VerticalResizeHandle
       <VerticalResizeHandle
         hitAreaMargins={{ coarse: 0, fine: 0 }}
         hitAreaMargins={{ coarse: 0, fine: 0 }}
-        disabled={!outlineEnabled || !fileTreeExpanded}
+        disabled={!canShowOutline}
       />
       />
       <Panel
       <Panel
         className="file-outline-panel"
         className="file-outline-panel"
@@ -39,6 +48,9 @@ function FileTreeOutlinePanel() {
         order={2}
         order={2}
         collapsible
         collapsible
         ref={outlinePanelRef}
         ref={outlinePanelRef}
+        onExpand={expandOutline}
+        onCollapse={collapseOutline}
+        minSize={10}
       >
       >
         <OutlineContainer />
         <OutlineContainer />
       </Panel>
       </Panel>

+ 14 - 2
services/web/frontend/js/features/ide-redesign/hooks/use-collapsible-file-tree.tsx

@@ -4,9 +4,21 @@ import useCollapsiblePanel from '@/features/ide-react/hooks/use-collapsible-pane
 import { useFileTreeOpenContext } from '@/features/ide-react/context/file-tree-open-context'
 import { useFileTreeOpenContext } from '@/features/ide-react/context/file-tree-open-context'
 
 
 export default function useCollapsibleFileTree() {
 export default function useCollapsibleFileTree() {
-  const { fileTreeExpanded, toggleFileTreeExpanded } = useFileTreeOpenContext()
+  const {
+    fileTreeExpanded,
+    toggleFileTreeExpanded,
+    expandFileTree,
+    collapseFileTree,
+  } = useFileTreeOpenContext()
   const fileTreePanelRef = useRef<ImperativePanelHandle>(null)
   const fileTreePanelRef = useRef<ImperativePanelHandle>(null)
+
   useCollapsiblePanel(fileTreeExpanded, fileTreePanelRef)
   useCollapsiblePanel(fileTreeExpanded, fileTreePanelRef)
 
 
-  return { fileTreeExpanded, fileTreePanelRef, toggleFileTreeExpanded }
+  return {
+    fileTreeExpanded,
+    fileTreePanelRef,
+    toggleFileTreeExpanded,
+    expandFileTree,
+    collapseFileTree,
+  }
 }
 }