PagePresentationModal.tsx 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. import React, { useCallback } from 'react';
  2. import type { PresentationProps } from '@growi/presentation';
  3. import { useFullScreen } from '@growi/ui/dist/utils';
  4. import dynamic from 'next/dynamic';
  5. import type { ReactMarkdownOptions } from 'react-markdown/lib/react-markdown';
  6. import {
  7. Modal, ModalBody,
  8. } from 'reactstrap';
  9. import { usePagePresentationModal } from '~/stores/modal';
  10. import { useSWRxCurrentPage } from '~/stores/page';
  11. import { usePresentationViewOptions } from '~/stores/renderer';
  12. import { useNextThemes } from '~/stores/use-next-themes';
  13. import styles from './PagePresentationModal.module.scss';
  14. const Presentation = dynamic<PresentationProps>(() => import('./Presentation/Presentation').then(mod => mod.Presentation), {
  15. ssr: false,
  16. loading: () => (
  17. <i className="fa fa-4x fa-spinner fa-pulse text-muted"></i>
  18. ),
  19. });
  20. const PagePresentationModal = (): JSX.Element => {
  21. const { data: presentationModalData, close: closePresentationModal } = usePagePresentationModal();
  22. const { isDarkMode } = useNextThemes();
  23. const fullscreen = useFullScreen();
  24. const { data: currentPage } = useSWRxCurrentPage();
  25. const { data: rendererOptions } = usePresentationViewOptions();
  26. const toggleFullscreenHandler = useCallback(() => {
  27. if (fullscreen.active) {
  28. fullscreen.exit();
  29. }
  30. else {
  31. fullscreen.enter();
  32. }
  33. }, [fullscreen]);
  34. const closeHandler = useCallback(() => {
  35. if (fullscreen.active) {
  36. fullscreen.exit();
  37. }
  38. closePresentationModal();
  39. }, [fullscreen, closePresentationModal]);
  40. const isOpen = presentationModalData?.isOpened ?? false;
  41. if (!isOpen) {
  42. return <></>;
  43. }
  44. const markdown = currentPage?.revision.body;
  45. return (
  46. <Modal
  47. isOpen={isOpen}
  48. toggle={closeHandler}
  49. data-testid="page-presentation-modal"
  50. className={`grw-presentation-modal ${styles['grw-presentation-modal']}`}
  51. >
  52. <div className="grw-presentation-controls d-flex">
  53. <button className="close btn-fullscreen" type="button" aria-label="fullscreen" onClick={toggleFullscreenHandler}>
  54. <i className={`${fullscreen.active ? 'icon-size-actual' : 'icon-size-fullscreen'}`} aria-hidden></i>
  55. </button>
  56. <button className="close btn-close" type="button" aria-label="close" onClick={closeHandler}>
  57. <i className="ti ti-close" aria-hidden></i>
  58. </button>
  59. </div>
  60. <ModalBody className="modal-body d-flex justify-content-center align-items-center">
  61. { rendererOptions != null && (
  62. <Presentation
  63. options={{
  64. rendererOptions: rendererOptions as ReactMarkdownOptions,
  65. revealOptions: {
  66. embedded: true,
  67. hash: true,
  68. },
  69. isDarkMode,
  70. }}
  71. >
  72. {markdown}
  73. </Presentation>
  74. ) }
  75. </ModalBody>
  76. </Modal>
  77. );
  78. };
  79. export default PagePresentationModal;