Merge pull request #730 from Half-Shot/hs/video-gif-autoplay

Autoplay videos and GIFs if enabled by the user.
This commit is contained in:
David Baker 2017-03-02 13:41:30 +00:00 committed by GitHub
commit 8be66d0f04
3 changed files with 34 additions and 20 deletions

View file

@ -39,6 +39,10 @@ const REACT_SDK_VERSION =
// 'id' gives the key name in the im.vector.web.settings account data event
// 'label' is how we describe it in the UI.
const SETTINGS_LABELS = [
{
id: 'autoplayGifsAndVideos',
label: 'Autoplay GIFs and videos',
},
/*
{
id: 'alwaysShowTimestamps',

View file

@ -25,6 +25,7 @@ import sdk from '../../../index';
import dis from '../../../dispatcher';
import { decryptFile, readBlobAsDataUri } from '../../../utils/DecryptFile';
import q from 'q';
import UserSettingsStore from '../../../UserSettingsStore';
module.exports = React.createClass({
displayName: 'MImageBody',
@ -42,7 +43,7 @@ module.exports = React.createClass({
decryptedUrl: null,
decryptedThumbnailUrl: null,
decryptedBlob: null,
error: null
error: null,
};
},
@ -55,7 +56,7 @@ module.exports = React.createClass({
const ImageView = sdk.getComponent("elements.ImageView");
const params = {
src: httpUrl,
mxEvent: this.props.mxEvent
mxEvent: this.props.mxEvent,
};
if (content.info) {
@ -70,22 +71,26 @@ module.exports = React.createClass({
_isGif: function() {
const content = this.props.mxEvent.getContent();
return (content && content.info && content.info.mimetype === "image/gif");
return (
content &&
content.info &&
content.info.mimetype === "image/gif"
);
},
onImageEnter: function(e) {
if (!this._isGif()) {
if (!this._isGif() || UserSettingsStore.getSyncedSetting("autoplayGifsAndVideos", false)) {
return;
}
var imgElement = e.target;
const imgElement = e.target;
imgElement.src = this._getContentUrl();
},
onImageLeave: function(e) {
if (!this._isGif()) {
if (!this._isGif() || UserSettingsStore.getSyncedSetting("autoplayGifsAndVideos", false)) {
return;
}
var imgElement = e.target;
const imgElement = e.target;
imgElement.src = this._getThumbUrl();
},
@ -101,6 +106,7 @@ module.exports = React.createClass({
_getThumbUrl: function() {
const content = this.props.mxEvent.getContent();
if (content.file !== undefined) {
// Don't use the thumbnail for clients wishing to autoplay gifs.
if (this.state.decryptedThumbnailUrl) {
return this.state.decryptedThumbnailUrl;
}
@ -115,15 +121,15 @@ module.exports = React.createClass({
this.fixupHeight();
const content = this.props.mxEvent.getContent();
if (content.file !== undefined && this.state.decryptedUrl === null) {
var thumbnailPromise = q(null);
let thumbnailPromise = q(null);
if (content.info.thumbnail_file) {
thumbnailPromise = decryptFile(
content.info.thumbnail_file
content.info.thumbnail_file,
).then(function(blob) {
return readBlobAsDataUri(blob);
});
}
var decryptedBlob;
let decryptedBlob;
thumbnailPromise.then((thumbnailUrl) => {
return decryptFile(content.file).then(function(blob) {
decryptedBlob = blob;
@ -168,7 +174,7 @@ module.exports = React.createClass({
// the alternative here would be 600*timelineWidth/800; to scale them down to fit inside a 4:3 bounding box
//console.log("trying to fit image into timelineWidth of " + this.refs.body.offsetWidth + " or " + this.refs.body.clientWidth);
var thumbHeight = null;
let thumbHeight = null;
if (content.info) {
thumbHeight = ImageUtils.thumbHeight(content.info.w, content.info.h, timelineWidth, maxHeight);
}
@ -190,7 +196,6 @@ module.exports = React.createClass({
}
if (content.file !== undefined && this.state.decryptedUrl === null) {
// Need to decrypt the attachment
// The attachment is decrypted in componentDidMount.
// For now add an img tag with a spinner.
@ -210,7 +215,12 @@ module.exports = React.createClass({
}
const contentUrl = this._getContentUrl();
const thumbUrl = this._getThumbUrl();
let thumbUrl;
if (this._isGif() && UserSettingsStore.getSyncedSetting("autoplayGifsAndVideos", false)) {
thumbUrl = contentUrl;
} else {
thumbUrl = this._getThumbUrl();
}
if (thumbUrl) {
return (

View file

@ -23,6 +23,7 @@ import Model from '../../../Modal';
import sdk from '../../../index';
import { decryptFile, readBlobAsDataUri } from '../../../utils/DecryptFile';
import q from 'q';
import UserSettingsStore from '../../../UserSettingsStore';
module.exports = React.createClass({
displayName: 'MVideoBody',
@ -152,11 +153,11 @@ module.exports = React.createClass({
const contentUrl = this._getContentUrl();
const thumbUrl = this._getThumbUrl();
var height = null;
var width = null;
var poster = null;
var preload = "metadata";
const autoplay = UserSettingsStore.getSyncedSetting("autoplayGifsAndVideos", false);
let height = null;
let width = null;
let poster = null;
let preload = "metadata";
if (content.info) {
const scale = this.thumbScale(content.info.w, content.info.h, 480, 360);
if (scale) {
@ -169,11 +170,10 @@ module.exports = React.createClass({
preload = "none";
}
}
return (
<span className="mx_MVideoBody">
<video className="mx_MVideoBody" src={contentUrl} alt={content.body}
controls preload={preload} autoPlay={false}
controls preload={preload} muted={autoplay} autoPlay={autoplay}
height={height} width={width} poster={poster}>
</video>
<MFileBody {...this.props} decryptedBlob={this.state.decryptedBlob} />