about summary refs log tree commit diff
path: root/app/javascript/flavours/glitch/features/drawer/index.js
diff options
context:
space:
mode:
authorkibigo! <marrus-sh@users.noreply.github.com>2017-12-23 22:16:45 -0800
committerkibigo! <marrus-sh@users.noreply.github.com>2018-01-04 18:21:59 -0800
commit924ffe81d477a8cf890c8117efb94b908760bccc (patch)
treeacefef7362929f4495424fbb037c3be59cca318f /app/javascript/flavours/glitch/features/drawer/index.js
parentfc884d015a1a2d6c31976af3d63039390fa15939 (diff)
WIPgit status <Compose> Refactor; <Composer> ed.
Diffstat (limited to 'app/javascript/flavours/glitch/features/drawer/index.js')
-rw-r--r--app/javascript/flavours/glitch/features/drawer/index.js198
1 files changed, 198 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..8386ae47c
--- /dev/null
+++ b/app/javascript/flavours/glitch/features/drawer/index.js
@@ -0,0 +1,198 @@
+//  Package imports.
+import PropTypes from 'prop-types';
+import React from 'react';
+import ImmutablePropTypes from 'react-immutable-proptypes';
+import { injectIntl, defineMessages } from 'react-intl';
+import spring from 'react-motion/lib/spring';
+import { connect } from 'react-redux';
+import { Link } from 'react-router-dom';
+
+//  Actions.
+import { changeComposing } from 'flavours/glitch/actions/compose';
+import { changeLocalSetting } from 'flavours/glitch/actions/local_settings';
+import { openModal } from 'flavours/glitch/actions/modal';
+
+//  Components.
+import Icon from 'flavours/glitch/components/icon';
+import Compose from 'flavours/glitch/features/compose';
+import NavigationContainer from './containers/navigation_container';
+import SearchContainer from './containers/search_container';
+import SearchResultsContainer from './containers/search_results_container';
+
+//  Utils.
+import Motion from 'flavours/glitch/util/optional_motion';
+import {
+  assignHandlers,
+  conditionalRender,
+} from 'flavours/glitch/util/react_helpers';
+
+//  Messages.
+const messages = defineMessages({
+  community: {
+    defaultMessage: 'Local timeline',
+    id: 'navigation_bar.community_timeline',
+  },
+  home_timeline: {
+    defaultMessage: 'Home',
+    id: 'tabs_bar.home',
+  },
+  logout: {
+    defaultMessage: 'Logout',
+    id: 'navigation_bar.logout',
+  },
+  notifications: {
+    defaultMessage: 'Notifications',
+    id: 'tabs_bar.notifications',
+  },
+  public: {
+    defaultMessage: 'Federated timeline',
+    id: 'navigation_bar.public_timeline',
+  },
+  settings: {
+    defaultMessage: 'App settings',
+    id: 'navigation_bar.app_settings',
+  },
+  start: {
+    defaultMessage: 'Getting started',
+    id: 'getting_started.heading',
+  },
+});
+
+//  State mapping.
+const mapStateToProps = state => ({
+  columns: state.getIn(['settings', 'columns']),
+  showSearch: state.getIn(['search', 'submitted']) && !state.getIn(['search', 'hidden']),
+});
+
+//  Dispatch mapping.
+const mapDispatchToProps = dispatch => ({
+  onBlur () {
+    dispatch(changeComposing(false));
+  },
+  onFocus () {
+    dispatch(changeComposing(true));
+  },
+  onSettingsOpen () {
+    dispatch(openModal('SETTINGS', {}));
+  },
+});
+
+//  The component.
+@connect(mapStateToProps, mapDispatchToProps)
+@injectIntl
+export default function Drawer ({
+  columns,
+  intl,
+  multiColumn,
+  onBlur,
+  onFocus,
+  onSettingsOpen,
+  showSearch,
+}) {
+
+  //  Only renders the component if the column isn't being shown.
+  const renderForColumn = conditionalRender.bind(
+    columnId => !columns.some(column => column.get('id') === columnId)
+  );
+
+  //  The result.
+  return (
+    <div className='drawer'>
+      {multiColumn ? (
+        <nav className='drawer__header'>
+          <Link
+            aria-label={intl.formatMessage(messages.start)}
+            className='drawer__tab'
+            title={intl.formatMessage(messages.start)}
+            to='/getting-started'
+          ><Icon icon='asterisk' /></Link>
+          {renderForColumn('HOME', (
+            <Link
+              aria-label={intl.formatMessage(messages.home_timeline)}
+              className='drawer__tab'
+              title={intl.formatMessage(messages.home_timeline)}
+              to='/timelines/home'
+            ><Icon icon='home' /></Link>
+          ))}
+          {renderForColumn('NOTIFICATIONS', (
+            <Link
+              aria-label={intl.formatMessage(messages.notifications)}
+              className='drawer__tab'
+              title={intl.formatMessage(messages.notifications)}
+              to='/notifications'
+            ><Icon icon='bell' /></Link>
+          ))}
+          {renderForColumn('COMMUNITY', (
+            <Link
+              aria-label={intl.formatMessage(messages.community)}
+              className='drawer__tab'
+              title={intl.formatMessage(messages.community)}
+              to='/timelines/public/local'
+            ><Icon icon='users' /></Link>
+          ))}
+          {renderForColumn('PUBLIC', (
+            <Link
+              aria-label={intl.formatMessage(messages.public)}
+              className='drawer__tab'
+              title={intl.formatMessage(messages.public)}
+              to='/timelines/public'
+            ><Icon icon='globe' /></Link>
+          ))}
+          <a
+            aria-label={intl.formatMessage(messages.settings)}
+            className='drawer__tab'
+            onClick={settings}
+            role='button'
+            title={intl.formatMessage(messages.settings)}
+            tabIndex='0'
+          ><Icon icon='cogs' /></a>
+          <a
+            aria-label={intl.formatMessage(messages.logout)}
+            className='drawer__tab'
+            data-method='delete'
+            href='/auth/sign_out'
+            title={intl.formatMessage(messages.logout)}
+          ><Icon icon='sign-out' /></a>
+        </nav>
+      ) : null}
+      <SearchContainer />
+      <div className='drawer__pager'>
+        <div
+          className='drawer__inner scrollable optionally-scrollable'
+          onFocus={focus}
+        >
+          <NavigationContainer onClose={blur} />
+          <Compose />
+        </div>
+        <Motion
+          defaultStyle={{ x: -100 }}
+          style={{
+            x: spring(showSearch ? 0 : -100, {
+              stiffness: 210,
+              damping: 20,
+            })
+          }}
+        >
+          {({ x }) => (
+            <div
+              className='drawer__inner darker scrollable optionally-scrollable'
+              style={{
+                transform: `translateX(${x}%)`,
+                visibility: x === -100 ? 'hidden' : 'visible'
+              }}
+            ><SearchResultsContainer /></div>
+          )}
+        </Motion>
+      </div>
+    </div>
+  );
+}
+
+//  Props.
+Drawer.propTypes = {
+  dispatch: PropTypes.func.isRequired,
+  columns: ImmutablePropTypes.list.isRequired,
+  multiColumn: PropTypes.bool,
+  showSearch: PropTypes.bool,
+  intl: PropTypes.object.isRequired,
+};