about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--app/javascript/mastodon/features/ui/components/onboarding_modal.js90
-rw-r--r--app/javascript/styles/components.scss8
2 files changed, 79 insertions, 19 deletions
diff --git a/app/javascript/mastodon/features/ui/components/onboarding_modal.js b/app/javascript/mastodon/features/ui/components/onboarding_modal.js
index a06338b25..c121bfb17 100644
--- a/app/javascript/mastodon/features/ui/components/onboarding_modal.js
+++ b/app/javascript/mastodon/features/ui/components/onboarding_modal.js
@@ -3,6 +3,7 @@ import { connect } from 'react-redux';
 import PropTypes from 'prop-types';
 import ImmutablePropTypes from 'react-immutable-proptypes';
 import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
+import classNames from 'classnames';
 import Permalink from '../../../components/permalink';
 import TransitionMotion from 'react-motion/lib/TransitionMotion';
 import spring from 'react-motion/lib/spring';
@@ -59,6 +60,7 @@ const PageTwo = ({ me }) => (
         onClearSuggestions={noop}
         onFetchSuggestions={noop}
         onSuggestionSelected={noop}
+        showSearch
       />
     </div>
 
@@ -180,6 +182,25 @@ class OnboardingModal extends React.PureComponent {
     currentIndex: 0,
   };
 
+  componentWillMount() {
+    const { me, admin, domain, intl } = this.props;
+    this.pages = [
+      <PageOne acct={me.get('acct')} domain={domain} />,
+      <PageTwo me={me} />,
+      <PageThree me={me} domain={domain} />,
+      <PageFour domain={domain} intl={intl} />,
+      <PageSix admin={admin} domain={domain} />,
+    ];
+  };
+
+  componentDidMount() {
+    window.addEventListener('keyup', this.handleKeyUp);
+  }
+
+  componentWillUnmount() {
+    window.addEventListener('keyup', this.handleKeyUp);
+  }
+
   handleSkip = (e) => {
     e.preventDefault();
     this.props.onClose();
@@ -191,27 +212,36 @@ class OnboardingModal extends React.PureComponent {
     this.setState({ currentIndex: i });
   }
 
+  handlePrev = () => {
+    this.setState(({ currentIndex }) => ({
+      currentIndex: Math.max(0, currentIndex - 1),
+    }));
+  }
+
   handleNext = () => {
+    const { pages } = this;
     this.setState(({ currentIndex }) => ({
-      currentIndex: currentIndex + 1,
+      currentIndex: Math.min(currentIndex + 1, pages.length - 1),
     }));
   }
 
+  handleKeyUp = ({ key }) => {
+    switch (key) {
+    case 'ArrowLeft':
+      this.handlePrev();
+      break;
+    case 'ArrowRight':
+      this.handleNext();
+      break;
+    }
+  }
+
   handleClose = () => {
     this.props.onClose();
   }
 
   render () {
-    const { me, admin, domain, intl } = this.props;
-
-    const pages = [
-      <PageOne acct={me.get('acct')} domain={domain} />,
-      <PageTwo me={me} />,
-      <PageThree me={me} domain={domain} />,
-      <PageFour domain={domain} intl={intl} />,
-      <PageSix admin={admin} domain={domain} />,
-    ];
-
+    const { pages } = this;
     const { currentIndex } = this.state;
     const hasMore = currentIndex < pages.length - 1;
 
@@ -231,21 +261,29 @@ class OnboardingModal extends React.PureComponent {
       </button>
     );
 
-    const styles = pages.map((page, i) => ({
+    const styles = pages.map((data, i) => ({
       key: `page-${i}`,
-      style: { opacity: spring(i === currentIndex ? 1 : 0) },
+      data,
+      style: {
+        opacity: spring(i === currentIndex ? 1 : 0),
+      },
     }));
 
     return (
       <div className='modal-root__modal onboarding-modal'>
         <TransitionMotion styles={styles}>
-          {interpolatedStyles =>
+          {interpolatedStyles => (
             <div className='onboarding-modal__pager'>
-              {pages.map((page, i) =>
-                <div key={`page-${i}`} style={{ opacity: interpolatedStyles[i].style.opacity, pointerEvents: i === currentIndex ? 'auto' : 'none' }}>{page}</div>
-              )}
+              {interpolatedStyles.map(({ key, data, style }, i) => {
+                const className = classNames('onboarding-modal__page__wrapper', {
+                  'onboarding-modal__page__wrapper--active': i === currentIndex,
+                });
+                return (
+                  <div key={key} style={style} className={className}>{data}</div>
+                );
+              })}
             </div>
-          }
+          )}
         </TransitionMotion>
 
         <div className='onboarding-modal__paginator'>
@@ -259,7 +297,21 @@ class OnboardingModal extends React.PureComponent {
           </div>
 
           <div className='onboarding-modal__dots'>
-            {pages.map((_, i) => <div key={i} role='button' tabIndex='0' data-index={i} onClick={this.handleDot} className={`onboarding-modal__dot ${i === currentIndex ? 'active' : ''}`} />)}
+            {pages.map((_, i) => {
+              const className = classNames('onboarding-modal__dot', {
+                active: i === currentIndex,
+              });
+              return (
+                <div
+                  key={`dot-${i}`}
+                  role='button'
+                  tabIndex='0'
+                  data-index={i}
+                  onClick={this.handleDot}
+                  className={className}
+                />
+              );
+            })}
           </div>
 
           <div>
diff --git a/app/javascript/styles/components.scss b/app/javascript/styles/components.scss
index 7f2b5cfe0..3301e6e47 100644
--- a/app/javascript/styles/components.scss
+++ b/app/javascript/styles/components.scss
@@ -3073,6 +3073,14 @@ button.icon-button.active i.fa-retweet {
   }
 }
 
+.onboarding-modal__page__wrapper {
+  pointer-events: none;
+
+  &.onboading-modal__page__wrapper--active {
+    pointer-events: auto;
+  }
+}
+
 .onboarding-modal__page {
   cursor: default;
   line-height: 21px;