mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-11-14 14:13:43 +01:00
Editor Redesign Cleanup: main layout, toolbar, and rail (#31031)
* feat: integrate main layout, toolbar, and rail from redesign into main ide-react folder * feat: remove additional files no longer used after ide redesign GitOrigin-RevId: 8fd77f63cb9c67be91995a9dde13b0fe2376d80f
This commit is contained in:
committed by
Copybot
parent
c790449196
commit
fc8d564320
@@ -0,0 +1,185 @@
|
||||
import { sendSearchEvent } from '@/features/event-tracking/search-events'
|
||||
import { useProjectContext } from '@/shared/context/project-context'
|
||||
import useEventListener from '@/shared/hooks/use-event-listener'
|
||||
import usePersistedState from '@/shared/hooks/use-persisted-state'
|
||||
import { isMac } from '@/shared/utils/os'
|
||||
import {
|
||||
createContext,
|
||||
Dispatch,
|
||||
FC,
|
||||
SetStateAction,
|
||||
useCallback,
|
||||
useContext,
|
||||
useLayoutEffect,
|
||||
useMemo,
|
||||
useRef,
|
||||
useState,
|
||||
} from 'react'
|
||||
import { ImperativePanelHandle } from 'react-resizable-panels'
|
||||
|
||||
export type RailTabKey =
|
||||
| 'file-tree'
|
||||
| 'integrations'
|
||||
| 'review-panel'
|
||||
| 'chat'
|
||||
| 'full-project-search'
|
||||
| 'workbench'
|
||||
|
||||
export type RailModalKey = 'keyboard-shortcuts' | 'contact-us' | 'dictionary'
|
||||
|
||||
const RailContext = createContext<
|
||||
| {
|
||||
selectedTab: RailTabKey
|
||||
isOpen: boolean
|
||||
setIsOpen: Dispatch<SetStateAction<boolean>>
|
||||
panelRef: React.RefObject<ImperativePanelHandle>
|
||||
togglePane: () => void
|
||||
handlePaneExpand: () => void
|
||||
handlePaneCollapse: () => void
|
||||
resizing: boolean
|
||||
setResizing: Dispatch<SetStateAction<boolean>>
|
||||
activeModal: RailModalKey | null
|
||||
setActiveModal: Dispatch<SetStateAction<RailModalKey | null>>
|
||||
openTab: (tab: RailTabKey) => void
|
||||
selectTab: (tab: RailTabKey) => void
|
||||
}
|
||||
| undefined
|
||||
>(undefined)
|
||||
|
||||
export const RailProvider: FC<React.PropsWithChildren> = ({ children }) => {
|
||||
const { projectId } = useProjectContext()
|
||||
const [isOpen, setIsOpen] = usePersistedState(
|
||||
`rail-is-open-${projectId}`,
|
||||
true
|
||||
)
|
||||
const [resizing, setResizing] = useState(false)
|
||||
const [activeModal, setActiveModalInternal] = useState<RailModalKey | null>(
|
||||
null
|
||||
)
|
||||
const setActiveModal: Dispatch<SetStateAction<RailModalKey | null>> =
|
||||
useCallback(modalKey => {
|
||||
setActiveModalInternal(modalKey)
|
||||
}, [])
|
||||
|
||||
const panelRef = useRef<ImperativePanelHandle>(null)
|
||||
|
||||
const togglePane = useCallback(() => {
|
||||
setIsOpen(value => !value)
|
||||
}, [setIsOpen])
|
||||
|
||||
const handlePaneExpand = useCallback(() => {
|
||||
setIsOpen(true)
|
||||
}, [setIsOpen])
|
||||
|
||||
const handlePaneCollapse = useCallback(() => {
|
||||
setIsOpen(false)
|
||||
}, [setIsOpen])
|
||||
|
||||
const [selectedTab, setSelectedTab] = usePersistedState<RailTabKey>(
|
||||
`selected-rail-tab-${projectId}`,
|
||||
'file-tree'
|
||||
)
|
||||
|
||||
// Keep the panel collapse/expanded state in sync with isOpen and selectedTab
|
||||
useLayoutEffect(() => {
|
||||
const panelHandle = panelRef.current
|
||||
|
||||
if (panelHandle) {
|
||||
if (isOpen) {
|
||||
panelHandle.expand()
|
||||
} else {
|
||||
panelHandle.collapse()
|
||||
}
|
||||
}
|
||||
}, [isOpen, selectedTab])
|
||||
|
||||
const selectTab = useCallback(
|
||||
(tab: RailTabKey) => {
|
||||
setSelectedTab(tab)
|
||||
},
|
||||
[setSelectedTab]
|
||||
)
|
||||
|
||||
const openTab = useCallback(
|
||||
(tab: RailTabKey) => {
|
||||
setSelectedTab(tab)
|
||||
setIsOpen(true)
|
||||
},
|
||||
[setIsOpen, setSelectedTab]
|
||||
)
|
||||
|
||||
useEventListener(
|
||||
'ui.toggle-review-panel',
|
||||
useCallback(() => {
|
||||
if (isOpen && selectedTab === 'review-panel') {
|
||||
handlePaneCollapse()
|
||||
} else {
|
||||
openTab('review-panel')
|
||||
}
|
||||
}, [handlePaneCollapse, selectedTab, isOpen, openTab])
|
||||
)
|
||||
|
||||
useEventListener(
|
||||
'keydown',
|
||||
useCallback(
|
||||
(event: KeyboardEvent) => {
|
||||
if (
|
||||
(isMac ? event.metaKey : event.ctrlKey) &&
|
||||
event.shiftKey &&
|
||||
event.code === 'KeyF'
|
||||
) {
|
||||
event.preventDefault()
|
||||
sendSearchEvent('search-open', {
|
||||
searchType: 'full-project',
|
||||
method: 'keyboard',
|
||||
})
|
||||
openTab('full-project-search')
|
||||
}
|
||||
},
|
||||
[openTab]
|
||||
)
|
||||
)
|
||||
|
||||
const value = useMemo(
|
||||
() => ({
|
||||
selectedTab,
|
||||
isOpen,
|
||||
setIsOpen,
|
||||
panelRef,
|
||||
togglePane,
|
||||
handlePaneExpand,
|
||||
handlePaneCollapse,
|
||||
resizing,
|
||||
setResizing,
|
||||
activeModal,
|
||||
setActiveModal,
|
||||
openTab,
|
||||
selectTab,
|
||||
}),
|
||||
[
|
||||
selectedTab,
|
||||
isOpen,
|
||||
setIsOpen,
|
||||
panelRef,
|
||||
togglePane,
|
||||
handlePaneExpand,
|
||||
handlePaneCollapse,
|
||||
resizing,
|
||||
setResizing,
|
||||
activeModal,
|
||||
setActiveModal,
|
||||
openTab,
|
||||
selectTab,
|
||||
]
|
||||
)
|
||||
|
||||
return <RailContext.Provider value={value}>{children}</RailContext.Provider>
|
||||
}
|
||||
|
||||
export const useRailContext = () => {
|
||||
const context = useContext(RailContext)
|
||||
if (!context) {
|
||||
throw new Error('useRailContext is only available inside RailProvider')
|
||||
}
|
||||
return context
|
||||
}
|
||||
@@ -20,7 +20,7 @@ import { OnlineUsersProvider } from '@/features/ide-react/context/online-users-c
|
||||
import { OutlineProvider } from '@/features/ide-react/context/outline-context'
|
||||
import { PermissionsProvider } from '@/features/ide-react/context/permissions-context'
|
||||
import { ProjectProvider } from '@/shared/context/project-context'
|
||||
import { RailProvider } from '@/features/ide-redesign/contexts/rail-context'
|
||||
import { RailProvider } from '@/features/ide-react/context/rail-context'
|
||||
import { ProjectSettingsProvider } from '@/features/editor-left-menu/context/project-settings-context'
|
||||
import { ReferencesProvider } from '@/features/ide-react/context/references-context'
|
||||
import { SnapshotProvider } from '@/features/ide-react/context/snapshot-context'
|
||||
|
||||
Reference in New Issue
Block a user