@@ -17,41 +17,55 @@ limitations under the License.
17
17
import React from 'react' ;
18
18
import { Room } from "matrix-js-sdk/src/models/room" ;
19
19
import filesize from "filesize" ;
20
- import { IEventRelation } from 'matrix-js-sdk/src/matrix' ;
20
+ import { IAbortablePromise , IEventRelation } from 'matrix-js-sdk/src/matrix' ;
21
+ import { Optional } from "matrix-events-sdk" ;
21
22
22
23
import ContentMessages from '../../ContentMessages' ;
23
24
import dis from "../../dispatcher/dispatcher" ;
24
25
import { _t } from '../../languageHandler' ;
25
- import { ActionPayload } from "../../dispatcher/payloads" ;
26
26
import { Action } from "../../dispatcher/actions" ;
27
27
import ProgressBar from "../views/elements/ProgressBar" ;
28
- import AccessibleButton from "../views/elements/AccessibleButton" ;
28
+ import AccessibleButton , { ButtonEvent } from "../views/elements/AccessibleButton" ;
29
29
import { IUpload } from "../../models/IUpload" ;
30
30
import MatrixClientContext from "../../contexts/MatrixClientContext" ;
31
+ import { ActionPayload } from '../../dispatcher/payloads' ;
32
+ import { UploadPayload } from "../../dispatcher/payloads/UploadPayload" ;
31
33
32
34
interface IProps {
33
35
room : Room ;
34
36
relation ?: IEventRelation ;
35
37
}
36
38
37
39
interface IState {
38
- currentUpload ?: IUpload ;
39
- uploadsHere : IUpload [ ] ;
40
+ currentFile ?: string ;
41
+ currentPromise ?: IAbortablePromise < any > ;
42
+ currentLoaded ?: number ;
43
+ currentTotal ?: number ;
44
+ countFiles : number ;
40
45
}
41
46
42
- export default class UploadBar extends React . Component < IProps , IState > {
47
+ function isUploadPayload ( payload : ActionPayload ) : payload is UploadPayload {
48
+ return [
49
+ Action . UploadStarted ,
50
+ Action . UploadProgress ,
51
+ Action . UploadFailed ,
52
+ Action . UploadFinished ,
53
+ Action . UploadCanceled ,
54
+ ] . includes ( payload . action as Action ) ;
55
+ }
56
+
57
+ export default class UploadBar extends React . PureComponent < IProps , IState > {
43
58
static contextType = MatrixClientContext ;
44
59
45
- private dispatcherRef : string ;
46
- private mounted : boolean ;
60
+ private dispatcherRef : Optional < string > ;
61
+ private mounted = false ;
47
62
48
63
constructor ( props ) {
49
64
super ( props ) ;
50
65
51
66
// Set initial state to any available upload in this room - we might be mounting
52
67
// earlier than the first progress event, so should show something relevant.
53
- const uploadsHere = this . getUploadsInRoom ( ) ;
54
- this . state = { currentUpload : uploadsHere [ 0 ] , uploadsHere } ;
68
+ this . state = this . calculateState ( ) ;
55
69
}
56
70
57
71
componentDidMount ( ) {
@@ -61,53 +75,56 @@ export default class UploadBar extends React.Component<IProps, IState> {
61
75
62
76
componentWillUnmount ( ) {
63
77
this . mounted = false ;
64
- dis . unregister ( this . dispatcherRef ) ;
78
+ dis . unregister ( this . dispatcherRef ! ) ;
65
79
}
66
80
67
81
private getUploadsInRoom ( ) : IUpload [ ] {
68
82
const uploads = ContentMessages . sharedInstance ( ) . getCurrentUploads ( this . props . relation ) ;
69
83
return uploads . filter ( u => u . roomId === this . props . room . roomId ) ;
70
84
}
71
85
86
+ private calculateState ( ) : IState {
87
+ const [ currentUpload , ...otherUploads ] = this . getUploadsInRoom ( ) ;
88
+ return {
89
+ currentFile : currentUpload ?. fileName ,
90
+ currentPromise : currentUpload ?. promise ,
91
+ currentLoaded : currentUpload ?. loaded ,
92
+ currentTotal : currentUpload ?. total ,
93
+ countFiles : otherUploads . length + 1 ,
94
+ } ;
95
+ }
96
+
72
97
private onAction = ( payload : ActionPayload ) => {
73
- switch ( payload . action ) {
74
- case Action . UploadStarted :
75
- case Action . UploadProgress :
76
- case Action . UploadFinished :
77
- case Action . UploadCanceled :
78
- case Action . UploadFailed : {
79
- if ( ! this . mounted ) return ;
80
- const uploadsHere = this . getUploadsInRoom ( ) ;
81
- this . setState ( { currentUpload : uploadsHere [ 0 ] , uploadsHere } ) ;
82
- break ;
83
- }
98
+ if ( ! this . mounted ) return ;
99
+ if ( isUploadPayload ( payload ) ) {
100
+ this . setState ( this . calculateState ( ) ) ;
84
101
}
85
102
} ;
86
103
87
- private onCancelClick = ( ev ) => {
104
+ private onCancelClick = ( ev : ButtonEvent ) => {
88
105
ev . preventDefault ( ) ;
89
- ContentMessages . sharedInstance ( ) . cancelUpload ( this . state . currentUpload . promise , this . context ) ;
106
+ ContentMessages . sharedInstance ( ) . cancelUpload ( this . state . currentPromise ! , this . context ) ;
90
107
} ;
91
108
92
109
render ( ) {
93
- if ( ! this . state . currentUpload ) {
110
+ if ( ! this . state . currentFile ) {
94
111
return null ;
95
112
}
96
113
97
114
// MUST use var name 'count' for pluralization to kick in
98
115
const uploadText = _t (
99
116
"Uploading %(filename)s and %(count)s others" , {
100
- filename : this . state . currentUpload . fileName ,
101
- count : this . state . uploadsHere . length - 1 ,
117
+ filename : this . state . currentFile ,
118
+ count : this . state . countFiles - 1 ,
102
119
} ,
103
120
) ;
104
121
105
- const uploadSize = filesize ( this . state . currentUpload . total ) ;
122
+ const uploadSize = filesize ( this . state . currentTotal ! ) ;
106
123
return (
107
124
< div className = "mx_UploadBar" >
108
125
< div className = "mx_UploadBar_filename" > { uploadText } ({ uploadSize } )</ div >
109
126
< AccessibleButton onClick = { this . onCancelClick } className = 'mx_UploadBar_cancel' />
110
- < ProgressBar value = { this . state . currentUpload . loaded } max = { this . state . currentUpload . total } />
127
+ < ProgressBar value = { this . state . currentLoaded ! } max = { this . state . currentTotal ! } />
111
128
</ div >
112
129
) ;
113
130
}
0 commit comments