diff --git a/app/javascript/mastodon/features/account_gallery/components/media_item.js b/app/javascript/mastodon/features/account_gallery/components/media_item.js
index 9eb4ed0d3..c9a7af7f7 100644
--- a/app/javascript/mastodon/features/account_gallery/components/media_item.js
+++ b/app/javascript/mastodon/features/account_gallery/components/media_item.js
@@ -61,57 +61,9 @@ export default class MediaItem extends ImmutablePureComponent {
const width = `${Math.floor((displayWidth - 4) / 3) - 4}px`;
const height = width;
const status = attachment.get('status');
- const title = status.get('spoiler_text') || attachment.get('description');
+ const title = status.get('spoiler_text') || attachment.get('description');
- let thumbnail = '';
- let icon;
-
- if (attachment.get('type') === 'unknown') {
- // Skip
- } else if (attachment.get('type') === 'audio') {
- thumbnail = (
-
-
-
- );
- } else if (attachment.get('type') === 'image') {
- const focusX = attachment.getIn(['meta', 'focus', 'x']) || 0;
- const focusY = attachment.getIn(['meta', 'focus', 'y']) || 0;
- const x = ((focusX / 2) + .5) * 100;
- const y = ((focusY / -2) + .5) * 100;
-
- thumbnail = (
-
- );
- } else if (['gifv', 'video'].indexOf(attachment.get('type')) !== -1) {
- const autoPlay = !isIOS() && autoPlayGif;
- const label = attachment.get('type') === 'video' ? : 'GIF';
-
- thumbnail = (
-
-
-
- {label}
-
- );
- }
+ let thumbnail, label, icon, content;
if (!visible) {
icon = (
@@ -119,6 +71,60 @@ export default class MediaItem extends ImmutablePureComponent {
);
+ } else {
+ if (['audio', 'video'].includes(attachment.get('type'))) {
+ content = (
+
+ );
+
+ if (attachment.get('type') === 'audio') {
+ label = ;
+ } else {
+ label = ;
+ }
+ } else if (attachment.get('type') === 'image') {
+ const focusX = attachment.getIn(['meta', 'focus', 'x']) || 0;
+ const focusY = attachment.getIn(['meta', 'focus', 'y']) || 0;
+ const x = ((focusX / 2) + .5) * 100;
+ const y = ((focusY / -2) + .5) * 100;
+
+ content = (
+
+ );
+ } else if (attachment.get('type') === 'gifv') {
+ content = (
+
+ );
+
+ label = 'GIF';
+ }
+
+ thumbnail = (
+
+ {content}
+
+ {label}
+
+ );
}
return (
@@ -126,13 +132,11 @@ export default class MediaItem extends ImmutablePureComponent {
- {visible && thumbnail}
- {!visible && icon}
+
+ {visible ? thumbnail : icon}
);
diff --git a/app/javascript/mastodon/features/account_gallery/index.js b/app/javascript/mastodon/features/account_gallery/index.js
index de481075c..fc5aead48 100644
--- a/app/javascript/mastodon/features/account_gallery/index.js
+++ b/app/javascript/mastodon/features/account_gallery/index.js
@@ -101,9 +101,9 @@ class AccountGallery extends ImmutablePureComponent {
handleOpenMedia = attachment => {
if (attachment.get('type') === 'video') {
- this.props.dispatch(openModal('VIDEO', { media: attachment, status: attachment.get('status') }));
+ this.props.dispatch(openModal('VIDEO', { media: attachment, status: attachment.get('status'), options: { autoPlay: true } }));
} else if (attachment.get('type') === 'audio') {
- this.props.dispatch(openModal('AUDIO', { media: attachment, status: attachment.get('status') }));
+ this.props.dispatch(openModal('AUDIO', { media: attachment, status: attachment.get('status'), options: { autoPlay: true } }));
} else {
const media = attachment.getIn(['status', 'media_attachments']);
const index = media.findIndex(x => x.get('id') === attachment.get('id'));
diff --git a/app/javascript/mastodon/features/audio/index.js b/app/javascript/mastodon/features/audio/index.js
index a49489257..2f85ebb7e 100644
--- a/app/javascript/mastodon/features/audio/index.js
+++ b/app/javascript/mastodon/features/audio/index.js
@@ -37,6 +37,7 @@ class Audio extends React.PureComponent {
backgroundColor: PropTypes.string,
foregroundColor: PropTypes.string,
accentColor: PropTypes.string,
+ autoPlay: PropTypes.bool,
};
state = {
@@ -259,6 +260,14 @@ class Audio extends React.PureComponent {
this.setState({ hovered: false });
}
+ handleLoadedData = () => {
+ const { autoPlay } = this.props;
+
+ if (autoPlay) {
+ this.audio.play();
+ }
+ }
+
_initAudioContext () {
const context = new AudioContext();
const source = context.createMediaElementSource(this.audio);
@@ -336,7 +345,7 @@ class Audio extends React.PureComponent {
}
render () {
- const { src, intl, alt, editable } = this.props;
+ const { src, intl, alt, editable, autoPlay } = this.props;
const { paused, muted, volume, currentTime, duration, buffer, dragging } = this.state;
const progress = (currentTime / duration) * 100;
@@ -345,10 +354,11 @@ class Audio extends React.PureComponent {
diff --git a/app/javascript/mastodon/features/ui/components/audio_modal.js b/app/javascript/mastodon/features/ui/components/audio_modal.js
index dc033434e..a80776b22 100644
--- a/app/javascript/mastodon/features/ui/components/audio_modal.js
+++ b/app/javascript/mastodon/features/ui/components/audio_modal.js
@@ -2,17 +2,27 @@ import React from 'react';
import ImmutablePropTypes from 'react-immutable-proptypes';
import PropTypes from 'prop-types';
import Audio from 'mastodon/features/audio';
+import { connect } from 'react-redux';
import ImmutablePureComponent from 'react-immutable-pure-component';
import { FormattedMessage } from 'react-intl';
import { previewState } from './video_modal';
import classNames from 'classnames';
import Icon from 'mastodon/components/icon';
-export default class AudioModal extends ImmutablePureComponent {
+const mapStateToProps = (state, { status }) => ({
+ account: state.getIn(['accounts', status.get('account')]),
+});
+
+export default @connect(mapStateToProps)
+class AudioModal extends ImmutablePureComponent {
static propTypes = {
media: ImmutablePropTypes.map.isRequired,
status: ImmutablePropTypes.map,
+ options: PropTypes.shape({
+ autoPlay: PropTypes.bool,
+ }),
+ account: ImmutablePropTypes.map,
onClose: PropTypes.func.isRequired,
};
@@ -50,7 +60,8 @@ export default class AudioModal extends ImmutablePureComponent {
}
render () {
- const { media, status } = this.props;
+ const { media, status, account } = this.props;
+ const options = this.props.options || {};
return (
@@ -60,10 +71,11 @@ export default class AudioModal extends ImmutablePureComponent {
alt={media.get('description')}
duration={media.getIn(['meta', 'original', 'duration'], 0)}
height={150}
- poster={media.get('preview_url') || status.getIn(['account', 'avatar_static'])}
+ poster={media.get('preview_url') || account.get('avatar_static')}
backgroundColor={media.getIn(['meta', 'colors', 'background'])}
foregroundColor={media.getIn(['meta', 'colors', 'foreground'])}
accentColor={media.getIn(['meta', 'colors', 'accent'])}
+ autoPlay={options.autoPlay}
/>
diff --git a/app/javascript/mastodon/selectors/index.js b/app/javascript/mastodon/selectors/index.js
index 673268c5a..fd3b72f96 100644
--- a/app/javascript/mastodon/selectors/index.js
+++ b/app/javascript/mastodon/selectors/index.js
@@ -154,12 +154,13 @@ export const makeGetNotification = () => {
export const getAccountGallery = createSelector([
(state, id) => state.getIn(['timelines', `account:${id}:media`, 'items'], ImmutableList()),
state => state.get('statuses'),
-], (statusIds, statuses) => {
+ (state, id) => state.getIn(['accounts', id]),
+], (statusIds, statuses, account) => {
let medias = ImmutableList();
statusIds.forEach(statusId => {
const status = statuses.get(statusId);
- medias = medias.concat(status.get('media_attachments').map(media => media.set('status', status)));
+ medias = medias.concat(status.get('media_attachments').map(media => media.set('status', status).set('account', account)));
});
return medias;