mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-11-14 14:13:43 +01:00
Merge pull request #26583 from overleaf/td-editor-scope-values-to-context
Move scope values starting with `editor.` to contexts GitOrigin-RevId: 7ca349ceff002228cf4e931c644c8c386eb6c597
This commit is contained in:
@@ -1,22 +1,21 @@
|
||||
import { Panel, PanelGroup } from 'react-resizable-panels'
|
||||
import React, { FC, lazy, Suspense } from 'react'
|
||||
import useScopeValue from '@/shared/hooks/use-scope-value'
|
||||
import SourceEditor from '@/features/source-editor/components/source-editor'
|
||||
import { useEditorManagerContext } from '@/features/ide-react/context/editor-manager-context'
|
||||
import { useEditorOpenDocContext } from '@/features/ide-react/context/editor-open-doc-context'
|
||||
import { EditorScopeValue } from '@/features/ide-react/scope-adapters/editor-manager-context-adapter'
|
||||
import classNames from 'classnames'
|
||||
import { LoadingPane } from '@/features/ide-react/components/editor/loading-pane'
|
||||
import { FullSizeLoadingSpinner } from '@/shared/components/loading-spinner'
|
||||
import { VerticalResizeHandle } from '@/features/ide-react/components/resize/vertical-resize-handle'
|
||||
import { useFileTreeOpenContext } from '@/features/ide-react/context/file-tree-open-context'
|
||||
import { useEditorPropertiesContext } from '@/features/ide-react/context/editor-properties-context'
|
||||
|
||||
const SymbolPalettePane = lazy(
|
||||
() => import('@/features/ide-react/components/editor/symbol-palette-pane')
|
||||
)
|
||||
|
||||
export const EditorPane: FC = () => {
|
||||
const [editor] = useScopeValue<EditorScopeValue>('editor')
|
||||
const { showSymbolPalette } = useEditorPropertiesContext()
|
||||
const { selectedEntityCount, openEntity } = useFileTreeOpenContext()
|
||||
const { isLoading } = useEditorManagerContext()
|
||||
const { currentDocumentId } = useEditorOpenDocContext()
|
||||
@@ -41,7 +40,7 @@ export const EditorPane: FC = () => {
|
||||
{isLoading && <LoadingPane />}
|
||||
</Panel>
|
||||
|
||||
{editor.showSymbolPalette && (
|
||||
{showSymbolPalette && (
|
||||
<>
|
||||
<VerticalResizeHandle id="editor-symbol-palette" />
|
||||
<Panel
|
||||
|
||||
@@ -9,8 +9,6 @@ import {
|
||||
useState,
|
||||
} from 'react'
|
||||
import { sendMB } from '@/infrastructure/event-tracking'
|
||||
import useScopeValue from '@/shared/hooks/use-scope-value'
|
||||
import { useIdeContext } from '@/shared/context/ide-context'
|
||||
import { OpenDocuments } from '@/features/ide-react/editor/open-documents'
|
||||
import EditorWatchdogManager from '@/features/ide-react/connection/editor-watchdog-manager'
|
||||
import { useIdeReactContext } from '@/features/ide-react/context/ide-react-context'
|
||||
@@ -37,6 +35,7 @@ import { Update } from '@/features/history/services/types/update'
|
||||
import { useDebugDiffTracker } from '../hooks/use-debug-diff-tracker'
|
||||
import { convertFileRefToBinaryFile } from '@/features/ide-react/util/file-view'
|
||||
import { useEditorOpenDocContext } from '@/features/ide-react/context/editor-open-doc-context'
|
||||
import { useEditorPropertiesContext } from '@/features/ide-react/context/editor-properties-context'
|
||||
|
||||
export interface GotoOffsetOptions {
|
||||
gotoOffset: number
|
||||
@@ -52,7 +51,6 @@ interface OpenDocOptions
|
||||
|
||||
export type EditorManager = {
|
||||
getEditorType: () => EditorType | null
|
||||
showSymbolPalette: boolean
|
||||
getCurrentDocValue: () => string | null
|
||||
getCurrentDocumentId: () => DocId | null
|
||||
setIgnoringExternalUpdates: (value: boolean) => void
|
||||
@@ -62,12 +60,7 @@ export type EditorManager = {
|
||||
openFileWithId: (fileId: string) => void
|
||||
openInitialDoc: (docId: string) => void
|
||||
isLoading: boolean
|
||||
trackChanges: boolean
|
||||
jumpToLine: (options: GotoLineOptions) => void
|
||||
wantTrackChanges: boolean
|
||||
setWantTrackChanges: React.Dispatch<
|
||||
React.SetStateAction<EditorManager['wantTrackChanges']>
|
||||
>
|
||||
debugTimers: React.MutableRefObject<Record<string, number>>
|
||||
}
|
||||
|
||||
@@ -87,7 +80,6 @@ export const EditorManagerProvider: FC<React.PropsWithChildren> = ({
|
||||
children,
|
||||
}) => {
|
||||
const { t } = useTranslation()
|
||||
const { scopeStore } = useIdeContext()
|
||||
const { reportError, eventEmitter, projectId, setOutOfSync } =
|
||||
useIdeReactContext()
|
||||
const { socket, closeConnection, connectionState } = useConnectionContext()
|
||||
@@ -95,11 +87,15 @@ export const EditorManagerProvider: FC<React.PropsWithChildren> = ({
|
||||
const { showGenericMessageModal, genericModalVisible, showOutOfSyncModal } =
|
||||
useModalsContext()
|
||||
const { id: userId } = useUserContext()
|
||||
|
||||
const [showSymbolPalette, setShowSymbolPalette] = useScopeValue<boolean>(
|
||||
'editor.showSymbolPalette'
|
||||
)
|
||||
const [showVisual] = useScopeValue<boolean>('editor.showVisual')
|
||||
const {
|
||||
showVisual,
|
||||
opening,
|
||||
setOpening,
|
||||
errorState,
|
||||
setErrorState,
|
||||
setTrackChanges,
|
||||
wantTrackChanges,
|
||||
} = useEditorPropertiesContext()
|
||||
const {
|
||||
currentDocumentId,
|
||||
setCurrentDocumentId,
|
||||
@@ -107,15 +103,6 @@ export const EditorManagerProvider: FC<React.PropsWithChildren> = ({
|
||||
currentDocument,
|
||||
setCurrentDocument,
|
||||
} = useEditorOpenDocContext()
|
||||
const [opening, setOpening] = useScopeValue<boolean>('editor.opening')
|
||||
const [errorState, setIsInErrorState] =
|
||||
useScopeValue<boolean>('editor.error_state')
|
||||
const [trackChanges, setTrackChanges] = useScopeValue<boolean>(
|
||||
'editor.trackChanges'
|
||||
)
|
||||
const [wantTrackChanges, setWantTrackChanges] = useScopeValue<boolean>(
|
||||
'editor.wantTrackChanges'
|
||||
)
|
||||
|
||||
const wantTrackChangesRef = useRef(wantTrackChanges)
|
||||
useEffect(() => {
|
||||
@@ -191,22 +178,6 @@ export const EditorManagerProvider: FC<React.PropsWithChildren> = ({
|
||||
|
||||
const editorOpenDocEpochRef = useRef(0)
|
||||
|
||||
// TODO: This looks dodgy because it wraps a state setter and is itself
|
||||
// stored in React state in the scope store. The problem is that it needs to
|
||||
// be exposed via the scope store because some components access it that way;
|
||||
// it would be better to simply access it from a context, but the current
|
||||
// implementation in EditorManager interacts with Angular scope to update
|
||||
// the layout. Once Angular is gone, this can become a context method.
|
||||
useEffect(() => {
|
||||
scopeStore.set('editor.toggleSymbolPalette', () => {
|
||||
setShowSymbolPalette(show => {
|
||||
const newValue = !show
|
||||
sendMB(newValue ? 'symbol-palette-show' : 'symbol-palette-hide')
|
||||
return newValue
|
||||
})
|
||||
})
|
||||
}, [scopeStore, setShowSymbolPalette])
|
||||
|
||||
const getEditorType = useCallback((): EditorType | null => {
|
||||
if (!currentDocument) {
|
||||
return null
|
||||
@@ -587,7 +558,7 @@ export const EditorManagerProvider: FC<React.PropsWithChildren> = ({
|
||||
reportError(error, meta)
|
||||
|
||||
// Tell the user about the error state.
|
||||
setIsInErrorState(true)
|
||||
setErrorState(true)
|
||||
// Ensure that the editor is locked
|
||||
setOutOfSync(true)
|
||||
// Display the "out of sync" modal
|
||||
@@ -614,7 +585,7 @@ export const EditorManagerProvider: FC<React.PropsWithChildren> = ({
|
||||
eventEmitter,
|
||||
openDoc,
|
||||
reportError,
|
||||
setIsInErrorState,
|
||||
setErrorState,
|
||||
showGenericMessageModal,
|
||||
showOutOfSyncModal,
|
||||
setOutOfSync,
|
||||
@@ -661,25 +632,20 @@ export const EditorManagerProvider: FC<React.PropsWithChildren> = ({
|
||||
const value: EditorManager = useMemo(
|
||||
() => ({
|
||||
getEditorType,
|
||||
showSymbolPalette,
|
||||
getCurrentDocValue,
|
||||
getCurrentDocumentId,
|
||||
setIgnoringExternalUpdates,
|
||||
openDocWithId,
|
||||
openDoc,
|
||||
openDocs,
|
||||
trackChanges,
|
||||
isLoading,
|
||||
openFileWithId,
|
||||
openInitialDoc,
|
||||
jumpToLine,
|
||||
wantTrackChanges,
|
||||
setWantTrackChanges,
|
||||
debugTimers,
|
||||
}),
|
||||
[
|
||||
getEditorType,
|
||||
showSymbolPalette,
|
||||
getCurrentDocValue,
|
||||
getCurrentDocumentId,
|
||||
setIgnoringExternalUpdates,
|
||||
@@ -688,11 +654,8 @@ export const EditorManagerProvider: FC<React.PropsWithChildren> = ({
|
||||
openDocs,
|
||||
openFileWithId,
|
||||
openInitialDoc,
|
||||
trackChanges,
|
||||
isLoading,
|
||||
jumpToLine,
|
||||
wantTrackChanges,
|
||||
setWantTrackChanges,
|
||||
debugTimers,
|
||||
]
|
||||
)
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
import {
|
||||
createContext,
|
||||
Dispatch,
|
||||
FC,
|
||||
PropsWithChildren,
|
||||
SetStateAction,
|
||||
useCallback,
|
||||
useContext,
|
||||
useState,
|
||||
} from 'react'
|
||||
import customLocalStorage from '@/infrastructure/local-storage'
|
||||
import usePersistedState from '@/shared/hooks/use-persisted-state'
|
||||
import getMeta from '@/utils/meta'
|
||||
import { useUnstableStoreSync } from '@/shared/hooks/use-unstable-store-sync'
|
||||
import { sendMB } from '@/infrastructure/event-tracking'
|
||||
|
||||
// Context value type
|
||||
export type EditorPropertiesContextValue = {
|
||||
showVisual: boolean
|
||||
setShowVisual: Dispatch<SetStateAction<boolean>>
|
||||
showSymbolPalette: boolean
|
||||
setShowSymbolPalette: Dispatch<SetStateAction<boolean>>
|
||||
toggleSymbolPalette: () => void
|
||||
opening: boolean
|
||||
setOpening: Dispatch<SetStateAction<boolean>>
|
||||
trackChanges: boolean
|
||||
setTrackChanges: Dispatch<SetStateAction<boolean>>
|
||||
wantTrackChanges: boolean
|
||||
setWantTrackChanges: Dispatch<SetStateAction<boolean>>
|
||||
errorState: boolean
|
||||
setErrorState: Dispatch<SetStateAction<boolean>>
|
||||
}
|
||||
|
||||
export const EditorPropertiesContext = createContext<
|
||||
EditorPropertiesContextValue | undefined
|
||||
>(undefined)
|
||||
|
||||
function showVisualFallbackValue() {
|
||||
const projectId = getMeta('ol-project_id')
|
||||
const editorModeKey = `editor.mode.${projectId}`
|
||||
const editorModeVal = customLocalStorage.getItem(editorModeKey)
|
||||
|
||||
if (editorModeVal) {
|
||||
// clean up the old key
|
||||
customLocalStorage.removeItem(editorModeKey)
|
||||
}
|
||||
|
||||
return editorModeVal === 'rich-text'
|
||||
}
|
||||
|
||||
export const EditorPropertiesProvider: FC<PropsWithChildren> = ({
|
||||
children,
|
||||
}) => {
|
||||
const [showVisual, setShowVisual] = usePersistedState(
|
||||
`editor.lastUsedMode`,
|
||||
showVisualFallbackValue(),
|
||||
{
|
||||
converter: {
|
||||
toPersisted: showVisual => (showVisual ? 'visual' : 'code'),
|
||||
fromPersisted: mode => mode === 'visual',
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
// Sync the showVisual state with the exposed store
|
||||
useUnstableStoreSync('editor.showVisual', showVisual)
|
||||
|
||||
const [showSymbolPalette, setShowSymbolPalette] = useState(false)
|
||||
|
||||
const toggleSymbolPalette = useCallback(() => {
|
||||
setShowSymbolPalette(show => {
|
||||
const newValue = !show
|
||||
sendMB(newValue ? 'symbol-palette-show' : 'symbol-palette-hide')
|
||||
return newValue
|
||||
})
|
||||
}, [setShowSymbolPalette])
|
||||
|
||||
const [opening, setOpening] = useState(true)
|
||||
const [trackChanges, setTrackChanges] = useState(false)
|
||||
const [wantTrackChanges, setWantTrackChanges] = useState(false)
|
||||
const [errorState, setErrorState] = useState(false)
|
||||
|
||||
const value = {
|
||||
showVisual,
|
||||
setShowVisual,
|
||||
showSymbolPalette,
|
||||
setShowSymbolPalette,
|
||||
toggleSymbolPalette,
|
||||
opening,
|
||||
setOpening,
|
||||
trackChanges,
|
||||
setTrackChanges,
|
||||
wantTrackChanges,
|
||||
setWantTrackChanges,
|
||||
errorState,
|
||||
setErrorState,
|
||||
}
|
||||
|
||||
return (
|
||||
<EditorPropertiesContext.Provider value={value}>
|
||||
{children}
|
||||
</EditorPropertiesContext.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
export const useEditorPropertiesContext = (): EditorPropertiesContextValue => {
|
||||
const context = useContext(EditorPropertiesContext)
|
||||
if (!context) {
|
||||
throw new Error(
|
||||
'useEditorPropertiesContext is only available inside EditorPropertiesContext.Provider'
|
||||
)
|
||||
}
|
||||
return context
|
||||
}
|
||||
@@ -15,7 +15,6 @@ import {
|
||||
} from '@/features/ide-react/create-ide-event-emitter'
|
||||
import { JoinProjectPayload } from '@/features/ide-react/connection/join-project-payload'
|
||||
import { useConnectionContext } from '@/features/ide-react/context/connection-context'
|
||||
import { populateEditorScope } from '@/features/ide-react/scope-adapters/editor-manager-context-adapter'
|
||||
import { postJSON } from '@/infrastructure/fetch-json'
|
||||
import { ReactScopeEventEmitter } from '@/features/ide-react/scope-event-emitter/react-scope-event-emitter'
|
||||
import getMeta from '@/utils/meta'
|
||||
@@ -53,7 +52,7 @@ function populatePdfScope(store: ReactScopeValueStore) {
|
||||
store.allowNonExistentPath('pdf', true)
|
||||
}
|
||||
|
||||
export function createReactScopeValueStore(projectId: string) {
|
||||
export function createReactScopeValueStore() {
|
||||
const scopeStore = new ReactScopeValueStore()
|
||||
|
||||
// Populate the scope value store with default values that will be used by
|
||||
@@ -62,7 +61,6 @@ export function createReactScopeValueStore(projectId: string) {
|
||||
// initialization code together with the context and would only populate
|
||||
// necessary values in the store, but this is simpler for now
|
||||
populateIdeReactScope(scopeStore)
|
||||
populateEditorScope(scopeStore, projectId)
|
||||
populateProjectScope(scopeStore)
|
||||
populatePdfScope(scopeStore)
|
||||
|
||||
@@ -73,7 +71,7 @@ export function createReactScopeValueStore(projectId: string) {
|
||||
|
||||
export const IdeReactProvider: FC<React.PropsWithChildren> = ({ children }) => {
|
||||
const projectId = getMeta('ol-project_id')
|
||||
const [scopeStore] = useState(() => createReactScopeValueStore(projectId))
|
||||
const [scopeStore] = useState(() => createReactScopeValueStore())
|
||||
const [eventEmitter] = useState(createIdeEventEmitter)
|
||||
const [permissionsLevel, setPermissionsLevel] =
|
||||
useState<PermissionsLevel>('readOnly')
|
||||
|
||||
@@ -5,6 +5,7 @@ import { DetachCompileProvider } from '@/shared/context/detach-compile-context'
|
||||
import { DetachProvider } from '@/shared/context/detach-context'
|
||||
import { EditorManagerProvider } from '@/features/ide-react/context/editor-manager-context'
|
||||
import { EditorOpenDocProvider } from '@/features/ide-react/context/editor-open-doc-context'
|
||||
import { EditorPropertiesProvider } from '@/features/ide-react/context/editor-properties-context'
|
||||
import { EditorProvider } from '@/shared/context/editor-context'
|
||||
import { EditorViewProvider } from '@/features/ide-react/context/editor-view-context'
|
||||
import { FileTreeDataProvider } from '@/shared/context/file-tree-data-context'
|
||||
@@ -42,6 +43,7 @@ export const ReactContextRoot: FC<
|
||||
DetachProvider,
|
||||
EditorManagerProvider,
|
||||
EditorOpenDocProvider,
|
||||
EditorPropertiesProvider,
|
||||
EditorProvider,
|
||||
EditorViewProvider,
|
||||
FileTreeDataProvider,
|
||||
@@ -79,49 +81,51 @@ export const ReactContextRoot: FC<
|
||||
<Providers.ProjectProvider>
|
||||
<Providers.SnapshotProvider>
|
||||
<Providers.DetachProvider>
|
||||
<Providers.EditorViewProvider>
|
||||
<Providers.EditorOpenDocProvider>
|
||||
<Providers.EditorProvider>
|
||||
<Providers.FileTreeDataProvider>
|
||||
<Providers.FileTreePathProvider>
|
||||
<Providers.ReferencesProvider>
|
||||
<Providers.UserFeaturesProvider>
|
||||
<Providers.PermissionsProvider>
|
||||
<Providers.RailProvider>
|
||||
<Providers.LayoutProvider>
|
||||
<Providers.ProjectSettingsProvider>
|
||||
<Providers.EditorManagerProvider>
|
||||
<Providers.LocalCompileProvider>
|
||||
<Providers.DetachCompileProvider>
|
||||
<Providers.ChatProvider>
|
||||
<Providers.FileTreeOpenProvider>
|
||||
<Providers.OnlineUsersProvider>
|
||||
<Providers.MetadataProvider>
|
||||
<Providers.OutlineProvider>
|
||||
<Providers.IdeRedesignSwitcherProvider>
|
||||
<Providers.CommandRegistryProvider>
|
||||
{children}
|
||||
</Providers.CommandRegistryProvider>
|
||||
</Providers.IdeRedesignSwitcherProvider>
|
||||
</Providers.OutlineProvider>
|
||||
</Providers.MetadataProvider>
|
||||
</Providers.OnlineUsersProvider>
|
||||
</Providers.FileTreeOpenProvider>
|
||||
</Providers.ChatProvider>
|
||||
</Providers.DetachCompileProvider>
|
||||
</Providers.LocalCompileProvider>
|
||||
</Providers.EditorManagerProvider>
|
||||
</Providers.ProjectSettingsProvider>
|
||||
</Providers.LayoutProvider>
|
||||
</Providers.RailProvider>
|
||||
</Providers.PermissionsProvider>
|
||||
</Providers.UserFeaturesProvider>
|
||||
</Providers.ReferencesProvider>
|
||||
</Providers.FileTreePathProvider>
|
||||
</Providers.FileTreeDataProvider>
|
||||
</Providers.EditorProvider>
|
||||
</Providers.EditorOpenDocProvider>
|
||||
</Providers.EditorViewProvider>
|
||||
<Providers.EditorPropertiesProvider>
|
||||
<Providers.EditorViewProvider>
|
||||
<Providers.EditorOpenDocProvider>
|
||||
<Providers.EditorProvider>
|
||||
<Providers.FileTreeDataProvider>
|
||||
<Providers.FileTreePathProvider>
|
||||
<Providers.ReferencesProvider>
|
||||
<Providers.UserFeaturesProvider>
|
||||
<Providers.PermissionsProvider>
|
||||
<Providers.RailProvider>
|
||||
<Providers.LayoutProvider>
|
||||
<Providers.ProjectSettingsProvider>
|
||||
<Providers.EditorManagerProvider>
|
||||
<Providers.LocalCompileProvider>
|
||||
<Providers.DetachCompileProvider>
|
||||
<Providers.ChatProvider>
|
||||
<Providers.FileTreeOpenProvider>
|
||||
<Providers.OnlineUsersProvider>
|
||||
<Providers.MetadataProvider>
|
||||
<Providers.OutlineProvider>
|
||||
<Providers.IdeRedesignSwitcherProvider>
|
||||
<Providers.CommandRegistryProvider>
|
||||
{children}
|
||||
</Providers.CommandRegistryProvider>
|
||||
</Providers.IdeRedesignSwitcherProvider>
|
||||
</Providers.OutlineProvider>
|
||||
</Providers.MetadataProvider>
|
||||
</Providers.OnlineUsersProvider>
|
||||
</Providers.FileTreeOpenProvider>
|
||||
</Providers.ChatProvider>
|
||||
</Providers.DetachCompileProvider>
|
||||
</Providers.LocalCompileProvider>
|
||||
</Providers.EditorManagerProvider>
|
||||
</Providers.ProjectSettingsProvider>
|
||||
</Providers.LayoutProvider>
|
||||
</Providers.RailProvider>
|
||||
</Providers.PermissionsProvider>
|
||||
</Providers.UserFeaturesProvider>
|
||||
</Providers.ReferencesProvider>
|
||||
</Providers.FileTreePathProvider>
|
||||
</Providers.FileTreeDataProvider>
|
||||
</Providers.EditorProvider>
|
||||
</Providers.EditorOpenDocProvider>
|
||||
</Providers.EditorViewProvider>
|
||||
</Providers.EditorPropertiesProvider>
|
||||
</Providers.DetachProvider>
|
||||
</Providers.SnapshotProvider>
|
||||
</Providers.ProjectProvider>
|
||||
|
||||
-54
@@ -1,54 +0,0 @@
|
||||
import { ReactScopeValueStore } from '@/features/ide-react/scope-value-store/react-scope-value-store'
|
||||
import customLocalStorage from '@/infrastructure/local-storage'
|
||||
import { DocumentContainer } from '@/features/ide-react/editor/document-container'
|
||||
|
||||
export type EditorScopeValue = {
|
||||
showSymbolPalette: false
|
||||
toggleSymbolPalette: () => void
|
||||
sharejs_doc: DocumentContainer | null
|
||||
opening: boolean
|
||||
trackChanges: boolean
|
||||
wantTrackChanges: boolean
|
||||
showVisual: boolean
|
||||
error_state: boolean
|
||||
}
|
||||
|
||||
export function populateEditorScope(
|
||||
store: ReactScopeValueStore,
|
||||
projectId: string
|
||||
) {
|
||||
store.set('project.name', null)
|
||||
|
||||
const editor: Omit<EditorScopeValue, 'showVisual'> = {
|
||||
showSymbolPalette: false,
|
||||
toggleSymbolPalette: () => {},
|
||||
sharejs_doc: null,
|
||||
opening: true,
|
||||
trackChanges: false,
|
||||
wantTrackChanges: false,
|
||||
error_state: false,
|
||||
}
|
||||
store.set('editor', editor)
|
||||
|
||||
store.persisted(
|
||||
'editor.showVisual',
|
||||
showVisualFallbackValue(projectId),
|
||||
`editor.lastUsedMode`,
|
||||
{
|
||||
toPersisted: showVisual => (showVisual ? 'visual' : 'code'),
|
||||
fromPersisted: mode => mode === 'visual',
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
function showVisualFallbackValue(projectId: string) {
|
||||
const editorModeKey = `editor.mode.${projectId}`
|
||||
const editorModeVal = customLocalStorage.getItem(editorModeKey)
|
||||
|
||||
if (editorModeVal) {
|
||||
// clean up the old key
|
||||
customLocalStorage.removeItem(editorModeKey)
|
||||
}
|
||||
|
||||
return editorModeVal === 'rich-text'
|
||||
}
|
||||
Reference in New Issue
Block a user