diff options
| author | Janito Vaqueiro Ferreira Filho <janito@mullvad.net> | 2018-12-08 12:46:42 -0200 |
|---|---|---|
| committer | Janito Vaqueiro Ferreira Filho <janito@mullvad.net> | 2018-12-11 12:38:23 -0200 |
| commit | 22bb2777d95b79242f92c3ea06b72f087849e7d8 (patch) | |
| tree | 2c27af9b30e2eb7a5c83910f215e76700929dd8d /gui | |
| parent | 6cc5b2badae95ed840bfad3c1ba3a17efa82608a (diff) | |
| download | mullvadvpn-22bb2777d95b79242f92c3ea06b72f087849e7d8.tar.xz mullvadvpn-22bb2777d95b79242f92c3ea06b72f087849e7d8.zip | |
Implement warning when little account time remains
Diffstat (limited to 'gui')
4 files changed, 53 insertions, 3 deletions
diff --git a/gui/packages/desktop/src/renderer/components/Connect.js b/gui/packages/desktop/src/renderer/components/Connect.js index 852d7c053a..577f4e470a 100644 --- a/gui/packages/desktop/src/renderer/components/Connect.js +++ b/gui/packages/desktop/src/renderer/components/Connect.js @@ -199,6 +199,7 @@ export default class Connect extends Component<Props> { style={styles.notification_area} tunnelState={this.props.connection.status} version={this.props.version} + accountExpiry={this.props.accountExpiry} openExternalLink={this.props.onExternalLink} blockWhenDisconnected={this.props.blockWhenDisconnected} /> diff --git a/gui/packages/desktop/src/renderer/components/NotificationArea.js b/gui/packages/desktop/src/renderer/components/NotificationArea.js index dac5b916f6..d31308beed 100644 --- a/gui/packages/desktop/src/renderer/components/NotificationArea.js +++ b/gui/packages/desktop/src/renderer/components/NotificationArea.js @@ -1,4 +1,6 @@ // @flow + +import moment from 'moment'; import * as React from 'react'; import { Component, Types } from 'reactxp'; import { @@ -12,11 +14,13 @@ import { } from './NotificationBanner'; import { AuthFailure } from '../lib/auth-failure'; +import AccountExpiry from '../lib/account-expiry'; import type { BlockReason, TunnelStateTransition } from '../lib/daemon-rpc-proxy'; import type { VersionReduxState } from '../redux/version/reducers'; type Props = { style?: Types.ViewStyleRuleSet, + accountExpiry: ?AccountExpiry, tunnelState: TunnelStateTransition, version: VersionReduxState, openExternalLink: (string) => void, @@ -27,7 +31,8 @@ type NotificationAreaPresentation = | { type: 'blocking', reason: string } | { type: 'inconsistent-version' } | { type: 'unsupported-version', upgradeVersion: string } - | { type: 'update-available', upgradeVersion: string }; + | { type: 'update-available', upgradeVersion: string } + | { type: 'expires-soon', timeLeft: string }; type State = NotificationAreaPresentation & { visible: boolean, @@ -63,7 +68,7 @@ export default class NotificationArea extends Component<Props, State> { }; static getDerivedStateFromProps(props: Props, state: State) { - const { version, tunnelState, blockWhenDisconnected } = props; + const { accountExpiry, blockWhenDisconnected, tunnelState, version } = props; switch (tunnelState.state) { case 'connecting': @@ -124,6 +129,14 @@ export default class NotificationArea extends Component<Props, State> { }; } + if (accountExpiry && accountExpiry.willHaveExpiredIn(moment().add(3, 'days'))) { + return { + visible: true, + type: 'expires-soon', + timeLeft: accountExpiry.remainingTime(), + }; + } + return { ...state, visible: false, @@ -193,6 +206,23 @@ export default class NotificationArea extends Component<Props, State> { </NotificationActions> </React.Fragment> )} + + {this.state.type === 'expires-soon' && ( + <React.Fragment> + <NotificationIndicator type={'warning'} /> + <NotificationContent> + <NotificationTitle>{'ACCOUNT CREDIT EXPIRES SOON'}</NotificationTitle> + <NotificationSubtitle>{this.state.timeLeft}</NotificationSubtitle> + </NotificationContent> + <NotificationActions> + <NotificationOpenLinkAction + onPress={() => { + this.props.openExternalLink('purchase'); + }} + /> + </NotificationActions> + </React.Fragment> + )} </NotificationBanner> ); } diff --git a/gui/packages/desktop/src/renderer/lib/account-expiry.js b/gui/packages/desktop/src/renderer/lib/account-expiry.js index b3ecf0b665..af240c2039 100644 --- a/gui/packages/desktop/src/renderer/lib/account-expiry.js +++ b/gui/packages/desktop/src/renderer/lib/account-expiry.js @@ -10,7 +10,11 @@ export default class AccountExpiry { } hasExpired(): boolean { - return this._expiry.isSameOrBefore(moment()); + return this.willHaveExpiredIn(moment()); + } + + willHaveExpiredIn(time: moment): boolean { + return this._expiry.isSameOrBefore(time); } remainingTime(): string { diff --git a/gui/packages/desktop/test/components/NotificationArea.spec.js b/gui/packages/desktop/test/components/NotificationArea.spec.js index bdd001e8ab..08639e36ff 100644 --- a/gui/packages/desktop/test/components/NotificationArea.spec.js +++ b/gui/packages/desktop/test/components/NotificationArea.spec.js @@ -3,6 +3,7 @@ import * as React from 'react'; import { shallow } from 'enzyme'; import NotificationArea from '../../src/renderer/components/NotificationArea'; +import AccountExpiry from '../../src/renderer/lib/account-expiry'; describe('components/NotificationArea', () => { const defaultVersion = { @@ -15,6 +16,12 @@ describe('components/NotificationArea', () => { nextUpgrade: null, }; + const defaultExpiry = new AccountExpiry( + moment() + .add(1, 'year') + .format(), + ); + it('handles disconnecting state', () => { for (const reason of ['nothing', 'block', 'reconnect']) { const component = shallow( @@ -24,6 +31,7 @@ describe('components/NotificationArea', () => { details: { reason }, }} version={defaultVersion} + accountExpiry={defaultExpiry} />, ); expect(component.state('visible')).to.be.false; @@ -38,6 +46,7 @@ describe('components/NotificationArea', () => { state, }} version={defaultVersion} + accountExpiry={defaultExpiry} />, ); @@ -52,6 +61,7 @@ describe('components/NotificationArea', () => { state: 'connecting', }} version={defaultVersion} + accountExpiry={defaultExpiry} />, ); @@ -69,6 +79,7 @@ describe('components/NotificationArea', () => { }, }} version={defaultVersion} + accountExpiry={defaultExpiry} />, ); @@ -86,6 +97,7 @@ describe('components/NotificationArea', () => { ...defaultVersion, consistent: false, }} + accountExpiry={defaultExpiry} />, ); @@ -106,6 +118,7 @@ describe('components/NotificationArea', () => { current: '2018.1', nextUpgrade: '2018.2', }} + accountExpiry={defaultExpiry} />, ); @@ -127,6 +140,7 @@ describe('components/NotificationArea', () => { latestStable: '2018.3', nextUpgrade: '2018.3', }} + accountExpiry={defaultExpiry} />, ); @@ -149,6 +163,7 @@ describe('components/NotificationArea', () => { latestStable: '2018.3', nextUpgrade: '2018.4-beta3', }} + accountExpiry={defaultExpiry} />, ); |
