Merge pull request #5723 from matrix-org/travis/uploads
Refresh UI for file uploads
This commit is contained in:
commit
52621946de
15 changed files with 278 additions and 171 deletions
|
@ -606,6 +606,13 @@ input[type=text]:focus, input[type=password]:focus, textarea:focus {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@define-mixin ProgressBarBgColour $colour {
|
||||||
|
background-color: $colour;
|
||||||
|
&::-webkit-progress-bar {
|
||||||
|
background-color: $colour;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@define-mixin ProgressBarBorderRadius $radius {
|
@define-mixin ProgressBarBorderRadius $radius {
|
||||||
border-radius: $radius;
|
border-radius: $radius;
|
||||||
&::-moz-progress-bar {
|
&::-moz-progress-bar {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2015, 2016 OpenMarket Ltd
|
Copyright 2015, 2016, 2021 The Matrix.org Foundation C.I.C.
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -15,47 +15,45 @@ limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
.mx_UploadBar {
|
.mx_UploadBar {
|
||||||
|
padding-left: 65px; // line up with the shield area in the composer
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
|
.mx_ProgressBar {
|
||||||
|
width: calc(100% - 40px); // cheating at a right margin
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_UploadBar_uploadProgressOuter {
|
.mx_UploadBar_filename {
|
||||||
height: 5px;
|
|
||||||
margin-left: 63px;
|
|
||||||
margin-top: -1px;
|
|
||||||
padding-bottom: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mx_UploadBar_uploadProgressInner {
|
|
||||||
background-color: $accent-color;
|
|
||||||
height: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mx_UploadBar_uploadFilename {
|
|
||||||
margin-top: 5px;
|
margin-top: 5px;
|
||||||
margin-left: 65px;
|
color: $muted-fg-color;
|
||||||
opacity: 0.5;
|
|
||||||
color: $primary-fg-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mx_UploadBar_uploadIcon {
|
|
||||||
float: left;
|
|
||||||
margin-top: 5px;
|
|
||||||
margin-left: 14px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mx_UploadBar_uploadCancel {
|
|
||||||
float: right;
|
|
||||||
margin-top: 5px;
|
|
||||||
margin-right: 10px;
|
|
||||||
position: relative;
|
position: relative;
|
||||||
opacity: 0.6;
|
padding-left: 22px; // 18px for icon, 4px for padding
|
||||||
cursor: pointer;
|
font-size: $font-15px;
|
||||||
z-index: 1;
|
vertical-align: middle;
|
||||||
|
|
||||||
|
&::before {
|
||||||
|
content: "";
|
||||||
|
height: 18px;
|
||||||
|
width: 18px;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
mask-repeat: no-repeat;
|
||||||
|
mask-position: center;
|
||||||
|
background-color: $muted-fg-color;
|
||||||
|
mask-image: url('$(res)/img/element-icons/upload.svg');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.mx_UploadBar_uploadBytes {
|
.mx_UploadBar_cancel {
|
||||||
float: right;
|
position: absolute;
|
||||||
margin-top: 5px;
|
top: 0;
|
||||||
margin-right: 30px;
|
right: 0;
|
||||||
color: $accent-color;
|
height: 16px;
|
||||||
|
width: 16px;
|
||||||
|
margin-right: 16px; // align over rightmost button in composer
|
||||||
|
mask-repeat: no-repeat;
|
||||||
|
mask-position: center;
|
||||||
|
background-color: $muted-fg-color;
|
||||||
|
mask-image: url('$(res)/img/icons-close.svg');
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
Copyright 2020 The Matrix.org Foundation C.I.C.
|
Copyright 2020, 2021 The Matrix.org Foundation C.I.C.
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
@ -15,15 +15,15 @@ limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
progress.mx_ProgressBar {
|
progress.mx_ProgressBar {
|
||||||
height: 4px;
|
height: 6px;
|
||||||
width: 60px;
|
width: 60px;
|
||||||
border-radius: 10px;
|
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
appearance: none;
|
appearance: none;
|
||||||
border: 0;
|
border: none;
|
||||||
|
|
||||||
@mixin ProgressBarBorderRadius "10px";
|
@mixin ProgressBarBorderRadius "6px";
|
||||||
@mixin ProgressBarColour $accent-color;
|
@mixin ProgressBarColour $progressbar-fg-color;
|
||||||
|
@mixin ProgressBarBgColour $progressbar-bg-color;
|
||||||
::-webkit-progress-value {
|
::-webkit-progress-value {
|
||||||
transition: width 1s;
|
transition: width 1s;
|
||||||
}
|
}
|
||||||
|
|
4
res/img/element-icons/upload.svg
Normal file
4
res/img/element-icons/upload.svg
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M8.99902 14L8.99902 4" stroke="black" stroke-width="1.5" stroke-linecap="round"/>
|
||||||
|
<path d="M12.5352 7.52441L8.99944 4.00012L5.46373 7.52441" stroke="black" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 336 B |
|
@ -170,6 +170,9 @@ $button-link-bg-color: transparent;
|
||||||
// Toggle switch
|
// Toggle switch
|
||||||
$togglesw-off-color: $room-highlight-color;
|
$togglesw-off-color: $room-highlight-color;
|
||||||
|
|
||||||
|
$progressbar-fg-color: $accent-color;
|
||||||
|
$progressbar-bg-color: #21262c;
|
||||||
|
|
||||||
$visual-bell-bg-color: #800;
|
$visual-bell-bg-color: #800;
|
||||||
|
|
||||||
$room-warning-bg-color: $header-panel-bg-color;
|
$room-warning-bg-color: $header-panel-bg-color;
|
||||||
|
|
|
@ -165,6 +165,9 @@ $button-link-bg-color: transparent;
|
||||||
// Toggle switch
|
// Toggle switch
|
||||||
$togglesw-off-color: $room-highlight-color;
|
$togglesw-off-color: $room-highlight-color;
|
||||||
|
|
||||||
|
$progressbar-fg-color: $accent-color;
|
||||||
|
$progressbar-bg-color: #21262c;
|
||||||
|
|
||||||
$visual-bell-bg-color: #800;
|
$visual-bell-bg-color: #800;
|
||||||
|
|
||||||
$room-warning-bg-color: $header-panel-bg-color;
|
$room-warning-bg-color: $header-panel-bg-color;
|
||||||
|
|
|
@ -280,7 +280,8 @@ $togglesw-ball-color: #fff;
|
||||||
$slider-selection-color: $accent-color;
|
$slider-selection-color: $accent-color;
|
||||||
$slider-background-color: #c1c9d6;
|
$slider-background-color: #c1c9d6;
|
||||||
|
|
||||||
$progressbar-color: #000;
|
$progressbar-fg-color: $accent-color;
|
||||||
|
$progressbar-bg-color: rgba(141, 151, 165, 0.2);
|
||||||
|
|
||||||
$room-warning-bg-color: $yellow-background;
|
$room-warning-bg-color: $yellow-background;
|
||||||
|
|
||||||
|
|
|
@ -277,7 +277,8 @@ $togglesw-ball-color: #fff;
|
||||||
$slider-selection-color: $accent-color;
|
$slider-selection-color: $accent-color;
|
||||||
$slider-background-color: #c1c9d6;
|
$slider-background-color: #c1c9d6;
|
||||||
|
|
||||||
$progressbar-color: #000;
|
$progressbar-fg-color: $accent-color;
|
||||||
|
$progressbar-bg-color: rgba(141, 151, 165, 0.2);
|
||||||
|
|
||||||
$room-warning-bg-color: $yellow-background;
|
$room-warning-bg-color: $yellow-background;
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,14 @@ import Spinner from "./components/views/elements/Spinner";
|
||||||
import "blueimp-canvas-to-blob";
|
import "blueimp-canvas-to-blob";
|
||||||
import { Action } from "./dispatcher/actions";
|
import { Action } from "./dispatcher/actions";
|
||||||
import CountlyAnalytics from "./CountlyAnalytics";
|
import CountlyAnalytics from "./CountlyAnalytics";
|
||||||
|
import {
|
||||||
|
UploadCanceledPayload,
|
||||||
|
UploadErrorPayload,
|
||||||
|
UploadFinishedPayload,
|
||||||
|
UploadProgressPayload,
|
||||||
|
UploadStartedPayload,
|
||||||
|
} from "./dispatcher/payloads/UploadPayload";
|
||||||
|
import {IUpload} from "./models/IUpload";
|
||||||
|
|
||||||
const MAX_WIDTH = 800;
|
const MAX_WIDTH = 800;
|
||||||
const MAX_HEIGHT = 600;
|
const MAX_HEIGHT = 600;
|
||||||
|
@ -44,15 +52,6 @@ export class UploadCanceledError extends Error {}
|
||||||
|
|
||||||
type ThumbnailableElement = HTMLImageElement | HTMLVideoElement;
|
type ThumbnailableElement = HTMLImageElement | HTMLVideoElement;
|
||||||
|
|
||||||
interface IUpload {
|
|
||||||
fileName: string;
|
|
||||||
roomId: string;
|
|
||||||
total: number;
|
|
||||||
loaded: number;
|
|
||||||
promise: Promise<any>;
|
|
||||||
canceled?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface IMediaConfig {
|
interface IMediaConfig {
|
||||||
"m.upload.size"?: number;
|
"m.upload.size"?: number;
|
||||||
}
|
}
|
||||||
|
@ -478,7 +477,7 @@ export default class ContentMessages {
|
||||||
if (upload) {
|
if (upload) {
|
||||||
upload.canceled = true;
|
upload.canceled = true;
|
||||||
MatrixClientPeg.get().cancelUpload(upload.promise);
|
MatrixClientPeg.get().cancelUpload(upload.promise);
|
||||||
dis.dispatch({action: 'upload_canceled', upload});
|
dis.dispatch<UploadCanceledPayload>({action: Action.UploadCanceled, upload});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -539,7 +538,7 @@ export default class ContentMessages {
|
||||||
promise: prom,
|
promise: prom,
|
||||||
};
|
};
|
||||||
this.inprogress.push(upload);
|
this.inprogress.push(upload);
|
||||||
dis.dispatch({action: 'upload_started'});
|
dis.dispatch<UploadStartedPayload>({action: Action.UploadStarted, upload});
|
||||||
|
|
||||||
// Focus the composer view
|
// Focus the composer view
|
||||||
dis.fire(Action.FocusComposer);
|
dis.fire(Action.FocusComposer);
|
||||||
|
@ -547,7 +546,7 @@ export default class ContentMessages {
|
||||||
function onProgress(ev) {
|
function onProgress(ev) {
|
||||||
upload.total = ev.total;
|
upload.total = ev.total;
|
||||||
upload.loaded = ev.loaded;
|
upload.loaded = ev.loaded;
|
||||||
dis.dispatch({action: 'upload_progress', upload: upload});
|
dis.dispatch<UploadProgressPayload>({action: Action.UploadProgress, upload});
|
||||||
}
|
}
|
||||||
|
|
||||||
let error;
|
let error;
|
||||||
|
@ -601,9 +600,9 @@ export default class ContentMessages {
|
||||||
if (error && error.http_status === 413) {
|
if (error && error.http_status === 413) {
|
||||||
this.mediaConfig = null;
|
this.mediaConfig = null;
|
||||||
}
|
}
|
||||||
dis.dispatch({action: 'upload_failed', upload, error});
|
dis.dispatch<UploadErrorPayload>({action: Action.UploadFailed, upload, error});
|
||||||
} else {
|
} else {
|
||||||
dis.dispatch({action: 'upload_finished', upload});
|
dis.dispatch<UploadFinishedPayload>({action: Action.UploadFinished, upload});
|
||||||
dis.dispatch({action: 'message_sent'});
|
dis.dispatch({action: 'message_sent'});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -711,9 +711,9 @@ export default class RoomView extends React.Component<IProps, IState> {
|
||||||
[payload.file], this.state.room.roomId, this.context);
|
[payload.file], this.state.room.roomId, this.context);
|
||||||
break;
|
break;
|
||||||
case 'notifier_enabled':
|
case 'notifier_enabled':
|
||||||
case 'upload_started':
|
case Action.UploadStarted:
|
||||||
case 'upload_finished':
|
case Action.UploadFinished:
|
||||||
case 'upload_canceled':
|
case Action.UploadCanceled:
|
||||||
this.forceUpdate();
|
this.forceUpdate();
|
||||||
break;
|
break;
|
||||||
case 'call_state': {
|
case 'call_state': {
|
||||||
|
|
|
@ -1,109 +0,0 @@
|
||||||
/*
|
|
||||||
Copyright 2015, 2016 OpenMarket Ltd
|
|
||||||
Copyright 2019 The Matrix.org Foundation C.I.C.
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import React from 'react';
|
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import ContentMessages from '../../ContentMessages';
|
|
||||||
import dis from "../../dispatcher/dispatcher";
|
|
||||||
import filesize from "filesize";
|
|
||||||
import { _t } from '../../languageHandler';
|
|
||||||
|
|
||||||
export default class UploadBar extends React.Component {
|
|
||||||
static propTypes = {
|
|
||||||
room: PropTypes.object,
|
|
||||||
};
|
|
||||||
|
|
||||||
componentDidMount() {
|
|
||||||
this.dispatcherRef = dis.register(this.onAction);
|
|
||||||
this.mounted = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
componentWillUnmount() {
|
|
||||||
this.mounted = false;
|
|
||||||
dis.unregister(this.dispatcherRef);
|
|
||||||
}
|
|
||||||
|
|
||||||
onAction = payload => {
|
|
||||||
switch (payload.action) {
|
|
||||||
case 'upload_progress':
|
|
||||||
case 'upload_finished':
|
|
||||||
case 'upload_canceled':
|
|
||||||
case 'upload_failed':
|
|
||||||
if (this.mounted) this.forceUpdate();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
render() {
|
|
||||||
const uploads = ContentMessages.sharedInstance().getCurrentUploads();
|
|
||||||
|
|
||||||
// for testing UI... - also fix up the ContentMessages.getCurrentUploads().length
|
|
||||||
// check in RoomView
|
|
||||||
//
|
|
||||||
// uploads = [{
|
|
||||||
// roomId: this.props.room.roomId,
|
|
||||||
// loaded: 123493,
|
|
||||||
// total: 347534,
|
|
||||||
// fileName: "testing_fooble.jpg",
|
|
||||||
// }];
|
|
||||||
|
|
||||||
if (uploads.length == 0) {
|
|
||||||
return <div />;
|
|
||||||
}
|
|
||||||
|
|
||||||
let upload;
|
|
||||||
for (let i = 0; i < uploads.length; ++i) {
|
|
||||||
if (uploads[i].roomId == this.props.room.roomId) {
|
|
||||||
upload = uploads[i];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!upload) {
|
|
||||||
return <div />;
|
|
||||||
}
|
|
||||||
|
|
||||||
const innerProgressStyle = {
|
|
||||||
width: ((upload.loaded / (upload.total || 1)) * 100) + '%',
|
|
||||||
};
|
|
||||||
let uploadedSize = filesize(upload.loaded);
|
|
||||||
const totalSize = filesize(upload.total);
|
|
||||||
if (uploadedSize.replace(/^.* /, '') === totalSize.replace(/^.* /, '')) {
|
|
||||||
uploadedSize = uploadedSize.replace(/ .*/, '');
|
|
||||||
}
|
|
||||||
|
|
||||||
// MUST use var name 'count' for pluralization to kick in
|
|
||||||
const uploadText = _t(
|
|
||||||
"Uploading %(filename)s and %(count)s others", {filename: upload.fileName, count: (uploads.length - 1)},
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="mx_UploadBar">
|
|
||||||
<div className="mx_UploadBar_uploadProgressOuter">
|
|
||||||
<div className="mx_UploadBar_uploadProgressInner" style={innerProgressStyle}></div>
|
|
||||||
</div>
|
|
||||||
<img className="mx_UploadBar_uploadIcon mx_filterFlipColor" src={require("../../../res/img/fileicon.png")} width="17" height="22" />
|
|
||||||
<img className="mx_UploadBar_uploadCancel mx_filterFlipColor" src={require("../../../res/img/cancel.svg")} width="18" height="18"
|
|
||||||
onClick={function() { ContentMessages.sharedInstance().cancelUpload(upload.promise); }}
|
|
||||||
/>
|
|
||||||
<div className="mx_UploadBar_uploadBytes">
|
|
||||||
{ uploadedSize } / { totalSize }
|
|
||||||
</div>
|
|
||||||
<div className="mx_UploadBar_uploadFilename">{ uploadText }</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
100
src/components/structures/UploadBar.tsx
Normal file
100
src/components/structures/UploadBar.tsx
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
/*
|
||||||
|
Copyright 2015, 2016, 2019, 2021 The Matrix.org Foundation C.I.C.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import React from 'react';
|
||||||
|
import { Room } from "matrix-js-sdk/src/models/room";
|
||||||
|
import ContentMessages from '../../ContentMessages';
|
||||||
|
import dis from "../../dispatcher/dispatcher";
|
||||||
|
import filesize from "filesize";
|
||||||
|
import { _t } from '../../languageHandler';
|
||||||
|
import { ActionPayload } from "../../dispatcher/payloads";
|
||||||
|
import { Action } from "../../dispatcher/actions";
|
||||||
|
import ProgressBar from "../views/elements/ProgressBar";
|
||||||
|
import AccessibleButton from "../views/elements/AccessibleButton";
|
||||||
|
import { IUpload } from "../../models/IUpload";
|
||||||
|
|
||||||
|
interface IProps {
|
||||||
|
room: Room;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IState {
|
||||||
|
currentUpload?: IUpload;
|
||||||
|
uploadsHere: IUpload[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class UploadBar extends React.Component<IProps, IState> {
|
||||||
|
private dispatcherRef: string;
|
||||||
|
private mounted: boolean;
|
||||||
|
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.state = {uploadsHere: []};
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
this.dispatcherRef = dis.register(this.onAction);
|
||||||
|
this.mounted = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillUnmount() {
|
||||||
|
this.mounted = false;
|
||||||
|
dis.unregister(this.dispatcherRef);
|
||||||
|
}
|
||||||
|
|
||||||
|
private onAction = (payload: ActionPayload) => {
|
||||||
|
switch (payload.action) {
|
||||||
|
case Action.UploadStarted:
|
||||||
|
case Action.UploadProgress:
|
||||||
|
case Action.UploadFinished:
|
||||||
|
case Action.UploadCanceled:
|
||||||
|
case Action.UploadFailed: {
|
||||||
|
if (!this.mounted) return;
|
||||||
|
const uploads = ContentMessages.sharedInstance().getCurrentUploads();
|
||||||
|
const uploadsHere = uploads.filter(u => u.roomId === this.props.room.roomId);
|
||||||
|
this.setState({currentUpload: uploadsHere[0], uploadsHere});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private onCancelClick = (ev) => {
|
||||||
|
ev.preventDefault();
|
||||||
|
ContentMessages.sharedInstance().cancelUpload(this.state.currentUpload.promise);
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
if (!this.state.currentUpload) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// MUST use var name 'count' for pluralization to kick in
|
||||||
|
const uploadText = _t(
|
||||||
|
"Uploading %(filename)s and %(count)s others", {
|
||||||
|
filename: this.state.currentUpload.fileName,
|
||||||
|
count: this.state.uploadsHere.length - 1,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
const uploadSize = filesize(this.state.currentUpload.total);
|
||||||
|
return (
|
||||||
|
<div className="mx_UploadBar">
|
||||||
|
<div className="mx_UploadBar_filename">{uploadText} ({uploadSize})</div>
|
||||||
|
<AccessibleButton onClick={this.onCancelClick} className='mx_UploadBar_cancel' />
|
||||||
|
<ProgressBar value={this.state.currentUpload.loaded} max={this.state.currentUpload.total} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -113,4 +113,29 @@ export enum Action {
|
||||||
* XXX: Ditto
|
* XXX: Ditto
|
||||||
*/
|
*/
|
||||||
VirtualRoomSupportUpdated = "virtual_room_support_updated",
|
VirtualRoomSupportUpdated = "virtual_room_support_updated",
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fired when an upload has started. Should be used with UploadStartedPayload.
|
||||||
|
*/
|
||||||
|
UploadStarted = "upload_started",
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fired when an upload makes progress. Should be used with UploadProgressPayload.
|
||||||
|
*/
|
||||||
|
UploadProgress = "upload_progress",
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fired when an upload is completed. Should be used with UploadFinishedPayload.
|
||||||
|
*/
|
||||||
|
UploadFinished = "upload_finished",
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fired when an upload fails. Should be used with UploadErrorPayload.
|
||||||
|
*/
|
||||||
|
UploadFailed = "upload_failed",
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fired when an upload is cancelled by the user. Should be used with UploadCanceledPayload.
|
||||||
|
*/
|
||||||
|
UploadCanceled = "upload_canceled",
|
||||||
}
|
}
|
||||||
|
|
51
src/dispatcher/payloads/UploadPayload.ts
Normal file
51
src/dispatcher/payloads/UploadPayload.ts
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
/*
|
||||||
|
Copyright 2021 The Matrix.org Foundation C.I.C.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { ActionPayload } from "../payloads";
|
||||||
|
import { Action } from "../actions";
|
||||||
|
import {IUpload} from "../../models/IUpload";
|
||||||
|
|
||||||
|
interface UploadPayload extends ActionPayload {
|
||||||
|
/**
|
||||||
|
* The upload with fields representing the new upload state.
|
||||||
|
*/
|
||||||
|
upload: IUpload;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface UploadStartedPayload extends UploadPayload {
|
||||||
|
action: Action.UploadStarted;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface UploadProgressPayload extends UploadPayload {
|
||||||
|
action: Action.UploadProgress;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface UploadErrorPayload extends UploadPayload {
|
||||||
|
action: Action.UploadFailed;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An error to describe what went wrong with the upload.
|
||||||
|
*/
|
||||||
|
error: Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface UploadFinishedPayload extends UploadPayload {
|
||||||
|
action: Action.UploadFinished;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface UploadCanceledPayload extends UploadPayload {
|
||||||
|
action: Action.UploadCanceled;
|
||||||
|
}
|
24
src/models/IUpload.ts
Normal file
24
src/models/IUpload.ts
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
/*
|
||||||
|
Copyright 2021 The Matrix.org Foundation C.I.C.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
export interface IUpload {
|
||||||
|
fileName: string;
|
||||||
|
roomId: string;
|
||||||
|
total: number;
|
||||||
|
loaded: number;
|
||||||
|
promise: Promise<any>;
|
||||||
|
canceled?: boolean;
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue