ide-context.tsx 2.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. import { createContext, FC, useContext, useEffect, useMemo } from 'react'
  2. import { ScopeValueStore } from '../../../../types/ide/scope-value-store'
  3. import { ScopeEventEmitter } from '../../../../types/ide/scope-event-emitter'
  4. import { Socket } from '@/features/ide-react/connection/types/socket'
  5. import { useUserSettingsContext } from './user-settings-context'
  6. import { userStyles } from '../utils/styles'
  7. import { canUseNewEditor } from '@/features/ide-redesign/utils/new-editor-utils'
  8. import { useActiveOverallTheme } from '../hooks/use-active-overall-theme'
  9. export type Ide = {
  10. socket: Socket
  11. }
  12. type IdeContextValue = Ide & {
  13. scopeEventEmitter: ScopeEventEmitter
  14. unstableStore: ScopeValueStore
  15. }
  16. export const IdeContext = createContext<IdeContextValue | undefined>(undefined)
  17. export const IdeProvider: FC<
  18. React.PropsWithChildren<{
  19. ide: Ide
  20. scopeEventEmitter: ScopeEventEmitter
  21. unstableStore: ScopeValueStore
  22. }>
  23. > = ({ ide, scopeEventEmitter, unstableStore, children }) => {
  24. /**
  25. * Expose unstableStore via `window.overleaf.unstable.store`, so it can be accessed by external extensions.
  26. *
  27. * These properties are expected to be available:
  28. * - `editor.view`
  29. * - `editor.open_doc_name`,
  30. * - `editor.open_doc_id`,
  31. * - `settings.theme`
  32. * - `settings.keybindings`
  33. * - `settings.fontSize`
  34. * - `settings.fontFamily`
  35. * - `settings.lineHeight`
  36. */
  37. useEffect(() => {
  38. window.overleaf = {
  39. ...window.overleaf,
  40. unstable: {
  41. ...window.overleaf?.unstable,
  42. store: unstableStore,
  43. },
  44. }
  45. }, [unstableStore])
  46. const { userSettings } = useUserSettingsContext()
  47. const activeOverallTheme = useActiveOverallTheme()
  48. useEffect(() => {
  49. const { fontFamily, lineHeight } = userStyles(userSettings)
  50. unstableStore.set('settings', {
  51. overallTheme: activeOverallTheme,
  52. keybindings: userSettings.mode === 'none' ? 'default' : userSettings.mode,
  53. fontFamily,
  54. lineHeight,
  55. fontSize: userSettings.fontSize,
  56. isNewEditor: canUseNewEditor() && userSettings.enableNewEditor,
  57. })
  58. }, [unstableStore, userSettings, activeOverallTheme])
  59. const value = useMemo<IdeContextValue>(() => {
  60. return {
  61. ...ide,
  62. scopeEventEmitter,
  63. unstableStore,
  64. }
  65. }, [ide, scopeEventEmitter, unstableStore])
  66. return <IdeContext.Provider value={value}>{children}</IdeContext.Provider>
  67. }
  68. export function useIdeContext(): IdeContextValue {
  69. const context = useContext(IdeContext)
  70. if (!context) {
  71. throw new Error('useIdeContext is only available inside IdeProvider')
  72. }
  73. return context
  74. }