diff options
author | Nolan Lawson <nolan@nolanlawson.com> | 2017-10-27 08:04:44 -0700 |
---|---|---|
committer | unarist <m.unarist@gmail.com> | 2017-10-28 00:04:44 +0900 |
commit | 3de22a82bf1c3c0a3b593be4075cf42a3ec9291e (patch) | |
tree | 7b11776880a6122287b7fa0a84e0649bb346be86 | |
parent | e4080772b511e8dd436fddc79de10f44e4d83ff6 (diff) |
Refactor initial state: reduce_motion and auto_play_gif (#5501)
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) } |