EditorNavbarBottom.tsx 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. import React, { useCallback, useState, useEffect } from 'react';
  2. import PropTypes from 'prop-types';
  3. import { Collapse, Button } from 'reactstrap';
  4. import AppContainer from '~/client/services/AppContainer';
  5. import EditorContainer from '~/client/services/EditorContainer';
  6. import { useCurrentPagePath } from '~/stores/context';
  7. import { useSWRxSlackChannels, useSWRxIsSlackEnabledBydefault, useSWRxIsSlackEnabled } from '~/stores/editor';
  8. import {
  9. EditorMode, useDrawerOpened, useEditorMode, useIsDeviceSmallerThanMd,
  10. } from '~/stores/ui';
  11. import SavePageControls from '../SavePageControls';
  12. import SlackLogo from '../SlackLogo';
  13. import { SlackNotification } from '../SlackNotification';
  14. import { withUnstatedContainers } from '../UnstatedUtils';
  15. import OptionsSelector from './OptionsSelector';
  16. const EditorNavbarBottom = (props) => {
  17. const { data: editorMode } = useEditorMode();
  18. const [isExpanded, setExpanded] = useState(false);
  19. const [isSlackExpanded, setSlackExpanded] = useState(false);
  20. const isSlackConfigured = props.appContainer.getConfig().isSlackConfigured;
  21. const { mutate: mutateDrawerOpened } = useDrawerOpened();
  22. const { data: isDeviceSmallerThanMd } = useIsDeviceSmallerThanMd();
  23. const additionalClasses = ['grw-editor-navbar-bottom'];
  24. // const { data: currentPagePath } = useCurrentPagePath();
  25. const { data: slackChannelsData } = useSWRxSlackChannels();
  26. // const isSlackEnabledByDefault = (slackChannelsData != null && slackChannelsData.length > 0);
  27. // const { data: isSlackEnabledByDefault } = useSWRxIsSlackEnabledBydefault();
  28. const { data: isSlackEnabled, mutate: mutateIsSlackEnabled } = useSWRxIsSlackEnabled();
  29. console.log('isSlackEnabled_hoge', isSlackEnabled);
  30. const [slackChannelsStr, setSlackChannelsStr] = useState<string>('');
  31. useEffect(() => {
  32. if (slackChannelsData != null) {
  33. setSlackChannelsStr(slackChannelsData.toString());
  34. }
  35. }, [slackChannelsData]);
  36. const isSlackEnabledToggleHandler = (bool: boolean) => {
  37. mutateIsSlackEnabled(bool, false);
  38. };
  39. const slackChannelsChangedHandler = useCallback((slackChannels: string) => {
  40. setSlackChannelsStr(slackChannels);
  41. }, []);
  42. const renderDrawerButton = () => (
  43. <button
  44. type="button"
  45. className="btn btn-outline-secondary border-0"
  46. onClick={() => mutateDrawerOpened(true)}
  47. >
  48. <i className="icon-menu"></i>
  49. </button>
  50. );
  51. const renderExpandButton = () => (
  52. <div className="d-md-none ml-2">
  53. <button
  54. type="button"
  55. className={`btn btn-outline-secondary btn-expand border-0 ${isExpanded ? 'expand' : ''}`}
  56. onClick={() => setExpanded(!isExpanded)}
  57. >
  58. <i className="icon-arrow-up"></i>
  59. </button>
  60. </div>
  61. );
  62. const isOptionsSelectorEnabled = editorMode !== EditorMode.HackMD;
  63. const isCollapsedOptionsSelectorEnabled = isOptionsSelectorEnabled && isDeviceSmallerThanMd;
  64. return (
  65. <div className={`${isCollapsedOptionsSelectorEnabled ? 'fixed-bottom' : ''} `}>
  66. {/* Collapsed SlackNotification */}
  67. {isSlackConfigured && (
  68. <Collapse isOpen={isSlackExpanded && isDeviceSmallerThanMd === true}>
  69. <nav className={`navbar navbar-expand-lg border-top ${additionalClasses.join(' ')}`}>
  70. <SlackNotification
  71. isSlackEnabled={isSlackEnabled ?? false}
  72. slackChannels={slackChannelsStr}
  73. onEnabledFlagChange={isSlackEnabledToggleHandler}
  74. onChannelChange={slackChannelsChangedHandler}
  75. id="idForEditorNavbarBottomForMobile"
  76. />
  77. </nav>
  78. </Collapse>
  79. )
  80. }
  81. <div className={`navbar navbar-expand border-top px-2 px-md-3 ${additionalClasses.join(' ')}`}>
  82. <form className="form-inline">
  83. { isDeviceSmallerThanMd && renderDrawerButton() }
  84. { isOptionsSelectorEnabled && !isDeviceSmallerThanMd && <OptionsSelector /> }
  85. </form>
  86. <form className="form-inline flex-nowrap ml-auto">
  87. {/* Responsive Design for the SlackNotification */}
  88. {/* Button or the normal Slack banner */}
  89. {isSlackConfigured && (isDeviceSmallerThanMd ? (
  90. <Button
  91. className="grw-btn-slack border mr-2"
  92. onClick={() => (setSlackExpanded(!isSlackExpanded))}
  93. >
  94. <div className="grw-slack-logo">
  95. <SlackLogo />
  96. <span className="grw-btn-slack-triangle fa fa-caret-up ml-2"></span>
  97. </div>
  98. </Button>
  99. ) : (
  100. <div className="mr-2">
  101. <SlackNotification
  102. isSlackEnabled={isSlackEnabled || false}
  103. slackChannels={slackChannelsStr}
  104. onEnabledFlagChange={isSlackEnabledToggleHandler}
  105. onChannelChange={slackChannelsChangedHandler}
  106. id="idForEditorNavbarBottom"
  107. />
  108. </div>
  109. ))}
  110. <SavePageControls slackChannels={slackChannelsStr} isSlackEnabled={isSlackEnabled || false} />
  111. { isCollapsedOptionsSelectorEnabled && renderExpandButton() }
  112. </form>
  113. </div>
  114. {/* Collapsed OptionsSelector */}
  115. { isCollapsedOptionsSelectorEnabled && (
  116. <Collapse isOpen={isExpanded}>
  117. <div className="px-2"> {/* set padding for border-top */}
  118. <div className={`navbar navbar-expand border-top px-0 ${additionalClasses.join(' ')}`}>
  119. <form className="form-inline ml-auto">
  120. <OptionsSelector />
  121. </form>
  122. </div>
  123. </div>
  124. </Collapse>
  125. ) }
  126. </div>
  127. );
  128. };
  129. EditorNavbarBottom.propTypes = {
  130. appContainer: PropTypes.instanceOf(AppContainer).isRequired,
  131. editorContainer: PropTypes.instanceOf(EditorContainer).isRequired,
  132. };
  133. export default withUnstatedContainers(EditorNavbarBottom, [EditorContainer, AppContainer]);