about summary refs log tree commit diff
path: root/app/javascript/flavours/glitch/features/drawer/index.js
diff options
context:
space:
mode:
Diffstat (limited to 'app/javascript/flavours/glitch/features/drawer/index.js')
-rw-r--r--app/javascript/flavours/glitch/features/drawer/index.js175
1 files changed, 175 insertions, 0 deletions
diff --git a/app/javascript/flavours/glitch/features/drawer/index.js b/app/javascript/flavours/glitch/features/drawer/index.js
new file mode 100644
index 000000000..c8121b8e5
--- /dev/null
+++ b/app/javascript/flavours/glitch/features/drawer/index.js
@@ -0,0 +1,175 @@
+//  Package imports.
+import PropTypes from 'prop-types';
+import React from 'react';
+import ImmutablePropTypes from 'react-immutable-proptypes';
+import { defineMessages } from 'react-intl';
+import classNames from 'classnames';
+
+//  Actions.
+import { openModal } from 'flavours/glitch/actions/modal';
+import {
+  changeSearch,
+  clearSearch,
+  showSearch,
+  submitSearch,
+} from 'flavours/glitch/actions/search';
+import { cycleElefriendCompose } from 'flavours/glitch/actions/compose';
+
+//  Components.
+import Composer from 'flavours/glitch/features/composer';
+import DrawerAccount from './account';
+import DrawerHeader from './header';
+import DrawerResults from './results';
+import DrawerSearch from './search';
+
+//  Utils.
+import { me, mascot } from 'flavours/glitch/util/initial_state';
+import { wrap } from 'flavours/glitch/util/redux_helpers';
+
+//  Messages.
+const messages = defineMessages({
+  compose: { id: 'navigation_bar.compose', defaultMessage: 'Compose new toot' },
+});
+
+//  State mapping.
+const mapStateToProps = state => ({
+  account: state.getIn(['accounts', me]),
+  columns: state.getIn(['settings', 'columns']),
+  elefriend: state.getIn(['compose', 'elefriend']),
+  results: state.getIn(['search', 'results']),
+  searchHidden: state.getIn(['search', 'hidden']),
+  searchValue: state.getIn(['search', 'value']),
+  submitted: state.getIn(['search', 'submitted']),
+  unreadNotifications: state.getIn(['notifications', 'unread']),
+  showNotificationsBadge: state.getIn(['local_settings', 'notifications', 'tab_badge']),
+});
+
+//  Dispatch mapping.
+const mapDispatchToProps = (dispatch, { intl }) => ({
+  onChange (value) {
+    dispatch(changeSearch(value));
+  },
+  onClear () {
+    dispatch(clearSearch());
+  },
+  onClickElefriend () {
+    dispatch(cycleElefriendCompose());
+  },
+  onShow () {
+    dispatch(showSearch());
+  },
+  onSubmit () {
+    dispatch(submitSearch());
+  },
+  onOpenSettings (e) {
+    e.preventDefault();
+    e.stopPropagation();
+    dispatch(openModal('SETTINGS', {}));
+  },
+});
+
+//  The component.
+class Drawer extends React.Component {
+
+  //  Constructor.
+  constructor (props) {
+    super(props);
+  }
+
+  //  Rendering.
+  render () {
+    const {
+      account,
+      columns,
+      elefriend,
+      intl,
+      multiColumn,
+      onChange,
+      onClear,
+      onClickElefriend,
+      onOpenSettings,
+      onShow,
+      onSubmit,
+      results,
+      searchHidden,
+      searchValue,
+      submitted,
+      isSearchPage,
+      unreadNotifications,
+      showNotificationsBadge,
+    } = this.props;
+    const computedClass = classNames('drawer', `mbstobon-${elefriend}`);
+
+    //  The result.
+    return (
+      <div className={computedClass} role='region' aria-label={intl.formatMessage(messages.compose)}>
+        {multiColumn ? (
+          <DrawerHeader
+            columns={columns}
+            unreadNotifications={unreadNotifications}
+            showNotificationsBadge={showNotificationsBadge}
+            intl={intl}
+            onSettingsClick={onOpenSettings}
+          />
+        ) : null}
+        {(multiColumn || isSearchPage) && <DrawerSearch
+            intl={intl}
+            onChange={onChange}
+            onClear={onClear}
+            onShow={onShow}
+            onSubmit={onSubmit}
+            submitted={submitted}
+            value={searchValue}
+          /> }
+        <div className='drawer__pager'>
+          {!isSearchPage && <div className='drawer__inner'>
+            <DrawerAccount account={account} />
+            <Composer />
+            {multiColumn && (
+              <div className='drawer__inner__mastodon'>
+                {mascot ? <img alt='' draggable='false' src={mascot} /> : <button className='mastodon' onClick={onClickElefriend} />}
+              </div>
+            )}
+          </div>}
+
+          {(multiColumn || isSearchPage) &&
+            <DrawerResults
+              results={results}
+              visible={submitted && !searchHidden}
+            />}
+        </div>
+      </div>
+    );
+  }
+
+}
+
+//  Props.
+Drawer.propTypes = {
+  intl: PropTypes.object.isRequired,
+  isSearchPage: PropTypes.bool,
+  multiColumn: PropTypes.bool,
+
+  //  State props.
+  account: ImmutablePropTypes.map,
+  columns: ImmutablePropTypes.list,
+  results: ImmutablePropTypes.map,
+  elefriend: PropTypes.number,
+  searchHidden: PropTypes.bool,
+  searchValue: PropTypes.string,
+  submitted: PropTypes.bool,
+  unreadNotifications: PropTypes.number,
+  showNotificationsBadge: PropTypes.bool,
+
+  //  Dispatch props.
+  onChange: PropTypes.func,
+  onClear: PropTypes.func,
+  onClickElefriend: PropTypes.func,
+  onShow: PropTypes.func,
+  onSubmit: PropTypes.func,
+  onOpenSettings: PropTypes.func,
+};
+
+//  Connecting and export.
+export { Drawer as WrappedComponent };
+export default wrap(Drawer, mapStateToProps, mapDispatchToProps, true);