You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

175 lines
4.7 KiB

  1. // Package imports.
  2. import PropTypes from 'prop-types';
  3. import React from 'react';
  4. import ImmutablePropTypes from 'react-immutable-proptypes';
  5. import { defineMessages } from 'react-intl';
  6. import classNames from 'classnames';
  7. // Actions.
  8. import { openModal } from 'flavours/glitch/actions/modal';
  9. import {
  10. changeSearch,
  11. clearSearch,
  12. showSearch,
  13. submitSearch,
  14. } from 'flavours/glitch/actions/search';
  15. import { cycleElefriendCompose } from 'flavours/glitch/actions/compose';
  16. // Components.
  17. import Composer from 'flavours/glitch/features/composer';
  18. import DrawerAccount from './account';
  19. import DrawerHeader from './header';
  20. import DrawerResults from './results';
  21. import DrawerSearch from './search';
  22. // Utils.
  23. import { me, mascot } from 'flavours/glitch/util/initial_state';
  24. import { wrap } from 'flavours/glitch/util/redux_helpers';
  25. // Messages.
  26. const messages = defineMessages({
  27. compose: { id: 'navigation_bar.compose', defaultMessage: 'Compose new toot' },
  28. });
  29. // State mapping.
  30. const mapStateToProps = state => ({
  31. account: state.getIn(['accounts', me]),
  32. columns: state.getIn(['settings', 'columns']),
  33. elefriend: state.getIn(['compose', 'elefriend']),
  34. results: state.getIn(['search', 'results']),
  35. searchHidden: state.getIn(['search', 'hidden']),
  36. searchValue: state.getIn(['search', 'value']),
  37. submitted: state.getIn(['search', 'submitted']),
  38. unreadNotifications: state.getIn(['notifications', 'unread']),
  39. showNotificationsBadge: state.getIn(['local_settings', 'notifications', 'tab_badge']),
  40. });
  41. // Dispatch mapping.
  42. const mapDispatchToProps = (dispatch, { intl }) => ({
  43. onChange (value) {
  44. dispatch(changeSearch(value));
  45. },
  46. onClear () {
  47. dispatch(clearSearch());
  48. },
  49. onClickElefriend () {
  50. dispatch(cycleElefriendCompose());
  51. },
  52. onShow () {
  53. dispatch(showSearch());
  54. },
  55. onSubmit () {
  56. dispatch(submitSearch());
  57. },
  58. onOpenSettings (e) {
  59. e.preventDefault();
  60. e.stopPropagation();
  61. dispatch(openModal('SETTINGS', {}));
  62. },
  63. });
  64. // The component.
  65. class Drawer extends React.Component {
  66. // Constructor.
  67. constructor (props) {
  68. super(props);
  69. }
  70. // Rendering.
  71. render () {
  72. const {
  73. account,
  74. columns,
  75. elefriend,
  76. intl,
  77. multiColumn,
  78. onChange,
  79. onClear,
  80. onClickElefriend,
  81. onOpenSettings,
  82. onShow,
  83. onSubmit,
  84. results,
  85. searchHidden,
  86. searchValue,
  87. submitted,
  88. isSearchPage,
  89. unreadNotifications,
  90. showNotificationsBadge,
  91. } = this.props;
  92. const computedClass = classNames('drawer', `mbstobon-${elefriend}`);
  93. // The result.
  94. return (
  95. <div className={computedClass} role='region' aria-label={intl.formatMessage(messages.compose)}>
  96. {multiColumn ? (
  97. <DrawerHeader
  98. columns={columns}
  99. unreadNotifications={unreadNotifications}
  100. showNotificationsBadge={showNotificationsBadge}
  101. intl={intl}
  102. onSettingsClick={onOpenSettings}
  103. />
  104. ) : null}
  105. {(multiColumn || isSearchPage) && <DrawerSearch
  106. intl={intl}
  107. onChange={onChange}
  108. onClear={onClear}
  109. onShow={onShow}
  110. onSubmit={onSubmit}
  111. submitted={submitted}
  112. value={searchValue}
  113. /> }
  114. <div className='drawer__pager'>
  115. {!isSearchPage && <div className='drawer__inner'>
  116. <DrawerAccount account={account} />
  117. <Composer />
  118. {multiColumn && (
  119. <div className='drawer__inner__mastodon'>
  120. {mascot ? <img alt='' draggable='false' src={mascot} /> : <button className='mastodon' onClick={onClickElefriend} />}
  121. </div>
  122. )}
  123. </div>}
  124. {(multiColumn || isSearchPage) &&
  125. <DrawerResults
  126. results={results}
  127. visible={submitted && !searchHidden}
  128. />}
  129. </div>
  130. </div>
  131. );
  132. }
  133. }
  134. // Props.
  135. Drawer.propTypes = {
  136. intl: PropTypes.object.isRequired,
  137. isSearchPage: PropTypes.bool,
  138. multiColumn: PropTypes.bool,
  139. // State props.
  140. account: ImmutablePropTypes.map,
  141. columns: ImmutablePropTypes.list,
  142. results: ImmutablePropTypes.map,
  143. elefriend: PropTypes.number,
  144. searchHidden: PropTypes.bool,
  145. searchValue: PropTypes.string,
  146. submitted: PropTypes.bool,
  147. unreadNotifications: PropTypes.number,
  148. showNotificationsBadge: PropTypes.bool,
  149. // Dispatch props.
  150. onChange: PropTypes.func,
  151. onClear: PropTypes.func,
  152. onClickElefriend: PropTypes.func,
  153. onShow: PropTypes.func,
  154. onSubmit: PropTypes.func,
  155. onOpenSettings: PropTypes.func,
  156. };
  157. // Connecting and export.
  158. export { Drawer as WrappedComponent };
  159. export default wrap(Drawer, mapStateToProps, mapDispatchToProps, true);