diff options
| author | Janito Vaqueiro Ferreira Filho <janito@mullvad.net> | 2018-12-08 11:15:13 -0200 |
|---|---|---|
| committer | Andrej Mihajlov <and@mullvad.net> | 2019-01-15 16:16:20 +0100 |
| commit | b589b008a014a2ea3733796bc31121acd391b1a6 (patch) | |
| tree | 44a6ed46a7956ab224474f92b2014cbec432574a /gui/packages | |
| parent | e094b526b94bf75ccf25fc5e575cc641a62071ab (diff) | |
| download | mullvadvpn-b589b008a014a2ea3733796bc31121acd391b1a6.tar.xz mullvadvpn-b589b008a014a2ea3733796bc31121acd391b1a6.zip | |
Add custom modal container
Diffstat (limited to 'gui/packages')
| -rw-r--r-- | gui/packages/components/src/Modal.tsx | 52 | ||||
| -rw-r--r-- | gui/packages/components/src/index.ts | 1 | ||||
| -rw-r--r-- | gui/packages/desktop/src/renderer/components/Support.js | 174 | ||||
| -rw-r--r-- | gui/packages/desktop/src/renderer/components/SupportStyles.js | 22 |
4 files changed, 181 insertions, 68 deletions
diff --git a/gui/packages/components/src/Modal.tsx b/gui/packages/components/src/Modal.tsx new file mode 100644 index 0000000000..6eb070262b --- /dev/null +++ b/gui/packages/components/src/Modal.tsx @@ -0,0 +1,52 @@ +import * as React from 'react'; + +export class ModalContent extends React.Component { + public render() { + return ( + <div + style={{ + position: 'absolute', + display: 'flex', + flexDirection: 'column', + flex: 1, + top: 0, + left: 0, + right: 0, + bottom: 0, + }}> + {this.props.children} + </div> + ); + } +} + +export class ModalAlert extends React.Component { + public render() { + return ( + <div + style={{ + backgroundColor: 'rgba(0,0,0,0.5)', + position: 'absolute', + display: 'flex', + flexDirection: 'column', + flex: 1, + top: 0, + left: 0, + right: 0, + bottom: 0, + }}> + {this.props.children} + </div> + ); + } +} + +interface IModalContainerProps { + children?: Array<React.ReactElement<ModalContent | ModalAlert>>; +} + +export class ModalContainer extends React.Component<IModalContainerProps> { + public render() { + return <div style={{ position: 'relative', flex: 1 }}>{this.props.children}</div>; + } +} diff --git a/gui/packages/components/src/index.ts b/gui/packages/components/src/index.ts index 46c4ec3195..31c5ee6fec 100644 --- a/gui/packages/components/src/index.ts +++ b/gui/packages/components/src/index.ts @@ -5,3 +5,4 @@ export { default as SecuredLabel, SecuredDisplayStyle } from './SecuredLabel'; export { default as HeaderBar, HeaderBarStyle, Brand, SettingsBarButton } from './HeaderBar'; export { default as SettingsHeader, HeaderTitle, HeaderSubTitle } from './SettingsHeader'; export { default as ImageView } from './ImageView'; +export { ModalContainer, ModalAlert, ModalContent } from './Modal'; diff --git a/gui/packages/desktop/src/renderer/components/Support.js b/gui/packages/desktop/src/renderer/components/Support.js index 7db2f7458b..0398976589 100644 --- a/gui/packages/desktop/src/renderer/components/Support.js +++ b/gui/packages/desktop/src/renderer/components/Support.js @@ -2,7 +2,15 @@ import * as React from 'react'; import { Component, Text, View, TextInput } from 'reactxp'; -import { ImageView, SettingsHeader, HeaderTitle, HeaderSubTitle } from '@mullvad/components'; +import { + ImageView, + SettingsHeader, + HeaderTitle, + HeaderSubTitle, + ModalContainer, + ModalContent, + ModalAlert, +} from '@mullvad/components'; import * as AppButton from './AppButton'; import { Layout, Container } from './Layout'; import { NavigationBar, BackBarItem } from './NavigationBar'; @@ -14,7 +22,7 @@ type SupportState = { email: string, message: string, savedReport: ?string, - sendState: 'INITIAL' | 'CONFIRM_NO_EMAIL' | 'LOADING' | 'SUCCESS' | 'FAILED', + sendState: 'INITIAL' | 'CONFIRM' | 'LOADING' | 'SUCCESS' | 'FAILED', }; export type SupportProps = { @@ -103,17 +111,36 @@ export default class Support extends Component<SupportProps, SupportState> { } onSend = async (): Promise<void> => { - if (this.state.sendState === 'INITIAL' && this.state.email.length === 0) { - return new Promise((resolve) => { - this.setState({ sendState: 'CONFIRM_NO_EMAIL' }, () => resolve()); - }); - } else { - try { - await this._sendReport(); - } catch (error) { - // No-op - } + switch (this.state.sendState) { + case 'INITIAL': + if (this.state.email.length === 0) { + this.setState({ sendState: 'CONFIRM' }); + } else { + try { + await this._sendReport(); + } catch (error) { + // No-op + } + } + return Promise.resolve(); + + case 'CONFIRM': + try { + await this._sendReport(); + } catch (error) { + // No-op + } + return Promise.resolve(); + + default: + break; } + + return Promise.resolve(); + }; + + onCancelConfirmation = () => { + this.setState({ sendState: 'INITIAL' }); }; _sendReport(): Promise<void> { @@ -141,7 +168,7 @@ export default class Support extends Component<SupportProps, SupportState> { const header = ( <SettingsHeader> <HeaderTitle>Report a problem</HeaderTitle> - {(sendState === 'INITIAL' || sendState === 'CONFIRM_NO_EMAIL') && ( + {(sendState === 'INITIAL' || sendState === 'CONFIRM') && ( <HeaderSubTitle> { "To help you more effectively, your app's log file will be attached to this message. Your data will remain secure and private, as it is anonymised before being sent over an encrypted channel." @@ -156,17 +183,20 @@ export default class Support extends Component<SupportProps, SupportState> { return ( <Layout> <Container> - <View style={styles.support}> - <NavigationBar> - <BackBarItem action={this.props.onClose} title={'Settings'} /> - </NavigationBar> - - <View style={styles.support__container}> - {header} - - {content} - </View> - </View> + <ModalContainer> + <ModalContent> + <View style={styles.support}> + <NavigationBar> + <BackBarItem action={this.props.onClose} title={'Settings'} /> + </NavigationBar> + <View style={styles.support__container}> + {header} + {content} + </View> + </View> + </ModalContent> + {sendState === 'CONFIRM' && <ModalAlert>{this._renderConfirm()}</ModalAlert>} + </ModalContainer> </Container> </Layout> ); @@ -175,7 +205,7 @@ export default class Support extends Component<SupportProps, SupportState> { _renderContent() { switch (this.state.sendState) { case 'INITIAL': - case 'CONFIRM_NO_EMAIL': + case 'CONFIRM': return this._renderForm(); case 'LOADING': return this._renderLoading(); @@ -188,6 +218,10 @@ export default class Support extends Component<SupportProps, SupportState> { } } + _renderConfirm() { + return <ConfirmNoEmailDialog onConfirm={this.onSend} onDismiss={this.onCancelConfirmation} />; + } + _renderForm() { return ( <View style={styles.support__content}> @@ -214,52 +248,25 @@ export default class Support extends Component<SupportProps, SupportState> { </View> </View> <View style={styles.support__footer}> - {this.state.sendState === 'CONFIRM_NO_EMAIL' - ? this._renderNoEmailWarning() - : this._renderActionButtons()} + <AppButton.BlueButton + style={styles.view_logs_button} + onPress={this.onViewLog} + testName="support__view_logs"> + <AppButton.Label>View app logs</AppButton.Label> + <ImageView source="icon-extLink" height={16} width={16} /> + </AppButton.BlueButton> + <AppButton.GreenButton + disabled={!this.validate()} + onPress={this.onSend} + testName="support__send_logs"> + Send + </AppButton.GreenButton> </View> </View> </View> ); } - _renderNoEmailWarning() { - return ( - <View> - <Text style={styles.support__no_email_warning}> - You are about to send the problem report without a way for us to get back to you. If you - want an answer to your report you will have to enter an email address. - </Text> - <AppButton.GreenButton - disabled={!this.validate()} - onPress={this.onSend} - testName="support__send_logs"> - {'Send anyway'} - </AppButton.GreenButton> - </View> - ); - } - - _renderActionButtons() { - return ( - <View> - <AppButton.BlueButton - style={styles.view_logs_button} - onPress={this.onViewLog} - testName="support__view_logs"> - <AppButton.Label>View app logs</AppButton.Label> - <ImageView source="icon-extLink" height={16} width={16} /> - </AppButton.BlueButton> - <AppButton.GreenButton - disabled={!this.validate() || this.props.isOffline} - onPress={this.onSend} - testName="support__send_logs"> - Send - </AppButton.GreenButton> - </View> - ); - } - _renderLoading() { return ( <View style={styles.support__content}> @@ -331,3 +338,40 @@ export default class Support extends Component<SupportProps, SupportState> { ); } } + +type ConfirmNoEmailDialogProps = { + onConfirm: () => void, + onDismiss: () => void, +}; + +class ConfirmNoEmailDialog extends Component<ConfirmNoEmailDialogProps> { + render() { + return ( + <View style={styles.confirm_no_email_background}> + <View style={styles.confirm_no_email_dialog}> + <Text style={styles.confirm_no_email_warning}> + You are about to send the problem report without a way for us to get back to you. If you + want an answer to your report you will have to enter an email address. + </Text> + <AppButton.GreenButton onPress={this.props.onConfirm} testName="support__send_logs"> + {'Send anyway'} + </AppButton.GreenButton> + <AppButton.RedButton + onPress={this._dismiss} + style={styles.confirm_no_email_back_button} + testName="support__back"> + {'Back'} + </AppButton.RedButton> + </View> + </View> + ); + } + + _confirm = () => { + this.props.onConfirm(); + }; + + _dismiss = () => { + this.props.onDismiss(); + }; +} diff --git a/gui/packages/desktop/src/renderer/components/SupportStyles.js b/gui/packages/desktop/src/renderer/components/SupportStyles.js index e3b8491862..c2b4e2dbb7 100644 --- a/gui/packages/desktop/src/renderer/components/SupportStyles.js +++ b/gui/packages/desktop/src/renderer/components/SupportStyles.js @@ -119,11 +119,27 @@ export default { color: colors.white, marginBottom: 4, }), - support__no_email_warning: Styles.createTextStyle({ + confirm_no_email_background: Styles.createViewStyle({ + display: 'flex', + flex: 1, + justifyContent: 'center', + paddingLeft: 14, + paddingRight: 14, + }), + confirm_no_email_dialog: Styles.createViewStyle({ + backgroundColor: colors.darkBlue, + borderRadius: 11, + padding: 16, + }), + confirm_no_email_warning: Styles.createTextStyle({ fontFamily: 'Open Sans', - fontSize: 13, - lineHeight: 16, + fontSize: 16, + fontWeight: '500', + lineHeight: 20, color: colors.white80, marginBottom: 12, }), + confirm_no_email_back_button: Styles.createViewStyle({ + marginTop: 16, + }), }; |
