diff options
| author | Janito Vaqueiro Ferreira Filho <janito@mullvad.net> | 2018-10-02 08:18:26 -0300 |
|---|---|---|
| committer | Janito Vaqueiro Ferreira Filho <janito@mullvad.net> | 2018-10-02 08:18:26 -0300 |
| commit | d020ffbb3ca132fb9b51238014ffe8ea93fe9996 (patch) | |
| tree | 26afb4209936fc1192995aada30c89d93fdd4446 /gui | |
| parent | 41aef511ad4593106bcaf3c2e6db658af9d5e3a8 (diff) | |
| parent | ed57f26c5510b9f2620276483000922f9ad9d317 (diff) | |
| download | mullvadvpn-d020ffbb3ca132fb9b51238014ffe8ea93fe9996.tar.xz mullvadvpn-d020ffbb3ca132fb9b51238014ffe8ea93fe9996.zip | |
Merge branch 'cell-gui-refactor'
Diffstat (limited to 'gui')
10 files changed, 179 insertions, 214 deletions
diff --git a/gui/packages/desktop/src/renderer/components/Account.js b/gui/packages/desktop/src/renderer/components/Account.js index 319bbe3c58..1dbb896bf6 100644 --- a/gui/packages/desktop/src/renderer/components/Account.js +++ b/gui/packages/desktop/src/renderer/components/Account.js @@ -23,14 +23,6 @@ type Props = { }; export default class Account extends Component<Props> { - _copyTimer: ?TimeoutID; - - componentWillUnmount() { - if (this._copyTimer) { - clearTimeout(this._copyTimer); - } - } - render() { return ( <Layout> diff --git a/gui/packages/desktop/src/renderer/components/AdvancedSettings.js b/gui/packages/desktop/src/renderer/components/AdvancedSettings.js index 3763e9687d..8602b48b75 100644 --- a/gui/packages/desktop/src/renderer/components/AdvancedSettings.js +++ b/gui/packages/desktop/src/renderer/components/AdvancedSettings.js @@ -2,6 +2,7 @@ import * as React from 'react'; import { Button, Component, Text, View } from 'reactxp'; +import * as Cell from './Cell'; import { Layout, Container } from './Layout'; import NavigationBar, { BackBarItem } from './NavigationBar'; import SettingsHeader, { HeaderTitle } from './SettingsHeader'; @@ -10,7 +11,7 @@ import Switch from './Switch'; import styles from './AdvancedSettingsStyles'; import Img from './Img'; -type AdvancedSettingsProps = { +type Props = { enableIpv6: boolean, protocol: string, port: string | number, @@ -19,7 +20,7 @@ type AdvancedSettingsProps = { onClose: () => void, }; -export class AdvancedSettings extends Component<AdvancedSettingsProps> { +export class AdvancedSettings extends Component<Props> { render() { let portSelector = null; let protocol = this.props.protocol.toUpperCase(); @@ -43,19 +44,11 @@ export class AdvancedSettings extends Component<AdvancedSettingsProps> { <HeaderTitle>Advanced</HeaderTitle> </SettingsHeader> <CustomScrollbars style={styles.advanced_settings__scrollview} autoHide={true}> - <View style={styles.advanced_settings__ipv6}> - <View style={styles.advanced_settings__cell_label_container}> - <Text style={styles.advanced_settings__cell_label}>Enable IPv6</Text> - </View> - <View style={styles.advanced_settings__ipv6_accessory}> - <Switch isOn={this.props.enableIpv6} onChange={this.props.setEnableIpv6} /> - </View> - </View> - <View style={styles.advanced_settings__cell_footer}> - <Text style={styles.advanced_settings__cell_footer_label}> - {'Enable IPv6 communication through the tunnel.'} - </Text> - </View> + <Cell.Container> + <Cell.Label>Enable IPv6</Cell.Label> + <Switch isOn={this.props.enableIpv6} onChange={this.props.setEnableIpv6} /> + </Cell.Container> + <Cell.Footer>Enable IPv6 communication through the tunnel.</Cell.Footer> <View style={styles.advanced_settings__content}> <Selector diff --git a/gui/packages/desktop/src/renderer/components/AdvancedSettingsStyles.js b/gui/packages/desktop/src/renderer/components/AdvancedSettingsStyles.js index 30528ae4c7..d1f0b6d4d7 100644 --- a/gui/packages/desktop/src/renderer/components/AdvancedSettingsStyles.js +++ b/gui/packages/desktop/src/renderer/components/AdvancedSettingsStyles.js @@ -24,14 +24,6 @@ export default { flexBasis: 'auto', overflow: 'visible', }), - advanced_settings__ipv6: Styles.createViewStyle({ - backgroundColor: colors.blue, - flexDirection: 'row', - alignItems: 'center', - }), - advanced_settings__ipv6_accessory: Styles.createViewStyle({ - marginRight: 12, - }), advanced_settings__cell: Styles.createViewStyle({ cursor: 'default', backgroundColor: colors.green, @@ -70,19 +62,6 @@ export default { flexDirection: 'row', justifyContent: 'flex-start', }), - advanced_settings__cell_footer: Styles.createViewStyle({ - paddingTop: 8, - paddingRight: 24, - paddingBottom: 24, - paddingLeft: 24, - }), - advanced_settings__cell_label_container: Styles.createViewStyle({ - paddingTop: 14, - paddingRight: 12, - paddingBottom: 14, - paddingLeft: 24, - flexGrow: 1, - }), advanced_settings__section_title: Styles.createTextStyle({ backgroundColor: colors.blue, @@ -106,12 +85,4 @@ export default { color: colors.white, flex: 0, }), - advanced_settings__cell_footer_label: Styles.createTextStyle({ - fontFamily: 'Open Sans', - fontSize: 13, - fontWeight: '600', - lineHeight: 20, - letterSpacing: -0.2, - color: colors.white80, - }), }; diff --git a/gui/packages/desktop/src/renderer/components/Cell.js b/gui/packages/desktop/src/renderer/components/Cell.js index 8bdf517656..0135004caf 100644 --- a/gui/packages/desktop/src/renderer/components/Cell.js +++ b/gui/packages/desktop/src/renderer/components/Cell.js @@ -1,15 +1,15 @@ // @flow import * as React from 'react'; -import { Button, Text, Component, Styles, Types } from 'reactxp'; +import { Button, Text, Component, Styles, Types, View } from 'reactxp'; import PlainImg from './Img'; import { colors } from '../../config'; const styles = { - cell: Styles.createViewStyle({ + cellButton: Styles.createViewStyle({ backgroundColor: colors.blue, - paddingTop: 14, - paddingBottom: 14, + paddingTop: 0, + paddingBottom: 0, paddingLeft: 16, paddingRight: 16, marginBottom: 1, @@ -19,6 +19,48 @@ const styles = { alignContent: 'center', cursor: 'default', }), + cellContainer: Styles.createViewStyle({ + backgroundColor: colors.blue, + flexDirection: 'row', + alignItems: 'center', + paddingLeft: 16, + paddingRight: 12, + }), + + footer: { + container: Styles.createViewStyle({ + paddingTop: 8, + paddingRight: 24, + paddingBottom: 24, + paddingLeft: 24, + }), + text: Styles.createTextStyle({ + fontFamily: 'Open Sans', + fontSize: 13, + fontWeight: '600', + lineHeight: 20, + letterSpacing: -0.2, + color: colors.white80, + }), + }, + + label: { + container: Styles.createViewStyle({ + marginLeft: 8, + marginTop: 14, + marginBottom: 14, + flexGrow: 1, + }), + text: Styles.createTextStyle({ + fontFamily: 'DINPro', + fontSize: 20, + fontWeight: '900', + lineHeight: 26, + letterSpacing: -0.2, + color: colors.white, + }), + }, + cellHover: Styles.createViewStyle({ backgroundColor: colors.blue80, }), @@ -27,16 +69,6 @@ const styles = { marginLeft: 8, }), - label: Styles.createTextStyle({ - color: colors.white, - alignSelf: 'center', - fontFamily: 'DINPro', - fontSize: 20, - fontWeight: '900', - lineHeight: 26, - flex: 1, - marginLeft: 8, - }), subtext: Styles.createTextStyle({ color: colors.white60, fontFamily: 'Open Sans', @@ -47,10 +79,6 @@ const styles = { }), }; -export class SubText extends Text {} -export class Label extends Text {} -export class Img extends PlainImg {} - type CellButtonProps = { children?: React.Node, disabled?: boolean, @@ -60,59 +88,107 @@ type CellButtonProps = { type State = { hovered: boolean }; +const CellHoverContext = React.createContext(false); + export class CellButton extends Component<CellButtonProps, State> { state = { hovered: false }; - textStyle = (cellHoverStyle?: Types.ViewStyle) => (this.state.hovered ? cellHoverStyle : null); - iconStyle = (cellHoverStyle?: Types.ViewStyle) => (this.state.hovered ? cellHoverStyle : null); - subtextStyle = (cellHoverStyle?: Types.ViewStyle) => (this.state.hovered ? cellHoverStyle : null); - backgroundStyle = (cellHoverStyle?: Types.ViewStyle) => - this.state.hovered ? cellHoverStyle || styles.cellHover : null; - onHoverStart = () => (!this.props.disabled ? this.setState({ hovered: true }) : null); onHoverEnd = () => (!this.props.disabled ? this.setState({ hovered: false }) : null); render() { const { children, style, cellHoverStyle, ...otherProps } = this.props; + const hoverStyle = cellHoverStyle || styles.cellHover; return ( <Button - style={[styles.cell, style, this.backgroundStyle(cellHoverStyle)]} + style={[styles.cellButton, style, this.state.hovered && hoverStyle]} onHoverStart={this.onHoverStart} onHoverEnd={this.onHoverEnd} {...otherProps}> - {React.Children.map(children, (node) => { - if (React.isValidElement(node)) { - let updatedProps = {}; + <CellHoverContext.Provider value={this.state.hovered}>{children}</CellHoverContext.Provider> + </Button> + ); + } +} - if (node.type === Label) { - updatedProps = { - style: [styles.label, node.props.style, this.textStyle(node.props.cellHoverStyle)], - }; - } +type ContainerProps = { children: React.Node }; - if (node.type === Img) { - updatedProps = { - tintColor: 'currentColor', - style: [styles.icon, node.props.style, this.iconStyle(node.props.cellHoverStyle)], - }; - } +export function Container({ children }: ContainerProps) { + return <View style={styles.cellContainer}>{children}</View>; +} - if (node.type === SubText) { - updatedProps = { - style: [ - styles.subtext, - node.props.style, - this.subtextStyle(node.props.cellHoverStyle), - ], - }; - } +export type LabelProps = { + children: React.Node, + containerStyle?: Types.ViewStyle, + textStyle?: Types.TextStyle, + cellHoverContainerStyle?: Types.ViewStyle, + cellHoverTextStyle?: Types.TextStyle, +}; - return React.cloneElement(node, updatedProps); - } else if (node) { - return <Label style={[styles.label, this.textStyle()]}>{children}</Label>; - } - })} - </Button> - ); - } +export function Label({ + children, + containerStyle, + textStyle, + cellHoverContainerStyle, + cellHoverTextStyle, + ...otherProps +}: LabelProps) { + return ( + <CellHoverContext.Consumer> + {(hovered) => ( + <View + style={[styles.label.container, containerStyle, hovered && cellHoverContainerStyle]} + {...otherProps}> + <Text style={[styles.label.text, textStyle, hovered && cellHoverTextStyle]}> + {children} + </Text> + </View> + )} + </CellHoverContext.Consumer> + ); +} + +export type SubTextProps = { + children: React.Node, + cellHoverStyle?: Types.ViewStyle, + style?: Types.ViewStyle, +}; + +export function SubText({ children, style, cellHoverStyle, ...otherProps }: SubTextProps) { + return ( + <CellHoverContext.Consumer> + {(hovered) => ( + <Text style={[styles.subtext, style, hovered && cellHoverStyle]} {...otherProps}> + {children} + </Text> + )} + </CellHoverContext.Consumer> + ); +} + +export type IconProps = { + cellHoverStyle?: Types.ViewStyle, + style?: Types.ViewStyle, +}; + +export function Icon({ style, cellHoverStyle, ...otherProps }: IconProps) { + return ( + <CellHoverContext.Consumer> + {(hovered) => ( + <PlainImg + tintColor={'currentColor'} + style={[styles.icon, style, hovered && cellHoverStyle]} + {...otherProps} + /> + )} + </CellHoverContext.Consumer> + ); +} + +export function Footer({ children }: ContainerProps) { + return ( + <View style={styles.footer.container}> + <Text style={styles.footer.text}>{children}</Text> + </View> + ); } diff --git a/gui/packages/desktop/src/renderer/components/Login.js b/gui/packages/desktop/src/renderer/components/Login.js index 021cccf23c..160ec3f0f9 100644 --- a/gui/packages/desktop/src/renderer/components/Login.js +++ b/gui/packages/desktop/src/renderer/components/Login.js @@ -448,15 +448,16 @@ class AccountDropdownItem extends React.Component<AccountDropdownItemProps> { style={styles.account_dropdown__item} cellHoverStyle={styles.account_dropdown__item_hover}> <Cell.Label - style={styles.account_dropdown__label} - cellHoverStyle={styles.account_dropdown__label_hover} + textStyle={styles.account_dropdown__label} + containerStyle={styles.account_dropdown__label_container} + cellHoverTextStyle={styles.account_dropdown__label_hover} onPress={() => this.props.onSelect(this.props.value)}> {this.props.label} </Cell.Label> <Img style={styles.account_dropdown__remove} - cellHoverStyle={styles.account_dropdown__remove_cell_hover} hoverStyle={styles.account_dropdown__remove_hover} + tintColor={'currentColor'} source="icon-close-sml" height={16} width={16} diff --git a/gui/packages/desktop/src/renderer/components/LoginStyles.js b/gui/packages/desktop/src/renderer/components/LoginStyles.js index 55db4ebd13..1665b1c450 100644 --- a/gui/packages/desktop/src/renderer/components/LoginStyles.js +++ b/gui/packages/desktop/src/renderer/components/LoginStyles.js @@ -104,15 +104,17 @@ export default { paddingLeft: 12, marginLeft: 0, }), - account_dropdown__remove_cell_hover: Styles.createViewStyle({ - color: colors.blue60, - }), account_dropdown__remove_hover: Styles.createViewStyle({ color: colors.blue, }), account_dropdown__label_hover: Styles.createViewStyle({ color: colors.blue, }), + account_dropdown__label_container: Styles.createViewStyle({ + marginLeft: 12, + marginTop: 11, + marginBottom: 11, + }), login_footer__prompt: Styles.createTextStyle({ color: colors.white80, @@ -157,19 +159,10 @@ export default { flex: 1, }), account_dropdown__label: Styles.createTextStyle({ - flex: 1, - fontFamily: 'DINPro', - fontSize: 20, - fontWeight: '900', - lineHeight: 26, color: colors.blue80, borderWidth: 0, textAlign: 'left', marginLeft: 0, - paddingTop: 10, - paddingRight: 0, - paddingLeft: 12, - paddingBottom: 12, cursor: 'default', }), }; diff --git a/gui/packages/desktop/src/renderer/components/Preferences.js b/gui/packages/desktop/src/renderer/components/Preferences.js index ec70115d16..d0681f7e5e 100644 --- a/gui/packages/desktop/src/renderer/components/Preferences.js +++ b/gui/packages/desktop/src/renderer/components/Preferences.js @@ -1,7 +1,8 @@ // @flow import * as React from 'react'; -import { Component, Text, View } from 'reactxp'; +import { Component, View } from 'reactxp'; +import * as Cell from './Cell'; import { Layout, Container } from './Layout'; import NavigationBar, { BackBarItem } from './NavigationBar'; import SettingsHeader, { HeaderTitle } from './SettingsHeader'; @@ -47,49 +48,25 @@ export default class Preferences extends Component<PreferencesProps, State> { </SettingsHeader> <View style={styles.preferences__content}> - <View style={styles.preferences__cell}> - <View style={styles.preferences__cell_label_container}> - <Text style={styles.preferences__cell_label}>Auto-connect</Text> - </View> - <View style={styles.preferences__cell_accessory}> - <Switch isOn={this.props.autoConnect} onChange={this.props.setAutoConnect} /> - </View> - </View> - <View style={styles.preferences__cell_footer}> - <Text style={styles.preferences__cell_footer_label}> - {'Automatically connect the VPN when the computer starts.'} - </Text> - </View> + <Cell.Container> + <Cell.Label>Auto-connect</Cell.Label> + <Switch isOn={this.props.autoConnect} onChange={this.props.setAutoConnect} /> + </Cell.Container> + <Cell.Footer>Automatically connect the VPN when the computer starts.</Cell.Footer> - <View style={styles.preferences__cell}> - <View style={styles.preferences__cell_label_container}> - <Text style={styles.preferences__cell_label}>Auto-start</Text> - </View> - <View style={styles.preferences__cell_accessory}> - <Switch isOn={this.state.autoStart} onChange={this._onChangeAutoStart} /> - </View> - </View> - <View style={styles.preferences__cell_footer}> - <Text style={styles.preferences__cell_footer_label}> - {'Automatically open Mullvad VPN at login to the system.'} - </Text> - </View> + <Cell.Container> + <Cell.Label>Auto-start</Cell.Label> + <Switch isOn={this.state.autoStart} onChange={this._onChangeAutoStart} /> + </Cell.Container> + <Cell.Footer>Automatically open Mullvad VPN at login to the system.</Cell.Footer> - <View style={styles.preferences__cell}> - <View style={styles.preferences__cell_label_container}> - <Text style={styles.preferences__cell_label}>Local network sharing</Text> - </View> - <View style={styles.preferences__cell_accessory}> - <Switch isOn={this.props.allowLan} onChange={this.props.setAllowLan} /> - </View> - </View> - <View style={styles.preferences__cell_footer}> - <Text style={styles.preferences__cell_footer_label}> - { - 'Allows access to other devices on the same network for sharing, printing etc.' - } - </Text> - </View> + <Cell.Container> + <Cell.Label>Local network sharing</Cell.Label> + <Switch isOn={this.props.allowLan} onChange={this.props.setAllowLan} /> + </Cell.Container> + <Cell.Footer> + Allows access to other devices on the same network for sharing, printing etc. + </Cell.Footer> </View> </View> </View> diff --git a/gui/packages/desktop/src/renderer/components/PreferencesStyles.js b/gui/packages/desktop/src/renderer/components/PreferencesStyles.js index 2c35029ec9..1754142805 100644 --- a/gui/packages/desktop/src/renderer/components/PreferencesStyles.js +++ b/gui/packages/desktop/src/renderer/components/PreferencesStyles.js @@ -19,42 +19,4 @@ export default { flexShrink: 1, flexBasis: 'auto', }), - preferences__cell: Styles.createViewStyle({ - backgroundColor: colors.blue, - flexDirection: 'row', - alignItems: 'center', - }), - preferences__cell_accessory: Styles.createViewStyle({ - marginRight: 12, - }), - preferences__cell_footer: Styles.createViewStyle({ - paddingTop: 8, - paddingRight: 24, - paddingBottom: 24, - paddingLeft: 24, - }), - preferences__cell_label_container: Styles.createViewStyle({ - paddingTop: 14, - paddingRight: 12, - paddingBottom: 14, - paddingLeft: 24, - flexGrow: 1, - }), - - preferences__cell_label: Styles.createTextStyle({ - fontFamily: 'DINPro', - fontSize: 20, - fontWeight: '900', - lineHeight: 26, - letterSpacing: -0.2, - color: colors.white, - }), - preferences__cell_footer_label: Styles.createTextStyle({ - fontFamily: 'Open Sans', - fontSize: 13, - fontWeight: '600', - lineHeight: 20, - letterSpacing: -0.2, - color: colors.white80, - }), }; diff --git a/gui/packages/desktop/src/renderer/components/SelectLocation.js b/gui/packages/desktop/src/renderer/components/SelectLocation.js index f84cadd6f3..754b104037 100644 --- a/gui/packages/desktop/src/renderer/components/SelectLocation.js +++ b/gui/packages/desktop/src/renderer/components/SelectLocation.js @@ -165,7 +165,7 @@ export default class SelectLocation extends Component<Props, State> { const statusClass = active ? styles.relay_status__active : styles.relay_status__inactive; return isSelected ? ( - <Cell.Img style={styles.tick_icon} source="icon-tick" height={24} width={24} /> + <Cell.Icon style={styles.tick_icon} source="icon-tick" height={24} width={24} /> ) : ( <View style={[styles.relay_status, statusClass]} /> ); @@ -209,7 +209,7 @@ export default class SelectLocation extends Component<Props, State> { <Cell.Label>{relayCountry.name}</Cell.Label> {hasChildren ? ( - <Cell.Img + <Cell.Icon style={styles.collapse_button} hoverStyle={styles.expand_chevron_hover} onPress={handleCollapse} @@ -266,7 +266,7 @@ export default class SelectLocation extends Component<Props, State> { <Cell.Label>{relayCity.name}</Cell.Label> {relayCity.relays.length > 1 ? ( - <Cell.Img + <Cell.Icon style={styles.collapse_button} hoverStyle={styles.expand_chevron_hover} onPress={handleCollapse} diff --git a/gui/packages/desktop/src/renderer/components/Settings.js b/gui/packages/desktop/src/renderer/components/Settings.js index 8a7df34f43..f1cb4d8fdc 100644 --- a/gui/packages/desktop/src/renderer/components/Settings.js +++ b/gui/packages/desktop/src/renderer/components/Settings.js @@ -91,7 +91,7 @@ export default class Settings extends Component<Props> { style={styles.settings__account_paid_until_label__error}> {'OUT OF TIME'} </Cell.SubText> - <Cell.Img height={12} width={7} source="icon-chevron" /> + <Cell.Icon height={12} width={7} source="icon-chevron" /> </Cell.CellButton> ) : ( <Cell.CellButton @@ -101,19 +101,19 @@ export default class Settings extends Component<Props> { <Cell.SubText testName="settings__account_paid_until_subtext"> {formattedExpiry} </Cell.SubText> - <Cell.Img height={12} width={7} source="icon-chevron" /> + <Cell.Icon height={12} width={7} source="icon-chevron" /> </Cell.CellButton> )} </View> <Cell.CellButton onPress={this.props.onViewPreferences} testName="settings__preferences"> <Cell.Label>Preferences</Cell.Label> - <Cell.Img height={12} width={7} source="icon-chevron" /> + <Cell.Icon height={12} width={7} source="icon-chevron" /> </Cell.CellButton> <Cell.CellButton onPress={this.props.onViewAdvancedSettings} testName="settings__advanced"> <Cell.Label>Advanced</Cell.Label> - <Cell.Img height={12} width={7} source="icon-chevron" /> + <Cell.Icon height={12} width={7} source="icon-chevron" /> </Cell.CellButton> <View style={styles.settings__cell_spacer} /> </View> @@ -148,7 +148,7 @@ export default class Settings extends Component<Props> { {icon} <Cell.Label>App version</Cell.Label> <Cell.SubText>{this.props.appVersion}</Cell.SubText> - <Cell.Img height={16} width={16} source="icon-extLink" /> + <Cell.Icon height={16} width={16} source="icon-extLink" /> </Cell.CellButton> {footer} </View> @@ -162,19 +162,19 @@ export default class Settings extends Component<Props> { onPress={this.props.onExternalLink.bind(this, 'faq')} testName="settings__external_link"> <Cell.Label>FAQs</Cell.Label> - <Cell.Img height={16} width={16} source="icon-extLink" /> + <Cell.Icon height={16} width={16} source="icon-extLink" /> </Cell.CellButton> <Cell.CellButton onPress={this.props.onExternalLink.bind(this, 'guides')} testName="settings__external_link"> <Cell.Label>Guides</Cell.Label> - <Cell.Img height={16} width={16} source="icon-extLink" /> + <Cell.Icon height={16} width={16} source="icon-extLink" /> </Cell.CellButton> <Cell.CellButton onPress={this.props.onViewSupport} testName="settings__view_support"> <Cell.Label>Report a problem</Cell.Label> - <Cell.Img height={12} width={7} source="icon-chevron" /> + <Cell.Icon height={12} width={7} source="icon-chevron" /> </Cell.CellButton> </View> ); |
