project-context.tsx 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. import { FC, createContext, useContext, useMemo, useState } from 'react'
  2. import useScopeValue from '../hooks/use-scope-value'
  3. import getMeta from '@/utils/meta'
  4. import { ProjectContextValue } from './types/project-context'
  5. import { ProjectSnapshot } from '@/infrastructure/project-snapshot'
  6. const ProjectContext = createContext<ProjectContextValue | undefined>(undefined)
  7. export function useProjectContext() {
  8. const context = useContext(ProjectContext)
  9. if (!context) {
  10. throw new Error(
  11. 'useProjectContext is only available inside ProjectProvider'
  12. )
  13. }
  14. return context
  15. }
  16. // when the provider is created the project is still not added to the Angular
  17. // scope. A few props are populated to prevent errors in existing React
  18. // components
  19. const projectFallback = {
  20. _id: getMeta('ol-project_id'),
  21. name: '',
  22. features: {},
  23. }
  24. export const ProjectProvider: FC = ({ children }) => {
  25. const [project] = useScopeValue('project')
  26. const joinedOnce = !!project
  27. const {
  28. _id,
  29. compiler,
  30. imageName,
  31. name,
  32. rootDoc_id: rootDocId,
  33. members,
  34. invites,
  35. features,
  36. publicAccesLevel: publicAccessLevel,
  37. owner,
  38. trackChangesState,
  39. mainBibliographyDoc_id: mainBibliographyDocId,
  40. } = project || projectFallback
  41. const [projectSnapshot] = useState(() => new ProjectSnapshot(_id))
  42. const tags = useMemo(
  43. () =>
  44. (getMeta('ol-projectTags') || [])
  45. // `tag.name` data may be null for some old users
  46. .map((tag: any) => ({ ...tag, name: tag.name ?? '' })),
  47. []
  48. )
  49. const value = useMemo(() => {
  50. return {
  51. _id,
  52. compiler,
  53. imageName,
  54. name,
  55. rootDocId,
  56. members,
  57. invites,
  58. features,
  59. publicAccessLevel,
  60. owner,
  61. tags,
  62. trackChangesState,
  63. mainBibliographyDocId,
  64. projectSnapshot,
  65. joinedOnce,
  66. }
  67. }, [
  68. _id,
  69. compiler,
  70. imageName,
  71. name,
  72. rootDocId,
  73. members,
  74. invites,
  75. features,
  76. publicAccessLevel,
  77. owner,
  78. tags,
  79. trackChangesState,
  80. mainBibliographyDocId,
  81. projectSnapshot,
  82. joinedOnce,
  83. ])
  84. return (
  85. <ProjectContext.Provider value={value}>{children}</ProjectContext.Provider>
  86. )
  87. }