@@ -17,41 +17,55 @@ limitations under the License.
1717import React from 'react' ;
1818import { Room } from "matrix-js-sdk/src/models/room" ;
1919import 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" ;
2122
2223import ContentMessages from '../../ContentMessages' ;
2324import dis from "../../dispatcher/dispatcher" ;
2425import { _t } from '../../languageHandler' ;
25- import { ActionPayload } from "../../dispatcher/payloads" ;
2626import { Action } from "../../dispatcher/actions" ;
2727import ProgressBar from "../views/elements/ProgressBar" ;
28- import AccessibleButton from "../views/elements/AccessibleButton" ;
28+ import AccessibleButton , { ButtonEvent } from "../views/elements/AccessibleButton" ;
2929import { IUpload } from "../../models/IUpload" ;
3030import MatrixClientContext from "../../contexts/MatrixClientContext" ;
31+ import { ActionPayload } from '../../dispatcher/payloads' ;
32+ import { UploadPayload } from "../../dispatcher/payloads/UploadPayload" ;
3133
3234interface IProps {
3335 room : Room ;
3436 relation ?: IEventRelation ;
3537}
3638
3739interface IState {
38- currentUpload ?: IUpload ;
39- uploadsHere : IUpload [ ] ;
40+ currentFile ?: string ;
41+ currentPromise ?: IAbortablePromise < any > ;
42+ currentLoaded ?: number ;
43+ currentTotal ?: number ;
44+ countFiles : number ;
4045}
4146
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 > {
4358 static contextType = MatrixClientContext ;
4459
45- private dispatcherRef : string ;
46- private mounted : boolean ;
60+ private dispatcherRef : Optional < string > ;
61+ private mounted = false ;
4762
4863 constructor ( props ) {
4964 super ( props ) ;
5065
5166 // Set initial state to any available upload in this room - we might be mounting
5267 // 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 ( ) ;
5569 }
5670
5771 componentDidMount ( ) {
@@ -61,53 +75,56 @@ export default class UploadBar extends React.Component<IProps, IState> {
6175
6276 componentWillUnmount ( ) {
6377 this . mounted = false ;
64- dis . unregister ( this . dispatcherRef ) ;
78+ dis . unregister ( this . dispatcherRef ! ) ;
6579 }
6680
6781 private getUploadsInRoom ( ) : IUpload [ ] {
6882 const uploads = ContentMessages . sharedInstance ( ) . getCurrentUploads ( this . props . relation ) ;
6983 return uploads . filter ( u => u . roomId === this . props . room . roomId ) ;
7084 }
7185
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+
7297 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 ( ) ) ;
84101 }
85102 } ;
86103
87- private onCancelClick = ( ev ) => {
104+ private onCancelClick = ( ev : ButtonEvent ) => {
88105 ev . preventDefault ( ) ;
89- ContentMessages . sharedInstance ( ) . cancelUpload ( this . state . currentUpload . promise , this . context ) ;
106+ ContentMessages . sharedInstance ( ) . cancelUpload ( this . state . currentPromise ! , this . context ) ;
90107 } ;
91108
92109 render ( ) {
93- if ( ! this . state . currentUpload ) {
110+ if ( ! this . state . currentFile ) {
94111 return null ;
95112 }
96113
97114 // MUST use var name 'count' for pluralization to kick in
98115 const uploadText = _t (
99116 "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 ,
102119 } ,
103120 ) ;
104121
105- const uploadSize = filesize ( this . state . currentUpload . total ) ;
122+ const uploadSize = filesize ( this . state . currentTotal ! ) ;
106123 return (
107124 < div className = "mx_UploadBar" >
108125 < div className = "mx_UploadBar_filename" > { uploadText } ({ uploadSize } )</ div >
109126 < 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 ! } />
111128 </ div >
112129 ) ;
113130 }
0 commit comments