diff --git a/src/components/views/dialogs/BugReportDialog.js b/src/components/views/dialogs/BugReportDialog.js index 8db796eebc..92b3c4b1b9 100644 --- a/src/components/views/dialogs/BugReportDialog.js +++ b/src/components/views/dialogs/BugReportDialog.js @@ -26,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) { @@ -46,17 +53,22 @@ export default class BugReportDialog extends React.Component { }); return; } - this.setState({ busy: true, err: null }); + 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(() => { - this.setState({ busy: false }); + this.setState({ busy: false, progress: null }); this.props.onFinished(false); }, (err) => { - this.setState({ busy: false, err: `Failed: ${err.message}` }); + this.setState({ + busy: false, progress: null, + err: `Failed to send report: ${err.message}`, + }); }); }); } @@ -69,6 +81,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"); @@ -79,8 +98,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 (
@@ -110,6 +137,7 @@ export default class BugReportDialog extends React.Component { + {progress} {error}
@@ -117,8 +145,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 7430e3bee7..6ed49a1f5e 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(); } };