about summary refs log tree commit diff
path: root/app/javascript/flavours/glitch/features/ui
diff options
context:
space:
mode:
authorbeatrix <beatrix.bitrot@gmail.com>2018-01-05 18:29:08 -0500
committerGitHub <noreply@github.com>2018-01-05 18:29:08 -0500
commitfaf20eeaa4c6f48a97a41a948ed29e734c8c4f5e (patch)
treeda0b88781650d514c209641fc6af7cbb921afe0b /app/javascript/flavours/glitch/features/ui
parentf41b33eb0177b23bd72fede7df94af43da0c7c6b (diff)
parentd7ce339c2e33a5607c21d3eff316669cff9c6ea3 (diff)
Merge pull request #293 from glitch-soc/compose-refactor
Compose refactor
Diffstat (limited to 'app/javascript/flavours/glitch/features/ui')
-rw-r--r--app/javascript/flavours/glitch/features/ui/components/actions_modal.js75
-rw-r--r--app/javascript/flavours/glitch/features/ui/components/columns_area.js4
-rw-r--r--app/javascript/flavours/glitch/features/ui/components/onboarding_modal.js60
-rw-r--r--app/javascript/flavours/glitch/features/ui/index.js12
4 files changed, 91 insertions, 60 deletions
diff --git a/app/javascript/flavours/glitch/features/ui/components/actions_modal.js b/app/javascript/flavours/glitch/features/ui/components/actions_modal.js
index 0873c282f..c8b040f95 100644
--- a/app/javascript/flavours/glitch/features/ui/components/actions_modal.js
+++ b/app/javascript/flavours/glitch/features/ui/components/actions_modal.js
@@ -6,15 +6,26 @@ import StatusContent from 'flavours/glitch/components/status_content';
 import Avatar from 'flavours/glitch/components/avatar';
 import RelativeTimestamp from 'flavours/glitch/components/relative_timestamp';
 import DisplayName from 'flavours/glitch/components/display_name';
-import IconButton from 'flavours/glitch/components/icon_button';
 import classNames from 'classnames';
