editor-context.js 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. import React, { createContext, useCallback, useContext, useEffect } from 'react'
  2. import PropTypes from 'prop-types'
  3. import usePersistedState from '../../infrastructure/persisted-state-hook'
  4. export const EditorContext = createContext()
  5. export function EditorProvider({
  6. children,
  7. loading,
  8. chatIsOpenAngular,
  9. setChatIsOpenAngular
  10. }) {
  11. const cobranding = window.brandVariation
  12. ? {
  13. logoImgUrl: window.brandVariation.logo_url,
  14. brandVariationName: window.brandVariation.name,
  15. brandVariationHomeUrl: window.brandVariation.home_url
  16. }
  17. : undefined
  18. const ownerId =
  19. window._ide.$scope.project && window._ide.$scope.project.owner
  20. ? window._ide.$scope.project.owner._id
  21. : null
  22. const [chatIsOpen, setChatIsOpen] = usePersistedState(
  23. 'editor.ui.chat.open',
  24. false
  25. )
  26. const toggleChatOpen = useCallback(() => {
  27. setChatIsOpen(!chatIsOpen)
  28. setChatIsOpenAngular(!chatIsOpen)
  29. }, [chatIsOpen, setChatIsOpenAngular, setChatIsOpen])
  30. // updates React's `chatIsOpen` state when the chat is opened by Angular.
  31. // In order to prevent race conditions with `toggleChatOpen` it's not a 1:1 binding:
  32. // Angular forces the React state to `true`, but can only set it to `false` when
  33. // the React state is explicitly `true`.
  34. useEffect(() => {
  35. if (chatIsOpenAngular) {
  36. setChatIsOpen(true)
  37. } else if (chatIsOpen) {
  38. setChatIsOpen(false)
  39. }
  40. }, [chatIsOpenAngular, chatIsOpen, setChatIsOpen])
  41. const editorContextValue = {
  42. cobranding,
  43. loading,
  44. projectId: window.project_id,
  45. isProjectOwner: ownerId === window.user.id,
  46. ui: {
  47. chatIsOpen,
  48. toggleChatOpen
  49. }
  50. }
  51. return (
  52. <EditorContext.Provider value={editorContextValue}>
  53. {children}
  54. </EditorContext.Provider>
  55. )
  56. }
  57. EditorProvider.propTypes = {
  58. children: PropTypes.any,
  59. loading: PropTypes.bool,
  60. chatIsOpenAngular: PropTypes.bool,
  61. setChatIsOpenAngular: PropTypes.func.isRequired
  62. }
  63. export function useEditorContext() {
  64. const editorContext = useContext(EditorContext)
  65. return editorContext
  66. }