From 269f9a5ccc0a60ef6289de19616d3048d3a13459 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Wed, 12 Apr 2017 11:20:42 +0100 Subject: [PATCH 1/3] Load submit-rageshake asynchronously ... because it's 250K :/ --- .../views/dialogs/BugReportDialog.js | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/components/views/dialogs/BugReportDialog.js b/src/components/views/dialogs/BugReportDialog.js index badc994b..8db796ee 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 { @@ -48,14 +47,17 @@ 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}` }); + + require(['../../../vector/submit-rageshake'], (s) => { + s(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}` }); + }); }); } From d8bf57edc53f5266306dcd45491619e5bf389ef0 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Wed, 12 Apr 2017 14:53:47 +0100 Subject: [PATCH 2/3] Add progress reporting to rageshake submission --- .../views/dialogs/BugReportDialog.js | 41 ++++++++++++++++--- src/vector/submit-rageshake.js | 19 +++++++-- 2 files changed, 51 insertions(+), 9 deletions(-) diff --git a/src/components/views/dialogs/BugReportDialog.js b/src/components/views/dialogs/BugReportDialog.js index 8db796ee..92b3c4b1 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 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(); } }; From 25907301a3e4b13db87bc7421a88fd2933de7590 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Tue, 18 Apr 2017 12:53:15 +0100 Subject: [PATCH 3/3] More unmounted guards in BugReportDialog --- src/components/views/dialogs/BugReportDialog.js | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/components/views/dialogs/BugReportDialog.js b/src/components/views/dialogs/BugReportDialog.js index 92b3c4b1..7a65ac58 100644 --- a/src/components/views/dialogs/BugReportDialog.js +++ b/src/components/views/dialogs/BugReportDialog.js @@ -62,13 +62,17 @@ export default class BugReportDialog extends React.Component { sendLogs: sendLogs, progressCallback: this._sendProgressCallback, }).then(() => { - this.setState({ busy: false, progress: null }); - this.props.onFinished(false); + if (!this._unmounted) { + this.setState({ busy: false, progress: null }); + this.props.onFinished(false); + } }, (err) => { - this.setState({ - busy: false, progress: null, - err: `Failed to send report: ${err.message}`, - }); + if (!this._unmounted) { + this.setState({ + busy: false, progress: null, + err: `Failed to send report: ${err.message}`, + }); + } }); }); }