user-settings-context.tsx 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. import {
  2. createContext,
  3. useContext,
  4. useMemo,
  5. Dispatch,
  6. SetStateAction,
  7. FC,
  8. useState,
  9. useEffect,
  10. } from 'react'
  11. import { UserSettings } from '../../../../types/user-settings'
  12. import getMeta from '@/utils/meta'
  13. const defaultSettings: UserSettings = {
  14. pdfViewer: 'pdfjs',
  15. autoComplete: true,
  16. autoPairDelimiters: true,
  17. syntaxValidation: false,
  18. editorTheme: 'textmate',
  19. overallTheme: '',
  20. mode: 'default',
  21. fontSize: 12,
  22. fontFamily: 'monaco',
  23. lineHeight: 'normal',
  24. mathPreview: true,
  25. }
  26. type UserSettingsContextValue = {
  27. userSettings: UserSettings
  28. setUserSettings: Dispatch<
  29. SetStateAction<UserSettingsContextValue['userSettings']>
  30. >
  31. }
  32. export const UserSettingsContext = createContext<
  33. UserSettingsContextValue | undefined
  34. >(undefined)
  35. export const UserSettingsProvider: FC = ({ children }) => {
  36. const [userSettings, setUserSettings] = useState<
  37. UserSettingsContextValue['userSettings']
  38. >(() => getMeta('ol-userSettings') || defaultSettings)
  39. const value = useMemo<UserSettingsContextValue>(
  40. () => ({
  41. userSettings,
  42. setUserSettings,
  43. }),
  44. [userSettings, setUserSettings]
  45. )
  46. // Fire an event to inform non-React code of settings changes
  47. useEffect(() => {
  48. window.dispatchEvent(
  49. new CustomEvent('settings:change', { detail: userSettings })
  50. )
  51. }, [userSettings])
  52. return (
  53. <UserSettingsContext.Provider value={value}>
  54. {children}
  55. </UserSettingsContext.Provider>
  56. )
  57. }
  58. export function useUserSettingsContext() {
  59. const context = useContext(UserSettingsContext)
  60. if (!context) {
  61. throw new Error(
  62. 'useUserSettingsContext is only available inside UserSettingsProvider'
  63. )
  64. }
  65. return context
  66. }