summaryrefslogtreecommitdiffhomepage
path: root/app/components
diff options
context:
space:
mode:
authorAndrej Mihajlov <and@mullvad.net>2018-02-16 11:19:36 +0100
committerAndrej Mihajlov <and@mullvad.net>2018-02-16 11:19:36 +0100
commit5f15a7bec3e2a50162e54488c5a3f519b9553586 (patch)
tree9d61e6b951139dfb061c1898b7eb0aab4c5e3e73 /app/components
parentc6d4b3a2370fa6feeaaf33f0425127753e93039e (diff)
parent89eeb129f065d92a82393db2deca58c0c0f2ff38 (diff)
downloadmullvadvpn-5f15a7bec3e2a50162e54488c5a3f519b9553586.tar.xz
mullvadvpn-5f15a7bec3e2a50162e54488c5a3f519b9553586.zip
Merge branch 'buttons'
Diffstat (limited to 'app/components')
-rw-r--r--app/components/Account.css98
-rw-r--r--app/components/Account.js84
-rw-r--r--app/components/AccountStyles.js109
-rw-r--r--app/components/HeaderBarStyles.js11
-rw-r--r--app/components/Img.android.js17
-rw-r--r--app/components/Img.js3
-rw-r--r--app/components/PreferencesStyles.js16
-rw-r--r--app/components/Settings.js111
-rw-r--r--app/components/SettingsStyles.js98
-rw-r--r--app/components/Support.js61
-rw-r--r--app/components/SupportStyles.js132
-rw-r--r--app/components/styled/AppButton.js136
-rw-r--r--app/components/styled/CellButton.js116
-rw-r--r--app/components/styled/index.js11
14 files changed, 581 insertions, 422 deletions
diff --git a/app/components/Account.css b/app/components/Account.css
deleted file mode 100644
index 2f450e3828..0000000000
--- a/app/components/Account.css
+++ /dev/null
@@ -1,98 +0,0 @@
-.account {
- background: #192E45;
- height: 100%;
-}
-
-.account__container {
- display: flex;
- flex-direction: column;
- height: 100%;
-}
-
-.account__header {
- flex: 0 0 auto;
- padding: 40px 24px 24px;
- position: relative; /* anchor for close button */
-}
-
-.account__close {
- position: absolute;
- display: flex;
- align-items: center;
- border: 0;
- padding: 0;
- margin: 0;
- top: 24px;
- left: 12px;
- z-index: 1; /* part of .account__container covers the button */
-}
-
-.account__close-icon {
- opacity: 0.6;
- margin-right: 8px;
-}
-
-.account__close-title {
- font-family: "Open Sans";
- font-size: 13px;
- font-weight: 600;
- color: rgba(255, 255, 255, 0.6);
-}
-
-.account__title {
- font-family: DINPro;
- font-size: 32px;
- font-weight: 900;
- line-height: 40px;
- color: #FFFFFF;
-}
-
-.account__content {
- flex: 1 1 auto;
- display: flex;
- flex-direction: column;
- justify-content: space-between;
-}
-
-.account__main {
- margin-bottom: 24px;
-}
-
-.account__footer {
- padding: 24px;
-}
-
-.account__row {
- padding: 0 24px;
-}
-
-.account__row + .account__row {
- margin-top: 24px;
-}
-
-.account__row-label {
- font-family: "Open Sans";
- font-size: 13px;
- font-weight: 600;
- color: rgba(255, 255, 255, 0.8);
- margin-bottom: 8px;
-}
-
-.account__row-value {
- font-family: "Open Sans";
- font-size: 16px;
- font-weight: 800;
- color: rgba(255, 255, 255, 0.8);
-}
-
-.account__row-value--error {
- color: #d0021b;
-}
-
-.account__footer .button + .button {
- margin-top: 24px;
-}
-
-.account__id {
- user-select: text;
-}
diff --git a/app/components/Account.js b/app/components/Account.js
index 47c11a622c..afa36fe31a 100644
--- a/app/components/Account.js
+++ b/app/components/Account.js
@@ -1,9 +1,12 @@
// @flow
import moment from 'moment';
-import React, { Component } from 'react';
-import { Layout, Container, Header } from './Layout';
+import React from 'react';
+import { Component, Text, View } from 'reactxp';
+import { Button, RedButton, GreenButton, Label } from './styled';
+import { Layout, Container } from './Layout';
+import styles from './AccountStyles';
+import Img from './Img';
import { formatAccount } from '../lib/formatters';
-import ExternalLinkSVG from '../assets/images/icon-extLink.svg';
import type { AccountReduxState } from '../redux/account/reducers';
@@ -17,7 +20,7 @@ export type AccountProps = {
export default class Account extends Component {
props: AccountProps;
- render(): React.Element<*> {
+ render() {
const expiry = moment(this.props.account.expiry);
const formattedAccountToken = formatAccount(this.props.account.accountToken || '');
const formattedExpiry = expiry.format('hA, D MMMM YYYY').toUpperCase();
@@ -25,48 +28,57 @@ export default class Account extends Component {
return (
<Layout>
- <Header hidden={ true } style={ 'defaultDark' } />
<Container>
- <div className="account">
- <div className="account__close" onClick={ this.props.onClose }>
- <img className="account__close-icon" src="./assets/images/icon-back.svg" />
- <span className="account__close-title">Settings</span>
- </div>
- <div className="account__container">
+ <View style={styles.account}>
+ <Button style={styles.account__close}
+ onPress={ this.props.onClose }
+ testName='account__close'>
+ <Img style={styles.account__close_icon} source="icon-back" />
+ <Text style={styles.account__close_title}>Settings</Text>
+ </Button>
+ <View style={styles.account__container}>
- <div className="account__header">
- <h2 className="account__title">Account</h2>
- </div>
+ <View style={styles.account__header}>
+ <Text style={styles.account__title}>Account</Text>
+ </View>
- <div className="account__content">
- <div className="account__main">
+ <View style={styles.account__content}>
+ <View style={styles.account__main}>
- <div className="account__row">
- <div className="account__row-label">Account ID</div>
- <div className="account__row-value account__id">{ formattedAccountToken }</div>
- </div>
+ <View style={styles.account__row}>
+ <Text style={styles.account__row_label}>Account ID</Text>
+ <Text style={styles.account__row_value}>{ formattedAccountToken }</Text>
+ </View>
- <div className="account__row">
- <div className="account__row-label">Paid until</div>
+ <View style={styles.account__row}>
+ <Text style={styles.account__row_label}>Paid until</Text>
{ isOutOfTime ?
- <div className="account__out-of-time account__row-value account__row-value--error">OUT OF TIME</div>
+ <Text style={styles.account__out_of_time} testName='account__out_of_time'>OUT OF TIME</Text>
:
- <div className="account__row-value">{ formattedExpiry }</div>
+ <Text style={styles.account__row_value}>{ formattedExpiry }</Text>
}
- </div>
+ </View>
- <div className="account__footer">
- <button className="account__buymore button button--positive" onClick={ this.props.onBuyMore }>
- <span className="button-label">Buy more time</span>
- <ExternalLinkSVG className="button-icon button-icon--16" />
- </button>
- <button className="account__logout button button--negative" onClick={ this.props.onLogout }>Logout</button>
- </div>
+ <View style={styles.account__footer}>
+ <GreenButton
+ onPress={ this.props.onBuyMore }
+ text='Buy more credit'
+ icon='icon-extLink'
+ testName='account__buymore'>
+ <Label>Buy more credit</Label>
+ <Img source='icon-extLink' height='16' width='16' />
+ </GreenButton>
+ <RedButton
+ onPress={ this.props.onLogout }
+ testName='account__logout'>
+ Log out
+ </RedButton>
+ </View>
- </div>
- </div>
- </div>
- </div>
+ </View>
+ </View>
+ </View>
+ </View>
</Container>
</Layout>
);
diff --git a/app/components/AccountStyles.js b/app/components/AccountStyles.js
new file mode 100644
index 0000000000..406215cd4f
--- /dev/null
+++ b/app/components/AccountStyles.js
@@ -0,0 +1,109 @@
+// @flow
+
+import { createViewStyles, createTextStyles } from '../lib/styles';
+import { colors } from '../config';
+
+export default {
+ ...createViewStyles({
+ account: {
+ backgroundColor: colors.darkBlue,
+ height: '100%',
+ },
+ account__container: {
+ flexDirection: 'column',
+ height: '100%',
+ paddingBottom: 48,
+ },
+ account__header: {
+ flexGrow: 0,
+ flexShrink: 0,
+ flexBasis: 'auto',
+ paddingTop: 16,
+ paddingRight: 24,
+ paddingLeft: 24,
+ paddingBottom: 12,
+ },
+ account__close: {
+ flexDirection: 'row',
+ alignItems: 'center',
+ alignSelf: 'flex-start',
+ marginLeft: 12,
+ marginTop: 24,
+ cursor: 'default',
+ },
+ account__close_icon: {
+ width: 24,
+ height: 24,
+ opacity: 0.6,
+ marginRight: 8,
+ },
+ account__scrollview: {
+ flexGrow: 1,
+ flexShrink: 1,
+ flexBasis: '100%',
+ },
+ account__content: {
+ flexDirection: 'column',
+ flexGrow: 1,
+ flexShrink: 0,
+ flexBasis: 'auto',
+ },
+ account__main: {
+ marginBottom: 24,
+ },
+ account__row: {
+ paddingTop: 0,
+ paddingBottom: 0,
+ paddingLeft: 24,
+ paddingRight: 24,
+ marginTop: 24,
+ },
+ account__footer: {
+ marginTop: 12,
+ },
+ }),
+ ...createTextStyles({
+ account__close_title: {
+ fontFamily: 'Open Sans',
+ fontSize: 13,
+ fontWeight: '600',
+ color: colors.white60,
+ },
+ account__title: {
+ fontFamily: 'DINPro',
+ fontSize: 32,
+ fontWeight: '900',
+ lineHeight: 40,
+ color: colors.white,
+ },
+ account__row_label: {
+ fontFamily: 'Open Sans',
+ fontSize: 13,
+ fontWeight: '600',
+ lineHeight: 20,
+ letterSpacing: -0.2,
+ color: colors.white60,
+ marginBottom: 9,
+ },
+ account__row_value: {
+ fontFamily: 'Open Sans',
+ fontSize: 16,
+ fontWeight: '800',
+ color: colors.white,
+ },
+ account__out_of_time: {
+ fontFamily: 'Open Sans',
+ fontSize: 16,
+ fontWeight: '800',
+ color: colors.red,
+ },
+ account__footer_label: {
+ fontFamily: 'Open Sans',
+ fontSize: 13,
+ fontWeight: '600',
+ lineHeight: 20,
+ letterSpacing: -0.2,
+ color: colors.white80,
+ }
+ })
+}; \ No newline at end of file
diff --git a/app/components/HeaderBarStyles.js b/app/components/HeaderBarStyles.js
index c2d53a2036..a8569f2f81 100644
--- a/app/components/HeaderBarStyles.js
+++ b/app/components/HeaderBarStyles.js
@@ -1,5 +1,6 @@
// @flow
import { createTextStyles, createViewStyles } from '../lib/styles';
+import { colors } from '../config';
export default {
...createViewStyles({
@@ -8,7 +9,7 @@ export default {
paddingBottom: 12,
paddingLeft: 12,
paddingRight: 12,
- backgroundColor: '#294D73',
+ backgroundColor: colors.blue,
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
@@ -23,13 +24,13 @@ export default {
paddingTop: 24,
},
headerbar__style_defaultDark: {
- backgroundColor: '#192E45',
+ backgroundColor: colors.darkBlue,
},
headerbar__style_error: {
- backgroundColor: '#D0021B',
+ backgroundColor: colors.red,
},
headerbar__style_success: {
- backgroundColor: '#44AD4D',
+ backgroundColor: colors.green,
},
headerbar__container: {
display: 'flex',
@@ -55,7 +56,7 @@ export default {
fontWeight: '900',
lineHeight: 30,
letterSpacing: -0.5,
- color: 'rgba(255,255,255,0.6)',
+ color: colors.white60,
marginLeft: 8,
}
})
diff --git a/app/components/Img.android.js b/app/components/Img.android.js
index 436f805ccb..ced9d3f461 100644
--- a/app/components/Img.android.js
+++ b/app/components/Img.android.js
@@ -7,20 +7,25 @@ export default class Img extends Component {
props: {
source: string,
style: Object,
- tintColor?: string
+ tintColor?: string,
+ height?: number,
+ width?:number,
};
render(){
- const { source, tintColor, style } = this.props;
+ const width = this.props.width || 7;
+ const height = this.props.height || 12;
+ const source = this.props.source || 'icon-chevron';
+ const tintColor = this.props.tintColor || 'currentColor';
- if (tintColor === 'currentColor' && style) {
- const { color: tint, ...otherStyles } = StyleSheet.flatten(style);
+ if (tintColor === 'currentColor' && this.props.style) {
+ const { color: tint, ...otherStyles } = StyleSheet.flatten(this.props.style);
return(
- <Image style={[ otherStyles, { tintColor: tint } ]} source={ source }/>
+ <Image style={[ otherStyles, { tintColor: tint, height: height, width: width } ]} source={ source }/>
);
} else {
return(
- <Image style={ style } source={ source }/>
+ <Image style={[ this.props.style, { height: height, width: width } ]} source={ source }/>
);
}
}
diff --git a/app/components/Img.js b/app/components/Img.js
index 8c8244fc38..c4fb7637d5 100644
--- a/app/components/Img.js
+++ b/app/components/Img.js
@@ -9,7 +9,8 @@ export default class Img extends Component {
};
render() {
- const { source, tintColor, ...otherProps } = this.props;
+ const { source, ...otherProps } = this.props;
+ const tintColor = this.props.tintColor;
const url = './assets/images/' + source + '.svg';
let image;
diff --git a/app/components/PreferencesStyles.js b/app/components/PreferencesStyles.js
index 24d0884605..7c1693e300 100644
--- a/app/components/PreferencesStyles.js
+++ b/app/components/PreferencesStyles.js
@@ -1,17 +1,17 @@
// @flow
-
import { createViewStyles, createTextStyles } from '../lib/styles';
+import { colors } from '../config';
export default {
...createViewStyles({
preferences: {
- backgroundColor: '#192E45',
+ backgroundColor: colors.darkBlue,
height: '100%',
},
preferences__container: {
display: 'flex',
flexDirection: 'column',
- height: '100%',
+ flex: 1,
},
preferences__header: {
flexGrow: 0,
@@ -47,7 +47,7 @@ export default {
flexBasis: 'auto',
},
preferences__cell: {
- backgroundColor: 'rgba(41,71,115,1)',
+ backgroundColor: colors.blue,
flexDirection: 'row',
alignItems: 'center',
},
@@ -73,14 +73,14 @@ export default {
fontFamily: 'Open Sans',
fontSize: 13,
fontWeight: '600',
- color: 'rgba(255, 255, 255, 0.6)',
+ color: colors.white60,
},
preferences__title: {
fontFamily: 'DINPro',
fontSize: 32,
fontWeight: '900',
lineHeight: 40,
- color: '#fff',
+ color: colors.white
},
preferences__cell_label: {
fontFamily: 'DINPro',
@@ -88,7 +88,7 @@ export default {
fontWeight: '900',
lineHeight: 26,
letterSpacing: -0.2,
- color: '#fff',
+ color: colors.white,
},
preferences__cell_footer_label: {
fontFamily: 'Open Sans',
@@ -96,7 +96,7 @@ export default {
fontWeight: '600',
lineHeight: 20,
letterSpacing: -0.2,
- color: 'rgba(255,255,255,0.8)'
+ color: colors.white80
}
})
}; \ No newline at end of file
diff --git a/app/components/Settings.js b/app/components/Settings.js
index 4022054acd..cae2503127 100644
--- a/app/components/Settings.js
+++ b/app/components/Settings.js
@@ -2,8 +2,8 @@
import moment from 'moment';
import React from 'react';
import { Component, Text, View } from 'reactxp';
-import { Button } from './styled';
-import { Layout, Container, Header } from './Layout';
+import { Button, CellButton, RedButton, Label, SubText} from './styled';
+import { Layout, Container } from './Layout';
import CustomScrollbars from './CustomScrollbars';
import styles from './SettingsStyles';
import Img from './Img';
@@ -31,7 +31,6 @@ export default class Settings extends Component {
render() {
return (
<Layout>
- <Header hidden={ true } style={ 'defaultDark' } />
<Container>
<View style={styles.settings}>
<Button style={styles.settings__close} onPress={ this.props.onClose } testName='settings__close'>
@@ -48,9 +47,7 @@ export default class Settings extends Component {
<View style={styles.settings__content}>
<View>
{ this._renderTopButtons() }
- <View style={styles.settings__cell_spacer}/>
{ this._renderMiddleButtons() }
- <View style={styles.settings__cell_spacer}/>
{ this._renderBottomButtons() }
</View>
{ this._renderQuitButton() }
@@ -81,39 +78,47 @@ export default class Settings extends Component {
return <View>
<View style={styles.settings_account} testName='settings__account'>
- <Button onPress={ this.props.onViewAccount } testName='settings__view_account'>
- <View style={styles.settings__cell}>
- <Text style={styles.settings__cell_label}>Account</Text>
- {isOutOfTime ? (
- <Text style={styles.settings__account_paid_until_label__error} testName='settings__account_paid_until_label'>OUT OF TIME</Text>
- ) : (
- <Text style={styles.settings__cell_subtext} testName='settings__account_paid_until_label'>{formattedExpiry}</Text>
- )}
- <Img style={styles.settings__cell_disclosure} source='icon-chevron' tintColor='currentColor'/>
- </View>
- </Button>
+ {isOutOfTime ? (
+ <CellButton onPress={ this.props.onViewAccount }
+ testName='settings__account_paid_until_button'>
+ <Label>Account</Label>
+ <SubText testName='settings__account_paid_until_subtext' style={styles.settings__account_paid_until_Label__error}>OUT OF TIME</SubText>
+ <Img height='12' width='7' source='icon-chevron' />
+ </CellButton>
+ ) : (
+ <CellButton onPress={ this.props.onViewAccount }
+ testName='settings__account_paid_until_button'>
+ <Label>Account</Label>
+ <SubText testName='settings__account_paid_until_subtext'>{ formattedExpiry }</SubText>
+ <Img height='12' width='7' source='icon-chevron' />
+ </CellButton>
+ )}
</View>
- <ButtonCell onPress={ this.props.onViewPreferences } testName='settings__preferences'>
- <Text style={styles.settings__cell_label}>Preferences</Text>
- <Img style={styles.settings__cell_disclosure} source='icon-chevron' tintColor='currentColor' />
- </ButtonCell>
-
- <ButtonCell onPress={ this.props.onViewAdvancedSettings } testName='settings__advanced'>
- <Text style={styles.settings__cell_label}>Advanced</Text>
- <Img style={styles.settings__cell_disclosure} source='icon-chevron' tintColor='currentColor'/>
- </ButtonCell>
+ <CellButton onPress={ this.props.onViewPreferences }
+ testName='settings__preferences'>
+ <Label>Preferences</Label>
+ <Img height='12' width='7' source='icon-chevron' />
+ </CellButton>
+ <CellButton onPress={ this.props.onViewAdvancedSettings }
+ testName='settings__advanced'>
+ <Label>Advanced</Label>
+ <Img height='12' width='7' source='icon-chevron' />
+ </CellButton>
+ <View style={styles.settings__cell_spacer}/>
</View>;
}
_renderMiddleButtons() {
return <View>
- <ButtonCell onPress={ this.props.onExternalLink.bind(this, 'download') } testName='settings__version'>
- <Text style={styles.settings__cell_label}>App version</Text>
- <Text style={styles.settings__cell_subtext}>{this._formattedVersion()}</Text>
- <Img style={styles.settings__cell_icon} source='icon-extLink' tintColor='currentColor'/>
- </ButtonCell>
+ <CellButton onPress={ this.props.onExternalLink.bind(this, 'download') }
+ testName='settings__version'>
+ <Label>App version</Label>
+ <SubText>{this._formattedVersion()}</SubText>
+ <Img height='16' width='16' source='icon-extLink' />
+ </CellButton>
+ <View style={styles.settings__cell_spacer}/>
</View>;
}
@@ -128,37 +133,33 @@ export default class Settings extends Component {
_renderBottomButtons() {
return <View>
- <ButtonCell onPress={ this.props.onExternalLink.bind(this, 'faq') } testName='settings__external_link'>
- <Text style={styles.settings__cell_label}>FAQs</Text>
- <Img style={styles.settings__cell_icon} source='icon-extLink' tintColor='currentColor'/>
- </ButtonCell>
+ <CellButton onPress={ this.props.onExternalLink.bind(this, 'faq') }
+ testName='settings__external_link'>
+ <Label>FAQs</Label>
+ <Img height='16' width='16' source='icon-extLink' />
+ </CellButton>
- <ButtonCell onPress={ this.props.onExternalLink.bind(this, 'guides') } testName='settings__external_link'>
- <Text style={styles.settings__cell_label}>Guides</Text>
- <Img style={styles.settings__cell_icon} source='icon-extLink' tintColor='currentColor'/>
- </ButtonCell>
+ <CellButton onPress={ this.props.onExternalLink.bind(this, 'guides') }
+ testName='settings__external_link'>
+ <Label>Guides</Label>
+ <Img height='16' width='16' source='icon-extLink' />
+ </CellButton>
- <ButtonCell onPress={ this.props.onViewSupport } testName='settings__view_support'>
- <Text style={styles.settings__cell_label}>Contact support</Text>
- <Img style={styles.settings__cell_disclosure} source='icon-chevron' tintColor='currentColor'/>
- </ButtonCell>
+ <CellButton onPress={ this.props.onViewSupport }
+ testName='settings__view_support'>
+ <Label>Contact support</Label>
+ <Img height='12' width='7' source='icon-chevron' />
+ </CellButton>
</View>;
}
_renderQuitButton() {
return <View style={styles.settings__footer}>
- <Button style={styles.settings__footer_button} onPress={this.props.onQuit} testName='settings__quit'>
- <Text style={styles.settings__footer_button_label}>Quit app</Text>
- </Button>
+ <RedButton
+ onPress={this.props.onQuit}
+ testName='settings__quit'>
+ <Label>Quit app</Label>
+ </RedButton>
</View>;
}
-}
-
-function ButtonCell(props) {
- const { children, ...rest } = props;
- return <Button { ...rest } >
- <View style={styles.settings__cell}>
- { children }
- </View>
- </Button>;
-}
+} \ No newline at end of file
diff --git a/app/components/SettingsStyles.js b/app/components/SettingsStyles.js
index d37703a8fe..81d72277a3 100644
--- a/app/components/SettingsStyles.js
+++ b/app/components/SettingsStyles.js
@@ -1,22 +1,23 @@
import { createViewStyles, createTextStyles } from '../lib/styles';
+import { colors } from '../config';
export default Object.assign(createViewStyles({
settings: {
- backgroundColor: '#192E45',
+ backgroundColor: colors.darkBlue,
height: '100%'
},
settings__container:{
flexDirection: 'column',
- height: '100%'
+ flex: 1
},
settings__header:{
flexGrow: 0,
flexShrink: 0,
flexBasis: 'auto',
- paddingTop: 40,
+ paddingTop: 16,
paddingRight: 24,
paddingLeft: 24,
- paddingBottom: 24,
+ paddingBottom: 16,
},
settings__content: {
flexDirection: 'column',
@@ -29,13 +30,8 @@ export default Object.assign(createViewStyles({
flexBasis: '100%',
},
settings__close: {
- position: 'absolute',
- top: 0,
- left: 12,
- borderWidth: 0,
- padding: 0,
- margin: 0,
- zIndex: 1, /* part of .settings__close covers the button */
+ marginLeft: 12,
+ marginTop: 24,
cursor: 'default',
},
settings__close_icon:{
@@ -44,55 +40,13 @@ export default Object.assign(createViewStyles({
flex: 0,
opacity: 0.6,
},
- settings__cell:{
- backgroundColor: 'rgba(41,71,115,1)',
- paddingTop: 15,
- paddingBottom: 15,
- paddingLeft: 24,
- paddingRight: 24,
- marginBottom: 1,
- flex: 1,
- flexDirection: 'row',
- alignItems: 'center',
- justifyContent: 'space-between'
- },
- settings__cell_disclosure:{
- marginLeft: 8,
- color: 'rgba(255, 255, 255, 0.8)',
- width: 7,
- height: 12,
- },
settings__cell_spacer:{
height: 24,
flex: 0
},
- settings__cell__active_hover:{
- backgroundColor: 'rgba(41,71,115,0.9)'
- },
- settings__cell_icon:{
- marginLeft: 8,
- width: 16,
- height: 16,
- flexGrow: 0,
- flexShrink: 0,
- flexBasis: 'auto',
- alignItems: 'flex-end',
- color: 'rgba(255, 255, 255, 0.8)',
- },
- settings__footer_button:{
- backgroundColor: 'rgba(208,2,27,1)',
- paddingTop: 7,
- paddingLeft: 12,
- paddingRight: 12,
- paddingBottom: 9,
- borderRadius: 4,
- alignItems: 'center',
- },
settings__footer: {
- paddingTop: 24,
- paddingLeft: 24,
- paddingRight: 24,
- paddingBottom: 24,
+ paddingTop: 16,
+ paddingBottom: 16,
},
}), createTextStyles({
settings__title:{
@@ -100,39 +54,9 @@ export default Object.assign(createViewStyles({
fontSize: 32,
fontWeight: '900',
lineHeight: 40,
- color: '#FFFFFF'
- },
- settings__cell_label:{
- fontFamily: 'DINPro',
- fontSize: 20,
- fontWeight: '900',
- lineHeight: 26,
- color: '#FFFFFF',
- flexGrow: 1,
- flexShrink: 0,
- flexBasis: 'auto',
- },
- settings__footer_button_label:{
- fontFamily: 'DINPro',
- fontSize: 20,
- fontWeight: '900',
- lineHeight: 26,
- color: 'rgba(255,255,255,0.8)'
- },
- settings__cell_subtext:{
- fontFamily: 'Open Sans',
- fontSize: 13,
- fontWeight: '800',
- color: 'rgba(255, 255, 255, 0.8)',
- flexGrow: 0,
- textAlign: 'right',
+ color: colors.white
},
settings__account_paid_until_label__error:{
- fontFamily: 'Open Sans',
- fontSize: 13,
- fontWeight: '800',
- flexGrow: 0,
- textAlign: 'right',
- color: '#d0021b',
+ color: colors.red,
},
}));
diff --git a/app/components/Support.js b/app/components/Support.js
index dc646bdb0e..80116bcc1b 100644
--- a/app/components/Support.js
+++ b/app/components/Support.js
@@ -1,7 +1,8 @@
// @flow
import React from 'react';
-import { Component, Text, Button, View, TextInput } from 'reactxp';
-import { Layout, Container, Header } from './Layout';
+import { Component, Text, View, TextInput } from 'reactxp';
+import { Button, BlueButton, GreenButton, Label } from './styled';
+import { Layout, Container } from './Layout';
import styles from './SupportStyles';
import Img from './Img';
@@ -117,14 +118,11 @@ export default class Support extends Component {
return (
<Layout>
- <Header hidden={ true } style={ 'defaultDark' } />
<Container>
<View style={styles.support}>
<Button style={styles.support__close} onPress={ this.props.onClose } testName="support__close">
- <View style={styles.support__close}>
- <Img style={styles.support__close_icon} source="icon-back" />
- <Text style={styles.support__close_title}>Settings</Text>
- </View>
+ <Img style={styles.support__close_icon} source="icon-back" />
+ <Text style={styles.support__close_title}>Settings</Text>
</Button>
<View style={styles.support__container}>
@@ -193,24 +191,29 @@ export default class Support extends Component {
<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>
- <Button style={styles.support__form_send} disabled={ !this.validate() } onPress={ this.onSend } testName='support__send_logs'>
- <Text style={styles.support__button_label}>Send anyway</Text>
- </Button>
+ <GreenButton
+ disabled={ !this.validate() }
+ onPress={ this.onSend }
+ testName='support__send_logs'>
+ Send anyway
+ </GreenButton>
</View>;
}
_renderActionButtons() {
return [
- <Button key={1} onPress={ this.onViewLog } style={{'flex':1}} testName='support__view_logs'>
- <View style={styles.support__form_view_logs}>
- <View style={styles.support__open_icon}></View>
- <Text style={styles.support__button_label}>View app logs</Text>
- <Img source="icon-extLink" style={styles.support__open_icon} tintColor='currentColor'/>
- </View>
- </Button>,
- <Button key={2} style={styles.support__form_send} disabled={ !this.validate() } onPress={ this.onSend } testName='support__send_logs'>
- <Text style={styles.support__button_label}>Send</Text>
- </Button>
+ <BlueButton key={1}
+ onPress={ this.onViewLog }
+ testName='support__view_logs'>
+ <Label>View app logs</Label>
+ <Img source='icon-extLink' height='16' width='16' />
+ </BlueButton>,
+ <GreenButton key={2}
+ disabled={ !this.validate() }
+ onPress={ this.onSend }
+ testName='support__send_logs'>
+ Send
+ </GreenButton>
];
}
@@ -275,16 +278,14 @@ export default class Support extends Component {
</View>
</View>
<View style={styles.support__footer}>
- <Button onPress={ () => this.setState({ sendState: 'INITIAL' }) }>
- <View style={styles.support__form_edit_logs}>
- <Text style={styles.support__button_label}>Edit message</Text>
- </View>
- </Button>
- <Button onPress={ this.onSend }>
- <View style={styles.support__form_send}>
- <Text style={styles.support__button_label}>Try again</Text>
- </View>
- </Button>
+ <BlueButton onPress={ () => this.setState({ sendState: 'INITIAL' }) }>
+ Edit message
+ </BlueButton>
+ <GreenButton
+ onPress={ this.onSend }
+ testName='support__send_logs'>
+ Try again
+ </GreenButton>
</View>
</View>;
}
diff --git a/app/components/SupportStyles.js b/app/components/SupportStyles.js
index f0b0df5c18..85eb693fee 100644
--- a/app/components/SupportStyles.js
+++ b/app/components/SupportStyles.js
@@ -1,14 +1,15 @@
import { createViewStyles, createTextStyles } from '../lib/styles';
+import { colors } from '../config';
export default Object.assign(createViewStyles({
support:{
- backgroundColor: '#192E45',
+ backgroundColor: colors.darkBlue,
height: '100%',
},
support__container:{
display: 'flex',
flexDirection: 'column',
- height: '100%',
+ flex: 1
},
support__header:{
flex: 0,
@@ -16,10 +17,10 @@ export default Object.assign(createViewStyles({
paddingBottom: 12,
paddingLeft: 24,
paddingRight: 24,
- overflow: 'visible',
- position: 'relative' /* anchor for close button */
},
support__close:{
+ paddingLeft: 12,
+ paddingTop: 24,
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'flex-start',
@@ -37,7 +38,6 @@ export default Object.assign(createViewStyles({
display: 'flex',
flexDirection: 'column',
justifyContent: 'space-between',
- paddingBottom: 24,
},
support__form:{
display: 'flex',
@@ -46,17 +46,16 @@ export default Object.assign(createViewStyles({
},
support__form_row:{
paddingTop: 0,
- paddingBottom: 0,
- paddingLeft: 24,
- paddingRight: 24,
+ paddingBottom: 8,
+ paddingLeft: 22,
+ paddingRight: 22,
},
support__form_row_message:{
flex: 1,
paddingTop: 0,
- paddingBottom: 0,
- paddingLeft: 24,
- paddingRight: 24,
- marginTop: 8,
+ paddingBottom: 8,
+ paddingLeft: 22,
+ paddingRight: 22,
},
support__form_message_scroll_wrap:{
flex: 1,
@@ -65,81 +64,29 @@ export default Object.assign(createViewStyles({
overflow: 'hidden',
},
support__footer:{
- paddingTop: 1,
- paddingRight: 24,
- paddingLeft: 24,
- paddingBottom: 24,
- marginTop: 12,
+ paddingTop: 0,
+ paddingBottom: 16,
display: 'flex',
flexDirection: 'column',
flex: 0,
},
- support__form_view_logs:{
- backgroundColor: 'rgba(41,71,115,1)',
- color: 'rgba(255,255,255,0.8)',
- paddingTop: 7,
- paddingLeft: 12,
- paddingRight: 12,
- paddingBottom: 9,
- borderRadius: 4,
- justifyContent: 'space-between',
- alignItems: 'center',
- flexDirection: 'row',
- flex: 1,
- },
- support__form_edit_logs:{
- backgroundColor: 'rgba(41,71,115,1)',
- color: 'rgba(255,255,255,0.8)',
- paddingTop: 7,
- paddingLeft: 12,
- paddingRight: 12,
- paddingBottom: 9,
- borderRadius: 4,
- justifyContent: 'center',
- alignItems: 'center',
- flexDirection: 'row',
- flex: 1,
- },
- support__form_send:{
- backgroundColor: 'rgba(63,173,77,1)',
- color: 'rgba(255,255,255,0.8)',
- paddingTop: 7,
- paddingLeft: 12,
- paddingRight: 12,
- paddingBottom: 9,
- borderRadius: 4,
- marginTop: 16,
- justifyContent: 'space-between',
- alignItems: 'center',
- flex: 1,
- },
support__status_icon:{
textAlign: 'center',
marginBottom: 32,
},
- support__open_icon:{
- color: 'rgba(255,255,255,0.8)',
- marginLeft: 8,
- width: 16,
- height: 16,
- flexGrow: 0,
- flexShrink: 0,
- flexBasis: 'auto',
- alignItems: 'flex-end',
- },
}), createTextStyles({
support__close_title:{
fontFamily: 'Open Sans',
fontSize: 13,
fontWeight: '600',
- color: 'rgba(255, 255, 255, 0.6)',
+ color: colors.white60,
},
support__title:{
fontFamily: 'DINPro',
fontSize: 32,
fontWeight: '900',
lineHeight: 40,
- color: '#FFFFFF',
+ color: colors.white,
marginBottom: 16,
},
support__subtitle:{
@@ -147,40 +94,40 @@ export default Object.assign(createViewStyles({
fontSize: 13,
fontWeight: '600',
overflow: 'visible',
- color: 'rgba(255,255,255,0.8)',
+ color: colors.white80,
lineHeight: 20,
letterSpacing: -0.2,
},
support__form_email:{
- width: '100%',
+ flex: 1,
borderRadius: 4,
overflow: 'hidden',
- paddingTop: 10,
- paddingLeft: 12,
- paddingRight: 12,
- paddingBottom: 12,
+ paddingTop: 14,
+ paddingLeft: 14,
+ paddingRight: 14,
+ paddingBottom: 14,
fontFamily: 'Open Sans',
fontSize: 13,
fontWeight: '600',
lineHeight: 26,
- color: '#294D73',
- backgroundColor: '#fff',
+ color: colors.blue,
+ backgroundColor: colors.white,
},
support__form_message:{
- paddingTop: 10,
- paddingLeft: 12,
- paddingRight: 12,
- paddingBottom: 10,
+ paddingTop: 14,
+ paddingLeft: 14,
+ paddingRight: 14,
+ paddingBottom: 14,
fontFamily: 'Open Sans',
fontSize: 13,
fontWeight: '600',
- color: '#294D73',
- backgroundColor: '#fff',
+ color: colors.blue,
+ backgroundColor: colors.white,
flex: 1,
},
support__sent_email:{
fontWeight: '900',
- color: 'white',
+ color: colors.white,
},
support__status_security__secure:{
fontFamily: 'Open Sans',
@@ -188,7 +135,7 @@ export default Object.assign(createViewStyles({
fontWeight: '800',
lineHeight: 22,
marginBottom: 4,
- color: '#44AD4D',
+ color: colors.green,
},
support__send_status:{
fontFamily: 'DINPro',
@@ -197,22 +144,17 @@ export default Object.assign(createViewStyles({
maxHeight: 'calc(1.16em * 2)',
overflow: 'visible',
letterSpacing: -0.9,
- color: '#FFFFFF',
+ color: colors.white,
marginBottom: 4,
},
- support__button_label:{
- fontFamily: 'DINPro',
- fontSize: 20,
- fontWeight: '900',
- lineHeight: 26,
- justifyContent: 'center',
- alignItems: 'center',
- },
support__no_email_warning: {
fontFamily: 'Open Sans',
fontSize: 13,
lineHeight: 16,
-
- color: 'rgba(255,255,255,0.8)',
+ color: colors.white80,
+ paddingTop: 8,
+ paddingLeft: 24,
+ paddingRight: 24,
+ paddingBottom: 8,
},
}));
diff --git a/app/components/styled/AppButton.js b/app/components/styled/AppButton.js
new file mode 100644
index 0000000000..60da8edb3c
--- /dev/null
+++ b/app/components/styled/AppButton.js
@@ -0,0 +1,136 @@
+// @flow
+import React from 'react';
+import { Text, Component } from 'reactxp';
+import { Button } from './Button';
+import { colors } from '../../config';
+
+import { createViewStyles, createTextStyles } from '../../lib/styles';
+
+const styles = {
+ ...createViewStyles({
+ red:{
+ backgroundColor: colors.red95,
+ },
+ redHover: {
+ backgroundColor: colors.red,
+ },
+ green:{
+ backgroundColor: colors.green,
+ },
+ greenHover:{
+ backgroundColor: colors.green90,
+ },
+ blue:{
+ backgroundColor: colors.blue80,
+ },
+ blueHover:{
+ backgroundColor: colors.blue60,
+ },
+ transparent:{
+ backgroundColor: colors.white20,
+ },
+ transparentHover:{
+ backgroundColor: colors.white40,
+ },
+ white80:{
+ color: colors.white80,
+ },
+ white: {
+ color: colors.white,
+ },
+ icon:{
+ position: 'absolute',
+ alignSelf: 'flex-end',
+ right: 8,
+ marginLeft: 8,
+ },
+ common:{
+ paddingTop: 9,
+ paddingLeft: 9,
+ paddingRight: 9,
+ paddingBottom: 9,
+ marginTop: 8,
+ marginBottom: 8,
+ marginLeft: 24,
+ marginRight: 24,
+ borderRadius: 4,
+ flex: 1,
+ flexDirection: 'column',
+ alignContent: 'center',
+ justifyContent: 'center',
+ },
+ }),
+ ...createTextStyles({
+ label:{
+ alignSelf: 'center',
+ fontFamily: 'DINPro',
+ fontSize: 20,
+ fontWeight: '900',
+ lineHeight: 26,
+ flex: 1,
+ },
+ }),
+};
+
+export class Label extends Text {}
+
+export default class BaseButton extends Component {
+ props: {
+ children: Array<React.Element<*>> | React.Element<*>,
+ disabled: boolean,
+ };
+
+ state = { hovered: false };
+
+ textStyle = () => this.state.hovered ? styles.white80 : styles.white;
+ iconStyle = () => this.state.hovered ? styles.white80 : styles.white;
+ backgroundStyle = () => this.state.hovered ? styles.white80 : styles.white;
+
+ onHoverStart = () => !this.props.disabled ? this.setState({ hovered: true }) : null;
+ onHoverEnd = () => !this.props.disabled ? this.setState({ hovered: false }) : null;
+ render() {
+ const { children, ...otherProps } = this.props;
+ return (
+ <Button style={[ styles.common, this.backgroundStyle() ]}
+ onHoverStart={this.onHoverStart}
+ onHoverEnd={this.onHoverEnd}
+ {...otherProps}>
+ {
+ React.Children.map(children, (node) => {
+ if (React.isValidElement(node)){
+ let updatedProps = {};
+
+ if(node.type.name === 'Label') {
+ updatedProps = { style: [styles.label, this.textStyle()]};
+ }
+
+ if(node.type.name === 'Img') {
+ updatedProps = { tintColor:'currentColor', style: [styles.icon, this.iconStyle()]};
+ }
+
+ return React.cloneElement(node, updatedProps);
+ } else {
+ return <Label style={[styles.label, this.textStyle()]}>{children}</Label>;
+ }
+ })
+ }
+ </Button>
+ );
+ }
+}
+
+export class RedButton extends BaseButton{
+ backgroundStyle = () => this.state.hovered ? styles.redHover : styles.red;
+}
+
+export class GreenButton extends BaseButton{
+ backgroundStyle = () => this.state.hovered ? styles.greenHover : styles.green;
+}
+
+export class BlueButton extends BaseButton{
+ backgroundStyle = () => this.state.hovered ? styles.blueHover : styles.blue;
+}
+
+export class TransparentButton extends BaseButton{
+ backgroundStyle = () => this.state.hovered ? styles.transparentHover : styles.transparent;
+} \ No newline at end of file
diff --git a/app/components/styled/CellButton.js b/app/components/styled/CellButton.js
new file mode 100644
index 0000000000..7309180241
--- /dev/null
+++ b/app/components/styled/CellButton.js
@@ -0,0 +1,116 @@
+// @flow
+import React from 'react';
+import { Text, Component } from 'reactxp';
+import { Button } from './Button';
+import { colors } from '../../config';
+
+import { createViewStyles, createTextStyles } from '../../lib/styles';
+
+const styles = {
+ ...createViewStyles({
+ cell:{
+ paddingTop: 14,
+ paddingBottom: 14,
+ paddingLeft: 16,
+ paddingRight: 16,
+ marginBottom: 1,
+ flex: 1,
+ flexDirection: 'row',
+ alignItems: 'center',
+ alignContent: 'center',
+ },
+ blue:{
+ backgroundColor: colors.blue80,
+ },
+ blueHover:{
+ backgroundColor: colors.blue60,
+ },
+ white40:{
+ color: colors.white40,
+ },
+ white60:{
+ color: colors.white60,
+ },
+ white80:{
+ color: colors.white80,
+ },
+ white: {
+ color: colors.white,
+ },
+ icon: {
+ marginLeft: 8,
+ },
+ }),
+ ...createTextStyles({
+ label:{
+ alignSelf: 'center',
+ fontFamily: 'DINPro',
+ fontSize: 20,
+ fontWeight: '900',
+ lineHeight: 26,
+ flex: 1,
+ marginLeft: 8,
+ },
+ subtext:{
+ fontFamily: 'Open Sans',
+ fontSize: 13,
+ fontWeight: '800',
+ flex: 0,
+ textAlign: 'right',
+ },
+ }),
+};
+
+export class SubText extends Text {}
+export class Label extends Text {}
+
+export default class CellButton extends Component {
+ props: {
+ children: Array<React.Element<*>> | React.Element<*>,
+ disabled: boolean,
+ };
+
+ state = { hovered: false };
+
+ textStyle = () => this.state.hovered ? styles.white80 : styles.white;
+ iconStyle = () => this.state.hovered ? styles.white40 : styles.white60;
+ subtextStyle = () => this.state.hovered ? styles.white40 : styles.white60;
+ backgroundStyle = () => this.state.hovered ? styles.blueHover : styles.blue;
+
+ onHoverStart = () => !this.props.disabled ? this.setState({ hovered: true }) : null;
+ onHoverEnd = () => !this.props.disabled ? this.setState({ hovered: false }) : null;
+
+ render() {
+ const { children, ...otherProps } = this.props;
+ return (
+ <Button style={[ styles.cell, this.backgroundStyle() ]}
+ onHoverStart={this.onHoverStart}
+ onHoverEnd={this.onHoverEnd}
+ {...otherProps}>
+ {
+ React.Children.map(children, (node) => {
+ if (React.isValidElement(node)){
+ let updatedProps = {};
+
+ if(node.type.name === 'Label') {
+ updatedProps = { style: [styles.label, this.textStyle(), node.props.style]};
+ }
+
+ if(node.type.name === 'Img') {
+ updatedProps = { tintColor:'currentColor', style: [styles.icon, this.iconStyle(), node.props.style]};
+ }
+
+ if(node.type.name === 'SubText') {
+ updatedProps = { style: [styles.subtext, this.subtextStyle(), node.props.style]};
+ }
+
+ return React.cloneElement(node, updatedProps);
+ } else {
+ return <Label style={[styles.label, this.textStyle()]}>{children}</Label>;
+ }
+ })
+ }
+ </Button>
+ );
+ }
+}
diff --git a/app/components/styled/index.js b/app/components/styled/index.js
index 6699594f18..de18529cac 100644
--- a/app/components/styled/index.js
+++ b/app/components/styled/index.js
@@ -1,7 +1,16 @@
// @flow
import { Button } from './Button';
+import CellButton, { Label, SubText } from './CellButton';
+import { RedButton, GreenButton, BlueButton, TransparentButton } from './AppButton';
export {
- Button
+ Button,
+ CellButton,
+ RedButton,
+ GreenButton,
+ BlueButton,
+ TransparentButton,
+ Label,
+ SubText,
};