ide-context.tsx 1.8 KB

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