user-settings-context.tsx 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  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. import customLocalStorage from '@/infrastructure/local-storage'
  14. import { getLegacyWriteAndCiteMigration } from '../utils/write-and-cite-settings-migration'
  15. import { saveUserSettings } from '@/features/editor-left-menu/utils/api'
  16. export const defaultSettings: UserSettings = {
  17. pdfViewer: 'pdfjs',
  18. autoComplete: true,
  19. autoPairDelimiters: true,
  20. syntaxValidation: false,
  21. editorTheme: 'textmate',
  22. editorDarkTheme: 'overleaf_dark',
  23. editorLightTheme: 'textmate',
  24. overallTheme: '',
  25. mode: 'default',
  26. fontSize: 12,
  27. fontFamily: 'monaco',
  28. lineHeight: 'normal',
  29. mathPreview: true,
  30. referencesSearchMode: 'advanced',
  31. breadcrumbs: true,
  32. darkModePdf: false,
  33. zotero: {
  34. enabled: true,
  35. groups: [],
  36. disablePersonalLibrary: false,
  37. },
  38. mendeley: {
  39. enabled: true,
  40. groups: [],
  41. disablePersonalLibrary: false,
  42. },
  43. papers: {
  44. enabled: true,
  45. groups: [],
  46. disablePersonalLibrary: false,
  47. },
  48. }
  49. type UserSettingsContextValue = {
  50. userSettings: UserSettings
  51. setUserSettings: Dispatch<
  52. SetStateAction<UserSettingsContextValue['userSettings']>
  53. >
  54. }
  55. export const UserSettingsContext = createContext<
  56. UserSettingsContextValue | undefined
  57. >(undefined)
  58. export const UserSettingsProvider: FC<React.PropsWithChildren> = ({
  59. children,
  60. }) => {
  61. const [userSettings, setUserSettings] = useState<UserSettings>(
  62. () => getMeta('ol-userSettings') || defaultSettings
  63. )
  64. useEffect(() => {
  65. const { patch, keysToRemove } = getLegacyWriteAndCiteMigration(userSettings)
  66. if (Object.keys(patch).length === 0) {
  67. keysToRemove.forEach(customLocalStorage.removeItem)
  68. return
  69. }
  70. Promise.all(
  71. Object.entries(patch).map(([key, value]) =>
  72. saveUserSettings(
  73. key as keyof Pick<UserSettings, 'mendeley' | 'zotero' | 'papers'>,
  74. value
  75. )
  76. )
  77. ).then(() => {
  78. setUserSettings(currentSettings => ({
  79. ...currentSettings,
  80. ...patch,
  81. }))
  82. keysToRemove.forEach(customLocalStorage.removeItem)
  83. })
  84. // Only run once when the provider mounts
  85. // eslint-disable-next-line react-hooks/exhaustive-deps
  86. }, [])
  87. const value = useMemo<UserSettingsContextValue>(
  88. () => ({
  89. userSettings,
  90. setUserSettings,
  91. }),
  92. [userSettings, setUserSettings]
  93. )
  94. return (
  95. <UserSettingsContext.Provider value={value}>
  96. {children}
  97. </UserSettingsContext.Provider>
  98. )
  99. }
  100. export function useUserSettingsContext() {
  101. const context = useContext(UserSettingsContext)
  102. if (!context) {
  103. throw new Error(
  104. 'useUserSettingsContext is only available inside UserSettingsProvider'
  105. )
  106. }
  107. return context
  108. }