summaryrefslogtreecommitdiffhomepage
path: root/app/components
diff options
context:
space:
mode:
authorAndrej Mihajlov <and@mullvad.net>2018-08-08 16:53:23 +0200
committerAndrej Mihajlov <and@mullvad.net>2018-08-08 16:53:23 +0200
commitac98e48c68eadfdd7250eccd38aa492e6f830744 (patch)
tree05bfd7a9f05456220f11f40329093b127a5b20a2 /app/components
parentd53fda746465c0bb6525371b9d780cbfac90f942 (diff)
parenta8f2831cd50e98b1d126b8c3169adcf1ef75b8a2 (diff)
downloadmullvadvpn-ac98e48c68eadfdd7250eccd38aa492e6f830744.tar.xz
mullvadvpn-ac98e48c68eadfdd7250eccd38aa492e6f830744.zip
Merge branch 'remove-auto-login'
Diffstat (limited to 'app/components')
-rw-r--r--app/components/Account.js27
-rw-r--r--app/components/AccountStyles.js1
-rw-r--r--app/components/Cell.js1
-rw-r--r--app/components/Connect.js41
-rw-r--r--app/components/CustomScrollbars.js2
-rw-r--r--app/components/HeaderBar.js163
-rw-r--r--app/components/HeaderBarPlatformStyles.android.js2
-rw-r--r--app/components/HeaderBarPlatformStyles.js16
-rw-r--r--app/components/HeaderBarStyles.js53
-rw-r--r--app/components/Img.js8
-rw-r--r--app/components/Launch.js58
-rw-r--r--app/components/Layout.js11
-rw-r--r--app/components/Login.js6
-rw-r--r--app/components/LoginStyles.js24
-rw-r--r--app/components/Settings.js43
15 files changed, 288 insertions, 168 deletions
diff --git a/app/components/Account.js b/app/components/Account.js
index 2edf277fa4..700f33af2b 100644
--- a/app/components/Account.js
+++ b/app/components/Account.js
@@ -1,7 +1,7 @@
// @flow
import moment from 'moment';
import * as React from 'react';
-import { Component, Text, View, App, Types } from 'reactxp';
+import { Component, Text, View } from 'reactxp';
import * as AppButton from './AppButton';
import { Layout, Container } from './Layout';
import NavigationBar, { BackBarItem } from './NavigationBar';
@@ -9,10 +9,11 @@ import SettingsHeader, { HeaderTitle } from './SettingsHeader';
import styles from './AccountStyles';
import Img from './Img';
import { formatAccount } from '../lib/formatters';
+import WindowStateObserver from '../lib/window-state-observer';
import type { AccountToken } from '../lib/daemon-rpc';
-export type AccountProps = {
+type Props = {
accountToken: AccountToken,
accountExpiry: string,
expiryLocale: string,
@@ -28,27 +29,23 @@ type State = {
showAccountTokenCopiedMessage: boolean,
};
-export default class Account extends Component<AccountProps, State> {
+export default class Account extends Component<Props, State> {
state = {
isRefreshingExpiry: false,
showAccountTokenCopiedMessage: false,
};
- _activationStateToken: ?Types.SubscriptionToken;
-
_isMounted = false;
-
_copyTimer: ?TimeoutID;
+ _windowStateObserver = new WindowStateObserver();
componentDidMount() {
this._isMounted = true;
this._refreshAccountExpiry();
- this._activationStateToken = App.activationStateChangedEvent.subscribe((activationState) => {
- if (activationState === Types.AppActivationState.Active) {
- this._refreshAccountExpiry();
- }
- });
+ this._windowStateObserver.onShow = () => {
+ this._refreshAccountExpiry();
+ };
}
componentWillUnmount() {
@@ -58,11 +55,7 @@ export default class Account extends Component<AccountProps, State> {
clearTimeout(this._copyTimer);
}
- const activationStateToken = this._activationStateToken;
- if (activationStateToken) {
- activationStateToken.unsubscribe();
- this._activationStateToken = null;
- }
+ this._windowStateObserver.dispose();
}
onAccountTokenClick() {
@@ -119,7 +112,7 @@ export default class Account extends Component<AccountProps, State> {
<Text style={styles.account__row_label}>Paid until</Text>
{isOutOfTime ? (
<Text style={styles.account__out_of_time} testName="account__out_of_time">
- OUT OF TIME
+ {'OUT OF TIME'}
</Text>
) : (
<Text style={styles.account__row_value}>{formattedExpiry}</Text>
diff --git a/app/components/AccountStyles.js b/app/components/AccountStyles.js
index 14fc478a54..a96a8fcff6 100644
--- a/app/components/AccountStyles.js
+++ b/app/components/AccountStyles.js
@@ -56,6 +56,7 @@ export default {
account__row_value: {
fontFamily: 'Open Sans',
fontSize: 16,
+ lineHeight: 19,
fontWeight: '800',
color: colors.white,
},
diff --git a/app/components/Cell.js b/app/components/Cell.js
index 2b3c06a3b1..80b783352f 100644
--- a/app/components/Cell.js
+++ b/app/components/Cell.js
@@ -19,6 +19,7 @@ const styles = {
flexDirection: 'row',
alignItems: 'center',
alignContent: 'center',
+ cursor: 'default',
},
cellHover: {
backgroundColor: colors.blue80,
diff --git a/app/components/Connect.js b/app/components/Connect.js
index 037ab02495..9d7f52f7b1 100644
--- a/app/components/Connect.js
+++ b/app/components/Connect.js
@@ -3,19 +3,20 @@
import moment from 'moment';
import * as React from 'react';
import { Layout, Container, Header } from './Layout';
+import { SettingsBarButton, Brand } from './HeaderBar';
import { Component, Text, View, Types } from 'reactxp';
import * as AppButton from './AppButton';
import Img from './Img';
import Accordion from './Accordion';
import styles from './ConnectStyles';
-
import { NoCreditError, NoInternetError } from '../errors';
import Map from './Map';
+import WindowStateObserver from '../lib/window-state-observer';
import type { HeaderBarStyle } from './HeaderBar';
import type { ConnectionReduxState } from '../redux/connection/reducers';
-export type ConnectProps = {
+type Props = {
connection: ConnectionReduxState,
accountExpiry: string,
selectedRelayName: string,
@@ -25,22 +26,24 @@ export type ConnectProps = {
onCopyIP: () => void,
onDisconnect: () => void,
onExternalLink: (type: string) => void,
+ updateAccountExpiry: () => Promise<void>,
};
-type ConnectState = {
+type State = {
showCopyIPMessage: boolean,
mapOffset: [number, number],
};
-export default class Connect extends Component<ConnectProps, ConnectState> {
+export default class Connect extends Component<Props, State> {
state = {
showCopyIPMessage: false,
mapOffset: [0, 0],
};
_copyTimer: ?TimeoutID;
+ _windowStateObserver = new WindowStateObserver();
- shouldComponentUpdate(nextProps: ConnectProps, nextState: ConnectState) {
+ shouldComponentUpdate(nextProps: Props, nextState: State) {
const { connection: prevConnection, ...otherPrevProps } = this.props;
const { connection: nextConnection, ...otherNextProps } = nextProps;
@@ -56,10 +59,20 @@ export default class Connect extends Component<ConnectProps, ConnectState> {
);
}
+ componentDidMount() {
+ this.props.updateAccountExpiry();
+
+ this._windowStateObserver.onShow = () => {
+ this.props.updateAccountExpiry();
+ };
+ }
+
componentWillUnmount() {
if (this._copyTimer) {
clearTimeout(this._copyTimer);
}
+
+ this._windowStateObserver.dispose();
}
render() {
@@ -68,12 +81,10 @@ export default class Connect extends Component<ConnectProps, ConnectState> {
return (
<Layout>
- <Header
- style={this.headerStyle()}
- showSettings={true}
- onSettings={this.props.onSettings}
- testName="header"
- />
+ <Header barStyle={this.headerBarStyle()} testName="header">
+ <Brand />
+ <SettingsBarButton onPress={this.props.onSettings} />
+ </Header>
<Container>{child}</Container>
</Layout>
);
@@ -324,15 +335,17 @@ export default class Connect extends Component<ConnectProps, ConnectState> {
// Private
- headerStyle(): HeaderBarStyle {
- switch (this.props.connection.status) {
+ headerBarStyle(): HeaderBarStyle {
+ const { status } = this.props.connection;
+ switch (status) {
case 'disconnected':
return 'error';
case 'connecting':
case 'connected':
return 'success';
+ default:
+ throw new Error(`Invalid ConnectionState: ${(status: empty)}`);
}
- throw new Error('Invalid ConnectionState');
}
networkSecurityStyle(): Types.Style {
diff --git a/app/components/CustomScrollbars.js b/app/components/CustomScrollbars.js
index be74bfddb5..a149faff75 100644
--- a/app/components/CustomScrollbars.js
+++ b/app/components/CustomScrollbars.js
@@ -176,7 +176,7 @@ export default class CustomScrollbars extends React.Component<Props, State> {
return offsetTop - (scrollable.offsetHeight - child.clientHeight) * 0.5;
default:
- throw new Error(`Unknown enum type for ScrollPosition: ${scrollPosition}`);
+ throw new Error(`Unknown enum type for ScrollPosition: ${(scrollPosition: empty)}`);
}
}
diff --git a/app/components/HeaderBar.js b/app/components/HeaderBar.js
index a46856eb46..02b1d86e31 100644
--- a/app/components/HeaderBar.js
+++ b/app/components/HeaderBar.js
@@ -1,55 +1,148 @@
// @flow
import React from 'react';
-import { Component, Text, Button, View } from 'reactxp';
-
+import { Component, Text, Button, View, Styles } from 'reactxp';
import Img from './Img';
-
-import styles from './HeaderBarStyles';
-import platformStyles from './HeaderBarPlatformStyles';
+import { colors } from '../config';
export type HeaderBarStyle = 'default' | 'defaultDark' | 'error' | 'success';
-export type HeaderBarProps = {
- style: HeaderBarStyle,
- showSettings: boolean,
- onSettings: ?() => void,
+type HeaderBarProps = {
+ barStyle: HeaderBarStyle,
+};
+
+const headerBarStyles = {
+ container: {
+ base: Styles.createViewStyle({
+ paddingTop: 12,
+ paddingBottom: 12,
+ paddingLeft: 12,
+ paddingRight: 12,
+ }),
+ platformOverride: {
+ darwin: Styles.createViewStyle({
+ paddingTop: 24,
+ }),
+ linux: Styles.createViewStyle({
+ WebkitAppRegion: 'drag',
+ }),
+ },
+ },
+ content: Styles.createViewStyle({
+ flexDirection: 'row',
+ alignItems: 'center',
+ justifyContent: 'flex-end',
+ // the size of "brand" logo
+ minHeight: 51,
+ }),
+ barStyle: {
+ default: Styles.createViewStyle({
+ backgroundColor: colors.blue,
+ }),
+ defaultDark: Styles.createViewStyle({
+ backgroundColor: colors.darkBlue,
+ }),
+ error: Styles.createViewStyle({
+ backgroundColor: colors.red,
+ }),
+ success: Styles.createViewStyle({
+ backgroundColor: colors.green,
+ }),
+ },
};
export default class HeaderBar extends Component<HeaderBarProps> {
static defaultProps: HeaderBarProps = {
- style: 'default',
- showSettings: false,
- onSettings: null,
+ barStyle: 'default',
};
render() {
- const containerClass = [
- styles['headerbar'],
- platformStyles[process.platform],
- styles['style_' + this.props.style],
+ const style = [
+ headerBarStyles.container.base,
+ headerBarStyles.container.platformOverride[process.platform],
+ headerBarStyles.barStyle[this.props.barStyle],
+ this.props.style,
];
return (
- <View style={containerClass}>
- <View style={styles.container} testName="headerbar__container">
- <Img height={50} width={50} source="logo-icon" />
- <Text style={styles.title}>MULLVAD VPN</Text>
- </View>
+ <View style={style}>
+ <View style={headerBarStyles.content}>{this.props.children}</View>
+ </View>
+ );
+ }
+}
- {this.props.showSettings ? (
- <Button
- style={styles.settings}
- onPress={this.props.onSettings}
- testName="headerbar__settings">
- <Img
- height={24}
- width={24}
- source="icon-settings"
- style={[styles.settings_icon, platformStyles.settings_icon]}
- hoverStyle={styles.settings_icon_hover}
- />
- </Button>
- ) : null}
+const brandStyles = {
+ container: Styles.createViewStyle({
+ flex: 1,
+ flexDirection: 'row',
+ alignItems: 'center',
+ }),
+ title: Styles.createTextStyle({
+ fontFamily: 'DINPro',
+ fontSize: 24,
+ fontWeight: '900',
+ lineHeight: 30,
+ letterSpacing: -0.5,
+ color: colors.white60,
+ marginLeft: 8,
+ }),
+};
+
+export class Brand extends Component {
+ render() {
+ return (
+ <View style={brandStyles.container} testName="headerbar__container">
+ <Img width={50} height={50} source="logo-icon" />
+ <Text style={brandStyles.title}>{'MULLVAD VPN'}</Text>
</View>
);
}
}
+
+type SettingsButtonProps = {
+ onPress: ?() => void,
+};
+
+const settingsBarButtonStyles = {
+ container: {
+ base: Styles.createViewStyle({
+ cursor: 'default',
+ padding: 0,
+ marginLeft: 8,
+ }),
+ platformOverride: {
+ linux: Styles.createViewStyle({
+ WebkitAppRegion: 'no-drag',
+ }),
+ },
+ },
+ icon: {
+ normal: Styles.createViewStyle({
+ color: colors.white60,
+ }),
+ hover: Styles.createViewStyle({
+ color: colors.white,
+ }),
+ },
+};
+
+export class SettingsBarButton extends Component<SettingsButtonProps> {
+ render() {
+ return (
+ <Button
+ style={[
+ settingsBarButtonStyles.container.base,
+ settingsBarButtonStyles.container.platformOverride[process.platform],
+ ]}
+ onPress={this.props.onPress}
+ testName="headerbar__settings">
+ <Img
+ height={24}
+ width={24}
+ source="icon-settings"
+ style={settingsBarButtonStyles.icon.normal}
+ hoverStyle={settingsBarButtonStyles.icon.hover}
+ />
+ </Button>
+ );
+ }
+}
diff --git a/app/components/HeaderBarPlatformStyles.android.js b/app/components/HeaderBarPlatformStyles.android.js
deleted file mode 100644
index f2f97beb65..0000000000
--- a/app/components/HeaderBarPlatformStyles.android.js
+++ /dev/null
@@ -1,2 +0,0 @@
-import { createViewStyles } from '../lib/styles';
-export default { ...createViewStyles({}) };
diff --git a/app/components/HeaderBarPlatformStyles.js b/app/components/HeaderBarPlatformStyles.js
deleted file mode 100644
index c60967797a..0000000000
--- a/app/components/HeaderBarPlatformStyles.js
+++ /dev/null
@@ -1,16 +0,0 @@
-// @flow
-import { createViewStyles } from '../lib/styles';
-
-export default {
- ...createViewStyles({
- darwin: {
- paddingTop: 24,
- },
- linux: {
- WebkitAppRegion: 'drag',
- },
- settings_icon: {
- WebkitAppRegion: 'no-drag',
- },
- }),
-};
diff --git a/app/components/HeaderBarStyles.js b/app/components/HeaderBarStyles.js
deleted file mode 100644
index 7d3c94cdc9..0000000000
--- a/app/components/HeaderBarStyles.js
+++ /dev/null
@@ -1,53 +0,0 @@
-// @flow
-import { createTextStyles, createViewStyles } from '../lib/styles';
-import { colors } from '../config';
-
-export default {
- ...createViewStyles({
- headerbar: {
- paddingTop: 12,
- paddingBottom: 12,
- paddingLeft: 12,
- paddingRight: 12,
- backgroundColor: colors.blue,
- flexDirection: 'row',
- justifyContent: 'space-between',
- alignItems: 'center',
- },
- style_defaultDark: {
- backgroundColor: colors.darkBlue,
- },
- style_error: {
- backgroundColor: colors.red,
- },
- style_success: {
- backgroundColor: colors.green,
- },
- container: {
- display: 'flex',
- flexDirection: 'row',
- alignItems: 'center',
- },
- settings: {
- cursor: 'default',
- padding: 0,
- },
- settings_icon: {
- color: colors.white60,
- },
- settings_icon_hover: {
- color: colors.white,
- },
- }),
- ...createTextStyles({
- title: {
- fontFamily: 'DINPro',
- fontSize: 24,
- fontWeight: '900',
- lineHeight: 30,
- letterSpacing: -0.5,
- color: colors.white60,
- marginLeft: 8,
- },
- }),
-};
diff --git a/app/components/Img.js b/app/components/Img.js
index 1d6f6613f4..6b34f99360 100644
--- a/app/components/Img.js
+++ b/app/components/Img.js
@@ -4,6 +4,8 @@ import { View, Component, Types } from 'reactxp';
type Props = {
source: string,
+ width?: number,
+ heigth?: number,
tintColor?: string,
hoverStyle?: Types.ViewStyle,
disabled?: boolean,
@@ -20,7 +22,7 @@ export default class Img extends Component<Props, State> {
getHoverStyle = () => (this.state.hovered ? this.props.hoverStyle || null : null);
render() {
- const { source, style, onMouseEnter, onMouseLeave, ...otherProps } = this.props;
+ const { source, width, heigth, style, onMouseEnter, onMouseLeave, ...otherProps } = this.props;
const tintColor = this.props.tintColor;
const url = './assets/images/' + source + '.svg';
let image;
@@ -36,6 +38,8 @@ export default class Img extends Component<Props, State> {
}}>
<img
src={url}
+ width={width}
+ height={heigth}
style={{
visibility: 'hidden',
}}
@@ -43,7 +47,7 @@ export default class Img extends Component<Props, State> {
</div>
);
} else {
- image = <img src={url} />;
+ image = <img src={url} width={width} height={heigth} />;
}
return (
diff --git a/app/components/Launch.js b/app/components/Launch.js
new file mode 100644
index 0000000000..bab877dd53
--- /dev/null
+++ b/app/components/Launch.js
@@ -0,0 +1,58 @@
+// @flow
+import * as React from 'react';
+import { Component, Styles, View, Text } from 'reactxp';
+import { Layout, Container, Header } from './Layout';
+import { SettingsBarButton } from './HeaderBar';
+import Img from './Img';
+import { colors } from '../config';
+
+const styles = {
+ container: Styles.createViewStyle({
+ flex: 1,
+ flexDirection: 'column',
+ alignItems: 'center',
+ justifyContent: 'center',
+ marginTop: -150,
+ }),
+ logo: Styles.createViewStyle({
+ marginBottom: 4,
+ }),
+ title: Styles.createTextStyle({
+ fontFamily: 'DINPro',
+ fontSize: 24,
+ fontWeight: '900',
+ lineHeight: 30,
+ letterSpacing: -0.5,
+ color: colors.white60,
+ marginBottom: 4,
+ }),
+ subtitle: Styles.createTextStyle({
+ fontFamily: 'Open Sans',
+ fontSize: 14,
+ lineHeight: 20,
+ color: colors.white40,
+ }),
+};
+
+type Props = {
+ openSettings: () => void,
+};
+
+export default class Launch extends Component<Props> {
+ render() {
+ return (
+ <Layout>
+ <Header>
+ <SettingsBarButton onPress={this.props.openSettings} />
+ </Header>
+ <Container>
+ <View style={styles.container} testName="headerbar__container">
+ <Img height={120} width={120} source="logo-icon" style={styles.logo} />
+ <Text style={styles.title}>{'MULLVAD VPN'}</Text>
+ <Text style={styles.subtitle}>{'Connecting to daemon...'}</Text>
+ </View>
+ </Container>
+ </Layout>
+ );
+ }
+}
diff --git a/app/components/Layout.js b/app/components/Layout.js
index 2699b3e43d..1eb6984797 100644
--- a/app/components/Layout.js
+++ b/app/components/Layout.js
@@ -1,19 +1,16 @@
// @flow
import * as React from 'react';
-import HeaderBar from './HeaderBar';
import { View, Component } from 'reactxp';
-
-import type { HeaderBarProps } from './HeaderBar';
-
+import HeaderBar from './HeaderBar';
import styles from './LayoutStyles';
-export class Header extends Component<HeaderBarProps> {
+export class Header extends Component<React.ElementProps<typeof HeaderBar>> {
static defaultProps = HeaderBar.defaultProps;
render() {
return (
- <View style={styles.header}>
- <HeaderBar {...this.props} />
+ <View style={[styles.header, this.props.style]}>
+ <HeaderBar barStyle={this.props.barStyle}>{this.props.children}</HeaderBar>
</View>
);
}
diff --git a/app/components/Login.js b/app/components/Login.js
index d902bba1bc..b410f80553 100644
--- a/app/components/Login.js
+++ b/app/components/Login.js
@@ -2,6 +2,7 @@
import * as React from 'react';
import { Component, Text, View, Animated, Styles, UserInterface } from 'reactxp';
import { Layout, Container, Header } from './Layout';
+import { SettingsBarButton, Brand } from './HeaderBar';
import AccountInput from './AccountInput';
import Accordion from './Accordion';
import { formatAccount } from '../lib/formatters';
@@ -94,7 +95,10 @@ export default class Login extends Component<Props, State> {
render() {
return (
<Layout>
- <Header showSettings={true} onSettings={this.props.openSettings} />
+ <Header>
+ <Brand />
+ <SettingsBarButton onPress={this.props.openSettings} />
+ </Header>
<Container>
<View style={styles.login_form}>
{this._getStatusIcon()}
diff --git a/app/components/LoginStyles.js b/app/components/LoginStyles.js
index d9094a2f13..61e5026a71 100644
--- a/app/components/LoginStyles.js
+++ b/app/components/LoginStyles.js
@@ -14,9 +14,8 @@ export default {
},
status_icon: {
flex: 0,
- height: 48,
marginBottom: 30,
- justifyContent: 'center',
+ alignItems: 'center',
},
login_form: {
flex: 1,
@@ -88,13 +87,15 @@ export default {
backgroundColor: colors.darkBlue,
},
account_dropdown__item: {
- paddingTop: 10,
- paddingRight: 12,
- paddingLeft: 12,
- paddingBottom: 12,
+ paddingTop: 0,
+ paddingRight: 0,
+ paddingLeft: 0,
+ paddingBottom: 0,
marginBottom: 0,
flexDirection: 'row',
+ alignItems: 'stretch',
backgroundColor: colors.white60,
+ cursor: 'default',
},
account_dropdown__item_hover: {
backgroundColor: colors.white40,
@@ -102,6 +103,11 @@ export default {
account_dropdown__remove: {
justifyContent: 'center',
color: colors.blue40,
+ paddingTop: 10,
+ paddingRight: 12,
+ paddingBottom: 12,
+ paddingLeft: 12,
+ marginLeft: 0,
},
account_dropdown__remove_cell_hover: {
color: colors.blue60,
@@ -136,6 +142,7 @@ export default {
subtitle: {
fontFamily: 'Open Sans',
fontSize: 13,
+ lineHeight: 15,
fontWeight: '600',
letterSpacing: -0.2,
color: colors.white80,
@@ -165,6 +172,11 @@ export default {
borderWidth: 0,
textAlign: 'left',
marginLeft: 0,
+ paddingTop: 10,
+ paddingRight: 0,
+ paddingLeft: 12,
+ paddingBottom: 12,
+ cursor: 'default',
},
}),
};
diff --git a/app/components/Settings.js b/app/components/Settings.js
index 4a8784fe0e..0ed45c7685 100644
--- a/app/components/Settings.js
+++ b/app/components/Settings.js
@@ -10,14 +10,14 @@ import SettingsHeader, { HeaderTitle } from './SettingsHeader';
import CustomScrollbars from './CustomScrollbars';
import styles from './SettingsStyles';
import Img from './Img';
+import WindowStateObserver from '../lib/window-state-observer';
-import type { AccountReduxState } from '../redux/account/reducers';
-import type { SettingsReduxState } from '../redux/settings/reducers';
+import type { LoginState } from '../redux/account/reducers';
-export type SettingsProps = {
- account: AccountReduxState,
- settings: SettingsReduxState,
- version: string,
+type Props = {
+ loginState: LoginState,
+ accountExpiry: ?string,
+ appVersion: string,
onQuit: () => void,
onClose: () => void,
onViewAccount: () => void,
@@ -25,9 +25,24 @@ export type SettingsProps = {
onViewPreferences: () => void,
onViewAdvancedSettings: () => void,
onExternalLink: (type: string) => void,
+ updateAccountExpiry: () => Promise<void>,
};
-export default class Settings extends Component<SettingsProps> {
+export default class Settings extends Component<Props> {
+ _windowStateObserver = new WindowStateObserver();
+
+ componentDidMount() {
+ this.props.updateAccountExpiry();
+
+ this._windowStateObserver.onShow = () => {
+ this.props.updateAccountExpiry();
+ };
+ }
+
+ componentWillUnmount() {
+ this._windowStateObserver.dispose();
+ }
+
render() {
return (
<Layout>
@@ -60,17 +75,17 @@ export default class Settings extends Component<SettingsProps> {
}
_renderTopButtons() {
- const isLoggedIn = this.props.account.status === 'ok';
+ const isLoggedIn = this.props.loginState === 'ok';
if (!isLoggedIn) {
return null;
}
- let isOutOfTime = false,
- formattedExpiry = '';
- const expiryIso = this.props.account.expiry;
+ let isOutOfTime = false;
+ let formattedExpiry = '';
+ const expiryIso = this.props.accountExpiry;
if (isLoggedIn && expiryIso) {
- const expiry = moment(this.props.account.expiry);
+ const expiry = moment(expiryIso);
isOutOfTime = expiry.isSameOrBefore(moment());
formattedExpiry = (expiry.fromNow(true) + ' left').toUpperCase();
}
@@ -86,7 +101,7 @@ export default class Settings extends Component<SettingsProps> {
<Cell.SubText
testName="settings__account_paid_until_subtext"
style={styles.settings__account_paid_until_Label__error}>
- OUT OF TIME
+ {'OUT OF TIME'}
</Cell.SubText>
<Img height={12} width={7} source="icon-chevron" />
</Cell.CellButton>
@@ -136,7 +151,7 @@ export default class Settings extends Component<SettingsProps> {
// the version in package.json has to be semver, but we use a YEAR.release-channel
// version scheme. in package.json we thus have to write YEAR.release.X-channel and
// this function is responsible for removing .X part.
- return this.props.version
+ return this.props.appVersion
.replace('.0-', '-') // remove the .0 in 2018.1.0-beta9
.replace(/\.0$/, ''); // remove the .0 in 2018.1.0
}