diff --git a/services/web/frontend/js/features/ide-react/components/editor/editor-pane.tsx b/services/web/frontend/js/features/ide-react/components/editor/editor-pane.tsx index 4f5f816eef..cae4d1368a 100644 --- a/services/web/frontend/js/features/ide-react/components/editor/editor-pane.tsx +++ b/services/web/frontend/js/features/ide-react/components/editor/editor-pane.tsx @@ -19,18 +19,12 @@ const SymbolPalettePane = lazy( export const EditorPane: FC = () => { const [editor] = useScopeValue('editor') const { selectedEntityCount, openEntity } = useFileTreeOpenContext() - const { currentDocumentId } = useEditorManagerContext() + const { currentDocumentId, isLoading } = useEditorManagerContext() if (!currentDocumentId) { return null } - const isLoading = Boolean( - (!editor.sharejs_doc || editor.opening) && - !editor.error_state && - editor.open_doc_id - ) - return (
EditorType | null showSymbolPalette: boolean - currentDocument: DocumentContainer + currentDocument: DocumentContainer | null currentDocumentId: DocId | null getCurrentDocValue: () => string | null getCurrentDocumentId: () => DocId | null @@ -65,6 +65,10 @@ export type EditorManager = { openDocs: OpenDocuments openFileWithId: (fileId: string) => void openInitialDoc: (docId: string) => void + openDocName: string | null + setOpenDocName: (openDocName: string) => void + isLoading: boolean + trackChanges: boolean jumpToLine: (options: GotoLineOptions) => void wantTrackChanges: boolean setWantTrackChanges: React.Dispatch< @@ -102,8 +106,7 @@ export const EditorManagerContext = createContext( export const EditorManagerProvider: FC = ({ children }) => { const { t } = useTranslation() const { scopeStore } = useIdeContext() - const { projectId } = useIdeReactContext() - const { reportError, eventEmitter } = useIdeReactContext() + const { reportError, eventEmitter, projectId } = useIdeReactContext() const { setOutOfSync } = useEditorContext() const { socket, closeConnection, connectionState } = useConnectionContext() const { view, setView } = useLayoutContext() @@ -115,16 +118,19 @@ export const EditorManagerProvider: FC = ({ children }) => { ) const [showVisual] = useScopeValue('editor.showVisual') const [currentDocument, setCurrentDocument] = - useScopeValue('editor.sharejs_doc') + useScopeValue('editor.sharejs_doc') const [currentDocumentId, setCurrentDocumentId] = useScopeValue( 'editor.open_doc_id' ) - const [, setOpenDocName] = useScopeValue( + const [openDocName, setOpenDocName] = useScopeValue( 'editor.open_doc_name' ) - const [, setOpening] = useScopeValue('editor.opening') - const [, setIsInErrorState] = useScopeValue('editor.error_state') - const [, setTrackChanges] = useScopeValue('editor.trackChanges') + const [opening, setOpening] = useScopeValue('editor.opening') + const [errorState, setIsInErrorState] = + useScopeValue('editor.error_state') + const [trackChanges, setTrackChanges] = useScopeValue( + 'editor.trackChanges' + ) const [wantTrackChanges, setWantTrackChanges] = useScopeValue( 'editor.wantTrackChanges' ) @@ -385,7 +391,7 @@ export const EditorManagerProvider: FC = ({ children }) => { // - when the current one has pending ops that need flushing, to avoid // race conditions from cleanup const currentDocumentId = currentDocument?.doc_id - const hasBufferedOps = currentDocument?.hasBufferedOps() + const hasBufferedOps = currentDocument && currentDocument.hasBufferedOps() const changingDoc = currentDocument && currentDocumentId !== doc._id if (changingDoc || hasBufferedOps) { debugConsole.log('[openNewDocument] Leaving existing open doc...') @@ -679,13 +685,20 @@ export const EditorManagerProvider: FC = ({ children }) => { // Watch for changes in wantTrackChanges const previousWantTrackChangesRef = useRef(wantTrackChanges) useEffect(() => { - if (wantTrackChanges !== previousWantTrackChangesRef.current) { + if ( + currentDocument && + wantTrackChanges !== previousWantTrackChangesRef.current + ) { previousWantTrackChangesRef.current = wantTrackChanges syncTrackChangesState(currentDocument) } }, [currentDocument, syncTrackChangesState, wantTrackChanges]) - const value = useMemo( + const isLoading = Boolean( + (!currentDocument || opening) && !errorState && currentDocumentId + ) + + const value: EditorManager = useMemo( () => ({ getEditorType, showSymbolPalette, @@ -698,6 +711,10 @@ export const EditorManagerProvider: FC = ({ children }) => { openDocWithId, openDoc, openDocs, + openDocName, + setOpenDocName, + trackChanges, + isLoading, openFileWithId, openInitialDoc, jumpToLine, @@ -719,6 +736,10 @@ export const EditorManagerProvider: FC = ({ children }) => { openDocs, openFileWithId, openInitialDoc, + openDocName, + setOpenDocName, + trackChanges, + isLoading, jumpToLine, wantTrackChanges, setWantTrackChanges, diff --git a/services/web/frontend/js/features/ide-react/context/online-users-context.tsx b/services/web/frontend/js/features/ide-react/context/online-users-context.tsx index 685baa10be..15a1a15a60 100644 --- a/services/web/frontend/js/features/ide-react/context/online-users-context.tsx +++ b/services/web/frontend/js/features/ide-react/context/online-users-context.tsx @@ -20,6 +20,7 @@ import useSocketListener from '@/features/ide-react/hooks/use-socket-listener' import { debugConsole } from '@/utils/debugging' import { IdeEvents } from '@/features/ide-react/create-ide-event-emitter' import { getHueForUserId } from '@/shared/utils/colors' +import { useEditorManagerContext } from '@/features/ide-react/context/editor-manager-context' export type OnlineUser = { id: string @@ -76,7 +77,7 @@ const OnlineUsersContext = createContext( export const OnlineUsersProvider: FC = ({ children }) => { const { eventEmitter } = useIdeReactContext() const { socket } = useConnectionContext() - const [currentDocumentId] = useScopeValue('editor.open_doc_id') + const { currentDocumentId } = useEditorManagerContext() const { fileTreeData } = useFileTreeData() const [onlineUsers, setOnlineUsers] = diff --git a/services/web/frontend/js/features/ide-react/context/outline-context.tsx b/services/web/frontend/js/features/ide-react/context/outline-context.tsx index ddba020677..41c2c7b0f1 100644 --- a/services/web/frontend/js/features/ide-react/context/outline-context.tsx +++ b/services/web/frontend/js/features/ide-react/context/outline-context.tsx @@ -11,10 +11,10 @@ import { import useScopeEventEmitter from '@/shared/hooks/use-scope-event-emitter' import useEventListener from '@/shared/hooks/use-event-listener' import * as eventTracking from '@/infrastructure/event-tracking' -import useScopeValue from '@/shared/hooks/use-scope-value' import { isValidTeXFile } from '@/main/is-valid-tex-file' import localStorage from '@/infrastructure/local-storage' import { useProjectContext } from '@/shared/context/project-context' +import { useEditorManagerContext } from '@/features/ide-react/context/editor-manager-context' export type PartialFlatOutline = { level: number @@ -118,10 +118,10 @@ export const OutlineProvider: FC = ({ children }) => { [flatOutline, currentlyHighlightedLine] ) - const [docName] = useScopeValue('editor.open_doc_name') + const { openDocName } = useEditorManagerContext() const isTexFile = useMemo( - () => (docName ? isValidTeXFile(docName) : false), - [docName] + () => (openDocName ? isValidTeXFile(openDocName) : false), + [openDocName] ) const { _id: projectId } = useProjectContext() diff --git a/services/web/frontend/js/features/ide-react/context/review-panel/hooks/use-review-panel-state.ts b/services/web/frontend/js/features/ide-react/context/review-panel/hooks/use-review-panel-state.ts index c758e9e7d3..e9d467a216 100644 --- a/services/web/frontend/js/features/ide-react/context/review-panel/hooks/use-review-panel-state.ts +++ b/services/web/frontend/js/features/ide-react/context/review-panel/hooks/use-review-panel-state.ts @@ -495,11 +495,13 @@ function useReviewPanelState(): ReviewPanel.ReviewPanelState { const regenerateTrackChangesId = useCallback( (doc: typeof currentDocument) => { - const currentChangeTracker = getChangeTracker(doc.doc_id as DocId) - const oldId = currentChangeTracker.getIdSeed() - const newId = RangesTracker.generateIdSeed() - currentChangeTracker.setIdSeed(newId) - doc.setTrackChangesIdSeeds({ pending: newId, inflight: oldId }) + if (doc) { + const currentChangeTracker = getChangeTracker(doc.doc_id as DocId) + const oldId = currentChangeTracker.getIdSeed() + const newId = RangesTracker.generateIdSeed() + currentChangeTracker.setIdSeed(newId) + doc.setTrackChangesIdSeeds({ pending: newId, inflight: oldId }) + } }, [getChangeTracker] ) diff --git a/services/web/frontend/js/features/ide-react/hooks/use-debug-diff-tracker.ts b/services/web/frontend/js/features/ide-react/hooks/use-debug-diff-tracker.ts index 4cfea1188e..af5938eb9b 100644 --- a/services/web/frontend/js/features/ide-react/hooks/use-debug-diff-tracker.ts +++ b/services/web/frontend/js/features/ide-react/hooks/use-debug-diff-tracker.ts @@ -49,7 +49,7 @@ async function tryGetDiffSize( export const useDebugDiffTracker = ( projectId: string, - currentDocument: DocumentContainer + currentDocument: DocumentContainer | null ) => { const debugCurrentDocument = useRef(null) const debugProjectId = useRef(null) diff --git a/services/web/frontend/js/features/ide-react/scope-adapters/editor-manager-context-adapter.ts b/services/web/frontend/js/features/ide-react/scope-adapters/editor-manager-context-adapter.ts index 89bdc38c21..5083066986 100644 --- a/services/web/frontend/js/features/ide-react/scope-adapters/editor-manager-context-adapter.ts +++ b/services/web/frontend/js/features/ide-react/scope-adapters/editor-manager-context-adapter.ts @@ -6,10 +6,6 @@ export function populateEditorScope( store: ReactScopeValueStore, projectId: string ) { - // This value is not used in the React code. It's just here to prevent errors - // from EditorProvider - store.set('state.loading', false) - store.set('project.name', null) store.set('editor', { diff --git a/services/web/frontend/js/features/review-panel-new/context/ranges-context.tsx b/services/web/frontend/js/features/review-panel-new/context/ranges-context.tsx index 1384d6f18f..bf2d63a81d 100644 --- a/services/web/frontend/js/features/review-panel-new/context/ranges-context.tsx +++ b/services/web/frontend/js/features/review-panel-new/context/ranges-context.tsx @@ -7,7 +7,6 @@ import { useMemo, useState, } from 'react' -import useScopeValue from '@/shared/hooks/use-scope-value' import { DocumentContainer } from '@/features/ide-react/editor/document-container' import { Change, @@ -22,6 +21,7 @@ import { useIdeReactContext } from '@/features/ide-react/context/ide-react-conte import { useConnectionContext } from '@/features/ide-react/context/connection-context' import useSocketListener from '@/features/ide-react/hooks/use-socket-listener' import { throttle } from 'lodash' +import { useEditorManagerContext } from '@/features/ide-react/context/editor-manager-context' export type Ranges = { docId: string @@ -37,8 +37,8 @@ type RangesActions = { rejectChanges: (...ids: string[]) => void } -const buildRanges = (currentDoc: DocumentContainer | null) => { - const ranges = currentDoc?.ranges +const buildRanges = (currentDocument: DocumentContainer | null) => { + const ranges = currentDocument?.ranges if (!ranges) { return undefined @@ -73,7 +73,7 @@ const buildRanges = (currentDoc: DocumentContainer | null) => { changed.comments.has(comment.id) ? { ...comment } : comment ) : ranges.comments, - docId: currentDoc.doc_id, + docId: currentDocument.doc_id, total: ranges.changes.length + ranges.comments.length, } } @@ -83,46 +83,44 @@ const RangesActionsContext = createContext(undefined) export const RangesProvider: FC = ({ children }) => { const view = useCodeMirrorViewContext() const { projectId } = useIdeReactContext() - const [currentDoc] = useScopeValue( - 'editor.sharejs_doc' - ) + const { currentDocument } = useEditorManagerContext() const { socket } = useConnectionContext() const [ranges, setRanges] = useState(() => - buildRanges(currentDoc) + buildRanges(currentDocument) ) // rebuild the ranges when the current doc changes useEffect(() => { - setRanges(buildRanges(currentDoc)) - }, [currentDoc]) + setRanges(buildRanges(currentDocument)) + }, [currentDocument]) useEffect(() => { - if (currentDoc) { + if (currentDocument) { const listener = throttle( () => { window.setTimeout(() => { - setRanges(buildRanges(currentDoc)) + setRanges(buildRanges(currentDocument)) }) }, 500, { leading: true, trailing: true } ) - // currentDoc.on('ranges:clear.cm6', listener) - currentDoc.on('ranges:redraw.cm6', listener) - currentDoc.on('ranges:dirty.cm6', listener) + // currentDocument.on('ranges:clear.cm6', listener) + currentDocument.on('ranges:redraw.cm6', listener) + currentDocument.on('ranges:dirty.cm6', listener) return () => { - // currentDoc.off('ranges:clear.cm6') - currentDoc.off('ranges:redraw.cm6') - currentDoc.off('ranges:dirty.cm6') + // currentDocument.off('ranges:clear.cm6') + currentDocument.off('ranges:redraw.cm6') + currentDocument.off('ranges:dirty.cm6') } } - }, [currentDoc]) + }, [currentDocument]) // TODO: move this into DocumentContainer? useEffect(() => { - if (currentDoc) { + if (currentDocument) { const regenerateTrackChangesId = (doc: DocumentContainer) => { if (doc.ranges) { const inflight = doc.ranges.getIdSeed() @@ -132,51 +130,51 @@ export const RangesProvider: FC = ({ children }) => { } } - currentDoc.on('flipped_pending_to_inflight', () => - regenerateTrackChangesId(currentDoc) + currentDocument.on('flipped_pending_to_inflight', () => + regenerateTrackChangesId(currentDocument) ) - regenerateTrackChangesId(currentDoc) + regenerateTrackChangesId(currentDocument) return () => { - currentDoc.off('flipped_pending_to_inflight') + currentDocument.off('flipped_pending_to_inflight') } } - }, [currentDoc]) + }, [currentDocument]) useSocketListener( socket, 'accept-changes', useCallback( (docId: string, entryIds: string[]) => { - if (currentDoc?.ranges) { - if (docId === currentDoc.doc_id) { - currentDoc.ranges.removeChangeIds(entryIds) - setRanges(buildRanges(currentDoc)) + if (currentDocument?.ranges) { + if (docId === currentDocument.doc_id) { + currentDocument.ranges.removeChangeIds(entryIds) + setRanges(buildRanges(currentDocument)) } } }, - [currentDoc] + [currentDocument] ) ) const actions = useMemo( () => ({ async acceptChanges(...ids: string[]) { - if (currentDoc?.ranges) { - const url = `/project/${projectId}/doc/${currentDoc.doc_id}/changes/accept` + if (currentDocument?.ranges) { + const url = `/project/${projectId}/doc/${currentDocument.doc_id}/changes/accept` await postJSON(url, { body: { change_ids: ids } }) - currentDoc.ranges.removeChangeIds(ids) - setRanges(buildRanges(currentDoc)) + currentDocument.ranges.removeChangeIds(ids) + setRanges(buildRanges(currentDocument)) } }, rejectChanges(...ids: string[]) { - if (currentDoc?.ranges) { - view.dispatch(rejectChanges(view.state, currentDoc.ranges, ids)) + if (currentDocument?.ranges) { + view.dispatch(rejectChanges(view.state, currentDocument.ranges, ids)) } }, }), - [currentDoc, projectId, view] + [currentDocument, projectId, view] ) return ( diff --git a/services/web/frontend/js/features/review-panel-new/context/threads-context.tsx b/services/web/frontend/js/features/review-panel-new/context/threads-context.tsx index fefb06b353..4bf5b002f7 100644 --- a/services/web/frontend/js/features/review-panel-new/context/threads-context.tsx +++ b/services/web/frontend/js/features/review-panel-new/context/threads-context.tsx @@ -20,8 +20,7 @@ import { UserId } from '../../../../../types/user' import { deleteJSON, getJSON, postJSON } from '@/infrastructure/fetch-json' import RangesTracker from '@overleaf/ranges-tracker' import { CommentOperation } from '../../../../../types/change' -import useScopeValue from '@/shared/hooks/use-scope-value' -import { DocumentContainer } from '@/features/ide-react/editor/document-container' +import { useEditorManagerContext } from '@/features/ide-react/context/editor-manager-context' export type Threads = Record @@ -47,10 +46,7 @@ const ThreadsActionsContext = createContext( export const ThreadsProvider: FC = ({ children }) => { const { _id: projectId } = useProjectContext() - - const [currentDoc] = useScopeValue( - 'editor.sharejs_doc' - ) + const { currentDocument } = useEditorManagerContext() // const [error, setError] = useState() const [data, setData] = useState() @@ -254,23 +250,23 @@ export const ThreadsProvider: FC = ({ children }) => { t: threadId, } - currentDoc?.submitOp(op) + currentDocument?.submitOp(op) }, async resolveThread(threadId: string) { await postJSON( - `/project/${projectId}/doc/${currentDoc?.doc_id}/thread/${threadId}/resolve` + `/project/${projectId}/doc/${currentDocument?.doc_id}/thread/${threadId}/resolve` ) }, async reopenThread(threadId: string) { await postJSON( - `/project/${projectId}/doc/${currentDoc?.doc_id}/thread/${threadId}/reopen` + `/project/${projectId}/doc/${currentDocument?.doc_id}/thread/${threadId}/reopen` ) }, async deleteThread(threadId: string) { await deleteJSON( - `/project/${projectId}/doc/${currentDoc?.doc_id}/thread/${threadId}` + `/project/${projectId}/doc/${currentDocument?.doc_id}/thread/${threadId}` ) - currentDoc?.ranges?.removeCommentId(threadId) + currentDocument?.ranges?.removeCommentId(threadId) }, async addMessage(threadId: ThreadId, content: string) { await postJSON(`/project/${projectId}/thread/${threadId}/messages`, { @@ -293,7 +289,7 @@ export const ThreadsProvider: FC = ({ children }) => { ) }, }), - [currentDoc, projectId] + [currentDocument, projectId] ) return ( diff --git a/services/web/frontend/js/features/source-editor/components/editor-switch.tsx b/services/web/frontend/js/features/source-editor/components/editor-switch.tsx index 8df024ee99..bdeecfad79 100644 --- a/services/web/frontend/js/features/source-editor/components/editor-switch.tsx +++ b/services/web/frontend/js/features/source-editor/components/editor-switch.tsx @@ -9,14 +9,15 @@ import { EditorSwitchBeginnerTooltip, codeEditorModePrompt, } from './editor-switch-beginner-tooltip' +import { useEditorManagerContext } from '@/features/ide-react/context/editor-manager-context' function EditorSwitch() { const { t } = useTranslation() const [visual, setVisual] = useScopeValue('editor.showVisual') - const [docName] = useScopeValue('editor.open_doc_name') const [codeEditorOpened] = useScopeValue('editor.codeEditorOpened') + const { openDocName } = useEditorManagerContext() - const richTextAvailable = isValidTeXFile(docName) + const richTextAvailable = openDocName ? isValidTeXFile(openDocName) : false const { completeTutorial } = useTutorial(codeEditorModePrompt, { location: 'logs', name: codeEditorModePrompt, diff --git a/services/web/frontend/js/features/source-editor/hooks/use-codemirror-scope.ts b/services/web/frontend/js/features/source-editor/hooks/use-codemirror-scope.ts index 796c4652a1..9e593196a5 100644 --- a/services/web/frontend/js/features/source-editor/hooks/use-codemirror-scope.ts +++ b/services/web/frontend/js/features/source-editor/hooks/use-codemirror-scope.ts @@ -46,7 +46,6 @@ import { setDocName } from '@/features/source-editor/extensions/doc-name' import { isValidTeXFile } from '@/main/is-valid-tex-file' import { captureException } from '@/infrastructure/error-reporter' import grammarlyExtensionPresent from '@/shared/utils/grammarly' -import { DocumentContainer } from '@/features/ide-react/editor/document-container' import { useLayoutContext } from '@/shared/context/layout-context' import { debugConsole } from '@/utils/debugging' import { useMetadataContext } from '@/features/ide-react/context/metadata-context' @@ -60,6 +59,7 @@ import { useHunspell } from '@/features/source-editor/hooks/use-hunspell' import { isBootstrap5 } from '@/features/utils/bootstrap-5' import { Permissions } from '@/features/ide-react/types/permissions' import { lineHeights } from '@/shared/utils/styles' +import { useEditorManagerContext } from '@/features/ide-react/context/editor-manager-context' function useCodeMirrorScope(view: EditorView) { const { fileTreeData } = useFileTreeData() @@ -72,17 +72,12 @@ function useCodeMirrorScope(view: EditorView) { useCompileContext() const { reviewPanelOpen, miniReviewPanelVisible } = useLayoutContext() - + const { currentDocument, openDocName, trackChanges } = + useEditorManagerContext() const metadata = useMetadataContext() const [loadingThreads] = useScopeValue('loadingThreads') - const [currentDoc] = useScopeValue( - 'editor.sharejs_doc' - ) - const [docName] = useScopeValue('editor.open_doc_name') - const [trackChanges] = useScopeValue('editor.trackChanges') - const { id: userId } = useUserContext() const { userSettings } = useUserSettingsContext() const { @@ -174,16 +169,16 @@ function useCodeMirrorScope(view: EditorView) { }) const currentDocRef = useRef({ - currentDoc, + currentDocument, trackChanges, loadingThreads, }) useEffect(() => { - if (currentDoc) { - currentDocRef.current.currentDoc = currentDoc + if (currentDocument) { + currentDocRef.current.currentDocument = currentDocument } - }, [view, currentDoc]) + }, [view, currentDocument]) useEffect(() => { if (ranges && threads) { @@ -193,7 +188,7 @@ function useCodeMirrorScope(view: EditorView) { } }, [view, ranges, threads]) - const docNameRef = useRef(docName) + const docNameRef = useRef(openDocName) useEffect(() => { currentDocRef.current.loadingThreads = loadingThreads @@ -202,14 +197,14 @@ function useCodeMirrorScope(view: EditorView) { useEffect(() => { currentDocRef.current.trackChanges = trackChanges - if (currentDoc) { + if (currentDocument) { if (trackChanges) { - currentDoc.track_changes_as = userId || 'anonymous' + currentDocument.track_changes_as = userId || 'anonymous' } else { - currentDoc.track_changes_as = null + currentDocument.track_changes_as = null } } - }, [userId, currentDoc, trackChanges]) + }, [userId, currentDocument, trackChanges]) useEffect(() => { if (lineHeight && fontSize) { @@ -287,7 +282,7 @@ function useCodeMirrorScope(view: EditorView) { const { previewByPath } = useFileTreePathContext() - const showVisual = visual && isValidTeXFile(docName) + const showVisual = visual && !!openDocName && isValidTeXFile(openDocName) const visualRef = useRef({ previewByPath, @@ -312,18 +307,18 @@ function useCodeMirrorScope(view: EditorView) { }) }, []) - // create a new state when currentDoc changes + // create a new state when currentDocument changes useEffect(() => { - if (currentDoc) { + if (currentDocument) { debugConsole.log('creating new editor state') const state = EditorState.create({ - doc: currentDoc.getSnapshot(), + doc: currentDocument.getSnapshot(), extensions: createExtensions({ currentDoc: { ...currentDocRef.current, - currentDoc, + currentDoc: currentDocument, }, docName: docNameRef.current, theme: themeRef.current, @@ -333,7 +328,7 @@ function useCodeMirrorScope(view: EditorView) { spelling: spellingRef.current, visual: visualRef.current, projectFeatures: projectFeaturesRef.current, - changeManager: createChangeManager(view, currentDoc), + changeManager: createChangeManager(view, currentDocument), handleError, handleException, }), @@ -342,7 +337,7 @@ function useCodeMirrorScope(view: EditorView) { // synchronous config view.dispatch( - restoreCursorPosition(state.doc, currentDoc.doc_id), + restoreCursorPosition(state.doc, currentDocument.doc_id), setEditable(editableRef.current), setOptionsTheme(themeRef.current) ) @@ -363,26 +358,26 @@ function useCodeMirrorScope(view: EditorView) { }) } } - // IMPORTANT: This effect must not depend on anything variable apart from currentDoc, + // IMPORTANT: This effect must not depend on anything variable apart from currentDocument, // as the editor state is recreated when the effect runs. - }, [view, currentDoc, handleError, handleException]) + }, [view, currentDocument, handleError, handleException]) useEffect(() => { - if (docName) { - docNameRef.current = docName + if (openDocName) { + docNameRef.current = openDocName window.setTimeout(() => { view.dispatch( - setDocName(docNameRef.current), + setDocName(openDocName), setLanguage( - docNameRef.current, + openDocName, metadataRef.current, settingsRef.current.syntaxValidation ) ) }) } - }, [view, docName]) + }, [view, openDocName]) useEffect(() => { visualRef.current.visual = showVisual @@ -545,8 +540,8 @@ function useCodeMirrorScope(view: EditorView) { // set the compile log annotations when they change useEffect(() => { - if (currentDoc && logEntryAnnotations) { - const annotations = logEntryAnnotations[currentDoc.doc_id] + if (currentDocument && logEntryAnnotations) { + const annotations = logEntryAnnotations[currentDocument.doc_id] window.setTimeout(() => { view.dispatch( @@ -556,21 +551,21 @@ function useCodeMirrorScope(view: EditorView) { ) }) } - }, [view, currentDoc, logEntryAnnotations]) + }, [view, currentDocument, logEntryAnnotations]) const highlightsRef = useRef<{ cursorHighlights: Highlight[] }>({ cursorHighlights: [], }) useEffect(() => { - if (cursorHighlights && currentDoc) { - const items = cursorHighlights[currentDoc.doc_id] + if (cursorHighlights && currentDocument) { + const items = cursorHighlights[currentDocument.doc_id] highlightsRef.current.cursorHighlights = items window.setTimeout(() => { view.dispatch(setCursorHighlights(items)) }) } - }, [view, cursorHighlights, currentDoc]) + }, [view, cursorHighlights, currentDocument]) useEventListener( 'editor:focus', diff --git a/services/web/frontend/js/shared/context/editor-context.tsx b/services/web/frontend/js/shared/context/editor-context.tsx index f0d0739595..0508eaffe1 100644 --- a/services/web/frontend/js/shared/context/editor-context.tsx +++ b/services/web/frontend/js/shared/context/editor-context.tsx @@ -34,7 +34,6 @@ export const EditorContext = createContext< submitBtnHtml?: string } hasPremiumCompile?: boolean - loading?: boolean renameProject: (newName: string) => void setPermissionsLevel: (permissionsLevel: PermissionsLevel) => void showSymbolPalette?: boolean @@ -84,7 +83,6 @@ export const EditorProvider: FC = ({ children }) => { ) }, []) - const [loading] = useScopeValue('state.loading') const [projectName, setProjectName] = useScopeValue('project.name') const [permissionsLevel, setPermissionsLevel] = useScopeValue('permissionsLevel') @@ -188,7 +186,6 @@ export const EditorProvider: FC = ({ children }) => { () => ({ cobranding, hasPremiumCompile: features?.compileGroup === 'priority', - loading, renameProject, permissionsLevel: outOfSync ? 'readOnly' : permissionsLevel, setPermissionsLevel, @@ -215,7 +212,6 @@ export const EditorProvider: FC = ({ children }) => { features?.compileGroup, owner, userId, - loading, renameProject, permissionsLevel, setPermissionsLevel, diff --git a/services/web/frontend/js/shared/context/local-compile-context.tsx b/services/web/frontend/js/shared/context/local-compile-context.tsx index c4be1c1d63..9eaec47428 100644 --- a/services/web/frontend/js/shared/context/local-compile-context.tsx +++ b/services/web/frontend/js/shared/context/local-compile-context.tsx @@ -112,7 +112,7 @@ export const LocalCompileContext = createContext( export const LocalCompileProvider: FC = ({ children }) => { const { hasPremiumCompile, isProjectOwner } = useEditorContext() - const { openDocWithId, openDocs } = useEditorManagerContext() + const { openDocWithId, openDocs, currentDocument } = useEditorManagerContext() const { _id: projectId, rootDocId } = useProjectContext() @@ -248,9 +248,6 @@ export const LocalCompileProvider: FC = ({ children }) => { true ) - // the Document currently open in the editor - const [currentDoc] = useScopeValue('editor.sharejs_doc') - // whether the editor linter found errors const [hasLintingError, setHasLintingError] = useScopeValue('hasLintingError') @@ -302,8 +299,8 @@ export const LocalCompileProvider: FC = ({ children }) => { // keep currentDoc in sync with the compiler useEffect(() => { - compiler.currentDoc = currentDoc - }, [compiler, currentDoc]) + compiler.currentDoc = currentDocument + }, [compiler, currentDocument]) // keep the project rootDocId in sync with the compiler useEffect(() => { @@ -330,11 +327,11 @@ export const LocalCompileProvider: FC = ({ children }) => { // always compile the PDF once after opening the project, after the doc has loaded useEffect(() => { - if (!compiledOnce && currentDoc) { + if (!compiledOnce && currentDocument) { setCompiledOnce(true) compiler.compile({ isAutoCompileOnLoad: true }) } - }, [compiledOnce, currentDoc, compiler]) + }, [compiledOnce, currentDocument, compiler]) useEffect(() => { setHasShortCompileTimeout( diff --git a/services/web/frontend/js/shared/context/mock/mock-ide.js b/services/web/frontend/js/shared/context/mock/mock-ide.js index 96bfbd4533..822d3b165c 100644 --- a/services/web/frontend/js/shared/context/mock/mock-ide.js +++ b/services/web/frontend/js/shared/context/mock/mock-ide.js @@ -32,7 +32,6 @@ export const getMockIde = () => { email: '', }, }, - state: { loading: false }, permissionsLevel: 'readOnly', editor: { sharejs_doc: null,