editor-context.js 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. import React, { createContext, useCallback, useContext, useEffect } from 'react'
  2. import PropTypes from 'prop-types'
  3. import useScopeValue from './util/scope-value-hook'
  4. import useBrowserWindow from '../hooks/use-browser-window'
  5. export const EditorContext = createContext()
  6. EditorContext.Provider.propTypes = {
  7. value: PropTypes.shape({
  8. cobranding: PropTypes.shape({
  9. logoImgUrl: PropTypes.string.isRequired,
  10. brandVariationName: PropTypes.string.isRequired,
  11. brandVariationId: PropTypes.number.isRequired,
  12. brandId: PropTypes.number.isRequired,
  13. brandVariationHomeUrl: PropTypes.string.isRequired,
  14. publishGuideHtml: PropTypes.string,
  15. partner: PropTypes.string,
  16. brandedMenu: PropTypes.string,
  17. submitBtnHtml: PropTypes.string,
  18. }),
  19. hasPremiumCompile: PropTypes.bool,
  20. loading: PropTypes.bool,
  21. projectRootDocId: PropTypes.string,
  22. projectId: PropTypes.string.isRequired,
  23. projectName: PropTypes.string.isRequired,
  24. renameProject: PropTypes.func.isRequired,
  25. isProjectOwner: PropTypes.bool,
  26. isRestrictedTokenMember: PropTypes.bool,
  27. rootFolder: PropTypes.object,
  28. }),
  29. }
  30. export function EditorProvider({ children, ide, settings }) {
  31. const cobranding = window.brandVariation
  32. ? {
  33. logoImgUrl: window.brandVariation.logo_url,
  34. brandVariationName: window.brandVariation.name,
  35. brandVariationId: window.brandVariation.id,
  36. brandId: window.brandVariation.brand_id,
  37. brandVariationHomeUrl: window.brandVariation.home_url,
  38. publishGuideHtml: window.brandVariation.publish_guide_html,
  39. partner: window.brandVariation.partner,
  40. brandedMenu: window.brandVariation.branded_menu,
  41. submitBtnHtml: window.brandVariation.submit_button_html,
  42. }
  43. : undefined
  44. const ownerId =
  45. ide.$scope.project && ide.$scope.project.owner
  46. ? ide.$scope.project.owner._id
  47. : null
  48. const [loading] = useScopeValue('state.loading', ide.$scope)
  49. const [projectRootDocId] = useScopeValue('project.rootDoc_id', ide.$scope)
  50. const [projectName, setProjectName] = useScopeValue(
  51. 'project.name',
  52. ide.$scope
  53. )
  54. const [compileGroup] = useScopeValue(
  55. 'project.features.compileGroup',
  56. ide.$scope
  57. )
  58. const [rootFolder] = useScopeValue('rootFolder', ide.$scope)
  59. const renameProject = useCallback(
  60. newName => {
  61. setProjectName(oldName => {
  62. if (oldName !== newName) {
  63. settings.saveProjectSettings({ name: newName }).catch(response => {
  64. setProjectName(oldName)
  65. const { data, status } = response
  66. if (status === 400) {
  67. return ide.showGenericMessageModal('Error renaming project', data)
  68. } else {
  69. return ide.showGenericMessageModal(
  70. 'Error renaming project',
  71. 'Please try again in a moment'
  72. )
  73. }
  74. })
  75. }
  76. return newName
  77. })
  78. },
  79. [settings, ide, setProjectName]
  80. )
  81. const { setTitle } = useBrowserWindow()
  82. useEffect(() => {
  83. setTitle(
  84. `${projectName ? projectName + ' - ' : ''}Online LaTeX Editor ${
  85. window.ExposedSettings.appName
  86. }`
  87. )
  88. }, [projectName, setTitle])
  89. const editorContextValue = {
  90. cobranding,
  91. hasPremiumCompile: compileGroup === 'priority',
  92. loading,
  93. projectId: window.project_id,
  94. projectRootDocId,
  95. projectName: projectName || '', // initially might be empty in Angular
  96. renameProject,
  97. isProjectOwner: ownerId === window.user.id,
  98. isRestrictedTokenMember: window.isRestrictedTokenMember,
  99. rootFolder,
  100. }
  101. return (
  102. <>
  103. <EditorContext.Provider value={editorContextValue}>
  104. {children}
  105. </EditorContext.Provider>
  106. </>
  107. )
  108. }
  109. EditorProvider.propTypes = {
  110. children: PropTypes.any,
  111. ide: PropTypes.any.isRequired,
  112. settings: PropTypes.any.isRequired,
  113. }
  114. export function useEditorContext(propTypes) {
  115. const data = useContext(EditorContext)
  116. PropTypes.checkPropTypes(propTypes, data, 'data', 'EditorContext.Provider')
  117. return data
  118. }