From 165520a6f2ad2d6aaa6902d90eaeddcfeb09bef6 Mon Sep 17 00:00:00 2001 From: Alf Eaton Date: Fri, 8 Oct 2021 10:51:04 +0100 Subject: [PATCH] Refactor scoped layout values into LayoutContext (#5356) GitOrigin-RevId: b0b07ddd078bfc5acd944cac14bc00dc83d09d21 --- .../contexts/pdf-preview-context.js | 47 +++++------- .../js/shared/context/compile-context.js | 73 +++++++++++++++---- .../js/shared/context/layout-context.js | 29 ++++++-- 3 files changed, 101 insertions(+), 48 deletions(-) diff --git a/services/web/frontend/js/features/pdf-preview/contexts/pdf-preview-context.js b/services/web/frontend/js/features/pdf-preview/contexts/pdf-preview-context.js index 6147df1d91..0e0bbb16f7 100644 --- a/services/web/frontend/js/features/pdf-preview/contexts/pdf-preview-context.js +++ b/services/web/frontend/js/features/pdf-preview/contexts/pdf-preview-context.js @@ -23,6 +23,8 @@ import { useEditorContext } from '../../../shared/context/editor-context' import useAbortController from '../../../shared/hooks/use-abort-controller' import DocumentCompiler from '../util/compiler' import { useIdeContext } from '../../../shared/context/ide-context' +import { useLayoutContext } from '../../../shared/context/layout-context' +import { useCompileContext } from '../../../shared/context/compile-context' export const PdfPreviewContext = createContext(undefined) @@ -33,35 +35,26 @@ PdfPreviewProvider.propTypes = { export default function PdfPreviewProvider({ children }) { const ide = useIdeContext() + const { pdfHidden, pdfLayout, setPdfLayout, setView } = useLayoutContext() + const project = useProjectContext() const projectId = project._id const { hasPremiumCompile, isProjectOwner } = useEditorContext() - // the URL for loading the PDF in the preview pane - const [pdfUrl, setPdfUrl] = useScopeValue('pdf.url') - - // the URL for downloading the PDF - const [pdfDownloadUrl, setPdfDownloadUrl] = useScopeValue('pdf.downloadUrl') - - // the log entries parsed from the compile output log - const [logEntries, setLogEntries] = useScopeValue('pdf.logEntries') - - // the project is considered to be "uncompiled" if a doc has changed since the last compile started - const [uncompiled, setUncompiled] = useScopeValue('pdf.uncompiled') - - // annotations for display in the editor, built from the log entries - const [, setLogEntryAnnotations] = useScopeValue('pdf.logEntryAnnotations') - - // the id of the CLSI server which ran the compile - const [, setClsiServerId] = useScopeValue('pdf.clsiServerId') - - // whether to display the editor and preview side-by-side or full-width ("flat") - const [pdfLayout, setPdfLayout] = useScopeValue('ui.pdfLayout') - - // what to show in the "flat" view (editor or pdf) - const [, setUiView] = useScopeValue('ui.view') + const { + logEntries, + pdfDownloadUrl, + pdfUrl, + setClsiServerId, + setLogEntries, + setLogEntryAnnotations, + setPdfDownloadUrl, + setPdfUrl, + setUncompiled, + uncompiled, + } = useCompileContext() // whether a compile is in progress const [compiling, setCompiling] = useState(false) @@ -110,9 +103,6 @@ export default function PdfPreviewProvider({ children }) { // the Document currently open in the editor const [currentDoc] = useScopeValue('editor.sharejs_doc') - // whether the PDF view is hidden - const [pdfHidden] = useScopeValue('ui.pdfHidden') - // whether the editor linter found errors const [hasLintingError, setHasLintingError] = useScopeValue('hasLintingError') @@ -379,14 +369,15 @@ export default function PdfPreviewProvider({ children }) { }, [clearCache, compiler]) // switch to either side-by-side or flat (full-width) layout + // TODO: move this into LayoutContext? const switchLayout = useCallback(() => { setPdfLayout(layout => { const newLayout = layout === 'sideBySide' ? 'flat' : 'sideBySide' - setUiView(newLayout === 'sideBySide' ? 'editor' : 'pdf') + setView(newLayout === 'sideBySide' ? 'editor' : 'pdf') setPdfLayout(newLayout) window.localStorage.setItem('pdf.layout', newLayout) }) - }, [setPdfLayout, setUiView]) + }, [setPdfLayout, setView]) // the context value, memoized to minimize re-rendering const value = useMemo(() => { diff --git a/services/web/frontend/js/shared/context/compile-context.js b/services/web/frontend/js/shared/context/compile-context.js index 5f2d8b3d00..8186270ee4 100644 --- a/services/web/frontend/js/shared/context/compile-context.js +++ b/services/web/frontend/js/shared/context/compile-context.js @@ -1,4 +1,4 @@ -import { createContext, useContext } from 'react' +import { createContext, useContext, useMemo } from 'react' import PropTypes from 'prop-types' import useScopeValue from './util/scope-value-hook' @@ -6,25 +6,72 @@ export const CompileContext = createContext() CompileContext.Provider.propTypes = { value: PropTypes.shape({ - pdfUrl: PropTypes.string, - pdfDownloadUrl: PropTypes.string, + clsiServerId: PropTypes.string, logEntries: PropTypes.object, + logEntryAnnotations: PropTypes.object, + pdfDownloadUrl: PropTypes.string, + pdfUrl: PropTypes.string, + setClsiServerId: PropTypes.func.isRequired, + setLogEntries: PropTypes.func.isRequired, + setLogEntryAnnotations: PropTypes.func.isRequired, + setPdfDownloadUrl: PropTypes.func.isRequired, + setPdfUrl: PropTypes.func.isRequired, + setUncompiled: PropTypes.func.isRequired, uncompiled: PropTypes.bool, }), } export function CompileProvider({ children }) { - const [pdfUrl] = useScopeValue('pdf.url') - const [pdfDownloadUrl] = useScopeValue('pdf.downloadUrl') - const [logEntries] = useScopeValue('pdf.logEntries') - const [uncompiled] = useScopeValue('pdf.uncompiled') + // the log entries parsed from the compile output log + const [logEntries, setLogEntries] = useScopeValue('pdf.logEntries') - const value = { - pdfUrl, - pdfDownloadUrl, - logEntries, - uncompiled, - } + // annotations for display in the editor, built from the log entries + const [logEntryAnnotations, setLogEntryAnnotations] = useScopeValue( + 'pdf.logEntryAnnotations' + ) + + // the URL for downloading the PDF + const [pdfDownloadUrl, setPdfDownloadUrl] = useScopeValue('pdf.downloadUrl') + + // the URL for loading the PDF in the preview pane + const [pdfUrl, setPdfUrl] = useScopeValue('pdf.url') + + // the project is considered to be "uncompiled" if a doc has changed since the last compile started + const [uncompiled, setUncompiled] = useScopeValue('pdf.uncompiled') + + // the id of the CLSI server which ran the compile + const [clsiServerId, setClsiServerId] = useScopeValue('pdf.clsiServerId') + + const value = useMemo( + () => ({ + clsiServerId, + logEntries, + logEntryAnnotations, + pdfDownloadUrl, + pdfUrl, + setClsiServerId, + setLogEntries, + setLogEntryAnnotations, + setPdfDownloadUrl, + setPdfUrl, + setUncompiled, + uncompiled, + }), + [ + clsiServerId, + logEntries, + logEntryAnnotations, + pdfDownloadUrl, + pdfUrl, + setClsiServerId, + setLogEntries, + setLogEntryAnnotations, + setPdfDownloadUrl, + setPdfUrl, + setUncompiled, + uncompiled, + ] + ) return ( {children} diff --git a/services/web/frontend/js/shared/context/layout-context.js b/services/web/frontend/js/shared/context/layout-context.js index c066f76089..4009cb7f37 100644 --- a/services/web/frontend/js/shared/context/layout-context.js +++ b/services/web/frontend/js/shared/context/layout-context.js @@ -22,6 +22,7 @@ LayoutContext.Provider.propTypes = { export function LayoutProvider({ children }) { const { $scope } = useIdeContext() + // what to show in the "flat" view (editor or pdf) const [view, _setView] = useScopeValue('ui.view') const setView = useCallback( @@ -38,32 +39,46 @@ export function LayoutProvider({ children }) { [$scope, _setView] ) + // whether the chat pane is open const [chatIsOpen, setChatIsOpen] = useScopeValue('ui.chatOpen') + + // whether the review pane is open const [reviewPanelOpen, setReviewPanelOpen] = useScopeValue( 'ui.reviewPanelOpen' ) + + // whether the menu pane is open const [leftMenuShown, setLeftMenuShown] = useScopeValue('ui.leftMenuShown') - const [pdfLayout] = useScopeValue('ui.pdfLayout', $scope) + + // whether to display the editor and preview side-by-side or full-width ("flat") + const [pdfLayout, setPdfLayout] = useScopeValue('ui.pdfLayout') + + // whether the PDF preview pane is hidden + const [pdfHidden] = useScopeValue('ui.pdfHidden') const value = useMemo( () => ({ - view, - setView, chatIsOpen, - setChatIsOpen, - reviewPanelOpen, - setReviewPanelOpen, leftMenuShown, - setLeftMenuShown, + pdfHidden, pdfLayout, + reviewPanelOpen, + setChatIsOpen, + setLeftMenuShown, + setPdfLayout, + setReviewPanelOpen, + setView, + view, }), [ chatIsOpen, leftMenuShown, + pdfHidden, pdfLayout, reviewPanelOpen, setChatIsOpen, setLeftMenuShown, + setPdfLayout, setReviewPanelOpen, setView, view,