summaryrefslogtreecommitdiffhomepage
path: root/gui/src
diff options
context:
space:
mode:
Diffstat (limited to 'gui/src')
-rw-r--r--gui/src/renderer/app.tsx2
-rw-r--r--gui/src/renderer/components/Connect.tsx44
-rw-r--r--gui/src/renderer/components/ExpiredAccountErrorView.tsx62
-rw-r--r--gui/src/renderer/components/ExpiredAccountErrorViewStyles.tsx13
-rw-r--r--gui/src/renderer/components/HeaderBar.tsx33
-rw-r--r--gui/src/renderer/components/MainView.tsx13
-rw-r--r--gui/src/renderer/containers/ExpiredAccountErrorViewContainer.tsx1
-rw-r--r--gui/src/renderer/routes.tsx4
8 files changed, 100 insertions, 72 deletions
diff --git a/gui/src/renderer/app.tsx b/gui/src/renderer/app.tsx
index 9fa0e4a456..0fdcb47877 100644
--- a/gui/src/renderer/app.tsx
+++ b/gui/src/renderer/app.tsx
@@ -620,7 +620,7 @@ export default class AppRenderer {
private resetNavigation() {
if (this.connectedToDaemon) {
if (this.settings.accountToken) {
- this.history.resetWithIfDifferent('/connect');
+ this.history.resetWithIfDifferent('/main');
} else {
this.history.resetWithIfDifferent('/login');
}
diff --git a/gui/src/renderer/components/Connect.tsx b/gui/src/renderer/components/Connect.tsx
index a6654ad8c0..e48abf8d96 100644
--- a/gui/src/renderer/components/Connect.tsx
+++ b/gui/src/renderer/components/Connect.tsx
@@ -1,15 +1,13 @@
import * as React from 'react';
import styled from 'styled-components';
import { hasExpired } from '../../shared/account-expiry';
-import ExpiredAccountErrorViewContainer from '../containers/ExpiredAccountErrorViewContainer';
import NotificationArea from '../components/NotificationArea';
import { AuthFailureKind, parseAuthFailure } from '../../shared/auth-failure';
import { LoginState } from '../redux/account/reducers';
import { IConnectionReduxState } from '../redux/connection/reducers';
-import { FocusFallback } from './Focus';
-import { Brand, HeaderBarStyle, HeaderBarSettingsButton } from './HeaderBar';
+import { calculateHeaderBarStyle, DefaultHeaderBar } from './HeaderBar';
import ImageView from './ImageView';
-import { Container, Header, Layout } from './Layout';
+import { Container, Layout } from './Layout';
import Map, { MarkerStyle, ZoomLevel } from './Map';
import { ModalContainer } from './Modal';
import TunnelControl from './TunnelControl';
@@ -89,21 +87,8 @@ export default class Connect extends React.Component<IProps, IState> {
return (
<ModalContainer>
<Layout>
- <Header barStyle={this.headerBarStyle()}>
- <FocusFallback>
- <Brand />
- </FocusFallback>
- <HeaderBarSettingsButton />
- </Header>
- <StyledContainer>
- {this.state.isAccountExpired ||
- (this.props.loginState.type === 'ok' &&
- this.props.loginState.method === 'new_account') ? (
- <ExpiredAccountErrorViewContainer />
- ) : (
- this.renderMap()
- )}
- </StyledContainer>
+ <DefaultHeaderBar barStyle={calculateHeaderBarStyle(this.props.connection.status)} />
+ <StyledContainer>{this.renderMap()}</StyledContainer>
</Layout>
</ModalContainer>
);
@@ -171,27 +156,6 @@ export default class Connect extends React.Component<IProps, IState> {
);
}
- private headerBarStyle(): HeaderBarStyle {
- const { status } = this.props.connection;
- switch (status.state) {
- case 'disconnected':
- return HeaderBarStyle.error;
- case 'connecting':
- case 'connected':
- return HeaderBarStyle.success;
- case 'error':
- return !status.details.blockFailure ? HeaderBarStyle.success : HeaderBarStyle.error;
- case 'disconnecting':
- switch (status.details) {
- case 'block':
- case 'reconnect':
- return HeaderBarStyle.success;
- case 'nothing':
- return HeaderBarStyle.error;
- }
- }
- }
-
private getMapProps(): Map['props'] {
const {
longitude,
diff --git a/gui/src/renderer/components/ExpiredAccountErrorView.tsx b/gui/src/renderer/components/ExpiredAccountErrorView.tsx
index a01993787b..8623531cfc 100644
--- a/gui/src/renderer/components/ExpiredAccountErrorView.tsx
+++ b/gui/src/renderer/components/ExpiredAccountErrorView.tsx
@@ -2,7 +2,7 @@ import * as React from 'react';
import { sprintf } from 'sprintf-js';
import { links } from '../../config.json';
import { hasExpired } from '../../shared/account-expiry';
-import { AccountToken } from '../../shared/daemon-rpc-types';
+import { AccountToken, TunnelState } from '../../shared/daemon-rpc-types';
import { messages } from '../../shared/gettext';
import { LoginState } from '../redux/account/reducers';
import * as AppButton from './AppButton';
@@ -18,13 +18,16 @@ import {
StyledCustomScrollbars,
StyledDisconnectButton,
StyledFooter,
+ StyledHeader,
StyledMessage,
StyledModalCellContainer,
StyledStatusIcon,
StyledTitle,
} from './ExpiredAccountErrorViewStyles';
+import { calculateHeaderBarStyle, HeaderBarStyle } from './HeaderBar';
import ImageView from './ImageView';
-import { ModalAlert, ModalAlertType, ModalMessage } from './Modal';
+import { Layout } from './Layout';
+import { ModalAlert, ModalAlertType, ModalContainer, ModalMessage } from './Modal';
import { RedeemVoucherContainer, RedeemVoucherAlert } from './RedeemVoucher';
export enum RecoveryAction {
@@ -39,6 +42,7 @@ interface IExpiredAccountErrorViewProps {
accountToken?: AccountToken;
accountExpiry?: string;
loginState: LoginState;
+ tunnelState: TunnelState;
hideWelcomeView: () => void;
onExternalLinkWithAuth: (url: string) => Promise<void>;
onDisconnect: () => Promise<void>;
@@ -66,33 +70,43 @@ export default class ExpiredAccountErrorView extends React.Component<
}
public render() {
+ const headerBarStyle =
+ this.props.loginState.type === 'ok' && this.props.loginState.method === 'new_account'
+ ? HeaderBarStyle.default
+ : calculateHeaderBarStyle(this.props.tunnelState);
+
return (
- <StyledCustomScrollbars fillContainer>
- <StyledContainer>
- <StyledBody>{this.renderContent()}</StyledBody>
+ <ModalContainer>
+ <Layout>
+ <StyledHeader barStyle={headerBarStyle} />
+ <StyledCustomScrollbars fillContainer>
+ <StyledContainer>
+ <StyledBody>{this.renderContent()}</StyledBody>
- <StyledFooter>
- {this.getRecoveryAction() === RecoveryAction.disconnect && (
- <AppButton.BlockingButton onClick={this.props.onDisconnect}>
- <StyledDisconnectButton>
- {messages.pgettext('connect-view', 'Disconnect')}
- </StyledDisconnectButton>
- </AppButton.BlockingButton>
- )}
+ <StyledFooter>
+ {this.getRecoveryAction() === RecoveryAction.disconnect && (
+ <AppButton.BlockingButton onClick={this.props.onDisconnect}>
+ <StyledDisconnectButton>
+ {messages.pgettext('connect-view', 'Disconnect')}
+ </StyledDisconnectButton>
+ </AppButton.BlockingButton>
+ )}
- {this.renderExternalPaymentButton()}
+ {this.renderExternalPaymentButton()}
- <AppButton.GreenButton
- disabled={this.getRecoveryAction() === RecoveryAction.disconnect}
- onClick={this.onOpenRedeemVoucherAlert}>
- {messages.pgettext('connect-view', 'Redeem voucher')}
- </AppButton.GreenButton>
- </StyledFooter>
+ <AppButton.GreenButton
+ disabled={this.getRecoveryAction() === RecoveryAction.disconnect}
+ onClick={this.onOpenRedeemVoucherAlert}>
+ {messages.pgettext('connect-view', 'Redeem voucher')}
+ </AppButton.GreenButton>
+ </StyledFooter>
- {this.state.showRedeemVoucherAlert && this.renderRedeemVoucherAlert()}
- {this.state.showBlockWhenDisconnectedAlert && this.renderBlockWhenDisconnectedAlert()}
- </StyledContainer>
- </StyledCustomScrollbars>
+ {this.state.showRedeemVoucherAlert && this.renderRedeemVoucherAlert()}
+ {this.state.showBlockWhenDisconnectedAlert && this.renderBlockWhenDisconnectedAlert()}
+ </StyledContainer>
+ </StyledCustomScrollbars>
+ </Layout>
+ </ModalContainer>
);
}
diff --git a/gui/src/renderer/components/ExpiredAccountErrorViewStyles.tsx b/gui/src/renderer/components/ExpiredAccountErrorViewStyles.tsx
index 3559d3b8ad..8872bbb312 100644
--- a/gui/src/renderer/components/ExpiredAccountErrorViewStyles.tsx
+++ b/gui/src/renderer/components/ExpiredAccountErrorViewStyles.tsx
@@ -5,6 +5,12 @@ import * as AppButton from './AppButton';
import * as Cell from './cell';
import { bigText, smallText } from './common-styles';
import CustomScrollbars from './CustomScrollbars';
+import { DefaultHeaderBar } from './HeaderBar';
+import { Container } from './Layout';
+
+export const StyledHeader = styled(DefaultHeaderBar)({
+ flex: 0,
+});
export const StyledAccountTokenLabel = styled(AccountTokenLabel)({
fontFamily: 'Open Sans',
@@ -31,12 +37,10 @@ export const StyledCustomScrollbars = styled(CustomScrollbars)({
flex: 1,
});
-export const StyledContainer = styled.div({
- display: 'flex',
- flexDirection: 'column',
- flex: 1,
+export const StyledContainer = styled(Container)({
paddingTop: '22px',
minHeight: '100%',
+ backgroundColor: colors.darkBlue,
});
export const StyledBody = styled.div({
@@ -51,7 +55,6 @@ export const StyledFooter = styled.div({
flexDirection: 'column',
flex: 0,
padding: '18px 22px 22px',
- backgroundColor: colors.darkBlue,
});
export const StyledTitle = styled.span(bigText, {
diff --git a/gui/src/renderer/components/HeaderBar.tsx b/gui/src/renderer/components/HeaderBar.tsx
index bdf7d51924..b89811913e 100644
--- a/gui/src/renderer/components/HeaderBar.tsx
+++ b/gui/src/renderer/components/HeaderBar.tsx
@@ -3,8 +3,10 @@ import { useSelector } from 'react-redux';
import { useHistory } from 'react-router';
import styled from 'styled-components';
import { colors } from '../../config.json';
+import { TunnelState } from '../../shared/daemon-rpc-types';
import { messages } from '../../shared/gettext';
import { IReduxState } from '../redux/store';
+import { FocusFallback } from './Focus';
import ImageView from './ImageView';
export enum HeaderBarStyle {
@@ -118,3 +120,34 @@ export function HeaderBarSettingsButton() {
</HeaderBarSettingsButtonContainer>
);
}
+
+export function DefaultHeaderBar(props: IHeaderBarProps) {
+ return (
+ <HeaderBar {...props}>
+ <FocusFallback>
+ <Brand />
+ </FocusFallback>
+ <HeaderBarSettingsButton />
+ </HeaderBar>
+ );
+}
+
+export function calculateHeaderBarStyle(tunnelState: TunnelState): HeaderBarStyle {
+ switch (tunnelState.state) {
+ case 'disconnected':
+ return HeaderBarStyle.error;
+ case 'connecting':
+ case 'connected':
+ return HeaderBarStyle.success;
+ case 'error':
+ return !tunnelState.details.blockFailure ? HeaderBarStyle.success : HeaderBarStyle.error;
+ case 'disconnecting':
+ switch (tunnelState.details) {
+ case 'block':
+ case 'reconnect':
+ return HeaderBarStyle.success;
+ case 'nothing':
+ return HeaderBarStyle.error;
+ }
+ }
+}
diff --git a/gui/src/renderer/components/MainView.tsx b/gui/src/renderer/components/MainView.tsx
new file mode 100644
index 0000000000..a9daeb5453
--- /dev/null
+++ b/gui/src/renderer/components/MainView.tsx
@@ -0,0 +1,13 @@
+import React from 'react';
+import { useSelector } from 'react-redux';
+import { hasExpired } from '../../shared/account-expiry';
+import { IReduxState } from '../redux/store';
+import ConnectPage from '../containers/ConnectPage';
+import ExpiredAccountErrorViewContainer from '../containers/ExpiredAccountErrorViewContainer';
+
+export default function MainView() {
+ const accountExpiry = useSelector((state: IReduxState) => state.account.expiry);
+ const accountExpired = accountExpiry && hasExpired(accountExpiry);
+
+ return accountExpired ? <ExpiredAccountErrorViewContainer /> : <ConnectPage />;
+}
diff --git a/gui/src/renderer/containers/ExpiredAccountErrorViewContainer.tsx b/gui/src/renderer/containers/ExpiredAccountErrorViewContainer.tsx
index 8b01b5e996..46890cb169 100644
--- a/gui/src/renderer/containers/ExpiredAccountErrorViewContainer.tsx
+++ b/gui/src/renderer/containers/ExpiredAccountErrorViewContainer.tsx
@@ -11,6 +11,7 @@ const mapStateToProps = (state: IReduxState) => ({
accountToken: state.account.accountToken,
accountExpiry: state.account.expiry,
loginState: state.account.status,
+ tunnelState: state.connection.status,
isBlocked: state.connection.isBlocked,
blockWhenDisconnected: state.settings.blockWhenDisconnected,
});
diff --git a/gui/src/renderer/routes.tsx b/gui/src/renderer/routes.tsx
index 37c9851daa..4fb92a237e 100644
--- a/gui/src/renderer/routes.tsx
+++ b/gui/src/renderer/routes.tsx
@@ -2,12 +2,12 @@ import * as React from 'react';
import { Route, RouteComponentProps, Switch, withRouter } from 'react-router';
import Launch from './components/Launch';
import KeyboardNavigation from './components/KeyboardNavigation';
+import MainView from './components/MainView';
import Focus, { IFocusHandle } from './components/Focus';
import LinuxSplitTunnelingSettings from './components/LinuxSplitTunnelingSettings';
import TransitionContainer, { TransitionView } from './components/TransitionContainer';
import AccountPage from './containers/AccountPage';
import AdvancedSettingsPage from './containers/AdvancedSettingsPage';
-import ConnectPage from './containers/ConnectPage';
import LoginPage from './containers/LoginPage';
import PlatformWindowContainer from './containers/PlatformWindowContainer';
import PreferencesPage from './containers/PreferencesPage';
@@ -72,7 +72,7 @@ class AppRoutes extends React.Component<RouteComponentProps, IAppRoutesState> {
<Switch key={location.key} location={location}>
<Route exact={true} path="/" component={Launch} />
<Route exact={true} path="/login" component={LoginPage} />
- <Route exact={true} path="/connect" component={ConnectPage} />
+ <Route exact={true} path="/main" component={MainView} />
<Route exact={true} path="/settings" component={SettingsPage} />
<Route exact={true} path="/settings/language" component={SelectLanguagePage} />
<Route exact={true} path="/settings/account" component={AccountPage} />