user-settings-context.tsx 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. import {
  2. createContext,
  3. useContext,
  4. useMemo,
  5. Dispatch,
  6. SetStateAction,
  7. FC,
  8. useState,
  9. useEffect,
  10. } from 'react'
  11. import { UserSettings, Keybindings } from '../../../../types/user-settings'
  12. import getMeta from '@/utils/meta'
  13. import useScopeValue from '@/shared/hooks/use-scope-value'
  14. import { userStyles } from '../utils/styles'
  15. import { canUseNewEditor } from '@/features/ide-redesign/utils/new-editor-utils'
  16. const defaultSettings: UserSettings = {
  17. pdfViewer: 'pdfjs',
  18. autoComplete: true,
  19. autoPairDelimiters: true,
  20. syntaxValidation: false,
  21. editorTheme: 'textmate',
  22. overallTheme: '',
  23. mode: 'default',
  24. fontSize: 12,
  25. fontFamily: 'monaco',
  26. lineHeight: 'normal',
  27. mathPreview: true,
  28. referencesSearchMode: 'advanced',
  29. enableNewEditor: true,
  30. }
  31. type UserSettingsContextValue = {
  32. userSettings: UserSettings
  33. setUserSettings: Dispatch<
  34. SetStateAction<UserSettingsContextValue['userSettings']>
  35. >
  36. }
  37. type ScopeSettings = {
  38. overallTheme: 'light' | 'dark'
  39. keybindings: Keybindings
  40. fontSize: number
  41. fontFamily: string
  42. lineHeight: number
  43. isNewEditor: boolean
  44. }
  45. export const UserSettingsContext = createContext<
  46. UserSettingsContextValue | undefined
  47. >(undefined)
  48. export const UserSettingsProvider: FC<React.PropsWithChildren> = ({
  49. children,
  50. }) => {
  51. const [userSettings, setUserSettings] = useState<UserSettings>(
  52. () => getMeta('ol-userSettings') || defaultSettings
  53. )
  54. // update the global scope 'settings' value, for extensions
  55. const [, setScopeSettings] = useScopeValue<ScopeSettings>('settings')
  56. useEffect(() => {
  57. const { fontFamily, lineHeight } = userStyles(userSettings)
  58. setScopeSettings({
  59. overallTheme: userSettings.overallTheme === 'light-' ? 'light' : 'dark',
  60. keybindings: userSettings.mode === 'none' ? 'default' : userSettings.mode,
  61. fontFamily,
  62. lineHeight,
  63. fontSize: userSettings.fontSize,
  64. isNewEditor: canUseNewEditor() && userSettings.enableNewEditor,
  65. })
  66. }, [setScopeSettings, userSettings])
  67. const value = useMemo<UserSettingsContextValue>(
  68. () => ({
  69. userSettings,
  70. setUserSettings,
  71. }),
  72. [userSettings, setUserSettings]
  73. )
  74. return (
  75. <UserSettingsContext.Provider value={value}>
  76. {children}
  77. </UserSettingsContext.Provider>
  78. )
  79. }
  80. export function useUserSettingsContext() {
  81. const context = useContext(UserSettingsContext)
  82. if (!context) {
  83. throw new Error(
  84. 'useUserSettingsContext is only available inside UserSettingsProvider'
  85. )
  86. }
  87. return context
  88. }