diff --git a/app/javascript/mastodon/features/audio/index.js b/app/javascript/mastodon/features/audio/index.js
index 1b4cdbb4f..fda5a074f 100644
--- a/app/javascript/mastodon/features/audio/index.js
+++ b/app/javascript/mastodon/features/audio/index.js
@@ -37,15 +37,14 @@ class Audio extends React.PureComponent {
volume: 0.5,
};
- // hard coded in components.scss
- // any way to get ::before values programatically?
-
- volWidth = 50;
-
+ // Hard coded in components.scss
+ // Any way to get ::before values programatically?
+ volWidth = 50;
volOffset = 70;
volHandleOffset = v => {
const offset = v * this.volWidth + this.volOffset;
+
return (offset > 110) ? 110 : offset;
}
@@ -61,6 +60,8 @@ class Audio extends React.PureComponent {
if (this.waveform) {
this._updateWaveform();
}
+
+ window.addEventListener('scroll', this.handleScroll);
}
componentDidUpdate (prevProps) {
@@ -70,6 +71,8 @@ class Audio extends React.PureComponent {
}
componentWillUnmount () {
+ window.removeEventListener('scroll', this.handleScroll);
+
if (this.wavesurfer) {
this.wavesurfer.destroy();
this.wavesurfer = null;
@@ -128,16 +131,15 @@ class Audio extends React.PureComponent {
this.loaded = true;
}
- this.wavesurfer.play();
- this.setState({ paused: false });
+ this.setState({ paused: false }, () => this.wavesurfer.play());
} else {
- this.wavesurfer.pause();
- this.setState({ paused: true });
+ this.setState({ paused: true }, () => this.wavesurfer.pause());
}
}
toggleMute = () => {
- this.wavesurfer.setMute(!this.state.muted);
+ const muted = !this.state.muted;
+ this.setState({ muted }, () => this.wavesurfer.setMute(muted));
}
handleVolumeMouseDown = e => {
@@ -176,6 +178,19 @@ class Audio extends React.PureComponent {
}
}, 60);
+ handleScroll = throttle(() => {
+ if (!this.waveform || !this.wavesurfer) {
+ return;
+ }
+
+ const { top, height } = this.waveform.getBoundingClientRect();
+ const inView = (top <= (window.innerHeight || document.documentElement.clientHeight)) && (top + height >= 0);
+
+ if (!this.state.paused && !inView) {
+ this.setState({ paused: true }, () => this.wavesurfer.pause());
+ }
+ }, 150, { trailing: true })
+
render () {
const { height, intl, alt, editable } = this.props;
const { paused, muted, volume, currentTime } = this.state;
diff --git a/app/javascript/mastodon/features/video/index.js b/app/javascript/mastodon/features/video/index.js
index f6aeb8c9a..0e2a99416 100644
--- a/app/javascript/mastodon/features/video/index.js
+++ b/app/javascript/mastodon/features/video/index.js
@@ -124,12 +124,14 @@ class Video extends React.PureComponent {
revealed: this.props.visible !== undefined ? this.props.visible : (displayMedia !== 'hide_all' && !this.props.sensitive || displayMedia === 'show_all'),
};
- // hard coded in components.scss
- // any way to get ::before values programatically?
- volWidth = 50;
+ // Hard-coded in components.scss
+ // Any way to get ::before values programatically?
+ volWidth = 50;
volOffset = 70;
+
volHandleOffset = v => {
const offset = v * this.volWidth + this.volOffset;
+
return (offset > 110) ? 110 : offset;
}
@@ -138,6 +140,7 @@ class Video extends React.PureComponent {
if (c) {
if (this.props.cacheWidth) this.props.cacheWidth(this.player.offsetWidth);
+
this.setState({
containerWidth: c.offsetWidth,
});
@@ -205,12 +208,14 @@ class Video extends React.PureComponent {
const x = (e.clientX - rect.left) / this.volWidth; //x position within the element.
if(!isNaN(x)) {
- var slideamt = x;
+ let slideamt = x;
+
if(x > 1) {
slideamt = 1;
} else if(x < 0) {
slideamt = 0;
}
+
this.video.volume = slideamt;
this.setState({ volume: slideamt });
}
@@ -252,9 +257,9 @@ class Video extends React.PureComponent {
togglePlay = () => {
if (this.state.paused) {
- this.video.play();
+ this.setState({ paused: false }, () => this.video.play());
} else {
- this.video.pause();
+ this.setState({ paused: true }, () => this.video.pause());
}
}
@@ -272,12 +277,16 @@ class Video extends React.PureComponent {
document.addEventListener('mozfullscreenchange', this.handleFullscreenChange, true);
document.addEventListener('MSFullscreenChange', this.handleFullscreenChange, true);
+ window.addEventListener('scroll', this.handleScroll);
+
if (this.props.blurhash) {
this._decode();
}
}
componentWillUnmount () {
+ window.removeEventListener('scroll', this.handleScroll);
+
document.removeEventListener('fullscreenchange', this.handleFullscreenChange, true);
document.removeEventListener('webkitfullscreenchange', this.handleFullscreenChange, true);
document.removeEventListener('mozfullscreenchange', this.handleFullscreenChange, true);
@@ -294,6 +303,7 @@ class Video extends React.PureComponent {
if (prevState.revealed && !this.state.revealed && this.video) {
this.video.pause();
}
+
if (prevProps.blurhash !== this.props.blurhash && this.props.blurhash) {
this._decode();
}
@@ -313,6 +323,19 @@ class Video extends React.PureComponent {
}
}
+ handleScroll = throttle(() => {
+ if (!this.video) {
+ return;
+ }
+
+ const { top, height } = this.video.getBoundingClientRect();
+ const inView = (top <= (window.innerHeight || document.documentElement.clientHeight)) && (top + height >= 0);
+
+ if (!this.state.paused && !inView) {
+ this.setState({ paused: true }, () => this.video.pause());
+ }
+ }, 150, { trailing: true })
+
handleFullscreenChange = () => {
this.setState({ fullscreen: isFullscreen() });
}
@@ -326,8 +349,11 @@ class Video extends React.PureComponent {
}
toggleMute = () => {
- this.video.muted = !this.video.muted;
- this.setState({ muted: this.video.muted });
+ const muted = !this.video.muted;
+
+ this.setState({ muted }, () => {
+ this.video.muted = muted;
+ });
}
toggleReveal = () => {
@@ -430,7 +456,6 @@ class Video extends React.PureComponent {
src={src}
poster={preview}
preload={preload}
- loop
role='button'
tabIndex='0'
aria-label={alt}
@@ -495,13 +520,8 @@ class Video extends React.PureComponent {
{(!onCloseVideo && !editable) && }
{(!fullscreen && onOpenVideo) && }
{onCloseVideo && }
-
+
-