Răsfoiți Sursa

Migrate updating overallTheme to react

GitOrigin-RevId: 024ceb3c32c8d90ac0067fbb72d6e7d327b869f0
M Fahru 3 ani în urmă
părinte
comite
09b1974a3d

+ 65 - 0
services/web/frontend/js/features/editor-left-menu/hooks/use-set-overall-theme.tsx

@@ -0,0 +1,65 @@
+import { useCallback, useEffect, useState } from 'react'
+import _ from 'lodash'
+import { OverallTheme } from '../../../../../modules/source-editor/frontend/js/extensions/theme'
+import useScopeValue from '../../../shared/hooks/use-scope-value'
+import { OverallThemeMeta } from '../../../../../types/project-settings'
+import { saveUserSettings } from '../utils/api'
+
+export default function useSetOverallTheme() {
+  const [loadingStyleSheet, setLoadingStyleSheet] = useScopeValue<boolean>('ui.loadingStyleSheet')
+  const [chosenTheme, setChosenTheme] = useState<OverallThemeMeta | null>(null)
+  const [overallThemeScope, setOverallThemeScope] = useScopeValue<OverallTheme>(
+    'settings.overallTheme'
+  )
+
+  useEffect(() => {
+    const docHeadEl = document.querySelector('head')
+    const oldStyleSheetEl = document.getElementById('main-stylesheet')
+
+    const newStyleSheetEl = document.createElement('link')
+    newStyleSheetEl.setAttribute('rel', 'stylesheet')
+    newStyleSheetEl.setAttribute('id', 'main-stylesheet')
+    newStyleSheetEl.setAttribute('href', chosenTheme?.path ?? '')
+
+    const loadEventCallback = () => {
+      setLoadingStyleSheet(false)
+
+      if (docHeadEl && oldStyleSheetEl) {
+        docHeadEl.removeChild(oldStyleSheetEl)
+      }
+    }
+
+    if (loadingStyleSheet) {
+      newStyleSheetEl.addEventListener('load', loadEventCallback, {
+        once: true,
+      })
+
+      docHeadEl?.appendChild(newStyleSheetEl)
+    }
+
+    return () => {
+      newStyleSheetEl.removeEventListener('load', loadEventCallback)
+    }
+  }, [loadingStyleSheet, setLoadingStyleSheet, chosenTheme?.path])
+
+  const setOverallTheme = useCallback(
+    (overallTheme: OverallTheme) => {
+      if (overallThemeScope !== overallTheme) {
+        const chosenTheme = _.find(
+          window.overallThemes,
+          theme => theme.val === overallTheme
+        )
+
+        if (chosenTheme) {
+          setLoadingStyleSheet(true)
+          setChosenTheme(chosenTheme)
+          setOverallThemeScope(overallTheme)
+          saveUserSettings({ overallTheme })
+        }
+      }
+    },
+    [overallThemeScope, setLoadingStyleSheet, setOverallThemeScope]
+  )
+
+  return setOverallTheme
+}

+ 4 - 32
services/web/frontend/js/features/editor-left-menu/hooks/use-set-user-wide-settings.tsx

@@ -2,30 +2,12 @@ import { useCallback } from 'react'
 import {
   FontFamily,
   LineHeight,
-  OverallTheme,
 } from '../../../../../modules/source-editor/frontend/js/extensions/theme'
 import { Keybindings, PdfViewer } from '../../../../../types/project-settings'
-import { postJSON } from '../../../infrastructure/fetch-json'
 import useScopeValue from '../../../shared/hooks/use-scope-value'
-
-type UserSettingsScope = {
-  pdfViewer: PdfViewer
-  autoComplete: boolean
-  autoPairDelimiters: boolean
-  syntaxValidation: boolean
-  editorTheme: string
-  overallTheme: OverallTheme
-  mode: Keybindings
-  fontSize: string
-  fontFamily: FontFamily
-  lineHeight: LineHeight
-}
-
-function saveUserSettings(data: Partial<UserSettingsScope>) {
-  postJSON('/user/settings', {
-    body: data,
-  })
-}
+import { saveUserSettings } from '../utils/api'
+import type { UserSettingsScope } from '../utils/api'
+import useSetOverallTheme from './use-set-overall-theme'
 
 export default function useSetUserWideSettings() {
   const [userSettings, setUserSettings] = useScopeValue<UserSettingsScope>(
@@ -33,6 +15,7 @@ export default function useSetUserWideSettings() {
     true
   )
 
+  const setOverallTheme = useSetOverallTheme()
   const setAutoComplete = useCallback(
     (autoComplete: boolean) => {
       if (userSettings.autoComplete !== autoComplete) {
@@ -73,17 +56,6 @@ export default function useSetUserWideSettings() {
     [userSettings, setUserSettings]
   )
 
-  // TODO: business logic
-  const setOverallTheme = useCallback(
-    (overallTheme: OverallTheme) => {
-      if (userSettings.overallTheme !== overallTheme) {
-        setUserSettings({ ...userSettings, overallTheme })
-        saveUserSettings({ overallTheme })
-      }
-    },
-    [userSettings, setUserSettings]
-  )
-
   const setMode = useCallback(
     (mode: Keybindings) => {
       if (userSettings.mode !== mode) {

+ 26 - 0
services/web/frontend/js/features/editor-left-menu/utils/api.ts

@@ -0,0 +1,26 @@
+import {
+  FontFamily,
+  LineHeight,
+  OverallTheme,
+} from '../../../../../modules/source-editor/frontend/js/extensions/theme'
+import { Keybindings, PdfViewer } from '../../../../../types/project-settings'
+import { postJSON } from '../../../infrastructure/fetch-json'
+
+export type UserSettingsScope = {
+  pdfViewer: PdfViewer
+  autoComplete: boolean
+  autoPairDelimiters: boolean
+  syntaxValidation: boolean
+  editorTheme: string
+  overallTheme: OverallTheme
+  mode: Keybindings
+  fontSize: string
+  fontFamily: FontFamily
+  lineHeight: LineHeight
+}
+
+export function saveUserSettings(data: Partial<UserSettingsScope>) {
+  postJSON('/user/settings', {
+    body: data,
+  })
+}

+ 2 - 0
services/web/types/window.ts

@@ -1,5 +1,6 @@
 import { ExposedSettings } from './exposed-settings'
 import { OAuthProviders } from './oauth-providers'
+import { OverallThemeMeta } from './project-settings'
 import { User } from './user'
 
 declare global {
@@ -31,5 +32,6 @@ declare global {
     MathJax: {
       Hub: Record<string, any>
     }
+    overallThemes: OverallThemeMeta[]
   }
 }