diff options
| -rw-r--r-- | gui/src/renderer/components/Connect.tsx | 5 | ||||
| -rw-r--r-- | gui/src/renderer/components/HeaderBar.tsx | 175 | ||||
| -rw-r--r-- | gui/src/renderer/components/Launch.tsx | 44 | ||||
| -rw-r--r-- | gui/src/renderer/components/Layout.tsx | 17 | ||||
| -rw-r--r-- | gui/src/renderer/components/LayoutStyles.tsx | 7 | ||||
| -rw-r--r-- | gui/src/renderer/components/Login.tsx | 5 | ||||
| -rw-r--r-- | gui/src/renderer/containers/ConnectPage.tsx | 3 | ||||
| -rw-r--r-- | gui/src/renderer/containers/LaunchPage.tsx | 17 | ||||
| -rw-r--r-- | gui/src/renderer/containers/LoginPage.tsx | 5 | ||||
| -rw-r--r-- | gui/src/renderer/routes.tsx | 4 |
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} /> |