+import Icon from 'flavours/glitch/components/icon';
+import Link from 'flavours/glitch/components/link';
+import Toggle from 'react-toggle';
 
 export default class ActionsModal extends ImmutablePureComponent {
 
   static propTypes = {
     status: ImmutablePropTypes.map,
-    actions: PropTypes.array,
-    onClick: PropTypes.func,
+    actions: PropTypes.arrayOf(PropTypes.shape({
+      active: PropTypes.bool,
+      href: PropTypes.string,
+      icon: PropTypes.string,
+      meta: PropTypes.node,
+      name: PropTypes.string,
+      on: PropTypes.bool,
+      onClick: PropTypes.func,
+      onPassiveClick: PropTypes.func,
+      text: PropTypes.node,
+    })),
   };
 
   renderAction = (action, i) => {
@@ -22,17 +33,57 @@ export default class ActionsModal extends ImmutablePureComponent {
       return <li key={`sep-${i}`} className='dropdown-menu__separator' />;
     }
 
-    const { icon = null, text, meta = null, active = false, href = '#' } = action;
+    const {
+      active,
+      href,
+      icon,
+      meta,
+      name,
+      on,
+      onClick,
+      onPassiveClick,
+      text,
+    } = action;
 
     return (
-      <li key={`${text}-${i}`}>
-        <a href={href} target='_blank' rel='noopener' onClick={this.props.onClick} data-index={i} className={classNames({ active })}>
-          {icon && <IconButton title={text} icon={icon} role='presentation' tabIndex='-1' />}
-          <div>
-            <div className={classNames({ 'actions-modal__item-label': !!meta })}>{text}</div>
-            <div>{meta}</div>
-          </div>
-        </a>
+      <li key={name || i}>
+        <Link
+          className={classNames('link', { active })}
+          href={href}
+          onClick={on !== null && typeof on !== 'undefined' && onPassiveClick || onClick}
+          role={onClick ? 'button' : null}
+        >
+          {function () {
+
+            //  We render a `<Toggle>` if we were provided an `on`
+            //  property, and otherwise show an `<Icon>` if available.
+            switch (true) {
+            case on !== null && typeof on !== 'undefined':
+              return (
+                <Toggle
+                  checked={on}
+                  onChange={onPassiveClick || onClick}
+                />
+              );
+            case !!icon:
+              return (
+                <Icon
+                  className='icon'
+                  fullwidth
+                  icon={icon}
+                />
+              );
+            default:
+              return null;
+            }
+          }()}
+          {meta ? (
+            <div>
+              <strong>{text}</strong>
+              {meta}
+            </div>
+          ) : <div>{text}</div>}
+        </Link>
       </li>
     );
   }
diff --git a/app/javascript/flavours/glitch/features/ui/components/columns_area.js b/app/javascript/flavours/glitch/features/ui/components/columns_area.js
index 91d4df93f..e4556899d 100644
--- a/app/javascript/flavours/glitch/features/ui/components/columns_area.js
+++ b/app/javascript/flavours/glitch/features/ui/components/columns_area.js
@@ -11,13 +11,13 @@ import BundleContainer from '../containers/bundle_container';
 import ColumnLoading from './column_loading';
 import DrawerLoading from './drawer_loading';
 import BundleColumnError from './bundle_column_error';
-import { Compose, Notifications, HomeTimeline, CommunityTimeline, PublicTimeline, HashtagTimeline, DirectTimeline, FavouritedStatuses, ListTimeline } from 'flavours/glitch/util/async-components';
+import { Drawer, Notifications, HomeTimeline, CommunityTimeline, PublicTimeline, HashtagTimeline, DirectTimeline, FavouritedStatuses, ListTimeline } from 'flavours/glitch/util/async-components';
 
 import detectPassiveEvents from 'detect-passive-events';
 import { scrollRight } from 'flavours/glitch/util/scroll';
 
 const componentMap = {
-  'COMPOSE': Compose,
+  'COMPOSE': Drawer,
   'HOME': HomeTimeline,
   'NOTIFICATIONS': Notifications,
   'PUBLIC': PublicTimeline,
diff --git a/app/javascript/flavours/glitch/features/ui/components/onboarding_modal.js b/app/javascript/flavours/glitch/features/ui/components/onboarding_modal.js
index 21f1addea..91a83f330 100644
--- a/app/javascript/flavours/glitch/features/ui/components/onboarding_modal.js
+++ b/app/javascript/flavours/glitch/features/ui/components/onboarding_modal.js
@@ -6,18 +6,12 @@ import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
 import ReactSwipeableViews from 'react-swipeable-views';
 import classNames from 'classnames';
 import Permalink from 'flavours/glitch/components/permalink';
-import ComposeForm from 'flavours/glitch/features/compose/components/compose_form';
-import Search from 'flavours/glitch/features/compose/components/search';
-import NavigationBar from 'flavours/glitch/features/compose/components/navigation_bar';
+import { WrappedComponent as RawComposer } from 'flavours/glitch/features/composer';
+import DrawerAccount from 'flavours/glitch/features/drawer/account';
+import DrawerSearch from 'flavours/glitch/features/drawer/search';
 import ColumnHeader from './column_header';
-import {
-  List as ImmutableList,
-  Map as ImmutableMap,
-} from 'immutable';
 import { me } from 'flavours/glitch/util/initial_state';
 
-const noop = () => { };
-
 const messages = defineMessages({
   home_title: { id: 'column.home', defaultMessage: 'Home' },
   notifications_title: { id: 'column.notifications', defaultMessage: 'Notifications' },
@@ -44,29 +38,21 @@ PageOne.propTypes = {
   domain: PropTypes.string.isRequired,
 };
 
-const PageTwo = ({ myAccount }) => (
+const composerState = {
+  showSearch: true,
+  text: 'Awoo! #introductions',
+};
+
+const PageTwo = ({ intl, myAccount }) => (
   <div className='onboarding-modal__page onboarding-modal__page-two'>
     <div className='figure non-interactive'>
       <div className='pseudo-drawer'>
-        <NavigationBar onClose={noop} account={myAccount} />
+        <DrawerAccount account={myAccount} />
+        <RawComposer
+          intl={intl}
+          state={composerState}
+        />
       </div>
-      <ComposeForm
-        text='Awoo! #introductions'
-        suggestions={ImmutableList()}
-        mentionedDomains={[]}
-        spoiler={false}
-        onChange={noop}
-        onSubmit={noop}
-        onPaste={noop}
-        onPickEmoji={noop}
-        onChangeSpoilerText={noop}
-        onClearSuggestions={noop}
-        onFetchSuggestions={noop}
-        onSuggestionSelected={noop}
-        onPrivacyChange={noop}
-        showSearch
-        settings={ImmutableMap.of('side_arm', 'none')}
-      />
     </div>
 
     <p><FormattedMessage id='onboarding.page_two.compose' defaultMessage='Write posts from the compose column. You can upload images, change privacy settings, and add content warnings with the icons below.' /></p>
@@ -74,22 +60,17 @@ const PageTwo = ({ myAccount }) => (
 );
 
 PageTwo.propTypes = {
+  intl: PropTypes.object.isRequired,
   myAccount: ImmutablePropTypes.map.isRequired,
 };
 
-const PageThree = ({ myAccount }) => (
+const PageThree = ({ intl, myAccount }) => (
   <div className='onboarding-modal__page onboarding-modal__page-three'>
     <div className='figure non-interactive'>
-      <Search
-        value=''
-        onChange={noop}
-        onSubmit={noop}
-        onClear={noop}
-        onShow={noop}
-      />
+      <DrawerSearch intl={intl} />
 
       <div className='pseudo-drawer'>
-        <NavigationBar onClose={noop} account={myAccount} />
+        <DrawerAccount account={myAccount} />
       </div>
     </div>
 
@@ -99,6 +80,7 @@ const PageThree = ({ myAccount }) => (
 );
 
 PageThree.propTypes = {
+  intl: PropTypes.object.isRequired,
   myAccount: ImmutablePropTypes.map.isRequired,
 };
 
@@ -192,8 +174,8 @@ export default class OnboardingModal extends React.PureComponent {
     const { myAccount, admin, domain, intl } = this.props;
     this.pages = [
       <PageOne acct={myAccount.get('acct')} domain={domain} />,
-      <PageTwo myAccount={myAccount} />,
-      <PageThree myAccount={myAccount} />,
+      <PageTwo myAccount={myAccount} intl={intl} />,
+      <PageThree myAccount={myAccount} intl={intl} />,
       <PageFour domain={domain} intl={intl} />,
       <PageSix admin={admin} domain={domain} />,
     ];
diff --git a/app/javascript/flavours/glitch/features/ui/index.js b/app/javascript/flavours/glitch/features/ui/index.js
index 5c80ea07b..fae705deb 100644
--- a/app/javascript/flavours/glitch/features/ui/index.js
+++ b/app/javascript/flavours/glitch/features/ui/index.js
@@ -17,7 +17,7 @@ import UploadArea from './components/upload_area';
 import ColumnsAreaContainer from './containers/columns_area_container';
 import classNames from 'classnames';
 import {
-  Compose,
+  Drawer,
   Status,
   GettingStarted,
   KeyboardShortcuts,
@@ -56,7 +56,6 @@ const messages = defineMessages({
 });
 
 const mapStateToProps = state => ({
-  isComposing: state.getIn(['compose', 'is_composing']),
   hasComposingText: state.getIn(['compose', 'text']) !== '',
   layout: state.getIn(['local_settings', 'layout']),
   isWide: state.getIn(['local_settings', 'stretch']),
@@ -120,9 +119,9 @@ export default class UI extends React.Component {
   };
 
   handleBeforeUnload = (e) => {
-    const { intl, isComposing, hasComposingText } = this.props;
+    const { intl, hasComposingText } = this.props;
 
-    if (isComposing && hasComposingText) {
+    if (hasComposingText) {
       // Setting returnValue to any string causes confirmation dialog.
       // Many browsers no longer display this text to users,
       // but we set user-friendly message for other browsers, e.g. Edge.
@@ -227,9 +226,8 @@ export default class UI extends React.Component {
   }
 
   shouldComponentUpdate (nextProps) {
-    if (nextProps.isComposing !== this.props.isComposing) {
+    if (nextProps.navbarUnder !== this.props.navbarUnder) {
       // Avoid expensive update just to toggle a class
-      this.node.classList.toggle('is-composing', nextProps.isComposing);
       this.node.classList.toggle('navbar-under', nextProps.navbarUnder);
 
       return false;
@@ -427,7 +425,7 @@ export default class UI extends React.Component {
               <WrappedRoute path='/favourites' component={FavouritedStatuses} content={children} />
               <WrappedRoute path='/pinned' component={PinnedStatuses} content={children} />
 
-              <WrappedRoute path='/statuses/new' component={Compose} content={children} />
+              <WrappedRoute path='/statuses/new' component={Drawer} content={children} />
               <WrappedRoute path='/statuses/:statusId' exact component={Status} content={children} />
               <WrappedRoute path='/statuses/:statusId/reblogs' component={Reblogs} content={children} />
               <WrappedRoute path='/statuses/:statusId/favourites' component={Favourites} content={children} />