diff --git a/src/components/views/dialogs/BugReportDialog.js b/src/components/views/dialogs/BugReportDialog.js index badc994b..7a65ac58 100644 --- a/src/components/views/dialogs/BugReportDialog.js +++ b/src/components/views/dialogs/BugReportDialog.js @@ -16,7 +16,6 @@ limitations under the License. import React from 'react'; import sdk from 'matrix-react-sdk'; -import submit_rageshake from '../../../vector/submit-rageshake'; import SdkConfig from 'matrix-react-sdk/lib/SdkConfig'; export default class BugReportDialog extends React.Component { @@ -27,11 +26,18 @@ export default class BugReportDialog extends React.Component { busy: false, err: null, text: "", + progress: null, }; + this._unmounted = false; this._onSubmit = this._onSubmit.bind(this); this._onCancel = this._onCancel.bind(this); this._onTextChange = this._onTextChange.bind(this); this._onSendLogsChange = this._onSendLogsChange.bind(this); + this._sendProgressCallback = this._sendProgressCallback.bind(this); + } + + componentWillUnmount() { + this._unmounted = true; } _onCancel(ev) { @@ -47,15 +53,27 @@ export default class BugReportDialog extends React.Component { }); return; } - this.setState({ busy: true, err: null }); - submit_rageshake(SdkConfig.get().bug_report_endpoint_url, { - userText: userText, - sendLogs: sendLogs, - }).then(() => { - this.setState({ busy: false }); - this.props.onFinished(false); - }, (err) => { - this.setState({ busy: false, err: `Failed: ${err.message}` }); + this.setState({ busy: true, progress: null, err: null }); + this._sendProgressCallback("Loading bug report module"); + + require(['../../../vector/submit-rageshake'], (s) => { + s(SdkConfig.get().bug_report_endpoint_url, { + userText: userText, + sendLogs: sendLogs, + progressCallback: this._sendProgressCallback, + }).then(() => { + if (!this._unmounted) { + this.setState({ busy: false, progress: null }); + this.props.onFinished(false); + } + }, (err) => { + if (!this._unmounted) { + this.setState({ + busy: false, progress: null, + err: `Failed to send report: ${err.message}`, + }); + } + }); }); } @@ -67,6 +85,13 @@ export default class BugReportDialog extends React.Component { this.setState({ sendLogs: ev.target.checked }); } + _sendProgressCallback(progress) { + if (this._unmounted) { + return; + } + this.setState({progress: progress}); + } + render() { const Loader = sdk.getComponent("elements.Spinner"); @@ -77,8 +102,6 @@ export default class BugReportDialog extends React.Component { ; } - const okLabel = this.state.busy ? : 'Send'; - let cancelButton = null; if (!this.state.busy) { cancelButton = ; } + let progress = null; + if (this.state.busy) { + progress = ( +
+ + {this.state.progress} ... +
+ ); + } + return (
@@ -108,6 +141,7 @@ export default class BugReportDialog extends React.Component { + {progress} {error}
@@ -115,8 +149,9 @@ export default class BugReportDialog extends React.Component { className="mx_Dialog_primary danger" onClick={this._onSubmit} autoFocus={true} + disabled={this.state.busy} > - {okLabel} + Send {cancelButton} diff --git a/src/vector/submit-rageshake.js b/src/vector/submit-rageshake.js index 7430e3be..6ed49a1f 100644 --- a/src/vector/submit-rageshake.js +++ b/src/vector/submit-rageshake.js @@ -30,10 +30,17 @@ if (!TextEncoder) { /** * Send a bug report. + * * @param {string} bugReportEndpoint HTTP url to send the report to + * * @param {object} opts optional dictionary of options + * * @param {string} opts.userText Any additional user input. + * * @param {boolean} opts.sendLogs True to send logs + * + * @param {function(string)} opts.progressCallback Callback to call with progress updates + * * @return {Promise} Resolved when the bug report is sent. */ export default async function sendBugReport(bugReportEndpoint, opts) { @@ -42,7 +49,9 @@ export default async function sendBugReport(bugReportEndpoint, opts) { } opts = opts || {}; + const progressCallback = opts.progressCallback || (() => {}); + progressCallback("Collecting app version information"); let version = "UNKNOWN"; try { version = await PlatformPeg.get().getAppVersion(); @@ -63,6 +72,7 @@ export default async function sendBugReport(bugReportEndpoint, opts) { body.append('user_agent', userAgent); if (opts.sendLogs) { + progressCallback("Collecting logs"); const logs = await rageshake.getLogsForReport(); for (let entry of logs) { // encode as UTF-8 @@ -72,17 +82,20 @@ export default async function sendBugReport(bugReportEndpoint, opts) { } } - await _submitReport(bugReportEndpoint, body); + progressCallback("Uploading report"); + await _submitReport(bugReportEndpoint, body, progressCallback); } -function _submitReport(endpoint, body) { +function _submitReport(endpoint, body, progressCallback) { const deferred = q.defer(); const req = new XMLHttpRequest(); req.open("POST", endpoint); req.timeout = 5 * 60 * 1000; req.onreadystatechange = function() { - if (req.readyState === XMLHttpRequest.DONE) { + if (req.readyState === XMLHttpRequest.LOADING) { + progressCallback("Waiting for response from server"); + } else if (req.readyState === XMLHttpRequest.DONE) { on_done(); } };