PagePresentationModal.tsx 2.5 KB

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