diff --git a/app/javascript/mastodon/components/status.js b/app/javascript/mastodon/components/status.js
index 238a0d7349..dee935a6cd 100644
--- a/app/javascript/mastodon/components/status.js
+++ b/app/javascript/mastodon/components/status.js
@@ -409,6 +409,10 @@ class Status extends ImmutablePureComponent {
height={110}
cacheWidth={this.props.cacheMediaWidth}
deployPictureInPicture={pictureInPicture.get('available') ? this.handleDeployPictureInPicture : undefined}
+ sensitive={status.get('sensitive')}
+ blurhash={attachment.get('blurhash')}
+ visible={this.state.showMedia}
+ onToggleVisibility={this.handleToggleMediaVisibility}
/>
)}
diff --git a/app/javascript/mastodon/features/audio/index.js b/app/javascript/mastodon/features/audio/index.js
index c47f55dd1e..00854d0e49 100644
--- a/app/javascript/mastodon/features/audio/index.js
+++ b/app/javascript/mastodon/features/audio/index.js
@@ -1,6 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
-import { defineMessages, injectIntl } from 'react-intl';
+import { defineMessages, FormattedMessage, injectIntl } from 'react-intl';
import { formatTime } from 'mastodon/features/video';
import Icon from 'mastodon/components/icon';
import classNames from 'classnames';
@@ -8,6 +8,9 @@ import { throttle } from 'lodash';
import { getPointerPosition, fileNameFromURL } from 'mastodon/features/video';
import { debounce } from 'lodash';
import Visualizer from './visualizer';
+import { displayMedia, useBlurhash } from '../../initial_state';
+import Blurhash from '../../components/blurhash';
+import { is } from 'immutable';
const messages = defineMessages({
play: { id: 'video.play', defaultMessage: 'Play' },
@@ -15,6 +18,7 @@ const messages = defineMessages({
mute: { id: 'video.mute', defaultMessage: 'Mute sound' },
unmute: { id: 'video.unmute', defaultMessage: 'Unmute sound' },
download: { id: 'video.download', defaultMessage: 'Download file' },
+ hide: { id: 'audio.hide', defaultMessage: 'Hide audio' },
});
const TICK_SIZE = 10;
@@ -30,10 +34,14 @@ class Audio extends React.PureComponent {
duration: PropTypes.number,
width: PropTypes.number,
height: PropTypes.number,
+ sensitive: PropTypes.bool,
editable: PropTypes.bool,
fullscreen: PropTypes.bool,
intl: PropTypes.object.isRequired,
+ blurhash: PropTypes.string,
cacheWidth: PropTypes.func,
+ visible: PropTypes.bool,
+ onToggleVisibility: PropTypes.func,
backgroundColor: PropTypes.string,
foregroundColor: PropTypes.string,
accentColor: PropTypes.string,
@@ -53,6 +61,7 @@ class Audio extends React.PureComponent {
muted: false,
volume: 0.5,
dragging: false,
+ revealed: this.props.visible !== undefined ? this.props.visible : (displayMedia !== 'hide_all' && !this.props.sensitive || displayMedia === 'show_all'),
};
constructor (props) {
@@ -78,6 +87,8 @@ class Audio extends React.PureComponent {
backgroundColor: this.props.backgroundColor,
foregroundColor: this.props.foregroundColor,
accentColor: this.props.accentColor,
+ sensitive: this.props.sensitive,
+ visible: this.props.visible,
};
}
@@ -126,6 +137,12 @@ class Audio extends React.PureComponent {
}
}
+ componentWillReceiveProps (nextProps) {
+ if (!is(nextProps.visible, this.props.visible) && nextProps.visible !== undefined) {
+ this.setState({ revealed: nextProps.visible });
+ }
+ }
+
componentWillUnmount () {
window.removeEventListener('scroll', this.handleScroll);
window.removeEventListener('resize', this.handleResize);
@@ -189,6 +206,14 @@ class Audio extends React.PureComponent {
});
}
+ toggleReveal = () => {
+ if (this.props.onToggleVisibility) {
+ this.props.onToggleVisibility();
+ } else {
+ this.setState({ revealed: !this.state.revealed });
+ }
+ }
+
handleVolumeMouseDown = e => {
document.addEventListener('mousemove', this.handleMouseVolSlide, true);
document.addEventListener('mouseup', this.handleVolumeMouseUp, true);
@@ -433,13 +458,29 @@ class Audio extends React.PureComponent {
}
render () {
- const { src, intl, alt, editable, autoPlay } = this.props;
- const { paused, muted, volume, currentTime, duration, buffer, dragging } = this.state;
+ const { src, intl, alt, editable, autoPlay, sensitive, blurhash } = this.props;
+ const { paused, muted, volume, currentTime, duration, buffer, dragging, revealed } = this.state;
const progress = Math.min((currentTime / duration) * 100, 100);
+ let warning;
+ if (sensitive) {
+ warning =