user-settings-context.tsx 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  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. const defaultSettings: UserSettings = {
  15. pdfViewer: 'pdfjs',
  16. autoComplete: true,
  17. autoPairDelimiters: true,
  18. syntaxValidation: false,
  19. editorTheme: 'textmate',
  20. overallTheme: '',
  21. mode: 'default',
  22. fontSize: 12,
  23. fontFamily: 'monaco',
  24. lineHeight: 'normal',
  25. mathPreview: true,
  26. referencesSearchMode: 'advanced',
  27. }
  28. type UserSettingsContextValue = {
  29. userSettings: UserSettings
  30. setUserSettings: Dispatch<
  31. SetStateAction<UserSettingsContextValue['userSettings']>
  32. >
  33. }
  34. type ScopeSettings = {
  35. overallTheme: 'light' | 'dark'
  36. keybindings: Keybindings
  37. fontSize: number
  38. }
  39. export const UserSettingsContext = createContext<
  40. UserSettingsContextValue | undefined
  41. >(undefined)
  42. export const UserSettingsProvider: FC = ({ children }) => {
  43. const [userSettings, setUserSettings] = useState<UserSettings>(
  44. () => getMeta('ol-userSettings') || defaultSettings
  45. )
  46. // update the global scope 'settings' value, for extensions
  47. const [, setScopeSettings] = useScopeValue<ScopeSettings>('settings')
  48. useEffect(() => {
  49. setScopeSettings({
  50. overallTheme: userSettings.overallTheme === 'light-' ? 'light' : 'dark',
  51. keybindings: userSettings.mode === 'none' ? 'default' : userSettings.mode,
  52. fontSize: userSettings.fontSize,
  53. })
  54. }, [setScopeSettings, userSettings])
  55. const value = useMemo<UserSettingsContextValue>(
  56. () => ({
  57. userSettings,
  58. setUserSettings,
  59. }),
  60. [userSettings, setUserSettings]
  61. )
  62. return (
  63. <UserSettingsContext.Provider value={value}>
  64. {children}
  65. </UserSettingsContext.Provider>
  66. )
  67. }
  68. export function useUserSettingsContext() {
  69. const context = useContext(UserSettingsContext)
  70. if (!context) {
  71. throw new Error(
  72. 'useUserSettingsContext is only available inside UserSettingsProvider'
  73. )
  74. }
  75. return context
  76. }