user-settings-context.tsx 2.9 KB

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