user-settings-context.tsx 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  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 = ({ children }) => {
  49. const [userSettings, setUserSettings] = useState<UserSettings>(
  50. () => getMeta('ol-userSettings') || defaultSettings
  51. )
  52. // update the global scope 'settings' value, for extensions
  53. const [, setScopeSettings] = useScopeValue<ScopeSettings>('settings')
  54. useEffect(() => {
  55. const { fontFamily, lineHeight } = userStyles(userSettings)
  56. setScopeSettings({
  57. overallTheme: userSettings.overallTheme === 'light-' ? 'light' : 'dark',
  58. keybindings: userSettings.mode === 'none' ? 'default' : userSettings.mode,
  59. fontFamily,
  60. lineHeight,
  61. fontSize: userSettings.fontSize,
  62. isNewEditor: canUseNewEditor() && userSettings.enableNewEditor,
  63. })
  64. }, [setScopeSettings, userSettings])
  65. const value = useMemo<UserSettingsContextValue>(
  66. () => ({
  67. userSettings,
  68. setUserSettings,
  69. }),
  70. [userSettings, setUserSettings]
  71. )
  72. return (
  73. <UserSettingsContext.Provider value={value}>
  74. {children}
  75. </UserSettingsContext.Provider>
  76. )
  77. }
  78. export function useUserSettingsContext() {
  79. const context = useContext(UserSettingsContext)
  80. if (!context) {
  81. throw new Error(
  82. 'useUserSettingsContext is only available inside UserSettingsProvider'
  83. )
  84. }
  85. return context
  86. }