mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-11-12 21:23:45 +01:00
Minimise use of ide context provider (#23308)
GitOrigin-RevId: 468b8d4b33925bdb97bd46d2c4e7acb969f3d82b
This commit is contained in:
+9
-9
@@ -4,7 +4,7 @@ import useScopeValue from '../../../shared/hooks/use-scope-value'
|
||||
import type { ProjectSettings } from '../utils/api'
|
||||
|
||||
export default function useProjectWideSettingsSocketListener() {
|
||||
const ide = useIdeContext()
|
||||
const { socket } = useIdeContext()
|
||||
|
||||
const [project, setProject] = useScopeValue<ProjectSettings | undefined>(
|
||||
'project'
|
||||
@@ -41,18 +41,18 @@ export default function useProjectWideSettingsSocketListener() {
|
||||
// data is not available on initial mounting
|
||||
const dataAvailable = !!project
|
||||
|
||||
if (dataAvailable && ide?.socket) {
|
||||
ide.socket.on('compilerUpdated', setCompiler)
|
||||
ide.socket.on('imageNameUpdated', setImageName)
|
||||
ide.socket.on('spellCheckLanguageUpdated', setSpellCheckLanguage)
|
||||
if (dataAvailable && socket) {
|
||||
socket.on('compilerUpdated', setCompiler)
|
||||
socket.on('imageNameUpdated', setImageName)
|
||||
socket.on('spellCheckLanguageUpdated', setSpellCheckLanguage)
|
||||
return () => {
|
||||
ide.socket.removeListener('compilerUpdated', setCompiler)
|
||||
ide.socket.removeListener('imageNameUpdated', setImageName)
|
||||
ide.socket.removeListener(
|
||||
socket.removeListener('compilerUpdated', setCompiler)
|
||||
socket.removeListener('imageNameUpdated', setImageName)
|
||||
socket.removeListener(
|
||||
'spellCheckLanguageUpdated',
|
||||
setSpellCheckLanguage
|
||||
)
|
||||
}
|
||||
}
|
||||
}, [ide?.socket, project, setCompiler, setImageName, setSpellCheckLanguage])
|
||||
}, [socket, project, setCompiler, setImageName, setSpellCheckLanguage])
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ import { fileCollator } from '@/features/file-tree/util/file-collator'
|
||||
import { Folder } from '../../../../../types/folder'
|
||||
import { FileTreeEntity } from '../../../../../types/file-tree-entity'
|
||||
import { isMac } from '@/shared/utils/os'
|
||||
import useEventListener from '@/shared/hooks/use-event-listener'
|
||||
|
||||
const FileTreeSelectableContext = createContext<
|
||||
| {
|
||||
@@ -188,18 +189,22 @@ export const FileTreeSelectableProvider: FC<{
|
||||
setSelectedEntities,
|
||||
])
|
||||
|
||||
useEffect(() => {
|
||||
// listen for `editor.openDoc` and selected that doc
|
||||
function handleOpenDoc(ev: any) {
|
||||
const found = findInTree(fileTreeData, ev.detail)
|
||||
if (!found) return
|
||||
// Synchronize the file tree when openFileWithId or openDocWithId is called on the editor
|
||||
// manager context from elsewhere. If the file tree does change, it will
|
||||
// trigger the onSelect handler in this component, which will update the local
|
||||
// state.
|
||||
useEventListener(
|
||||
'entity:opened',
|
||||
useCallback(
|
||||
(event: CustomEvent<string>) => {
|
||||
const found = findInTree(fileTreeData, event.detail)
|
||||
if (!found) return
|
||||
|
||||
dispatch({ type: ACTION_TYPES.SELECT, id: found.entity._id })
|
||||
}
|
||||
|
||||
window.addEventListener('editor.openDoc', handleOpenDoc)
|
||||
return () => window.removeEventListener('editor.openDoc', handleOpenDoc)
|
||||
}, [fileTreeData])
|
||||
dispatch({ type: ACTION_TYPES.SELECT, id: found.entity._id })
|
||||
},
|
||||
[fileTreeData]
|
||||
)
|
||||
)
|
||||
|
||||
const select = useCallback(id => {
|
||||
dispatch({ type: ACTION_TYPES.SELECT, id })
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { sendMB } from '../../../../infrastructure/event-tracking'
|
||||
import { useIdeContext } from '../../../../shared/context/ide-context'
|
||||
import { useLayoutContext } from '../../../../shared/context/layout-context'
|
||||
import { restoreFile } from '../../services/api'
|
||||
import { isFileRemoved } from '../../utils/file-diff'
|
||||
@@ -10,6 +9,7 @@ import { useFileTreeData } from '@/shared/context/file-tree-data-context'
|
||||
import { findInTree } from '@/features/file-tree/util/find-in-tree'
|
||||
import { useCallback, useEffect, useState } from 'react'
|
||||
import { RestoreFileResponse } from '@/features/history/services/types/restore-file'
|
||||
import { useEditorManagerContext } from '@/features/ide-react/context/editor-manager-context'
|
||||
|
||||
type RestorationState =
|
||||
| 'idle'
|
||||
@@ -21,8 +21,8 @@ type RestorationState =
|
||||
|
||||
export function useRestoreDeletedFile() {
|
||||
const { projectId } = useHistoryContext()
|
||||
const ide = useIdeContext()
|
||||
const { setView } = useLayoutContext()
|
||||
const { openDocWithId, openFileWithId } = useEditorManagerContext()
|
||||
const handleError = useErrorHandler()
|
||||
const { fileTreeData } = useFileTreeData()
|
||||
const [state, setState] = useState<RestorationState>('idle')
|
||||
@@ -39,12 +39,10 @@ export function useRestoreDeletedFile() {
|
||||
const { _id: id } = result.entity
|
||||
setView('editor')
|
||||
|
||||
// Once Angular is gone, these can be replaced with calls to context
|
||||
// methods
|
||||
if (restoredFileMetadata.type === 'doc') {
|
||||
ide.editorManager.openDocWithId(id)
|
||||
openDocWithId(id)
|
||||
} else {
|
||||
ide.binaryFilesManager.openFileWithId(id)
|
||||
openFileWithId(id)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -52,8 +50,8 @@ export function useRestoreDeletedFile() {
|
||||
state,
|
||||
fileTreeData,
|
||||
restoredFileMetadata,
|
||||
ide.editorManager,
|
||||
ide.binaryFilesManager,
|
||||
openDocWithId,
|
||||
openFileWithId,
|
||||
setView,
|
||||
])
|
||||
|
||||
|
||||
+6
-8
@@ -1,4 +1,3 @@
|
||||
import { useIdeContext } from '../../../../shared/context/ide-context'
|
||||
import { useLayoutContext } from '../../../../shared/context/layout-context'
|
||||
import { restoreFileToVersion } from '../../services/api'
|
||||
import { isFileRemoved } from '../../utils/file-diff'
|
||||
@@ -9,6 +8,7 @@ import { useFileTreeData } from '@/shared/context/file-tree-data-context'
|
||||
import { findInTree } from '@/features/file-tree/util/find-in-tree'
|
||||
import { useCallback, useEffect, useState } from 'react'
|
||||
import { RestoreFileResponse } from '../../services/types/restore-file'
|
||||
import { useEditorManagerContext } from '@/features/ide-react/context/editor-manager-context'
|
||||
|
||||
const RESTORE_FILE_TIMEOUT = 3000
|
||||
|
||||
@@ -22,8 +22,8 @@ type RestoreState =
|
||||
|
||||
export function useRestoreSelectedFile() {
|
||||
const { projectId } = useHistoryContext()
|
||||
const ide = useIdeContext()
|
||||
const { setView } = useLayoutContext()
|
||||
const { openDocWithId, openFileWithId } = useEditorManagerContext()
|
||||
const handleError = useErrorHandler()
|
||||
const { fileTreeData } = useFileTreeData()
|
||||
const [state, setState] = useState<RestoreState>('idle')
|
||||
@@ -40,12 +40,10 @@ export function useRestoreSelectedFile() {
|
||||
const { _id: id } = result.entity
|
||||
setView('editor')
|
||||
|
||||
// Once Angular is gone, these can be replaced with calls to context
|
||||
// methods
|
||||
if (restoredFileMetadata.type === 'doc') {
|
||||
ide.editorManager.openDocWithId(id)
|
||||
openDocWithId(id)
|
||||
} else {
|
||||
ide.binaryFilesManager.openFileWithId(id)
|
||||
openFileWithId(id)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -53,8 +51,8 @@ export function useRestoreSelectedFile() {
|
||||
state,
|
||||
fileTreeData,
|
||||
restoredFileMetadata,
|
||||
ide.editorManager,
|
||||
ide.binaryFilesManager,
|
||||
openDocWithId,
|
||||
openFileWithId,
|
||||
setView,
|
||||
])
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@ import { MainLayout } from '@/features/ide-react/components/layout/main-layout'
|
||||
import EditorLeftMenu from '@/features/editor-left-menu/components/editor-left-menu'
|
||||
import { useLayoutEventTracking } from '@/features/ide-react/hooks/use-layout-event-tracking'
|
||||
import useSocketListeners from '@/features/ide-react/hooks/use-socket-listeners'
|
||||
import { useOpenFile } from '@/features/ide-react/hooks/use-open-file'
|
||||
import { useEditingSessionHeartbeat } from '@/features/ide-react/hooks/use-editing-session-heartbeat'
|
||||
import { useRegisterUserActivity } from '@/features/ide-react/hooks/use-register-user-activity'
|
||||
import { useHasLintingError } from '@/features/ide-react/hooks/use-has-linting-error'
|
||||
@@ -26,7 +25,6 @@ export default function IdePage() {
|
||||
useEditingSessionHeartbeat() // send a batched event when user is active
|
||||
useRegisterUserActivity() // record activity and ensure connection when user is active
|
||||
useHasLintingError() // pass editor:lint hasLintingError to the compiler
|
||||
useOpenFile() // create ide.binaryFilesManager (TODO: move to the history file restore component)
|
||||
|
||||
const newEditor = useFeatureFlag('editor-redesign')
|
||||
|
||||
|
||||
@@ -21,7 +21,10 @@ import { useLayoutContext } from '@/shared/context/layout-context'
|
||||
import { GotoLineOptions } from '@/features/ide-react/types/goto-line-options'
|
||||
import { Doc } from '../../../../../types/doc'
|
||||
import { useFileTreeData } from '@/shared/context/file-tree-data-context'
|
||||
import { findDocEntityById } from '@/features/ide-react/util/find-doc-entity-by-id'
|
||||
import {
|
||||
findDocEntityById,
|
||||
findFileRefEntityById,
|
||||
} from '@/features/ide-react/util/find-doc-entity-by-id'
|
||||
import useScopeEventEmitter from '@/shared/hooks/use-scope-event-emitter'
|
||||
import { useModalsContext } from '@/features/ide-react/context/modals-context'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
@@ -32,6 +35,9 @@ import { DocId } from '../../../../../types/project-settings'
|
||||
import { Update } from '@/features/history/services/types/update'
|
||||
import { useDebugDiffTracker } from '../hooks/use-debug-diff-tracker'
|
||||
import { useEditorContext } from '@/shared/context/editor-context'
|
||||
import useScopeValueSetterOnly from '@/shared/hooks/use-scope-value-setter-only'
|
||||
import { BinaryFile } from '@/features/file-view/types/binary-file'
|
||||
import { convertFileRefToBinaryFile } from '@/features/ide-react/util/file-view'
|
||||
|
||||
export interface GotoOffsetOptions {
|
||||
gotoOffset: number
|
||||
@@ -57,6 +63,7 @@ export type EditorManager = {
|
||||
openDocWithId: (docId: string, options?: OpenDocOptions) => void
|
||||
openDoc: (document: Doc, options?: OpenDocOptions) => void
|
||||
openDocs: OpenDocuments
|
||||
openFileWithId: (fileId: string) => void
|
||||
openInitialDoc: (docId: string) => void
|
||||
jumpToLine: (options: GotoLineOptions) => void
|
||||
wantTrackChanges: boolean
|
||||
@@ -94,7 +101,7 @@ export const EditorManagerContext = createContext<EditorManager | undefined>(
|
||||
|
||||
export const EditorManagerProvider: FC = ({ children }) => {
|
||||
const { t } = useTranslation()
|
||||
const ide = useIdeContext()
|
||||
const { scopeStore } = useIdeContext()
|
||||
const { projectId } = useIdeReactContext()
|
||||
const { reportError, eventEmitter } = useIdeReactContext()
|
||||
const { setOutOfSync } = useEditorContext()
|
||||
@@ -203,14 +210,14 @@ export const EditorManagerProvider: FC = ({ children }) => {
|
||||
// implementation in EditorManager interacts with Angular scope to update
|
||||
// the layout. Once Angular is gone, this can become a context method.
|
||||
useEffect(() => {
|
||||
ide.scopeStore.set('editor.toggleSymbolPalette', () => {
|
||||
scopeStore.set('editor.toggleSymbolPalette', () => {
|
||||
setShowSymbolPalette(show => {
|
||||
const newValue = !show
|
||||
sendMB(newValue ? 'symbol-palette-show' : 'symbol-palette-hide')
|
||||
return newValue
|
||||
})
|
||||
})
|
||||
}, [ide.scopeStore, setShowSymbolPalette])
|
||||
}, [scopeStore, setShowSymbolPalette])
|
||||
|
||||
const getEditorType = useCallback((): EditorType | null => {
|
||||
if (!currentDocument) {
|
||||
@@ -443,6 +450,11 @@ export const EditorManagerProvider: FC = ({ children }) => {
|
||||
detail: { isNewDoc, docId: doc._id },
|
||||
})
|
||||
)
|
||||
window.dispatchEvent(
|
||||
new CustomEvent('entity:opened', {
|
||||
detail: doc._id,
|
||||
})
|
||||
)
|
||||
if (hasGotoLine(options)) {
|
||||
window.setTimeout(() => jumpToLine(options))
|
||||
|
||||
@@ -527,6 +539,24 @@ export const EditorManagerProvider: FC = ({ children }) => {
|
||||
[fileTreeData, openDoc]
|
||||
)
|
||||
|
||||
const [, setOpenFile] = useScopeValueSetterOnly<BinaryFile | null>('openFile')
|
||||
|
||||
const openFileWithId = useCallback(
|
||||
(fileRefId: string) => {
|
||||
const fileRef = findFileRefEntityById(fileTreeData, fileRefId)
|
||||
if (!fileRef) {
|
||||
return
|
||||
}
|
||||
setOpenFile(convertFileRefToBinaryFile(fileRef))
|
||||
window.dispatchEvent(
|
||||
new CustomEvent('entity:opened', {
|
||||
detail: fileRef._id,
|
||||
})
|
||||
)
|
||||
},
|
||||
[fileTreeData, setOpenFile]
|
||||
)
|
||||
|
||||
const openInitialDoc = useCallback(
|
||||
(fallbackDocId: string) => {
|
||||
const docId =
|
||||
@@ -655,7 +685,7 @@ export const EditorManagerProvider: FC = ({ children }) => {
|
||||
}
|
||||
}, [currentDocument, syncTrackChangesState, wantTrackChanges])
|
||||
|
||||
const editorManager = useMemo(
|
||||
const value = useMemo(
|
||||
() => ({
|
||||
getEditorType,
|
||||
showSymbolPalette,
|
||||
@@ -668,6 +698,7 @@ export const EditorManagerProvider: FC = ({ children }) => {
|
||||
openDocWithId,
|
||||
openDoc,
|
||||
openDocs,
|
||||
openFileWithId,
|
||||
openInitialDoc,
|
||||
jumpToLine,
|
||||
wantTrackChanges,
|
||||
@@ -686,6 +717,7 @@ export const EditorManagerProvider: FC = ({ children }) => {
|
||||
openDocWithId,
|
||||
openDoc,
|
||||
openDocs,
|
||||
openFileWithId,
|
||||
openInitialDoc,
|
||||
jumpToLine,
|
||||
wantTrackChanges,
|
||||
@@ -694,12 +726,8 @@ export const EditorManagerProvider: FC = ({ children }) => {
|
||||
]
|
||||
)
|
||||
|
||||
// Expose editorManager via ide object because some React code relies on it,
|
||||
// for now
|
||||
ide.editorManager = editorManager
|
||||
|
||||
return (
|
||||
<EditorManagerContext.Provider value={editorManager}>
|
||||
<EditorManagerContext.Provider value={value}>
|
||||
{children}
|
||||
</EditorManagerContext.Provider>
|
||||
)
|
||||
|
||||
@@ -11,8 +11,7 @@ import {
|
||||
import { useProjectContext } from '@/shared/context/project-context'
|
||||
import { useIdeReactContext } from '@/features/ide-react/context/ide-react-context'
|
||||
import { useEditorManagerContext } from '@/features/ide-react/context/editor-manager-context'
|
||||
import { useSelectFileTreeEntity } from '@/features/ide-react/hooks/use-select-file-tree-entity'
|
||||
import useScopeValue from '@/shared/hooks/use-scope-value'
|
||||
import useScopeValueSetterOnly from '@/shared/hooks/use-scope-value-setter-only'
|
||||
import { BinaryFile } from '@/features/file-view/types/binary-file'
|
||||
import {
|
||||
FileTreeDocumentFindResult,
|
||||
@@ -23,7 +22,6 @@ import { debugConsole } from '@/utils/debugging'
|
||||
import { convertFileRefToBinaryFile } from '@/features/ide-react/util/file-view'
|
||||
import { sendMB } from '@/infrastructure/event-tracking'
|
||||
import { FileRef } from '../../../../../types/file-ref'
|
||||
import useEventListener from '@/shared/hooks/use-event-listener'
|
||||
|
||||
const FileTreeOpenContext = createContext<
|
||||
| {
|
||||
@@ -41,8 +39,7 @@ export const FileTreeOpenProvider: FC = ({ children }) => {
|
||||
const { eventEmitter, projectJoined } = useIdeReactContext()
|
||||
const { openDocWithId, currentDocumentId, openInitialDoc } =
|
||||
useEditorManagerContext()
|
||||
const { selectEntity } = useSelectFileTreeEntity()
|
||||
const [, setOpenFile] = useScopeValue<BinaryFile | null>('openFile')
|
||||
const [, setOpenFile] = useScopeValueSetterOnly<BinaryFile | null>('openFile')
|
||||
const [openEntity, setOpenEntity] = useState<
|
||||
FileTreeDocumentFindResult | FileTreeFileRefFindResult | null
|
||||
>(null)
|
||||
@@ -111,20 +108,6 @@ export const FileTreeOpenProvider: FC = ({ children }) => {
|
||||
[eventEmitter, currentDocumentId, openDocWithId, rootDocId]
|
||||
)
|
||||
|
||||
// Synchronize the file tree when openDoc or openDocWithId is called on the editor
|
||||
// manager context from elsewhere. If the file tree does change, it will
|
||||
// trigger the onSelect handler in this component, which will update the local
|
||||
// state.
|
||||
useEventListener(
|
||||
'doc:after-opened',
|
||||
useCallback(
|
||||
(event: CustomEvent<{ docId: string }>) => {
|
||||
selectEntity(event.detail.docId)
|
||||
},
|
||||
[selectEntity]
|
||||
)
|
||||
)
|
||||
|
||||
// Open a document once the file tree and project are ready
|
||||
const initialOpenDoneRef = useRef(false)
|
||||
useEffect(() => {
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
import { useIdeContext } from '@/shared/context/ide-context'
|
||||
import { useFileTreeData } from '@/shared/context/file-tree-data-context'
|
||||
import { useCallback } from 'react'
|
||||
import { findInTree } from '@/features/file-tree/util/find-in-tree'
|
||||
|
||||
export function useOpenFile() {
|
||||
const ide = useIdeContext()
|
||||
|
||||
const { fileTreeData } = useFileTreeData()
|
||||
|
||||
const openFileWithId = useCallback(
|
||||
(id: string) => {
|
||||
const result = findInTree(fileTreeData, id)
|
||||
if (result?.type === 'fileRef') {
|
||||
window.dispatchEvent(new CustomEvent('editor.openDoc', { detail: id }))
|
||||
}
|
||||
},
|
||||
[fileTreeData]
|
||||
)
|
||||
|
||||
// Expose BinaryFilesManager via ide object solely for the benefit of the file
|
||||
// restore feature in history. This can be removed once Angular is gone.
|
||||
ide.binaryFilesManager = { openFileWithId }
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
import { useFileTreeData } from '@/shared/context/file-tree-data-context'
|
||||
import { useCallback } from 'react'
|
||||
import { findInTree } from '@/features/file-tree/util/find-in-tree'
|
||||
|
||||
export function useSelectFileTreeEntity() {
|
||||
const { fileTreeData, selectedEntities } = useFileTreeData()
|
||||
|
||||
const selectEntity = useCallback(
|
||||
id => {
|
||||
if (
|
||||
selectedEntities.length === 1 &&
|
||||
selectedEntities[0].entity._id === id
|
||||
) {
|
||||
return
|
||||
}
|
||||
const entityToSelect = findInTree(fileTreeData, id)
|
||||
if (entityToSelect) {
|
||||
window.dispatchEvent(new CustomEvent('editor.openDoc', { detail: id }))
|
||||
}
|
||||
},
|
||||
[fileTreeData, selectedEntities]
|
||||
)
|
||||
|
||||
return { selectEntity }
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
import { findInTree } from '@/features/file-tree/util/find-in-tree'
|
||||
import { Folder } from '../../../../../types/folder'
|
||||
import { Doc } from '../../../../../types/doc'
|
||||
import { FileRef } from '../../../../../types/file-ref'
|
||||
|
||||
export function findDocEntityById(fileTreeData: Folder, docId: string) {
|
||||
const item = findInTree(fileTreeData, docId)
|
||||
@@ -9,3 +10,11 @@ export function findDocEntityById(fileTreeData: Folder, docId: string) {
|
||||
}
|
||||
return item.entity as Doc
|
||||
}
|
||||
|
||||
export function findFileRefEntityById(fileTreeData: Folder, docId: string) {
|
||||
const item = findInTree(fileTreeData, docId)
|
||||
if (!item || item.type !== 'fileRef') {
|
||||
return null
|
||||
}
|
||||
return item.entity as FileRef
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import classNames from 'classnames'
|
||||
import { memo, useCallback, useEffect, useState, useRef } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { useIdeContext } from '../../../shared/context/ide-context'
|
||||
import { useProjectContext } from '../../../shared/context/project-context'
|
||||
import { getJSON } from '../../../infrastructure/fetch-json'
|
||||
import { useDetachCompileContext as useCompileContext } from '../../../shared/context/detach-compile-context'
|
||||
@@ -25,6 +24,7 @@ import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/boots
|
||||
import MaterialIcon from '@/shared/components/material-icon'
|
||||
import { Spinner } from 'react-bootstrap-5'
|
||||
import { bsVersion } from '@/features/utils/bootstrap-5'
|
||||
import { useEditorManagerContext } from '@/features/ide-react/context/editor-manager-context'
|
||||
|
||||
function GoToCodeButton({
|
||||
position,
|
||||
@@ -170,8 +170,6 @@ function GoToPdfButton({
|
||||
}
|
||||
|
||||
function PdfSynctexControls() {
|
||||
const ide = useIdeContext()
|
||||
|
||||
const { _id: projectId, rootDocId } = useProjectContext()
|
||||
|
||||
const { detachRole } = useLayoutContext()
|
||||
@@ -187,10 +185,11 @@ function PdfSynctexControls() {
|
||||
|
||||
const { selectedEntities } = useFileTreeData()
|
||||
const { findEntityByPath, dirname, pathInFolder } = useFileTreePathContext()
|
||||
const { getCurrentDocumentId, openDocWithId } = useEditorManagerContext()
|
||||
|
||||
const [cursorPosition, setCursorPosition] = useState(() => {
|
||||
const position = localStorage.getItem(
|
||||
`doc.position.${ide.editorManager.getCurrentDocumentId()}`
|
||||
`doc.position.${getCurrentDocumentId()}`
|
||||
)
|
||||
return position ? position.cursorPosition : null
|
||||
})
|
||||
@@ -203,7 +202,7 @@ function PdfSynctexControls() {
|
||||
const listener = event => setCursorPosition(event.detail)
|
||||
window.addEventListener('cursor:editor:update', listener)
|
||||
return () => window.removeEventListener('cursor:editor:update', listener)
|
||||
}, [ide])
|
||||
}, [])
|
||||
|
||||
const [syncToPdfInFlight, setSyncToPdfInFlight] = useState(false)
|
||||
const [syncToCodeInFlight, setSyncToCodeInFlight] = useDetachState(
|
||||
@@ -216,7 +215,7 @@ function PdfSynctexControls() {
|
||||
const [, setSynctexError] = useScopeValue('sync_tex_error')
|
||||
|
||||
const getCurrentFilePath = useCallback(() => {
|
||||
const docId = ide.editorManager.getCurrentDocumentId()
|
||||
const docId = getCurrentDocumentId()
|
||||
let path = pathInFolder(docId)
|
||||
|
||||
// If the root file is folder/main.tex, then synctex sees the path as folder/./main.tex
|
||||
@@ -227,7 +226,7 @@ function PdfSynctexControls() {
|
||||
}
|
||||
|
||||
return path
|
||||
}, [dirname, ide.editorManager, pathInFolder, rootDocId])
|
||||
}, [dirname, getCurrentDocumentId, pathInFolder, rootDocId])
|
||||
|
||||
const goToCodeLine = useCallback(
|
||||
(file, line) => {
|
||||
@@ -238,7 +237,7 @@ function PdfSynctexControls() {
|
||||
return
|
||||
}
|
||||
|
||||
ide.editorManager.openDocWithId(doc._id, {
|
||||
openDocWithId(doc._id, {
|
||||
gotoLine: line,
|
||||
})
|
||||
} else {
|
||||
@@ -251,7 +250,7 @@ function PdfSynctexControls() {
|
||||
}, 4000)
|
||||
}
|
||||
},
|
||||
[findEntityByPath, ide.editorManager, isMounted, setSynctexError]
|
||||
[findEntityByPath, openDocWithId, isMounted, setSynctexError]
|
||||
)
|
||||
|
||||
const goToPdfLocation = useCallback(
|
||||
|
||||
+3
-3
@@ -1,7 +1,7 @@
|
||||
import PropTypes from 'prop-types'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useIdeContext } from '../../../shared/context/ide-context'
|
||||
import { useProjectContext } from '../../../shared/context/project-context'
|
||||
import { useProjectContext } from '@/shared/context/project-context'
|
||||
import { useLocalCompileContext } from '@/shared/context/local-compile-context'
|
||||
import { useWordCount } from '../hooks/use-word-count'
|
||||
import {
|
||||
OLModalBody,
|
||||
@@ -20,7 +20,7 @@ import BootstrapVersionSwitcher from '@/features/ui/components/bootstrap-5/boots
|
||||
// NOTE: this component is only mounted when the modal is open
|
||||
export default function WordCountModalContent({ handleHide }) {
|
||||
const { _id: projectId } = useProjectContext()
|
||||
const { clsiServerId } = useIdeContext()
|
||||
const { clsiServerId } = useLocalCompileContext()
|
||||
const { t } = useTranslation()
|
||||
const { data, error, loading } = useWordCount(projectId, clsiServerId)
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ export const EditorContext = createContext<
|
||||
>(undefined)
|
||||
|
||||
export const EditorProvider: FC = ({ children }) => {
|
||||
const ide = useIdeContext()
|
||||
const { socket } = useIdeContext()
|
||||
const { id: userId, featureUsage } = useUserContext()
|
||||
const { role } = useDetachContext()
|
||||
const { showGenericMessageModal } = useModalsContext()
|
||||
@@ -127,12 +127,11 @@ export const EditorProvider: FC = ({ children }) => {
|
||||
)
|
||||
|
||||
useEffect(() => {
|
||||
if (ide?.socket) {
|
||||
ide.socket.on('projectNameUpdated', setProjectName)
|
||||
return () =>
|
||||
ide.socket.removeListener('projectNameUpdated', setProjectName)
|
||||
if (socket) {
|
||||
socket.on('projectNameUpdated', setProjectName)
|
||||
return () => socket.removeListener('projectNameUpdated', setProjectName)
|
||||
}
|
||||
}, [ide?.socket, setProjectName])
|
||||
}, [socket, setProjectName])
|
||||
|
||||
const renameProject = useCallback(
|
||||
(newName: string) => {
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { createContext, FC, useContext, useEffect, useMemo } from 'react'
|
||||
import { ScopeValueStore } from '../../../../types/ide/scope-value-store'
|
||||
import { ScopeEventEmitter } from '../../../../types/ide/scope-event-emitter'
|
||||
import { Socket } from '@/features/ide-react/connection/types/socket'
|
||||
|
||||
export type Ide = {
|
||||
[key: string]: any // TODO: define the rest of the `ide` and `$scope` properties
|
||||
$scope: Record<string, any>
|
||||
socket: Socket
|
||||
}
|
||||
|
||||
type IdeContextValue = Ide & {
|
||||
|
||||
@@ -28,7 +28,6 @@ import {
|
||||
handleLogFiles,
|
||||
handleOutputFiles,
|
||||
} from '../../features/pdf-preview/util/output-files'
|
||||
import { useIdeContext } from './ide-context'
|
||||
import { useProjectContext } from './project-context'
|
||||
import { useEditorContext } from './editor-context'
|
||||
import { buildFileList } from '../../features/pdf-preview/util/file-list'
|
||||
@@ -112,8 +111,6 @@ export const LocalCompileContext = createContext<CompileContext | undefined>(
|
||||
)
|
||||
|
||||
export const LocalCompileProvider: FC = ({ children }) => {
|
||||
const ide = useIdeContext()
|
||||
|
||||
const { hasPremiumCompile, isProjectOwner } = useEditorContext()
|
||||
const { openDocWithId, openDocs } = useEditorManagerContext()
|
||||
|
||||
@@ -530,7 +527,6 @@ export const LocalCompileProvider: FC = ({ children }) => {
|
||||
}
|
||||
}, [
|
||||
data,
|
||||
ide,
|
||||
alphaProgram,
|
||||
labsProgram,
|
||||
features,
|
||||
|
||||
@@ -53,9 +53,5 @@ export const getMockIde = () => {
|
||||
settings: { syntaxValidation: false, pdfViewer: 'pdfjs' },
|
||||
hasLintingError: false,
|
||||
},
|
||||
editorManager: {
|
||||
openDoc: () => {},
|
||||
getCurrentDocumentId: () => {},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -101,12 +101,6 @@ const initialize = () => {
|
||||
socket: new SocketIOShim.SocketShimNoop(
|
||||
new SocketIOMock()
|
||||
) as unknown as Socket,
|
||||
editorManager: {
|
||||
getCurrentDocumentId: () => 'foo',
|
||||
openDoc: (id: string, options: unknown) => {
|
||||
console.log('open doc', id, options)
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// window.metaAttributesCache is reset in preview.tsx
|
||||
|
||||
@@ -175,50 +175,6 @@ describe('<FileTreeRoot/>', function () {
|
||||
])
|
||||
})
|
||||
|
||||
it('listen to editor.openDoc', function () {
|
||||
const rootFolder = [
|
||||
{
|
||||
_id: 'root-folder-id',
|
||||
name: 'rootFolder',
|
||||
docs: [
|
||||
{ _id: '456def', name: 'main.tex' },
|
||||
{ _id: '789ghi', name: 'other.tex' },
|
||||
],
|
||||
folders: [],
|
||||
fileRefs: [],
|
||||
},
|
||||
]
|
||||
|
||||
cy.mount(
|
||||
<EditorProviders
|
||||
rootFolder={rootFolder as any}
|
||||
projectId="123abc"
|
||||
rootDocId="456def"
|
||||
features={{} as any}
|
||||
permissionsLevel="readOnly"
|
||||
>
|
||||
<FileTreeRoot
|
||||
refProviders={{}}
|
||||
setRefProviderEnabled={cy.stub()}
|
||||
setStartedFreeTrial={cy.stub()}
|
||||
onSelect={cy.stub()}
|
||||
onInit={cy.stub()}
|
||||
isConnected
|
||||
/>
|
||||
</EditorProviders>
|
||||
)
|
||||
|
||||
cy.findByRole('treeitem', { name: 'main.tex', selected: true })
|
||||
|
||||
// entities not found should be ignored
|
||||
cy.document().trigger('editor.openDoc', { detail: 'not-an-id' })
|
||||
cy.findByRole('treeitem', { name: 'main.tex', selected: true })
|
||||
|
||||
cy.document().trigger('editor.openDoc', { detail: '789ghi' })
|
||||
cy.findByRole('treeitem', { name: 'main.tex', selected: false })
|
||||
cy.findByRole('treeitem', { name: 'other.tex', selected: true })
|
||||
})
|
||||
|
||||
it('only shows a menu button when a single item is selected', function () {
|
||||
const rootFolder = [
|
||||
{
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import 'recurly__recurly-js'
|
||||
import { ScopeValueStore } from './ide/scope-value-store'
|
||||
import { MetaAttributesCache } from '@/utils/meta'
|
||||
import { Socket } from '@/features/ide-react/connection/types/socket'
|
||||
|
||||
declare global {
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
@@ -12,10 +13,7 @@ declare global {
|
||||
logEntryAnnotations: Record<string, unknown>
|
||||
}
|
||||
}
|
||||
socket: {
|
||||
on: (event: string, listener: any) => void
|
||||
removeListener: (event: string, listener: any) => void
|
||||
}
|
||||
socket: Socket
|
||||
}
|
||||
MathJax: Record<string, any>
|
||||
crypto: {
|
||||
|
||||
Reference in New Issue
Block a user