1
1
/*
2
2
Copyright 2015, 2016, 2018, 2021 The Matrix.org Foundation C.I.C.
3
+ Copyright 2021 Šimon Brandner <[email protected] >
3
4
4
5
Licensed under the Apache License, Version 2.0 (the "License");
5
6
you may not use this file except in compliance with the License.
@@ -14,17 +15,17 @@ See the License for the specific language governing permissions and
14
15
limitations under the License.
15
16
*/
16
17
17
- import React , { createRef } from 'react' ;
18
- import PropTypes from 'prop-types' ;
18
+ import React from 'react' ;
19
19
import filesize from 'filesize' ;
20
20
import { _t } from '../../../languageHandler' ;
21
- import { decryptFile } from '../../../utils/DecryptFile' ;
21
+ import { decryptFile } from '../../../utils/DecryptFile' ;
22
22
import Modal from '../../../Modal' ;
23
- import AccessibleButton from "../elements/AccessibleButton " ;
24
- import { replaceableComponent } from "../../../utils/replaceableComponent " ;
25
- import { mediaFromContent } from " ../../../customisations/Media" ;
23
+ import { replaceableComponent } from "../../../utils/replaceableComponent " ;
24
+ import { mediaFromContent } from "../../../customisations/Media " ;
25
+ import AccessibleButton from ' ../elements/AccessibleButton' ;
26
26
import ErrorDialog from "../dialogs/ErrorDialog" ;
27
27
import AccessibleTooltipButton from '../elements/AccessibleTooltipButton' ;
28
+ import { MatrixEvent } from 'matrix-js-sdk' ;
28
29
29
30
// User supplied content can contain scripts, we have to be careful that
30
31
// we don't accidentally run those script within the same origin as the
@@ -56,22 +57,20 @@ import AccessibleTooltipButton from '../elements/AccessibleTooltipButton';
56
57
// the downside of using a sandboxed iframe is that the browers are overly
57
58
// restrictive in what you are allowed to do with the generated URL.
58
59
59
- @replaceableComponent ( "views.messages.MFileBody" )
60
- export default class MFileBody extends React . Component {
61
- decrypting = false ;
60
+ interface IProps {
61
+ mxEvent : MatrixEvent ,
62
+ decryptedBlob ?: Blob ; // already decrypted blob
63
+ tileShape ?: string ; // the shape of the tile, used
64
+ showGenericPlaceholder ?: boolean ; // whether or not to show the default placeholder for the file. Defaults to true.
65
+ }
62
66
63
- static propTypes = {
64
- /* the MatrixEvent to show */
65
- mxEvent : PropTypes . object . isRequired ,
66
- /* already decrypted blob */
67
- decryptedBlob : PropTypes . object ,
68
- /* called when the download link iframe is shown */
69
- onHeightChanged : PropTypes . func ,
70
- /* the shape of the tile, used */
71
- tileShape : PropTypes . string ,
72
- /* whether or not to show the default placeholder for the file. Defaults to true. */
73
- showGenericPlaceholder : PropTypes . bool ,
74
- } ;
67
+ interface IState {
68
+ decryptedBlob : Blob ;
69
+ }
70
+
71
+ @replaceableComponent ( "views.messages.MFileBody" )
72
+ export default class MFileBody extends React . Component < IProps , IState > {
73
+ private decrypting = false ;
75
74
76
75
static defaultProps = {
77
76
showGenericPlaceholder : true ,
@@ -81,11 +80,8 @@ export default class MFileBody extends React.Component {
81
80
super ( props ) ;
82
81
83
82
this . state = {
84
- decryptedBlob : ( this . props . decryptedBlob ? this . props . decryptedBlob : null ) ,
83
+ decryptedBlob : this . props . decryptedBlob ,
85
84
} ;
86
-
87
- this . _iframe = createRef ( ) ;
88
- this . _dummyLink = createRef ( ) ;
89
85
}
90
86
91
87
/**
@@ -96,7 +92,7 @@ export default class MFileBody extends React.Component {
96
92
* @param {boolean } withSize Whether to include size information. Default true.
97
93
* @return {string } the human readable link text for the attachment.
98
94
*/
99
- presentableTextForFile ( content , withSize = true ) {
95
+ private presentableTextForFile ( content : any , withSize = true ) : string {
100
96
let linkText = _t ( "Attachment" ) ;
101
97
if ( content . body && content . body . length > 0 ) {
102
98
// The content body should be the name of the file including a
@@ -117,18 +113,12 @@ export default class MFileBody extends React.Component {
117
113
return linkText ;
118
114
}
119
115
120
- _getContentUrl ( ) {
116
+ private getContentUrl ( ) : string {
121
117
const media = mediaFromContent ( this . props . mxEvent . getContent ( ) ) ;
122
118
return media . srcHttp ;
123
119
}
124
120
125
- componentDidUpdate ( prevProps , prevState ) {
126
- if ( this . props . onHeightChanged && ! prevState . decryptedBlob && this . state . decryptedBlob ) {
127
- this . props . onHeightChanged ( ) ;
128
- }
129
- }
130
-
131
- async _decrypt ( file ) {
121
+ private async decrypt ( file : any ) {
132
122
try {
133
123
const blob = await decryptFile ( file ) ;
134
124
await this . setState ( {
@@ -143,7 +133,7 @@ export default class MFileBody extends React.Component {
143
133
}
144
134
}
145
135
146
- _onDownloadClick = async ( ) => {
136
+ private onDownloadClick = async ( ) => {
147
137
const content = this . props . mxEvent . getContent ( ) ;
148
138
const fileSize = content . info ? content . info . size : null ;
149
139
const fileType = content . info ? content . info . mimetype : "application/octet-stream" ;
@@ -161,7 +151,7 @@ export default class MFileBody extends React.Component {
161
151
// decrypt it
162
152
if ( this . decrypting ) return ;
163
153
this . decrypting = true ;
164
- await this . _decrypt ( content . file ) ;
154
+ await this . decrypt ( content . file ) ;
165
155
this . decrypting = false ;
166
156
}
167
157
@@ -192,6 +182,7 @@ export default class MFileBody extends React.Component {
192
182
193
183
iframe . src = "usercontent/" ; // XXX: this path should probably be passed from the skin - Michael
194
184
iframe . onload = onIframeLoad ;
185
+ // @ts -ignore - TS thinks sandbox is readonly but we know better
195
186
iframe . sandbox = "allow-scripts allow-downloads allow-downloads-without-user-activation" ;
196
187
document . body . appendChild ( iframe ) ;
197
188
} else if ( [ "application/pdf" ] . includes ( fileType ) && ! fileTooBig ) {
@@ -214,7 +205,7 @@ export default class MFileBody extends React.Component {
214
205
render ( ) {
215
206
const content = this . props . mxEvent . getContent ( ) ;
216
207
const isEncrypted = content . file !== undefined ;
217
- const contentUrl = this . _getContentUrl ( ) ;
208
+ const contentUrl = this . getContentUrl ( ) ;
218
209
219
210
if ( ! this . props . showGenericPlaceholder ) {
220
211
return (
0 commit comments