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' },
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,
}
hoverToPlay () {
- const { attachment, autoPlayGif } = this.props;
+ const { attachment } = this.props;
return !autoPlayGif && attachment.get('type') === 'gifv';
}
</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 })}>
height: PropTypes.number.isRequired,
onOpenMedia: PropTypes.func.isRequired,
intl: PropTypes.object.isRequired,
- autoPlayGif: PropTypes.bool,
};
static defaultProps = {
- autoPlayGif: false,
standalone: false,
};
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} />);
}
}
onHeightChange: PropTypes.func,
me: PropTypes.string,
boostModal: PropTypes.bool,
- autoPlayGif: PropTypes.bool,
muted: PropTypes.bool,
hidden: PropTypes.bool,
onMoveUp: PropTypes.func,
'account',
'me',
'boostModal',
- 'autoPlayGif',
'muted',
'hidden',
]
} 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>
);
}
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));
}
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 {
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;
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));
}
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' },
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 = {
}
render () {
- const { account, autoPlayGif } = this.props;
+ const { account } = this.props;
const { isHovered } = this.state;
return (
}
-@connect(makeMapStateToProps)
@injectIntl
export default class Header extends ImmutablePureComponent {
me: PropTypes.string.isRequired,
onFollow: PropTypes.func.isRequired,
intl: PropTypes.object.isRequired,
- autoPlayGif: PropTypes.bool.isRequired,
};
render () {
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>
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)
medias: ImmutablePropTypes.list.isRequired,
isLoading: PropTypes.bool,
hasMore: PropTypes.bool,
- autoPlayGif: PropTypes.bool,
};
componentDidMount () {
}
render () {
- const { medias, autoPlayGif, isLoading, hasMore } = this.props;
+ const { medias, isLoading, hasMore } = this.props;
let loadMore = null;
<MediaItem
key={media.get('id')}
media={media}
- autoPlayGif={autoPlayGif}
/>
)}
{loadMore}
status: ImmutablePropTypes.map.isRequired,
onOpenMedia: PropTypes.func.isRequired,
onOpenVideo: PropTypes.func.isRequired,
- autoPlayGif: PropTypes.bool,
};
handleAccountClick = (e) => {
media={status.get('media_attachments')}
height={300}
onOpenMedia={this.props.onOpenMedia}
- autoPlayGif={this.props.autoPlayGif}
/>
);
}
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;
me: PropTypes.string,
boostModal: PropTypes.bool,
deleteModal: PropTypes.bool,
- autoPlayGif: PropTypes.bool,
intl: PropTypes.object.isRequired,
};
render () {
let ancestors, descendants;
- const { status, ancestorsIds, descendantsIds, me, autoPlayGif } = this.props;
+ const { status, ancestorsIds, descendantsIds, me } = this.props;
if (status === null) {
return (
<div className='focusable' tabIndex='0'>
<DetailedStatus
status={status}
- autoPlayGif={autoPlayGif}
me={me}
onOpenVideo={this.handleOpenVideo}
onOpenMedia={this.handleOpenMedia}
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;
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)) {
--- /dev/null
+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;
= 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) }