PageEditorModeManager.jsx 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. import React, { useCallback } from 'react';
  2. import PropTypes from 'prop-types';
  3. import { useTranslation } from 'react-i18next';
  4. import { UncontrolledTooltip } from 'reactstrap';
  5. import AppContainer from '~/client/services/AppContainer';
  6. import { useCurrentUser } from '~/stores/context';
  7. import { EditorMode, useIsDeviceSmallerThanMd } from '~/stores/ui';
  8. import { withUnstatedContainers } from '../UnstatedUtils';
  9. /* eslint-disable react/prop-types */
  10. const PageEditorModeButtonWrapper = React.memo(({
  11. editorMode, isBtnDisabled, onClick, targetMode, icon, label, id,
  12. }) => {
  13. const classNames = [`btn btn-outline-primary ${targetMode}-button px-1`];
  14. if (editorMode === targetMode) {
  15. classNames.push('active');
  16. }
  17. if (isBtnDisabled) {
  18. classNames.push('disabled');
  19. }
  20. return (
  21. <button
  22. type="button"
  23. className={classNames.join(' ')}
  24. onClick={() => { onClick(targetMode) }}
  25. id={id}
  26. >
  27. <span className="d-flex flex-column flex-md-row justify-content-center">
  28. <span className="grw-page-editor-mode-manager-icon mr-md-1">{icon}</span>
  29. <span className="grw-page-editor-mode-manager-label">{label}</span>
  30. </span>
  31. </button>
  32. );
  33. });
  34. /* eslint-enable react/prop-types */
  35. function PageEditorModeManager(props) {
  36. const {
  37. appContainer,
  38. editorMode, onPageEditorModeButtonClicked, isBtnDisabled,
  39. } = props;
  40. const { t } = useTranslation();
  41. const { data: isDeviceSmallerThanMd } = useIsDeviceSmallerThanMd();
  42. const { data: currentUser } = useCurrentUser();
  43. const isAdmin = currentUser?.isAdmin;
  44. const isHackmdEnabled = appContainer.config.env.HACKMD_URI != null;
  45. const showHackmdBtn = isHackmdEnabled || isAdmin;
  46. const pageEditorModeButtonClickedHandler = useCallback((viewType) => {
  47. if (isBtnDisabled) {
  48. return;
  49. }
  50. if (onPageEditorModeButtonClicked != null) {
  51. onPageEditorModeButtonClicked(viewType);
  52. }
  53. }, [isBtnDisabled, onPageEditorModeButtonClicked]);
  54. return (
  55. <>
  56. <div
  57. className="btn-group grw-page-editor-mode-manager"
  58. role="group"
  59. aria-label="page-editor-mode-manager"
  60. id="grw-page-editor-mode-manager"
  61. >
  62. {(!isDeviceSmallerThanMd || editorMode !== EditorMode.View) && (
  63. <PageEditorModeButtonWrapper
  64. editorMode={editorMode}
  65. isBtnDisabled={isBtnDisabled}
  66. onClick={pageEditorModeButtonClickedHandler}
  67. targetMode={EditorMode.View}
  68. icon={<i className="icon-control-play" />}
  69. label={t('view')}
  70. />
  71. )}
  72. {(!isDeviceSmallerThanMd || editorMode === EditorMode.View) && (
  73. <PageEditorModeButtonWrapper
  74. editorMode={editorMode}
  75. isBtnDisabled={isBtnDisabled}
  76. onClick={pageEditorModeButtonClickedHandler}
  77. targetMode={EditorMode.Editor}
  78. icon={<i className="icon-note" />}
  79. label={t('Edit')}
  80. />
  81. )}
  82. {(!isDeviceSmallerThanMd || editorMode === EditorMode.View) && showHackmdBtn && (
  83. <>
  84. <PageEditorModeButtonWrapper
  85. editorMode={editorMode}
  86. isBtnDisabled={isBtnDisabled || !isHackmdEnabled}
  87. onClick={isHackmdEnabled ? pageEditorModeButtonClickedHandler : undefined}
  88. targetMode={EditorMode.HackMD}
  89. icon={<i className="fa fa-file-text-o" />}
  90. label={t('hackmd.hack_md')}
  91. id="grw-page-editor-mode-manager-hackmd-button"
  92. />
  93. { !isHackmdEnabled && (
  94. <UncontrolledTooltip placement="top" target="grw-page-editor-mode-manager-hackmd-button" fade={false}>
  95. {t('hackmd.not_set_up')}
  96. </UncontrolledTooltip>
  97. )}
  98. </>
  99. )}
  100. </div>
  101. {isBtnDisabled && (
  102. <UncontrolledTooltip placement="top" target="grw-page-editor-mode-manager" fade={false}>
  103. {t('Not available for guest')}
  104. </UncontrolledTooltip>
  105. )}
  106. </>
  107. );
  108. }
  109. PageEditorModeManager.propTypes = {
  110. appContainer: PropTypes.instanceOf(AppContainer).isRequired,
  111. onPageEditorModeButtonClicked: PropTypes.func,
  112. isBtnDisabled: PropTypes.bool,
  113. editorMode: PropTypes.string,
  114. };
  115. PageEditorModeManager.defaultProps = {
  116. isBtnDisabled: false,
  117. };
  118. /**
  119. * Wrapper component for using unstated
  120. */
  121. const PageEditorModeManagerWrapper = withUnstatedContainers(PageEditorModeManager, [AppContainer]);
  122. export default PageEditorModeManagerWrapper;