summaryrefslogtreecommitdiffhomepage
path: root/app/components
diff options
context:
space:
mode:
authorAndrej Mihajlov <and@mullvad.net>2018-07-05 13:49:10 +0200
committerAndrej Mihajlov <and@mullvad.net>2018-07-05 17:13:43 +0200
commit7b5bc3ce5f182f83437aae244dd9772a8d51f072 (patch)
tree76fed1c3d9f608e0ae6821b8eeccb112062ba1ee /app/components
parent6403d3b357a247c7601edf40bcd4e06f5d85addf (diff)
downloadmullvadvpn-7b5bc3ce5f182f83437aae244dd9772a8d51f072.tar.xz
mullvadvpn-7b5bc3ce5f182f83437aae244dd9772a8d51f072.zip
Add initial form data to Support form, save form data when failed to submit the problem report
Diffstat (limited to 'app/components')
-rw-r--r--app/components/Support.js136
1 files changed, 84 insertions, 52 deletions
diff --git a/app/components/Support.js b/app/components/Support.js
index 7897f594ec..1f03d67375 100644
--- a/app/components/Support.js
+++ b/app/components/Support.js
@@ -6,14 +6,8 @@ import { Layout, Container } from './Layout';
import styles from './SupportStyles';
import Img from './Img';
-import type { AccountReduxState } from '../redux/account/reducers';
-
-export type SupportReport = {
- email: string,
- message: string,
- savedReport: ?string,
-};
-
+import type { AccountToken } from '../lib/daemon-rpc';
+import type { SupportReportForm } from '../redux/support/actions';
type SupportState = {
email: string,
message: string,
@@ -22,11 +16,15 @@ type SupportState = {
};
export type SupportProps = {
- account: AccountReduxState,
+ defaultEmail: string,
+ defaultMessage: string,
+ accountHistory: Array<AccountToken>,
onClose: () => void,
- onViewLog: (string) => void,
- onCollectLog: (Array<string>) => Promise<string>,
- onSend: (email: string, message: string, savedReport: string) => void,
+ viewLog: (path: string) => void,
+ saveReportForm: (form: SupportReportForm) => void,
+ clearReportForm: () => void,
+ collectProblemReport: (accountsToRedact: Array<string>) => Promise<string>,
+ sendProblemReport: (email: string, message: string, savedReport: string) => Promise<void>,
};
export default class Support extends Component<SupportProps, SupportState> {
@@ -37,68 +35,102 @@ export default class Support extends Component<SupportProps, SupportState> {
sendState: 'INITIAL',
};
+ _collectLogPromise: ?Promise<string>;
+
+ constructor(props: SupportProps) {
+ super(props);
+
+ // seed initial data from props
+ this.state.email = props.defaultEmail;
+ this.state.message = props.defaultMessage;
+ }
+
validate() {
return this.state.message.trim().length > 0;
}
onChangeEmail = (email: string) => {
- this.setState({ email: email });
+ this.setState({ email: email }, () => {
+ this._saveFormData();
+ });
};
onChangeDescription = (description: string) => {
- this.setState({ message: description });
+ this.setState({ message: description }, () => {
+ this._saveFormData();
+ });
};
- onViewLog = () => {
- this._getLog().then((path) => {
- this.props.onViewLog(path);
- });
+ onViewLog = async (): Promise<void> => {
+ try {
+ const reportPath = await this._collectLog();
+ this.props.viewLog(reportPath);
+ } catch (error) {
+ // TODO: handle error
+ }
};
- _getLog(): Promise<string> {
- const accountsToRedact = this.props.account.accountHistory;
- const { savedReport } = this.state;
- return savedReport
- ? Promise.resolve(savedReport)
- : this.props.onCollectLog(accountsToRedact).then((path) => {
- return new Promise((resolve) =>
- this.setState({ savedReport: path }, () => resolve(path)),
- );
+ _saveFormData() {
+ this.props.saveReportForm({
+ email: this.state.email,
+ message: this.state.message,
+ });
+ }
+
+ async _collectLog(): Promise<string> {
+ if (this._collectLogPromise) {
+ return this._collectLogPromise;
+ } else {
+ const collectPromise = this.props.collectProblemReport(this.props.accountHistory);
+
+ // save promise to prevent subsequent requests
+ this._collectLogPromise = collectPromise;
+
+ try {
+ const reportPath = await collectPromise;
+ return new Promise((resolve) => {
+ this.setState({ savedReport: reportPath }, () => resolve(reportPath));
});
+ } catch (error) {
+ this._collectLogPromise = null;
+
+ throw error;
+ }
+ }
}
- onSend = () => {
+ onSend = async (): Promise<void> => {
if (this.state.sendState === 'INITIAL' && this.state.email.length === 0) {
- this.setState({
- sendState: 'CONFIRM_NO_EMAIL',
+ return new Promise((resolve) => {
+ this.setState({ sendState: 'CONFIRM_NO_EMAIL' }, () => resolve());
});
} else {
- this._sendProblemReport();
+ try {
+ await this._sendReport();
+ } catch (error) {
+ // No-op
+ }
}
};
- _sendProblemReport() {
- this.setState(
- {
- sendState: 'LOADING',
- },
- () => {
- this._getLog()
- .then((path) => {
- return this.props.onSend(this.state.email, this.state.message, path);
- })
- .then(() => {
- this.setState({
- sendState: 'SUCCESS',
- });
- })
- .catch(() => {
- this.setState({
- sendState: 'FAILED',
- });
+ _sendReport(): Promise<void> {
+ return new Promise((resolve, reject) => {
+ this.setState({ sendState: 'LOADING' }, async () => {
+ try {
+ const { email, message } = this.state;
+ const reportPath = await this._collectLog();
+ await this.props.sendProblemReport(email, message, reportPath);
+ this.props.clearReportForm();
+ this.setState({ sendState: 'SUCCESS' }, () => {
+ resolve();
});
- },
- );
+ } catch (error) {
+ this.setState({ sendState: 'FAILED' }, () => {
+ reject(error);
+ });
+ }
+ });
+ });
}
render() {