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

Commit

Permalink
Move upload verification logic to RoomView.
Browse files Browse the repository at this point in the history
Improve upload dialog ux
  • Loading branch information
Half-Shot committed Jun 23, 2018
1 parent 736b76b commit 541f1d7
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 33 deletions.
55 changes: 35 additions & 20 deletions src/components/structures/RoomView.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ const React = require("react");
const ReactDOM = require("react-dom");
import PropTypes from 'prop-types';
import Promise from 'bluebird';
import filesize from 'filesize';
const classNames = require("classnames");
import { _t } from '../../languageHandler';

Expand All @@ -49,8 +50,6 @@ import SettingsStore, {SettingLevel} from "../../settings/SettingsStore";
const DEBUG = false;
let debuglog = function() {};

let mediaLimitCache = null;

const BROWSER_SUPPORTS_SANDBOX = 'sandbox' in document.createElement('iframe');

if (DEBUG) {
Expand Down Expand Up @@ -96,9 +95,9 @@ module.exports = React.createClass({
roomLoading: true,
peekLoading: false,
shouldPeek: true,
// Media limits for uploading, this may change.
mediaLimits: {},

// Media limits for uploading.
mediaConfig: undefined,

// The event to be scrolled to initially
initialEventId: null,
Expand Down Expand Up @@ -152,24 +151,31 @@ module.exports = React.createClass({
MatrixClientPeg.get().on("RoomState.members", this.onRoomStateMember);
MatrixClientPeg.get().on("RoomMember.membership", this.onRoomMemberMembership);
MatrixClientPeg.get().on("accountData", this.onAccountData);
this._fetchMediaLimits();
this._fetchMediaConfig();
// Start listening for RoomViewStore updates
this._roomStoreToken = RoomViewStore.addListener(this._onRoomViewStoreUpdate);
this._onRoomViewStoreUpdate(true);
},

_fetchMediaLimits: function(invalidateCache: boolean = false) {
let limits;
if(invalidateCache || mediaLimitCache == null) {
MatrixClientPeg.get().getMediaLimits().then((_limits) => {
limits = _limits;
}).catch(() => {
// Media repo can't or won't report limits, so provide an empty object (no limits).
limits = {};
});
mediaLimitCache = limits;
_fetchMediaConfig: function(invalidateCache: boolean = false) {
/// NOTE: Using global here so we don't make repeated requests for the
/// config every time we swap room.
if(global.mediaConfig !== undefined && !invalidateCache) {
this.setState({mediaConfig: global.mediaConfig});
return;
}
this.state.mediaLimits = limits;
console.log("[Media Config] Fetching");
MatrixClientPeg.get().getMediaConfig().then((config) => {
console.log("[Media Config] Fetched config:", config);
return config;
}).catch(() => {
// Media repo can't or won't report limits, so provide an empty object (no limits).
console.log("[Media Config] Could not fetch config, so not limiting uploads.");
return {};
}).then((config) => {
global.mediaConfig = config;
this.setState({mediaConfig: config});
});
},

_onRoomViewStoreUpdate: function(initial) {
Expand Down Expand Up @@ -501,8 +507,8 @@ module.exports = React.createClass({
case 'notifier_enabled':
case 'upload_failed':
// 413: File was too big or upset the server in some way.
if(payload.data.error.http_status === 413) {
this._fetchMediaLimits(true);
if(payload.error.http_status === 413) {
this._fetchMediaConfig(true);
}
case 'upload_started':
case 'upload_finished':
Expand Down Expand Up @@ -935,6 +941,15 @@ module.exports = React.createClass({
this.setState({ draggingFile: false });
},

isFileUploadAllowed(file) {
if (this.state.mediaConfig !== undefined &&
this.state.mediaConfig["m.upload.size"] !== undefined &&
file.size > this.state.mediaConfig["m.upload.size"]) {
return _t("File is too big. Maximum file size is %(fileSize)s", {fileSize: filesize(this.state.mediaConfig["m.upload.size"])});
}
return true;
},

uploadFile: async function(file) {
dis.dispatch({action: 'focus_composer'});

Expand Down Expand Up @@ -1677,7 +1692,7 @@ module.exports = React.createClass({
callState={this.state.callState}
disabled={this.props.disabled}
showApps={this.state.showApps}
mediaLimits={this.state.mediaLimits}
uploadAllowed={this.isFileUploadAllowed}
/>;
}

Expand Down
25 changes: 12 additions & 13 deletions src/components/views/rooms/MessageComposer.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ limitations under the License.
*/
import React from 'react';
import PropTypes from 'prop-types';
import filesize from 'filesize';
import { _t } from '../../../languageHandler';
import CallHandler from '../../../CallHandler';
import MatrixClientPeg from '../../../MatrixClientPeg';
Expand Down Expand Up @@ -102,15 +101,6 @@ export default class MessageComposer extends React.Component {
this.uploadFiles(tfiles);
}

isFileUploadAllowed(file) {
if (this.props.mediaLimits !== undefined &&
this.props.mediaLimits.upload_size !== undefined &&
file.size > this.props.mediaLimits.upload_size) {
return _t("File is too big. Maximum file size is %(fileSize)s", {fileSize: filesize(this.mediaLimits.upload_size)});
}
return true;
}

uploadFiles(files) {
const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
const TintableSvg = sdk.getComponent("elements.TintableSvg");
Expand All @@ -120,15 +110,15 @@ export default class MessageComposer extends React.Component {
const failedFiles = [];

for (let i=0; i<files.length; i++) {
const fileAcceptedOrError = this.isFileUploadAllowed(files[i]);
const fileAcceptedOrError = this.props.uploadAllowed(files[i]);
if (fileAcceptedOrError === true) {
acceptedFiles.push(<li key={i}>
<TintableSvg key={i} src="img/files.svg" width="16" height="16" /> { files[i].name || _t('Attachment') }
</li>);
fileList.push(files[i]);
} else {
failedFiles.push(<li key={i}>
<TintableSvg key={i} src="img/files.svg" width="16" height="16" /> { files[i].name || _t('Attachment') } <b>{ _t('Reason') + ": " + fileAcceptedOrError}</b>
<TintableSvg key={i} src="img/files.svg" width="16" height="16" /> { files[i].name || _t('Attachment') } <p>{ _t('Reason') + ": " + fileAcceptedOrError}</p>
</li>);
}
}
Expand Down Expand Up @@ -158,6 +148,12 @@ export default class MessageComposer extends React.Component {
</ul>
</div>
);
let buttonText;
if (acceptedFiles.length > 0 && failedFiles.length > 0) {
buttonText = "Upload selected"
} else if (failedFiles.length > 0) {
buttonText = "Close"
}

Modal.createTrackedDialog('Upload Files confirmation', '', QuestionDialog, {
title: _t('Upload Files'),
Expand All @@ -168,6 +164,8 @@ export default class MessageComposer extends React.Component {
{ replyToWarning }
</div>
),
hasCancelButton: acceptedFiles.length > 0,
button: buttonText,
onFinished: (shouldUpload) => {
if (shouldUpload) {
// MessageComposer shouldn't have to rely on its parent passing in a callback to upload a file
Expand Down Expand Up @@ -425,7 +423,8 @@ MessageComposer.propTypes = {
// callback when a file to upload is chosen
uploadFile: PropTypes.func.isRequired,

mediaLimits: PropTypes.object,
// function to test whether a file should be allowed to be uploaded.
uploadAllowed: PropTypes.func.isRequired,

// string representing the current room app drawer state
showApps: PropTypes.bool
Expand Down

0 comments on commit 541f1d7

Please sign in to comment.