diff --git a/services/web/frontend/js/features/editor-left-menu/context/project-settings-context.tsx b/services/web/frontend/js/features/editor-left-menu/context/project-settings-context.tsx index bdf4d5f806..520d7901b4 100644 --- a/services/web/frontend/js/features/editor-left-menu/context/project-settings-context.tsx +++ b/services/web/frontend/js/features/editor-left-menu/context/project-settings-context.tsx @@ -3,33 +3,33 @@ import type { PropsWithChildren } from 'react' import useProjectWideSettings from '../hooks/use-project-wide-settings' import useUserWideSettings from '../hooks/use-user-wide-settings' import useProjectWideSettingsSocketListener from '../hooks/use-project-wide-settings-socket-listener' -import type { ProjectSettingsScope, UserSettingsScope } from '../utils/api' +import type { ProjectSettings, UserSettings } from '../utils/api' type ProjectSettingsSetterContextValue = { - setCompiler: (compiler: ProjectSettingsScope['compiler']) => void - setImageName: (imageName: ProjectSettingsScope['imageName']) => void - setRootDocId: (rootDocId: ProjectSettingsScope['rootDocId']) => void + setCompiler: (compiler: ProjectSettings['compiler']) => void + setImageName: (imageName: ProjectSettings['imageName']) => void + setRootDocId: (rootDocId: ProjectSettings['rootDocId']) => void setSpellCheckLanguage: ( - spellCheckLanguage: ProjectSettingsScope['spellCheckLanguage'] + spellCheckLanguage: ProjectSettings['spellCheckLanguage'] ) => void - setAutoComplete: (autoComplete: UserSettingsScope['autoComplete']) => void + setAutoComplete: (autoComplete: UserSettings['autoComplete']) => void setAutoPairDelimiters: ( - autoPairDelimiters: UserSettingsScope['autoPairDelimiters'] + autoPairDelimiters: UserSettings['autoPairDelimiters'] ) => void setSyntaxValidation: ( - syntaxValidation: UserSettingsScope['syntaxValidation'] + syntaxValidation: UserSettings['syntaxValidation'] ) => void - setMode: (mode: UserSettingsScope['mode']) => void - setEditorTheme: (editorTheme: UserSettingsScope['editorTheme']) => void - setOverallTheme: (overallTheme: UserSettingsScope['overallTheme']) => void - setFontSize: (fontSize: UserSettingsScope['fontSize']) => void - setFontFamily: (fontFamily: UserSettingsScope['fontFamily']) => void - setLineHeight: (lineHeight: UserSettingsScope['lineHeight']) => void - setPdfViewer: (pdfViewer: UserSettingsScope['pdfViewer']) => void + setMode: (mode: UserSettings['mode']) => void + setEditorTheme: (editorTheme: UserSettings['editorTheme']) => void + setOverallTheme: (overallTheme: UserSettings['overallTheme']) => void + setFontSize: (fontSize: UserSettings['fontSize']) => void + setFontFamily: (fontFamily: UserSettings['fontFamily']) => void + setLineHeight: (lineHeight: UserSettings['lineHeight']) => void + setPdfViewer: (pdfViewer: UserSettings['pdfViewer']) => void } -type ProjectSettingsContextValue = Partial & - Partial & +type ProjectSettingsContextValue = Partial & + Partial & ProjectSettingsSetterContextValue export const ProjectSettingsContext = createContext< diff --git a/services/web/frontend/js/features/editor-left-menu/hooks/use-project-wide-settings-socket-listener.tsx b/services/web/frontend/js/features/editor-left-menu/hooks/use-project-wide-settings-socket-listener.tsx index 822375c4d8..8cfba364ae 100644 --- a/services/web/frontend/js/features/editor-left-menu/hooks/use-project-wide-settings-socket-listener.tsx +++ b/services/web/frontend/js/features/editor-left-menu/hooks/use-project-wide-settings-socket-listener.tsx @@ -1,45 +1,46 @@ import { useCallback, useEffect } from 'react' import { useIdeContext } from '../../../shared/context/ide-context' import useScopeValue from '../../../shared/hooks/use-scope-value' -import type { ProjectSettingsScope } from '../utils/api' +import type { ProjectSettings } from '../utils/api' export default function useProjectWideSettingsSocketListener() { const ide = useIdeContext() - const [projectScope, setProjectScope] = useScopeValue< - ProjectSettingsScope | undefined - >('project', true) + const [project, setProject] = useScopeValue( + 'project', + true + ) const setCompiler = useCallback( - (compiler: ProjectSettingsScope['compiler']) => { - if (projectScope) { - setProjectScope({ ...projectScope, compiler }) + (compiler: ProjectSettings['compiler']) => { + if (project) { + setProject({ ...project, compiler }) } }, - [projectScope, setProjectScope] + [project, setProject] ) const setImageName = useCallback( - (imageName: ProjectSettingsScope['imageName']) => { - if (projectScope) { - setProjectScope({ ...projectScope, imageName }) + (imageName: ProjectSettings['imageName']) => { + if (project) { + setProject({ ...project, imageName }) } }, - [projectScope, setProjectScope] + [project, setProject] ) const setSpellCheckLanguage = useCallback( - (spellCheckLanguage: ProjectSettingsScope['spellCheckLanguage']) => { - if (projectScope) { - setProjectScope({ ...projectScope, spellCheckLanguage }) + (spellCheckLanguage: ProjectSettings['spellCheckLanguage']) => { + if (project) { + setProject({ ...project, spellCheckLanguage }) } }, - [projectScope, setProjectScope] + [project, setProject] ) useEffect(() => { // data is not available on initial mounting - const dataAvailable = !!projectScope + const dataAvailable = !!project if (dataAvailable && ide?.socket) { ide.socket.on('compilerUpdated', setCompiler) @@ -54,11 +55,5 @@ export default function useProjectWideSettingsSocketListener() { ) } } - }, [ - ide?.socket, - projectScope, - setCompiler, - setImageName, - setSpellCheckLanguage, - ]) + }, [ide?.socket, project, setCompiler, setImageName, setSpellCheckLanguage]) } diff --git a/services/web/frontend/js/features/editor-left-menu/hooks/use-project-wide-settings.tsx b/services/web/frontend/js/features/editor-left-menu/hooks/use-project-wide-settings.tsx index 12db02f968..b78f1bd6b5 100644 --- a/services/web/frontend/js/features/editor-left-menu/hooks/use-project-wide-settings.tsx +++ b/services/web/frontend/js/features/editor-left-menu/hooks/use-project-wide-settings.tsx @@ -1,20 +1,20 @@ import { useCallback } from 'react' import { useProjectContext } from '../../../shared/context/project-context' import useScopeValue from '../../../shared/hooks/use-scope-value' -import { type ProjectSettingsScope, saveProjectSettings } from '../utils/api' +import { type ProjectSettings, saveProjectSettings } from '../utils/api' import useRootDocId from './use-root-doc-id' import useSetSpellCheckLanguage from './use-set-spell-check-language' export default function useProjectWideSettings() { // The value will be undefined on mount - const [project, setProject] = useScopeValue( + const [project, setProject] = useScopeValue( 'project', true ) const { _id: projectId } = useProjectContext() const setCompiler = useCallback( - (compiler: ProjectSettingsScope['compiler']) => { + (compiler: ProjectSettings['compiler']) => { const allowUpdate = project?.compiler if (allowUpdate) { @@ -26,7 +26,7 @@ export default function useProjectWideSettings() { ) const setImageName = useCallback( - (imageName: ProjectSettingsScope['imageName']) => { + (imageName: ProjectSettings['imageName']) => { const allowUpdate = project?.imageName if (allowUpdate) { diff --git a/services/web/frontend/js/features/editor-left-menu/hooks/use-root-doc-id.tsx b/services/web/frontend/js/features/editor-left-menu/hooks/use-root-doc-id.tsx index 78754758bb..58b6014276 100644 --- a/services/web/frontend/js/features/editor-left-menu/hooks/use-root-doc-id.tsx +++ b/services/web/frontend/js/features/editor-left-menu/hooks/use-root-doc-id.tsx @@ -2,16 +2,16 @@ import { useCallback } from 'react' import { useEditorContext } from '../../../shared/context/editor-context' import { useProjectContext } from '../../../shared/context/project-context' import useScopeValue from '../../../shared/hooks/use-scope-value' -import { type ProjectSettingsScope, saveProjectSettings } from '../utils/api' +import { type ProjectSettings, saveProjectSettings } from '../utils/api' export default function useRootDocId() { const [rootDocId, setRootDocId] = - useScopeValue('project.rootDoc_id') + useScopeValue('project.rootDoc_id') const { permissionsLevel } = useEditorContext() const { _id: projectId } = useProjectContext() const setRootDocIdFunc = useCallback( - async (newRootDocId: ProjectSettingsScope['rootDocId']) => { + async (newRootDocId: ProjectSettings['rootDocId']) => { const allowUpdate = typeof rootDocId !== 'undefined' && permissionsLevel !== 'readOnly' && diff --git a/services/web/frontend/js/features/editor-left-menu/hooks/use-save-user-settings.tsx b/services/web/frontend/js/features/editor-left-menu/hooks/use-save-user-settings.tsx index 9a90237298..ec1f1e605b 100644 --- a/services/web/frontend/js/features/editor-left-menu/hooks/use-save-user-settings.tsx +++ b/services/web/frontend/js/features/editor-left-menu/hooks/use-save-user-settings.tsx @@ -1,17 +1,19 @@ import useScopeValue from '../../../shared/hooks/use-scope-value' import { sendMB } from '../../../infrastructure/event-tracking' import { saveUserSettings } from '../utils/api' -import type { UserSettingsScope } from '../utils/api' +import type { UserSettings } from '../utils/api' export default function useSaveUserSettings() { - const [userSettingsScope, setUserSettingsScope] = - useScopeValue('settings', true) + const [userSettings, setUserSettings] = useScopeValue( + 'settings', + true + ) return ( - key: keyof UserSettingsScope, - newSetting: UserSettingsScope[keyof UserSettingsScope] + key: keyof UserSettings, + newSetting: UserSettings[keyof UserSettings] ) => { - const currentSetting = userSettingsScope[key] + const currentSetting = userSettings[key] sendMB('setting-changed', { changedSetting: key, @@ -19,7 +21,7 @@ export default function useSaveUserSettings() { }) if (currentSetting !== newSetting) { - setUserSettingsScope({ ...userSettingsScope, [key]: newSetting }) + setUserSettings({ ...userSettings, [key]: newSetting }) saveUserSettings({ [key]: newSetting }) } } diff --git a/services/web/frontend/js/features/editor-left-menu/hooks/use-set-overall-theme.tsx b/services/web/frontend/js/features/editor-left-menu/hooks/use-set-overall-theme.tsx index 8b52a3835a..b608549275 100644 --- a/services/web/frontend/js/features/editor-left-menu/hooks/use-set-overall-theme.tsx +++ b/services/web/frontend/js/features/editor-left-menu/hooks/use-set-overall-theme.tsx @@ -2,15 +2,15 @@ import { useCallback, useEffect, useState } from 'react' import _ from 'lodash' import useScopeValue from '../../../shared/hooks/use-scope-value' import type { OverallThemeMeta } from '../../../../../types/project-settings' -import { saveUserSettings, type UserSettingsScope } from '../utils/api' +import { saveUserSettings, type UserSettings } from '../utils/api' export default function useSetOverallTheme() { const [chosenTheme, setChosenTheme] = useState(null) const [loadingStyleSheet, setLoadingStyleSheet] = useScopeValue( 'ui.loadingStyleSheet' ) - const [overallThemeScope, setOverallThemeScope] = useScopeValue< - UserSettingsScope['overallTheme'] + const [overallTheme, setOverallTheme] = useScopeValue< + UserSettings['overallTheme'] >('settings.overallTheme') useEffect(() => { @@ -43,24 +43,22 @@ export default function useSetOverallTheme() { } }, [loadingStyleSheet, setLoadingStyleSheet, chosenTheme?.path]) - const setOverallTheme = useCallback( - (overallTheme: UserSettingsScope['overallTheme']) => { - if (overallThemeScope !== overallTheme) { + return useCallback( + (newOverallTheme: UserSettings['overallTheme']) => { + if (overallTheme !== newOverallTheme) { const chosenTheme = _.find( window.overallThemes, - theme => theme.val === overallTheme + theme => theme.val === newOverallTheme ) if (chosenTheme) { setLoadingStyleSheet(true) setChosenTheme(chosenTheme) - setOverallThemeScope(overallTheme) - saveUserSettings({ overallTheme }) + setOverallTheme(newOverallTheme) + saveUserSettings({ overallTheme: newOverallTheme }) } } }, - [overallThemeScope, setLoadingStyleSheet, setOverallThemeScope] + [overallTheme, setLoadingStyleSheet, setOverallTheme] ) - - return setOverallTheme } diff --git a/services/web/frontend/js/features/editor-left-menu/hooks/use-set-spell-check-language.tsx b/services/web/frontend/js/features/editor-left-menu/hooks/use-set-spell-check-language.tsx index db8cc14245..ca055fd8a2 100644 --- a/services/web/frontend/js/features/editor-left-menu/hooks/use-set-spell-check-language.tsx +++ b/services/web/frontend/js/features/editor-left-menu/hooks/use-set-spell-check-language.tsx @@ -3,37 +3,38 @@ import { sendMB } from '../../../infrastructure/event-tracking' import { useProjectContext } from '../../../shared/context/project-context' import useScopeValue from '../../../shared/hooks/use-scope-value' import { - type ProjectSettingsScope, + type ProjectSettings, saveProjectSettings, saveUserSettings, } from '../utils/api' export default function useSetSpellCheckLanguage() { - const [spellCheckLanguageScope, setSpellCheckLanguageScope] = useScopeValue< - ProjectSettingsScope['spellCheckLanguage'] + const [spellCheckLanguage, setSpellCheckLanguage] = useScopeValue< + ProjectSettings['spellCheckLanguage'] >('project.spellCheckLanguage') const { _id: projectId } = useProjectContext() - const setSpellCheckLanguage = useCallback( - (spellCheckLanguage: ProjectSettingsScope['spellCheckLanguage']) => { + return useCallback( + (newSpellCheckLanguage: ProjectSettings['spellCheckLanguage']) => { const allowUpdate = - spellCheckLanguage && spellCheckLanguage !== spellCheckLanguageScope + newSpellCheckLanguage && newSpellCheckLanguage !== spellCheckLanguage if (allowUpdate) { sendMB('setting-changed', { changedSetting: 'spellCheckLanguage', - changedSettingVal: spellCheckLanguage, + changedSettingVal: newSpellCheckLanguage, }) - setSpellCheckLanguageScope(spellCheckLanguage) + setSpellCheckLanguage(newSpellCheckLanguage) // save to both project setting and user setting - saveProjectSettings({ projectId, spellCheckLanguage }) - saveUserSettings({ spellCheckLanguage }) + saveProjectSettings({ + projectId, + spellCheckLanguage: newSpellCheckLanguage, + }) + saveUserSettings({ spellCheckLanguage: newSpellCheckLanguage }) } }, - [projectId, setSpellCheckLanguageScope, spellCheckLanguageScope] + [projectId, setSpellCheckLanguage, spellCheckLanguage] ) - - return setSpellCheckLanguage } diff --git a/services/web/frontend/js/features/editor-left-menu/hooks/use-user-wide-settings.tsx b/services/web/frontend/js/features/editor-left-menu/hooks/use-user-wide-settings.tsx index ba7c9b8bde..55978004ae 100644 --- a/services/web/frontend/js/features/editor-left-menu/hooks/use-user-wide-settings.tsx +++ b/services/web/frontend/js/features/editor-left-menu/hooks/use-user-wide-settings.tsx @@ -2,76 +2,76 @@ import { useCallback } from 'react' import useScopeValue from '../../../shared/hooks/use-scope-value' import useSetOverallTheme from './use-set-overall-theme' import useSaveUserSettings from './use-save-user-settings' -import type { UserSettingsScope } from '../utils/api' +import type { UserSettings } from '../utils/api' export default function useUserWideSettings() { const saveUserSettings = useSaveUserSettings() // this may be undefined on test environments - const [userSettings] = useScopeValue( + const [userSettings] = useScopeValue( 'settings', true ) const setOverallTheme = useSetOverallTheme() const setAutoComplete = useCallback( - (autoComplete: UserSettingsScope['autoComplete']) => { + (autoComplete: UserSettings['autoComplete']) => { saveUserSettings('autoComplete', autoComplete) }, [saveUserSettings] ) const setAutoPairDelimiters = useCallback( - (autoPairDelimiters: UserSettingsScope['autoPairDelimiters']) => { + (autoPairDelimiters: UserSettings['autoPairDelimiters']) => { saveUserSettings('autoPairDelimiters', autoPairDelimiters) }, [saveUserSettings] ) const setSyntaxValidation = useCallback( - (syntaxValidation: UserSettingsScope['syntaxValidation']) => { + (syntaxValidation: UserSettings['syntaxValidation']) => { saveUserSettings('syntaxValidation', syntaxValidation) }, [saveUserSettings] ) const setEditorTheme = useCallback( - (editorTheme: UserSettingsScope['editorTheme']) => { + (editorTheme: UserSettings['editorTheme']) => { saveUserSettings('editorTheme', editorTheme) }, [saveUserSettings] ) const setMode = useCallback( - (mode: UserSettingsScope['mode']) => { + (mode: UserSettings['mode']) => { saveUserSettings('mode', mode) }, [saveUserSettings] ) const setFontSize = useCallback( - (fontSize: UserSettingsScope['fontSize']) => { + (fontSize: UserSettings['fontSize']) => { saveUserSettings('fontSize', fontSize) }, [saveUserSettings] ) const setFontFamily = useCallback( - (fontFamily: UserSettingsScope['fontFamily']) => { + (fontFamily: UserSettings['fontFamily']) => { saveUserSettings('fontFamily', fontFamily) }, [saveUserSettings] ) const setLineHeight = useCallback( - (lineHeight: UserSettingsScope['lineHeight']) => { + (lineHeight: UserSettings['lineHeight']) => { saveUserSettings('lineHeight', lineHeight) }, [saveUserSettings] ) const setPdfViewer = useCallback( - (pdfViewer: UserSettingsScope['pdfViewer']) => { + (pdfViewer: UserSettings['pdfViewer']) => { saveUserSettings('pdfViewer', pdfViewer) }, [saveUserSettings] diff --git a/services/web/frontend/js/features/editor-left-menu/utils/api.ts b/services/web/frontend/js/features/editor-left-menu/utils/api.ts index b51fe3d3f3..bb6f96592a 100644 --- a/services/web/frontend/js/features/editor-left-menu/utils/api.ts +++ b/services/web/frontend/js/features/editor-left-menu/utils/api.ts @@ -10,7 +10,7 @@ import type { } from '../../../../../types/project-settings' import { postJSON } from '../../../infrastructure/fetch-json' -export type UserSettingsScope = { +export type UserSettings = { pdfViewer: PdfViewer autoComplete: boolean autoPairDelimiters: boolean @@ -23,7 +23,7 @@ export type UserSettingsScope = { lineHeight: LineHeight } -export type ProjectSettingsScope = { +export type ProjectSettings = { compiler: ProjectCompiler imageName: string rootDocId: string @@ -31,8 +31,8 @@ export type ProjectSettingsScope = { } type SaveUserSettings = Partial< - UserSettingsScope & { - spellCheckLanguage: ProjectSettingsScope['spellCheckLanguage'] + UserSettings & { + spellCheckLanguage: ProjectSettings['spellCheckLanguage'] } > @@ -44,7 +44,7 @@ export function saveUserSettings(data: SaveUserSettings) { type SaveProjectSettings = { projectId: string -} & Partial +} & Partial export const saveProjectSettings = async ({ projectId,