summaryrefslogtreecommitdiffhomepage
path: root/gui/src
diff options
context:
space:
mode:
authorOskar Nyberg <oskar@mullvad.net>2020-06-28 19:04:41 +0200
committerOskar Nyberg <oskar@mullvad.net>2020-07-01 10:55:33 +0200
commitf6219ce2bd4774dbfc21a96a3afef1c2fad1e1d9 (patch)
treec25ee3d857381697b5ad169a1897d9b007447a92 /gui/src
parentf074c054d23a8539135adcbc8f5e237c25c6cad3 (diff)
downloadmullvadvpn-f6219ce2bd4774dbfc21a96a3afef1c2fad1e1d9.tar.xz
mullvadvpn-f6219ce2bd4774dbfc21a96a3afef1c2fad1e1d9.zip
Convert HeaderBar components from ReactXP
Diffstat (limited to 'gui/src')
-rw-r--r--gui/src/renderer/components/Connect.tsx5
-rw-r--r--gui/src/renderer/components/HeaderBar.tsx175
-rw-r--r--gui/src/renderer/components/Launch.tsx44
-rw-r--r--gui/src/renderer/components/Layout.tsx17
-rw-r--r--gui/src/renderer/components/LayoutStyles.tsx7
-rw-r--r--gui/src/renderer/components/Login.tsx5
-rw-r--r--gui/src/renderer/containers/ConnectPage.tsx3
-rw-r--r--gui/src/renderer/containers/LaunchPage.tsx17
-rw-r--r--gui/src/renderer/containers/LoginPage.tsx5
-rw-r--r--gui/src/renderer/routes.tsx4
10 files changed, 101 insertions, 181 deletions
diff --git a/gui/src/renderer/components/Connect.tsx b/gui/src/renderer/components/Connect.tsx
index 9ee96c273e..bc5d854bf1 100644
--- a/gui/src/renderer/components/Connect.tsx
+++ b/gui/src/renderer/components/Connect.tsx
@@ -7,7 +7,7 @@ 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 { Brand, HeaderBarStyle, SettingsBarButton } from './HeaderBar';
+import { Brand, HeaderBarStyle, HeaderBarSettingsButton } from './HeaderBar';
import ImageView from './ImageView';
import { Container, Header, Layout } from './Layout';
import Map, { MarkerStyle, ZoomLevel } from './Map';
@@ -20,7 +20,6 @@ interface IProps {
accountExpiry?: string;
blockWhenDisconnected: boolean;
selectedRelayName: string;
- onSettings: () => void;
onSelectLocation: () => void;
onConnect: () => void;
onDisconnect: () => void;
@@ -88,7 +87,7 @@ export default class Connect extends React.Component<IProps, IState> {
<Layout>
<Header barStyle={this.headerBarStyle()}>
<Brand />
- <SettingsBarButton onPress={this.props.onSettings} />
+ <HeaderBarSettingsButton />
</Header>
<StyledContainer>
{this.state.isAccountExpired ||
diff --git a/gui/src/renderer/components/HeaderBar.tsx b/gui/src/renderer/components/HeaderBar.tsx
index b32e81be9b..22de5ea050 100644
--- a/gui/src/renderer/components/HeaderBar.tsx
+++ b/gui/src/renderer/components/HeaderBar.tsx
@@ -1,5 +1,5 @@
-import * as React from 'react';
-import { Button, Component, Styles, Text, Types, View } from 'reactxp';
+import React, { useCallback } from 'react';
+import { useHistory } from 'react-router';
import styled from 'styled-components';
import { colors } from '../../config.json';
import { messages } from '../../shared/gettext';
@@ -12,121 +12,92 @@ export enum HeaderBarStyle {
success = 'success',
}
-export interface IHeaderBarProps {
- barStyle: HeaderBarStyle;
- style?: Types.ViewStyleRuleSet;
-}
-
-const headerBarStyles = {
- container: {
- base: Styles.createViewStyle({
- paddingTop: 12,
- paddingBottom: 12,
- paddingLeft: 12,
- paddingRight: 12,
- }),
- darwin: Styles.createViewStyle({
- paddingTop: 24,
- }),
- },
- 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,
- }),
- },
+const headerBarStyleColorMap = {
+ [HeaderBarStyle.default]: colors.blue,
+ [HeaderBarStyle.defaultDark]: colors.darkBlue,
+ [HeaderBarStyle.error]: colors.red,
+ [HeaderBarStyle.success]: colors.green,
};
-export default class HeaderBar extends Component<IHeaderBarProps> {
- public static defaultProps: IHeaderBarProps = {
- barStyle: HeaderBarStyle.default,
- };
+const HeaderBarContainer = styled.div({}, (props: { barStyle?: HeaderBarStyle }) => ({
+ padding: '12px',
+ paddingTop: process.platform === 'darwin' ? '24px' : '12px',
+ backgroundColor: headerBarStyleColorMap[props.barStyle ?? HeaderBarStyle.default],
+}));
- public render() {
- const style = [
- headerBarStyles.container.base,
- process.platform === 'darwin' ? headerBarStyles.container.darwin : undefined,
- headerBarStyles.barStyle[this.props.barStyle],
- this.props.style,
- ];
+const HeaderBarContent = styled.div({
+ display: 'flex',
+ alignItems: 'center',
+ justifyContent: 'flex-end',
+});
- return (
- <View style={style}>
- <View style={headerBarStyles.content}>{this.props.children}</View>
- </View>
- );
- }
+interface IHeaderBarProps {
+ barStyle?: HeaderBarStyle;
+ className?: string;
+ children?: React.ReactNode;
}
-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.white80,
- marginLeft: 9,
- }),
-};
+export default function HeaderBar(props: IHeaderBarProps) {
+ return (
+ <HeaderBarContainer barStyle={props.barStyle} className={props.className}>
+ <HeaderBarContent>{props.children}</HeaderBarContent>
+ </HeaderBarContainer>
+ );
+}
-const Logo = styled(ImageView)({
- marginLeft: '6px',
+const BrandContainer = styled.div({
+ display: 'flex',
+ flex: 1,
+ alignItems: 'center',
});
-export class Brand extends Component {
- public render() {
- return (
- <View style={brandStyles.container}>
- <Logo width={44} height={44} source="logo-icon" />
- <Text style={brandStyles.title}>{messages.pgettext('generic', 'MULLVAD VPN')}</Text>
- </View>
- );
- }
-}
+const Title = styled.span({
+ fontFamily: 'DINPro',
+ fontSize: '24px',
+ fontWeight: 900,
+ lineHeight: '30px',
+ letterSpacing: -0.5,
+ color: colors.white80,
+ marginLeft: '9px',
+});
+
+const Logo = styled(ImageView)({
+ margin: '4px 0 3px 6px',
+});
-interface ISettingsButtonProps {
- onPress?: () => void;
+export function Brand() {
+ return (
+ <BrandContainer>
+ <Logo width={44} height={44} source="logo-icon" />
+ <Title>{messages.pgettext('generic', 'MULLVAD VPN')}</Title>
+ </BrandContainer>
+ );
}
-const settingsBarButtonStyle = Styles.createButtonStyle({
+const HeaderBarSettingsButtonContainer = styled.button({
cursor: 'default',
padding: 0,
marginLeft: 8,
+ backgroundColor: 'transparent',
+ border: 'none',
});
-export class SettingsBarButton extends Component<ISettingsButtonProps> {
- public render() {
- return (
- <Button style={settingsBarButtonStyle} onPress={this.props.onPress}>
- <ImageView
- height={24}
- width={24}
- source="icon-settings"
- tintColor={'rgba(255, 255, 255, 0.8)'}
- tintHoverColor={'rgba(255, 255, 255, 1.0)'}
- />
- </Button>
- );
- }
+export function HeaderBarSettingsButton() {
+ const history = useHistory();
+
+ const openSettings = useCallback(() => {
+ history.push('/settings');
+ }, [history]);
+
+ return (
+ <HeaderBarSettingsButtonContainer onClick={openSettings}>
+ <ImageView
+ height={24}
+ width={24}
+ source="icon-settings"
+ tintColor={'rgba(255, 255, 255, 0.8)'}
+ tintHoverColor={'rgba(255, 255, 255, 1.0)'}
+ />
+ </HeaderBarSettingsButtonContainer>
+ );
}
diff --git a/gui/src/renderer/components/Launch.tsx b/gui/src/renderer/components/Launch.tsx
index 65d18f68ff..7f1e40dbd4 100644
--- a/gui/src/renderer/components/Launch.tsx
+++ b/gui/src/renderer/components/Launch.tsx
@@ -1,9 +1,9 @@
import * as React from 'react';
-import { Component, Styles, Text, View } from 'reactxp';
+import { Styles, Text, View } from 'reactxp';
import styled from 'styled-components';
import { colors } from '../../config.json';
import { messages } from '../../shared/gettext';
-import { SettingsBarButton } from './HeaderBar';
+import { HeaderBarSettingsButton } from './HeaderBar';
import ImageView from './ImageView';
import { Container, Header, Layout } from './Layout';
@@ -37,27 +37,21 @@ const Logo = styled(ImageView)({
marginBottom: '5px',
});
-interface IProps {
- openSettings: () => void;
-}
-
-export default class Launch extends Component<IProps> {
- public render() {
- return (
- <Layout>
- <Header>
- <SettingsBarButton onPress={this.props.openSettings} />
- </Header>
- <Container>
- <View style={styles.container}>
- <Logo height={106} width={106} source="logo-icon" />
- <Text style={styles.title}>{messages.pgettext('generic', 'MULLVAD VPN')}</Text>
- <Text style={styles.subtitle}>
- {messages.pgettext('launch-view', 'Connecting to Mullvad system service...')}
- </Text>
- </View>
- </Container>
- </Layout>
- );
- }
+export default function Launch() {
+ return (
+ <Layout>
+ <Header>
+ <HeaderBarSettingsButton />
+ </Header>
+ <Container>
+ <View style={styles.container}>
+ <Logo height={106} width={106} source="logo-icon" />
+ <Text style={styles.title}>{messages.pgettext('generic', 'MULLVAD VPN')}</Text>
+ <Text style={styles.subtitle}>
+ {messages.pgettext('launch-view', 'Connecting to Mullvad system service...')}
+ </Text>
+ </View>
+ </Container>
+ </Layout>
+ );
}
diff --git a/gui/src/renderer/components/Layout.tsx b/gui/src/renderer/components/Layout.tsx
index 825cbf9190..8caf983b40 100644
--- a/gui/src/renderer/components/Layout.tsx
+++ b/gui/src/renderer/components/Layout.tsx
@@ -1,21 +1,10 @@
-import * as React from 'react';
-import { Component, View } from 'reactxp';
import styled from 'styled-components';
import { colors } from '../../config.json';
import HeaderBar from './HeaderBar';
-import styles from './LayoutStyles';
-export class Header extends Component<HeaderBar['props']> {
- public static defaultProps = HeaderBar.defaultProps;
-
- public render() {
- return (
- <View style={[styles.header, this.props.style]}>
- <HeaderBar barStyle={this.props.barStyle}>{this.props.children}</HeaderBar>
- </View>
- );
- }
-}
+export const Header = styled(HeaderBar)({
+ flex: 0,
+});
export const Container = styled.div({
display: 'flex',
diff --git a/gui/src/renderer/components/LayoutStyles.tsx b/gui/src/renderer/components/LayoutStyles.tsx
deleted file mode 100644
index aa27549f39..0000000000
--- a/gui/src/renderer/components/LayoutStyles.tsx
+++ /dev/null
@@ -1,7 +0,0 @@
-import { Styles } from 'reactxp';
-
-export default {
- header: Styles.createViewStyle({
- flex: 0,
- }),
-};
diff --git a/gui/src/renderer/components/Login.tsx b/gui/src/renderer/components/Login.tsx
index f22f72be67..ee5f7e40ac 100644
--- a/gui/src/renderer/components/Login.tsx
+++ b/gui/src/renderer/components/Login.tsx
@@ -6,7 +6,7 @@ import { messages } from '../../shared/gettext';
import { formatAccountToken } from '../lib/account';
import Accordion from './Accordion';
import * as AppButton from './AppButton';
-import { Brand, SettingsBarButton } from './HeaderBar';
+import { Brand, HeaderBarSettingsButton } from './HeaderBar';
import ImageView from './ImageView';
import { Container, Header, Layout } from './Layout';
import styles, {
@@ -23,7 +23,6 @@ interface IProps {
accountToken?: AccountToken;
accountHistory: AccountToken[];
loginState: LoginState;
- openSettings?: () => void;
openExternalLink: (type: string) => void;
login: (accountToken: AccountToken) => void;
resetLoginError: () => void;
@@ -105,7 +104,7 @@ export default class Login extends Component<IProps, IState> {
<Layout>
<Header>
<Brand />
- <SettingsBarButton onPress={this.props.openSettings} />
+ <HeaderBarSettingsButton />
</Header>
<Container>
<View style={styles.login_form}>
diff --git a/gui/src/renderer/containers/ConnectPage.tsx b/gui/src/renderer/containers/ConnectPage.tsx
index 57f550d988..f09033ae43 100644
--- a/gui/src/renderer/containers/ConnectPage.tsx
+++ b/gui/src/renderer/containers/ConnectPage.tsx
@@ -76,9 +76,6 @@ const mapDispatchToProps = (dispatch: ReduxDispatch, props: IAppContext) => {
const history = bindActionCreators({ push }, dispatch);
return {
- onSettings: () => {
- history.push('/settings');
- },
onSelectLocation: () => {
history.push('/select-location');
},
diff --git a/gui/src/renderer/containers/LaunchPage.tsx b/gui/src/renderer/containers/LaunchPage.tsx
deleted file mode 100644
index aae7293bb1..0000000000
--- a/gui/src/renderer/containers/LaunchPage.tsx
+++ /dev/null
@@ -1,17 +0,0 @@
-import { push } from 'connected-react-router';
-import { connect } from 'react-redux';
-import { bindActionCreators } from 'redux';
-import Launch from '../components/Launch';
-import { IReduxState, ReduxDispatch } from '../redux/store';
-
-const mapStateToProps = (_state: IReduxState) => ({});
-const mapDispatchToProps = (dispatch: ReduxDispatch) => {
- const history = bindActionCreators({ push }, dispatch);
- return {
- openSettings() {
- history.push('/settings');
- },
- };
-};
-
-export default connect(mapStateToProps, mapDispatchToProps)(Launch);
diff --git a/gui/src/renderer/containers/LoginPage.tsx b/gui/src/renderer/containers/LoginPage.tsx
index 2cadcca426..d3cc89caf6 100644
--- a/gui/src/renderer/containers/LoginPage.tsx
+++ b/gui/src/renderer/containers/LoginPage.tsx
@@ -1,4 +1,3 @@
-import { push } from 'connected-react-router';
import { shell } from 'electron';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
@@ -17,12 +16,8 @@ const mapStateToProps = (state: IReduxState) => {
};
};
const mapDispatchToProps = (dispatch: ReduxDispatch, props: IAppContext) => {
- const history = bindActionCreators({ push }, dispatch);
const { resetLoginError, updateAccountToken } = bindActionCreators(accountActions, dispatch);
return {
- openSettings: () => {
- history.push('/settings');
- },
login: (account: string) => {
consumePromise(props.app.login(account));
},
diff --git a/gui/src/renderer/routes.tsx b/gui/src/renderer/routes.tsx
index d3ddc95128..c3aed29a7c 100644
--- a/gui/src/renderer/routes.tsx
+++ b/gui/src/renderer/routes.tsx
@@ -1,10 +1,10 @@
import * as React from 'react';
import { Route, RouteComponentProps, Switch, withRouter } from 'react-router';
+import Launch from './components/Launch';
import TransitionContainer, { TransitionView } from './components/TransitionContainer';
import AccountPage from './containers/AccountPage';
import AdvancedSettingsPage from './containers/AdvancedSettingsPage';
import ConnectPage from './containers/ConnectPage';
-import LaunchPage from './containers/LaunchPage';
import LoginPage from './containers/LoginPage';
import PlatformWindowContainer from './containers/PlatformWindowContainer';
import PreferencesPage from './containers/PreferencesPage';
@@ -60,7 +60,7 @@ class AppRoutes extends React.Component<RouteComponentProps, IAppRoutesState> {
<TransitionContainer {...transitionProps}>
<TransitionView viewId={location.key || ''}>
<Switch key={location.key} location={location}>
- <Route exact={true} path="/" component={LaunchPage} />
+ <Route exact={true} path="/" component={Launch} />
<Route exact={true} path="/login" component={LoginPage} />
<Route exact={true} path="/connect" component={ConnectPage} />
<Route exact={true} path="/settings" component={SettingsPage} />