ide-context.tsx 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. import { createContext, FC, useContext, useEffect, useMemo } from 'react'
  2. import { ScopeValueStore } from '../../../../types/ide/scope-value-store'
  3. import { Scope } from '../../../../types/angular/scope'
  4. import getMeta from '@/utils/meta'
  5. import { ScopeEventEmitter } from '../../../../types/ide/scope-event-emitter'
  6. export type Ide = {
  7. [key: string]: any // TODO: define the rest of the `ide` and `$scope` properties
  8. $scope: Scope
  9. }
  10. type IdeContextValue = Ide & {
  11. isReactIde: boolean
  12. scopeStore: ScopeValueStore
  13. scopeEventEmitter: ScopeEventEmitter
  14. }
  15. const IdeContext = createContext<IdeContextValue | undefined>(undefined)
  16. const isReactIde: boolean = getMeta('ol-idePageReact')
  17. export const IdeProvider: FC<{
  18. ide: Ide
  19. scopeStore: ScopeValueStore
  20. scopeEventEmitter: ScopeEventEmitter
  21. }> = ({ ide, scopeStore, scopeEventEmitter, children }) => {
  22. /**
  23. * Expose scopeStore 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. * - `project.spellcheckLanguage`
  28. * - `editor.open_doc_name`,
  29. * - `editor.open_doc_id`,
  30. */
  31. useEffect(() => {
  32. window.overleaf = {
  33. ...window.overleaf,
  34. unstable: {
  35. ...window.overleaf?.unstable,
  36. store: scopeStore,
  37. },
  38. }
  39. }, [scopeStore])
  40. const value = useMemo<IdeContextValue>(() => {
  41. return {
  42. ...ide,
  43. isReactIde,
  44. scopeStore,
  45. scopeEventEmitter,
  46. }
  47. }, [ide, scopeStore, scopeEventEmitter])
  48. return <IdeContext.Provider value={value}>{children}</IdeContext.Provider>
  49. }
  50. export function useIdeContext(): IdeContextValue {
  51. const context = useContext(IdeContext)
  52. if (!context) {
  53. throw new Error('useIdeContext is only available inside IdeProvider')
  54. }
  55. return context
  56. }