Skip to content
This repository was archived by the owner on Sep 11, 2024. It is now read-only.

Commit 7164284

Browse files
committed
Do not download encrypted video if autoplay is not on
1 parent bbb4c7f commit 7164284

File tree

1 file changed

+52
-15
lines changed

1 file changed

+52
-15
lines changed

src/components/views/messages/MVideoBody.tsx

Lines changed: 52 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,15 @@ interface IState {
3434
decryptedUrl: string|null,
3535
decryptedThumbnailUrl: string|null,
3636
decryptedBlob: Blob|null,
37-
error: string|null,
37+
error: any|null,
38+
fetchingData: boolean,
3839
}
3940

4041
export default class MVideoBody extends React.PureComponent<IProps, IState> {
4142
constructor(props) {
4243
super(props);
4344
this.state = {
45+
fetchingData: false,
4446
decryptedUrl: null,
4547
decryptedThumbnailUrl: null,
4648
decryptedBlob: null,
@@ -69,7 +71,7 @@ export default class MVideoBody extends React.PureComponent<IProps, IState> {
6971
}
7072
}
7173

72-
_getContentUrl(): string {
74+
_getContentUrl(): string|null {
7375
const content = this.props.mxEvent.getContent();
7476
if (content.file !== undefined) {
7577
return this.state.decryptedUrl;
@@ -89,7 +91,8 @@ export default class MVideoBody extends React.PureComponent<IProps, IState> {
8991
}
9092
}
9193

92-
componentDidMount() {
94+
async componentDidMount() {
95+
const autoplay = SettingsStore.getValue("autoplayGifsAndVideos") as boolean;
9396
const content = this.props.mxEvent.getContent();
9497
if (content.file !== undefined && this.state.decryptedUrl === null) {
9598
let thumbnailPromise = Promise.resolve(null);
@@ -100,26 +103,33 @@ export default class MVideoBody extends React.PureComponent<IProps, IState> {
100103
return URL.createObjectURL(blob);
101104
});
102105
}
103-
let decryptedBlob;
104-
thumbnailPromise.then((thumbnailUrl) => {
105-
return decryptFile(content.file).then(function(blob) {
106-
decryptedBlob = blob;
107-
return URL.createObjectURL(blob);
108-
}).then((contentUrl) => {
106+
try {
107+
const thumbnailUrl = await thumbnailPromise;
108+
if (autoplay) {
109+
console.log("Preloading video");
110+
const decryptedBlob = await decryptFile(content.file);
111+
const contentUrl = URL.createObjectURL(decryptedBlob);
109112
this.setState({
110113
decryptedUrl: contentUrl,
111114
decryptedThumbnailUrl: thumbnailUrl,
112115
decryptedBlob: decryptedBlob,
113116
});
114117
this.props.onHeightChanged();
115-
});
116-
}).catch((err) => {
118+
} else {
119+
console.log("NOT preloading video");
120+
this.setState({
121+
decryptedUrl: null,
122+
decryptedThumbnailUrl: thumbnailUrl,
123+
decryptedBlob: null,
124+
});
125+
}
126+
} catch (err) {
117127
console.warn("Unable to decrypt attachment: ", err);
118128
// Set a placeholder image when we can't decrypt the image.
119129
this.setState({
120130
error: err,
121131
});
122-
});
132+
}
123133
}
124134
}
125135

@@ -132,8 +142,35 @@ export default class MVideoBody extends React.PureComponent<IProps, IState> {
132142
}
133143
}
134144

145+
async _videoOnPlay() {
146+
const autoplay = SettingsStore.getValue("autoplayGifsAndVideos") as boolean;
147+
if (autoplay || this.state.decryptedUrl || this.state.fetchingData || this.state.error) {
148+
// The video has or will have the data.
149+
return;
150+
}
151+
this.setState({
152+
// To stop subsequent download attempts
153+
fetchingData: true,
154+
});
155+
const content = this.props.mxEvent.getContent();
156+
if (!content.file) {
157+
this.setState({
158+
error: "No file given in content",
159+
});
160+
return;
161+
}
162+
const decryptedBlob = await decryptFile(content.file);
163+
const contentUrl = URL.createObjectURL(decryptedBlob);
164+
this.setState({
165+
decryptedUrl: contentUrl,
166+
decryptedBlob: decryptedBlob,
167+
});
168+
this.props.onHeightChanged();
169+
}
170+
135171
render() {
136172
const content = this.props.mxEvent.getContent();
173+
const autoplay = SettingsStore.getValue("autoplayGifsAndVideos");
137174

138175
if (this.state.error !== null) {
139176
return (
@@ -144,7 +181,8 @@ export default class MVideoBody extends React.PureComponent<IProps, IState> {
144181
);
145182
}
146183

147-
if (content.file !== undefined && this.state.decryptedUrl === null) {
184+
// Important: If we aren't autoplaying and we haven't decrypred it yet, show a video with a poster.
185+
if (content.file !== undefined && this.state.decryptedUrl === null && autoplay) {
148186
// Need to decrypt the attachment
149187
// The attachment is decrypted in componentDidMount.
150188
// For now add an img tag with a spinner.
@@ -159,7 +197,6 @@ export default class MVideoBody extends React.PureComponent<IProps, IState> {
159197

160198
const contentUrl = this._getContentUrl();
161199
const thumbUrl = this._getThumbUrl();
162-
const autoplay = SettingsStore.getValue("autoplayGifsAndVideos");
163200
let height = null;
164201
let width = null;
165202
let poster = null;
@@ -180,7 +217,7 @@ export default class MVideoBody extends React.PureComponent<IProps, IState> {
180217
<span className="mx_MVideoBody">
181218
<video className="mx_MVideoBody" src={contentUrl} alt={content.body}
182219
controls preload={preload} muted={autoplay} autoPlay={autoplay}
183-
height={height} width={width} poster={poster}>
220+
height={height} width={width} poster={poster} onPlay={this._videoOnPlay.bind(this)}>
184221
</video>
185222
<MFileBody {...this.props} decryptedBlob={this.state.decryptedBlob} />
186223
</span>

0 commit comments

Comments
 (0)