ide-context.tsx 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  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. export type Ide = {
  6. socket: Socket
  7. }
  8. type IdeContextValue = Ide & {
  9. scopeStore: ScopeValueStore
  10. scopeEventEmitter: ScopeEventEmitter
  11. unstableStore: ScopeValueStore
  12. }
  13. export const IdeContext = createContext<IdeContextValue | undefined>(undefined)
  14. export const IdeProvider: FC<
  15. React.PropsWithChildren<{
  16. ide: Ide
  17. scopeStore: ScopeValueStore
  18. scopeEventEmitter: ScopeEventEmitter
  19. unstableStore: ScopeValueStore
  20. }>
  21. > = ({ ide, scopeStore, scopeEventEmitter, unstableStore, children }) => {
  22. /**
  23. * Expose unstableStore via `window.overleaf.unstable.store`, so it can be accessed by external extensions.
  24. *
  25. * These properties are expected to be available:
  26. * - `editor.view`
  27. * - `editor.open_doc_name`,
  28. * - `editor.open_doc_id`,
  29. * - `settings.theme`
  30. * - `settings.keybindings`
  31. * - `settings.fontSize`
  32. * - `settings.fontFamily`
  33. * - `settings.lineHeight`
  34. */
  35. useEffect(() => {
  36. window.overleaf = {
  37. ...window.overleaf,
  38. unstable: {
  39. ...window.overleaf?.unstable,
  40. store: unstableStore,
  41. },
  42. }
  43. }, [unstableStore])
  44. const value = useMemo<IdeContextValue>(() => {
  45. return {
  46. ...ide,
  47. scopeStore,
  48. scopeEventEmitter,
  49. unstableStore,
  50. }
  51. }, [ide, scopeStore, scopeEventEmitter, unstableStore])
  52. return <IdeContext.Provider value={value}>{children}</IdeContext.Provider>
  53. }
  54. export function useIdeContext(): IdeContextValue {
  55. const context = useContext(IdeContext)
  56. if (!context) {
  57. throw new Error('useIdeContext is only available inside IdeProvider')
  58. }
  59. return context
  60. }