editor-context.js 4.1 KB

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