about summary refs log tree commit diff
path: root/app
diff options
context:
space:
mode:
authorNolan Lawson <nolan@nolanlawson.com>2017-10-27 08:04:44 -0700
committerunarist <m.unarist@gmail.com>2017-10-28 00:04:44 +0900
commit3de22a82bf1c3c0a3b593be4075cf42a3ec9291e (patch)
tree7b11776880a6122287b7fa0a84e0649bb346be86 /app
parente4080772b511e8dd436fddc79de10f44e4d83ff6 (diff)
Refactor initial state: reduce_motion and auto_play_gif (#5501)
Diffstat (limited to 'app')
-rw-r--r--app/javascript/mastodon/components/media_gallery.js13
-rw-r--r--app/javascript/mastodon/components/status.js4
-rw-r--r--app/javascript/mastodon/containers/compose_container.js5
-rw-r--r--app/javascript/mastodon/containers/mastodon.js3
-rw-r--r--app/javascript/mastodon/containers/status_container.js1
-rw-r--r--app/javascript/mastodon/containers/timeline_container.js5
-rw-r--r--app/javascript/mastodon/features/account/components/header.js17
-rw-r--r--app/javascript/mastodon/features/account_gallery/index.js5
-rw-r--r--app/javascript/mastodon/features/status/components/detailed_status.js2
-rw-r--r--app/javascript/mastodon/features/status/index.js5
-rw-r--r--app/javascript/mastodon/features/ui/util/optional_motion.js9
-rw-r--r--app/javascript/mastodon/initial_state.js9
-rwxr-xr-xapp/views/layouts/application.html.haml1
13 files changed, 27 insertions, 52 deletions
diff --git a/app/javascript/mastodon/components/media_gallery.js b/app/javascript/mastodon/components/media_gallery.js
index fb71d8c5c..20febdb16 100644
--- a/app/javascript/mastodon/components/media_gallery.js
+++ b/app/javascript/mastodon/components/media_gallery.js
@@ -6,6 +6,7 @@ import IconButton from './icon_button';
 import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
 import { isIOS } from '../is_mobile';
 import classNames from 'classnames';
+import { autoPlayGif } from '../initial_state';
 
 const messages = defineMessages({
   toggle_visible: { id: 'media_gallery.toggle_visible', defaultMessage: 'Toggle visibility' },
@@ -23,11 +24,9 @@ class Item extends React.PureComponent {
     index: PropTypes.number.isRequired,
     size: PropTypes.number.isRequired,
     onClick: PropTypes.func.isRequired,
-    autoPlayGif: PropTypes.bool,
   };
 
   static defaultProps = {
-    autoPlayGif: false,
     standalone: false,
     index: 0,
     size: 1,
@@ -47,7 +46,7 @@ class Item extends React.PureComponent {
   }
 
   hoverToPlay () {
-    const { attachment, autoPlayGif } = this.props;
+    const { attachment } = this.props;
     return !autoPlayGif && attachment.get('type') === 'gifv';
   }
 
@@ -139,7 +138,7 @@ class Item extends React.PureComponent {
         </a>
       );
     } else if (attachment.get('type') === 'gifv') {
-      const autoPlay = !isIOS() && this.props.autoPlayGif;
+      const autoPlay = !isIOS() && autoPlayGif;
 
       thumbnail = (
         <div className={classNames('media-gallery__gifv', { autoplay: autoPlay })}>
@@ -181,11 +180,9 @@ export default class MediaGallery extends React.PureComponent {
     height: PropTypes.number.isRequired,
     onOpenMedia: PropTypes.func.isRequired,
     intl: PropTypes.object.isRequired,
-    autoPlayGif: PropTypes.bool,
   };
 
   static defaultProps = {
-    autoPlayGif: false,
     standalone: false,
   };
 
@@ -261,9 +258,9 @@ export default class MediaGallery extends React.PureComponent {
       const size = media.take(4).size;
 
       if (this.isStandaloneEligible()) {
-        children = <Item standalone onClick={this.handleClick} attachment={media.get(0)} autoPlayGif={this.props.autoPlayGif} />;
+        children = <Item standalone onClick={this.handleClick} attachment={media.get(0)} />;
       } else {
-        children = media.take(4).map((attachment, i) => <Item key={attachment.get('id')} onClick={this.handleClick} attachment={attachment} autoPlayGif={this.props.autoPlayGif} index={i} size={size} />);
+        children = media.take(4).map((attachment, i) => <Item key={attachment.get('id')} onClick={this.handleClick} attachment={attachment} index={i} size={size} />);
       }
     }
 
diff --git a/app/javascript/mastodon/components/status.js b/app/javascript/mastodon/components/status.js
index 70005436b..bed354059 100644
--- a/app/javascript/mastodon/components/status.js
+++ b/app/javascript/mastodon/components/status.js
@@ -38,7 +38,6 @@ export default class Status extends ImmutablePureComponent {
     onHeightChange: PropTypes.func,
     me: PropTypes.string,
     boostModal: PropTypes.bool,
-    autoPlayGif: PropTypes.bool,
     muted: PropTypes.bool,
     hidden: PropTypes.bool,
     onMoveUp: PropTypes.func,
@@ -56,7 +55,6 @@ export default class Status extends ImmutablePureComponent {
     'account',
     'me',
     'boostModal',
-    'autoPlayGif',
     'muted',
     'hidden',
   ]
@@ -197,7 +195,7 @@ export default class Status extends ImmutablePureComponent {
       } else {
         media = (
           <Bundle fetchComponent={MediaGallery} loading={this.renderLoadingMediaGallery} >
-            {Component => <Component media={status.get('media_attachments')} sensitive={status.get('sensitive')} height={110} onOpenMedia={this.props.onOpenMedia} autoPlayGif={this.props.autoPlayGif} />}
+            {Component => <Component media={status.get('media_attachments')} sensitive={status.get('sensitive')} height={110} onOpenMedia={this.props.onOpenMedia} />}
           </Bundle>
         );
       }
diff --git a/app/javascript/mastodon/containers/compose_container.js b/app/javascript/mastodon/containers/compose_container.js
index db452d03a..5ee1d2f14 100644
--- a/app/javascript/mastodon/containers/compose_container.js
+++ b/app/javascript/mastodon/containers/compose_container.js
@@ -6,15 +6,14 @@ import { hydrateStore } from '../actions/store';
 import { IntlProvider, addLocaleData } from 'react-intl';
 import { getLocale } from '../locales';
 import Compose from '../features/standalone/compose';
+import initialState from '../initial_state';
 
 const { localeData, messages } = getLocale();
 addLocaleData(localeData);
 
 const store = configureStore();
-const initialStateContainer = document.getElementById('initial-state');
 
-if (initialStateContainer !== null) {
-  const initialState = JSON.parse(initialStateContainer.textContent);
+if (initialState) {
   store.dispatch(hydrateStore(initialState));
 }
 
diff --git a/app/javascript/mastodon/containers/mastodon.js b/app/javascript/mastodon/containers/mastodon.js
index 56b7bda46..e1d89a5b8 100644
--- a/app/javascript/mastodon/containers/mastodon.js
+++ b/app/javascript/mastodon/containers/mastodon.js
@@ -10,12 +10,13 @@ import { hydrateStore } from '../actions/store';
 import { connectUserStream } from '../actions/streaming';
 import { IntlProvider, addLocaleData } from 'react-intl';
 import { getLocale } from '../locales';
+import initialState from '../initial_state';
 
 const { localeData, messages } = getLocale();
 addLocaleData(localeData);
 
 export const store = configureStore();
-const hydrateAction = hydrateStore(JSON.parse(document.getElementById('initial-state').textContent));
+const hydrateAction = hydrateStore(initialState);
 store.dispatch(hydrateAction);
 
 export default class Mastodon extends React.PureComponent {
diff --git a/app/javascript/mastodon/containers/status_container.js b/app/javascript/mastodon/containers/status_container.js
index c61b7d00d..29eb5f955 100644
--- a/app/javascript/mastodon/containers/status_container.js
+++ b/app/javascript/mastodon/containers/status_container.js
@@ -38,7 +38,6 @@ const makeMapStateToProps = () => {
     me: state.getIn(['meta', 'me']),
     boostModal: state.getIn(['meta', 'boost_modal']),
     deleteModal: state.getIn(['meta', 'delete_modal']),
-    autoPlayGif: state.getIn(['meta', 'auto_play_gif']),
   });
 
   return mapStateToProps;
diff --git a/app/javascript/mastodon/containers/timeline_container.js b/app/javascript/mastodon/containers/timeline_container.js
index 4be037955..e84c921ee 100644
--- a/app/javascript/mastodon/containers/timeline_container.js
+++ b/app/javascript/mastodon/containers/timeline_container.js
@@ -7,15 +7,14 @@ import { IntlProvider, addLocaleData } from 'react-intl';
 import { getLocale } from '../locales';
 import PublicTimeline from '../features/standalone/public_timeline';
 import HashtagTimeline from '../features/standalone/hashtag_timeline';
+import initialState from '../initial_state';
 
 const { localeData, messages } = getLocale();
 addLocaleData(localeData);
 
 const store = configureStore();
-const initialStateContainer = document.getElementById('initial-state');
 
-if (initialStateContainer !== null) {
-  const initialState = JSON.parse(initialStateContainer.textContent);
+if (initialState) {
   store.dispatch(hydrateStore(initialState));
 }
 
diff --git a/app/javascript/mastodon/features/account/components/header.js b/app/javascript/mastodon/features/account/components/header.js
index 07a6c5dec..99ead014e 100644
--- a/app/javascript/mastodon/features/account/components/header.js
+++ b/app/javascript/mastodon/features/account/components/header.js
@@ -5,8 +5,8 @@ import { defineMessages, injectIntl, FormattedMessage } from 'react-intl';
 import IconButton from '../../../components/icon_button';
 import Motion from '../../ui/util/optional_motion';
 import spring from 'react-motion/lib/spring';
-import { connect } from 'react-redux';
 import ImmutablePureComponent from 'react-immutable-pure-component';
+import { autoPlayGif } from '../../../initial_state';
 
 const messages = defineMessages({
   unfollow: { id: 'account.unfollow', defaultMessage: 'Unfollow' },
@@ -14,19 +14,10 @@ const messages = defineMessages({
   requested: { id: 'account.requested', defaultMessage: 'Awaiting approval. Click to cancel follow request' },
 });
 
-const makeMapStateToProps = () => {
-  const mapStateToProps = state => ({
-    autoPlayGif: state.getIn(['meta', 'auto_play_gif']),
-  });
-
-  return mapStateToProps;
-};
-
 class Avatar extends ImmutablePureComponent {
 
   static propTypes = {
     account: ImmutablePropTypes.map.isRequired,
-    autoPlayGif: PropTypes.bool.isRequired,
   };
 
   state = {
@@ -44,7 +35,7 @@ class Avatar extends ImmutablePureComponent {
   }
 
   render () {
-    const { account, autoPlayGif }   = this.props;
+    const { account }   = this.props;
     const { isHovered } = this.state;
 
     return (
@@ -71,7 +62,6 @@ class Avatar extends ImmutablePureComponent {
 
 }
 
-@connect(makeMapStateToProps)
 @injectIntl
 export default class Header extends ImmutablePureComponent {
 
@@ -80,7 +70,6 @@ export default class Header extends ImmutablePureComponent {
     me: PropTypes.string.isRequired,
     onFollow: PropTypes.func.isRequired,
     intl: PropTypes.object.isRequired,
-    autoPlayGif: PropTypes.bool.isRequired,
   };
 
   render () {
@@ -124,7 +113,7 @@ export default class Header extends ImmutablePureComponent {
     return (
       <div className='account__header' style={{ backgroundImage: `url(${account.get('header')})` }}>
         <div>
-          <Avatar account={account} autoPlayGif={this.props.autoPlayGif} />
+          <Avatar account={account} />
 
           <span className='account__header__display-name' dangerouslySetInnerHTML={displayNameHtml} />
           <span className='account__header__username'>@{account.get('acct')} {lockedIcon}</span>
diff --git a/app/javascript/mastodon/features/account_gallery/index.js b/app/javascript/mastodon/features/account_gallery/index.js
index 2a88addc4..6a5c07568 100644
--- a/app/javascript/mastodon/features/account_gallery/index.js
+++ b/app/javascript/mastodon/features/account_gallery/index.js
@@ -19,7 +19,6 @@ const mapStateToProps = (state, props) => ({
   medias: getAccountGallery(state, props.params.accountId),
   isLoading: state.getIn(['timelines', `account:${props.params.accountId}:media`, 'isLoading']),
   hasMore: !!state.getIn(['timelines', `account:${props.params.accountId}:media`, 'next']),
-  autoPlayGif: state.getIn(['meta', 'auto_play_gif']),
 });
 
 @connect(mapStateToProps)
@@ -31,7 +30,6 @@ export default class AccountGallery extends ImmutablePureComponent {
     medias: ImmutablePropTypes.list.isRequired,
     isLoading: PropTypes.bool,
     hasMore: PropTypes.bool,
-    autoPlayGif: PropTypes.bool,
   };
 
   componentDidMount () {
@@ -67,7 +65,7 @@ export default class AccountGallery extends ImmutablePureComponent {
   }
 
   render () {
-    const { medias, autoPlayGif, isLoading, hasMore } = this.props;
+    const { medias, isLoading, hasMore } = this.props;
 
     let loadMore = null;
 
@@ -100,7 +98,6 @@ export default class AccountGallery extends ImmutablePureComponent {
                 <MediaItem
                   key={media.get('id')}
                   media={media}
-                  autoPlayGif={autoPlayGif}
                 />
               )}
               {loadMore}
diff --git a/app/javascript/mastodon/features/status/components/detailed_status.js b/app/javascript/mastodon/features/status/components/detailed_status.js
index c10e2c531..81f71749b 100644
--- a/app/javascript/mastodon/features/status/components/detailed_status.js
+++ b/app/javascript/mastodon/features/status/components/detailed_status.js
@@ -22,7 +22,6 @@ export default class DetailedStatus extends ImmutablePureComponent {
     status: ImmutablePropTypes.map.isRequired,
     onOpenMedia: PropTypes.func.isRequired,
     onOpenVideo: PropTypes.func.isRequired,
-    autoPlayGif: PropTypes.bool,
   };
 
   handleAccountClick = (e) => {
@@ -70,7 +69,6 @@ export default class DetailedStatus extends ImmutablePureComponent {
             media={status.get('media_attachments')}
             height={300}
             onOpenMedia={this.props.onOpenMedia}
-            autoPlayGif={this.props.autoPlayGif}
           />
         );
       }
diff --git a/app/javascript/mastodon/features/status/index.js b/app/javascript/mastodon/features/status/index.js
index 7ad3a7644..6e95fa939 100644
--- a/app/javascript/mastodon/features/status/index.js
+++ b/app/javascript/mastodon/features/status/index.js
@@ -45,7 +45,6 @@ const makeMapStateToProps = () => {
     me: state.getIn(['meta', 'me']),
     boostModal: state.getIn(['meta', 'boost_modal']),
     deleteModal: state.getIn(['meta', 'delete_modal']),
-    autoPlayGif: state.getIn(['meta', 'auto_play_gif']),
   });
 
   return mapStateToProps;
@@ -68,7 +67,6 @@ export default class Status extends ImmutablePureComponent {
     me: PropTypes.string,
     boostModal: PropTypes.bool,
     deleteModal: PropTypes.bool,
-    autoPlayGif: PropTypes.bool,
     intl: PropTypes.object.isRequired,
   };
 
@@ -257,7 +255,7 @@ export default class Status extends ImmutablePureComponent {
 
   render () {
     let ancestors, descendants;
-    const { status, ancestorsIds, descendantsIds, me, autoPlayGif } = this.props;
+    const { status, ancestorsIds, descendantsIds, me } = this.props;
 
     if (status === null) {
       return (
@@ -298,7 +296,6 @@ export default class Status extends ImmutablePureComponent {
               <div className='focusable' tabIndex='0'>
                 <DetailedStatus
                   status={status}
-                  autoPlayGif={autoPlayGif}
                   me={me}
                   onOpenVideo={this.handleOpenVideo}
                   onOpenMedia={this.handleOpenMedia}
diff --git a/app/javascript/mastodon/features/ui/util/optional_motion.js b/app/javascript/mastodon/features/ui/util/optional_motion.js
index af6368738..82edbbe8f 100644
--- a/app/javascript/mastodon/features/ui/util/optional_motion.js
+++ b/app/javascript/mastodon/features/ui/util/optional_motion.js
@@ -4,11 +4,10 @@
 import React from 'react';
 import Motion from 'react-motion/lib/Motion';
 import PropTypes from 'prop-types';
+import { reduceMotion } from '../../../initial_state';
 
 const stylesToKeep = ['opacity', 'backgroundOpacity'];
 
-let reduceMotion;
-
 const extractValue = (value) => {
   // This is either an object with a "val" property or it's a number
   return (typeof value === 'object' && value && 'val' in value) ? value.val : value;
@@ -26,12 +25,6 @@ class OptionalMotion extends React.Component {
 
     const { style, defaultStyle, children } = this.props;
 
-    if (typeof reduceMotion !== 'boolean') {
-      // This never changes without a page reload, so we can just grab it
-      // once from the body classes as opposed to using Redux's connect(),
-      // which would unnecessarily update every state change
-      reduceMotion = document.body.classList.contains('reduce-motion');
-    }
     if (reduceMotion) {
       Object.keys(style).forEach(key => {
         if (stylesToKeep.includes(key)) {
diff --git a/app/javascript/mastodon/initial_state.js b/app/javascript/mastodon/initial_state.js
new file mode 100644
index 000000000..ac7315f68
--- /dev/null
+++ b/app/javascript/mastodon/initial_state.js
@@ -0,0 +1,9 @@
+const element = document.getElementById('initial-state');
+const initialState = element && JSON.parse(element.textContent);
+
+const getMeta = (prop) => initialState && initialState.meta && initialState.meta[prop];
+
+export const reduceMotion = getMeta('reduce_motion');
+export const autoPlayGif = getMeta('auto_play_gif');
+
+export default initialState;
diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml
index 831858bcf..ee995c987 100755
--- a/app/views/layouts/application.html.haml
+++ b/app/views/layouts/application.html.haml
@@ -27,7 +27,6 @@
     = yield :header_tags
 
   - body_classes ||= @body_classes || ''
-  - body_classes += ' reduce-motion' if current_account&.user&.setting_reduce_motion
   - body_classes += ' system-font' if current_account&.user&.setting_system_font_ui
 
   %body{ class: add_rtl_body_class(body_classes) }