layout-context.js 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. import { createContext, useContext, useCallback, useMemo } from 'react'
  2. import PropTypes from 'prop-types'
  3. import useScopeValue from '../hooks/use-scope-value'
  4. import { useIdeContext } from './ide-context'
  5. export const LayoutContext = createContext()
  6. LayoutContext.Provider.propTypes = {
  7. value: PropTypes.shape({
  8. view: PropTypes.string,
  9. setView: PropTypes.func.isRequired,
  10. chatIsOpen: PropTypes.bool,
  11. setChatIsOpen: PropTypes.func.isRequired,
  12. reviewPanelOpen: PropTypes.bool,
  13. setReviewPanelOpen: PropTypes.func.isRequired,
  14. leftMenuShown: PropTypes.bool,
  15. setLeftMenuShown: PropTypes.func.isRequired,
  16. pdfLayout: PropTypes.oneOf(['sideBySide', 'flat', 'split']).isRequired,
  17. }).isRequired,
  18. }
  19. export function LayoutProvider({ children }) {
  20. const { $scope } = useIdeContext()
  21. // what to show in the "flat" view (editor or pdf)
  22. const [view, _setView] = useScopeValue('ui.view')
  23. const setView = useCallback(
  24. value => {
  25. _setView(oldValue => {
  26. // ensure that the "history:toggle" event is broadcast when switching in or out of history view
  27. if (value === 'history' || oldValue === 'history') {
  28. $scope.toggleHistory()
  29. }
  30. return value
  31. })
  32. },
  33. [$scope, _setView]
  34. )
  35. // whether the chat pane is open
  36. const [chatIsOpen, setChatIsOpen] = useScopeValue('ui.chatOpen')
  37. // whether the review pane is open
  38. const [reviewPanelOpen, setReviewPanelOpen] = useScopeValue(
  39. 'ui.reviewPanelOpen'
  40. )
  41. // whether the menu pane is open
  42. const [leftMenuShown, setLeftMenuShown] = useScopeValue('ui.leftMenuShown')
  43. // whether to display the editor and preview side-by-side or full-width ("flat")
  44. const [pdfLayout, setPdfLayout] = useScopeValue('ui.pdfLayout')
  45. // whether the PDF preview pane is hidden
  46. const [pdfHidden] = useScopeValue('ui.pdfHidden')
  47. const value = useMemo(
  48. () => ({
  49. chatIsOpen,
  50. leftMenuShown,
  51. pdfHidden,
  52. pdfLayout,
  53. reviewPanelOpen,
  54. setChatIsOpen,
  55. setLeftMenuShown,
  56. setPdfLayout,
  57. setReviewPanelOpen,
  58. setView,
  59. view,
  60. }),
  61. [
  62. chatIsOpen,
  63. leftMenuShown,
  64. pdfHidden,
  65. pdfLayout,
  66. reviewPanelOpen,
  67. setChatIsOpen,
  68. setLeftMenuShown,
  69. setPdfLayout,
  70. setReviewPanelOpen,
  71. setView,
  72. view,
  73. ]
  74. )
  75. return (
  76. <LayoutContext.Provider value={value}>{children}</LayoutContext.Provider>
  77. )
  78. }
  79. LayoutProvider.propTypes = {
  80. children: PropTypes.any,
  81. }
  82. export function useLayoutContext(propTypes) {
  83. const data = useContext(LayoutContext)
  84. PropTypes.checkPropTypes(propTypes, data, 'data', 'LayoutContext.Provider')
  85. return data
  86. }