summaryrefslogtreecommitdiffhomepage
path: root/gui
diff options
context:
space:
mode:
authorAndrej Mihajlov <and@mullvad.net>2018-10-24 11:50:10 +0200
committerAndrej Mihajlov <and@mullvad.net>2018-10-24 11:50:10 +0200
commit3c22e2bfacd573d24af932cc6b0238f06335e4ae (patch)
treed8969b59205dbbad8701aea92b1133338ea5b5e8 /gui
parentced56025616659b116cca0d5ed1ee62c8e394061 (diff)
parent2eec1daf30a78806e13043db516ebfa3a3b050be (diff)
downloadmullvadvpn-3c22e2bfacd573d24af932cc6b0238f06335e4ae.tar.xz
mullvadvpn-3c22e2bfacd573d24af932cc6b0238f06335e4ae.zip
Merge branch 'typescriptify-bit-by-bit'
Diffstat (limited to 'gui')
-rw-r--r--gui/packages/components/.eslintrc5
-rw-r--r--gui/packages/components/src/HeaderBar.tsx (renamed from gui/packages/desktop/src/renderer/components/HeaderBar.js)79
-rw-r--r--gui/packages/components/src/ImageView.tsx76
-rw-r--r--gui/packages/components/src/SettingsHeader.tsx (renamed from gui/packages/desktop/src/renderer/components/SettingsHeader.js)25
-rw-r--r--gui/packages/components/src/index.ts3
-rw-r--r--gui/packages/components/tslint.json3
-rw-r--r--gui/packages/desktop/src/renderer/components/Account.js6
-rw-r--r--gui/packages/desktop/src/renderer/components/AdvancedSettings.js8
-rw-r--r--gui/packages/desktop/src/renderer/components/AdvancedSettingsStyles.js1
-rw-r--r--gui/packages/desktop/src/renderer/components/AppButton.js19
-rw-r--r--gui/packages/desktop/src/renderer/components/AppButtonStyles.js13
-rw-r--r--gui/packages/desktop/src/renderer/components/Cell.js21
-rw-r--r--gui/packages/desktop/src/renderer/components/Connect.js29
-rw-r--r--gui/packages/desktop/src/renderer/components/Img.js67
-rw-r--r--gui/packages/desktop/src/renderer/components/Launch.js5
-rw-r--r--gui/packages/desktop/src/renderer/components/Layout.js2
-rw-r--r--gui/packages/desktop/src/renderer/components/Login.js26
-rw-r--r--gui/packages/desktop/src/renderer/components/LoginStyles.js8
-rw-r--r--gui/packages/desktop/src/renderer/components/NavigationBar.js6
-rw-r--r--gui/packages/desktop/src/renderer/components/NotificationBanner.js4
-rw-r--r--gui/packages/desktop/src/renderer/components/Preferences.js2
-rw-r--r--gui/packages/desktop/src/renderer/components/SelectLocation.js18
-rw-r--r--gui/packages/desktop/src/renderer/components/SelectLocationStyles.js3
-rw-r--r--gui/packages/desktop/src/renderer/components/Settings.js9
-rw-r--r--gui/packages/desktop/src/renderer/components/Support.js11
25 files changed, 220 insertions, 229 deletions
diff --git a/gui/packages/components/.eslintrc b/gui/packages/components/.eslintrc
deleted file mode 100644
index e5a34aec6a..0000000000
--- a/gui/packages/components/.eslintrc
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "env": {
- "browser": true
- }
-}
diff --git a/gui/packages/desktop/src/renderer/components/HeaderBar.js b/gui/packages/components/src/HeaderBar.tsx
index 57549442c8..57e8373651 100644
--- a/gui/packages/desktop/src/renderer/components/HeaderBar.js
+++ b/gui/packages/components/src/HeaderBar.tsx
@@ -1,15 +1,18 @@
-// @flow
+import * as React from 'react';
+import { Button, Component, Styles, Text, Types, View } from 'reactxp';
+import ImageView from './ImageView';
-import React from 'react';
-import { Component, Text, Button, View, Styles } from 'reactxp';
-
-import Img from './Img';
-import { colors } from '../../config';
+export enum HeaderBarStyle {
+ default = 'default',
+ defaultDark = 'defaultDark',
+ error = 'error',
+ success = 'success',
+}
-export type HeaderBarStyle = 'default' | 'defaultDark' | 'error' | 'success';
-type HeaderBarProps = {
- barStyle: HeaderBarStyle,
-};
+interface IHeaderBarProps {
+ barStyle: HeaderBarStyle;
+ style?: Types.ViewStyleRuleSet;
+}
const headerBarStyles = {
container: {
@@ -24,6 +27,8 @@ const headerBarStyles = {
paddingTop: 24,
}),
linux: Styles.createViewStyle({
+ // WebKitAppRegion is not standard :/
+ // @ts-ignore
WebkitAppRegion: 'drag',
}),
},
@@ -37,28 +42,29 @@ const headerBarStyles = {
}),
barStyle: {
default: Styles.createViewStyle({
- backgroundColor: colors.blue,
+ backgroundColor: 'rgb(41, 77, 115)', // colors.blue
}),
defaultDark: Styles.createViewStyle({
- backgroundColor: colors.darkBlue,
+ backgroundColor: 'rgb(25, 46, 69)', // colors.darkBlue
}),
error: Styles.createViewStyle({
- backgroundColor: colors.red,
+ backgroundColor: 'rgb(208, 2, 27)', // colors.red
}),
success: Styles.createViewStyle({
- backgroundColor: colors.green,
+ backgroundColor: 'rgb(68, 173, 77)', // colors.green
}),
},
};
-export default class HeaderBar extends Component<HeaderBarProps> {
- static defaultProps: HeaderBarProps = {
- barStyle: 'default',
+export default class HeaderBar extends Component<IHeaderBarProps> {
+ public static defaultProps: IHeaderBarProps = {
+ barStyle: HeaderBarStyle.default,
};
- render() {
+ public render() {
const style = [
headerBarStyles.container.base,
+ // @ts-ignore
headerBarStyles.container.platformOverride[process.platform],
headerBarStyles.barStyle[this.props.barStyle],
this.props.style,
@@ -84,25 +90,25 @@ const brandStyles = {
fontWeight: '900',
lineHeight: 30,
letterSpacing: -0.5,
- color: colors.white60,
+ color: 'rgba(255, 255, 255, 0.6)', // colors.white60
marginLeft: 8,
}),
};
export class Brand extends Component {
- render() {
+ public render() {
return (
- <View style={brandStyles.container} testName="headerbar__container">
- <Img width={50} height={50} source="logo-icon" />
+ <View style={brandStyles.container}>
+ <ImageView width={50} height={50} source="logo-icon" />
<Text style={brandStyles.title}>{'MULLVAD VPN'}</Text>
</View>
);
}
}
-type SettingsButtonProps = {
- onPress: ?() => void,
-};
+interface ISettingsButtonProps {
+ onPress?: () => void;
+}
const settingsBarButtonStyles = {
container: {
@@ -113,36 +119,29 @@ const settingsBarButtonStyles = {
}),
platformOverride: {
linux: Styles.createViewStyle({
+ // WebKitAppRegion is not standard :/
+ // @ts-ignore
WebkitAppRegion: 'no-drag',
}),
},
},
- icon: {
- normal: Styles.createViewStyle({
- color: colors.white60,
- }),
- hover: Styles.createViewStyle({
- color: colors.white,
- }),
- },
};
-export class SettingsBarButton extends Component<SettingsButtonProps> {
- render() {
+export class SettingsBarButton extends Component<ISettingsButtonProps> {
+ public render() {
return (
<Button
style={[
settingsBarButtonStyles.container.base,
+ // @ts-ignore
settingsBarButtonStyles.container.platformOverride[process.platform],
]}
- onPress={this.props.onPress}
- testName="headerbar__settings">
- <Img
+ onPress={this.props.onPress}>
+ <ImageView
height={24}
width={24}
source="icon-settings"
- style={settingsBarButtonStyles.icon.normal}
- hoverStyle={settingsBarButtonStyles.icon.hover}
+ tintColor={'rgba(255, 255, 255, 0.6)'}
/>
</Button>
);
diff --git a/gui/packages/components/src/ImageView.tsx b/gui/packages/components/src/ImageView.tsx
new file mode 100644
index 0000000000..9602130a63
--- /dev/null
+++ b/gui/packages/components/src/ImageView.tsx
@@ -0,0 +1,76 @@
+import * as React from 'react';
+import { Component, Styles, Types, View } from 'reactxp';
+
+interface IProps {
+ source: string;
+ width?: number;
+ height?: number;
+ tintColor?: string;
+ tintHoverColor?: string;
+ style?: Types.ViewStyleRuleSet;
+ disabled?: boolean;
+}
+
+interface IState {
+ hovered: boolean;
+}
+
+export default class ImageView extends Component<IProps, IState> {
+ public state = { hovered: false };
+
+ public render() {
+ const { source, width, height, style, tintColor, tintHoverColor, ...otherProps } = this.props;
+ const url = `../assets/images/${source}.svg`;
+ let image;
+
+ const activeTintColor = (this.state.hovered && tintHoverColor) || tintColor;
+
+ if (activeTintColor) {
+ const maskWidth = typeof width === 'number' ? `${width}px` : 'auto';
+ const maskHeight = typeof height === 'number' ? `${height}px` : 'auto';
+ image = (
+ <div
+ style={{
+ WebkitMaskImage: `url('${url}')`,
+ WebkitMaskRepeat: 'no-repeat',
+ WebkitMaskSize: `${maskWidth} ${maskHeight}`,
+ backgroundColor: activeTintColor,
+ lineHeight: 0,
+ }}>
+ <img
+ src={url}
+ width={width}
+ height={height}
+ style={{
+ visibility: 'hidden',
+ }}
+ />
+ </div>
+ );
+ } else {
+ image = <img src={url} width={width} height={height} />;
+ }
+
+ return (
+ <View
+ {...otherProps}
+ onMouseEnter={this.onHoverStart}
+ onMouseLeave={this.onHoverEnd}
+ style={style}>
+ {image}
+ </View>
+ );
+ }
+
+ private onHoverStart = () => {
+ if (!this.props.disabled) {
+ this.setState({ hovered: true });
+ }
+ };
+
+ private onHoverEnd = () => {
+ if (!this.props.disabled) {
+ this.setState({ hovered: false });
+ }
+ };
+}
diff --git a/gui/packages/desktop/src/renderer/components/SettingsHeader.js b/gui/packages/components/src/SettingsHeader.tsx
index b5e54e9468..e099d29a2d 100644
--- a/gui/packages/desktop/src/renderer/components/SettingsHeader.js
+++ b/gui/packages/components/src/SettingsHeader.tsx
@@ -1,15 +1,10 @@
-// @flow
-
import * as React from 'react';
-import { Component, Text, View, Styles } from 'reactxp';
-import { colors } from '../../config';
+import { Component, Styles, Text, Types, View } from 'reactxp';
const styles = {
header: {
default: Styles.createViewStyle({
- flexGrow: 0,
- flexShrink: 0,
- flexBasis: 'auto',
+ flex: 0,
paddingTop: 4,
paddingRight: 24,
paddingLeft: 24,
@@ -21,7 +16,7 @@ const styles = {
fontSize: 32,
fontWeight: '900',
lineHeight: 40,
- color: colors.white,
+ color: 'rgb(255, 255, 255)',
}),
subtitle: Styles.createTextStyle({
marginTop: 4,
@@ -29,26 +24,30 @@ const styles = {
fontSize: 13,
fontWeight: '600',
overflow: 'visible',
- color: colors.white80,
+ color: 'rgba(255, 255, 255, 0.8)', // colors.white80
lineHeight: 20,
letterSpacing: -0.2,
}),
};
-export default class SettingsHeader extends Component {
- render() {
+interface ISettingsHeaderProps {
+ style?: Types.ViewStyleRuleSet;
+}
+
+export default class SettingsHeader extends Component<ISettingsHeaderProps> {
+ public render() {
return <View style={[styles.header.default, this.props.style]}>{this.props.children}</View>;
}
}
export class HeaderTitle extends Component {
- render() {
+ public render() {
return <Text style={[styles.title]}>{this.props.children}</Text>;
}
}
export class HeaderSubTitle extends Component {
- render() {
+ public render() {
return <Text style={[styles.subtitle]}>{this.props.children}</Text>;
}
}
diff --git a/gui/packages/components/src/index.ts b/gui/packages/components/src/index.ts
index 648ddabdf9..46c4ec3195 100644
--- a/gui/packages/components/src/index.ts
+++ b/gui/packages/components/src/index.ts
@@ -2,3 +2,6 @@ export { default as Accordion } from './Accordion';
export { default as ClipboardLabel } from './ClipboardLabel';
export { default as ConnectionInfo } from './ConnectionInfo';
export { default as SecuredLabel, SecuredDisplayStyle } from './SecuredLabel';
+export { default as HeaderBar, HeaderBarStyle, Brand, SettingsBarButton } from './HeaderBar';
+export { default as SettingsHeader, HeaderTitle, HeaderSubTitle } from './SettingsHeader';
+export { default as ImageView } from './ImageView';
diff --git a/gui/packages/components/tslint.json b/gui/packages/components/tslint.json
index 613436b4c3..03e14ec96a 100644
--- a/gui/packages/components/tslint.json
+++ b/gui/packages/components/tslint.json
@@ -6,7 +6,8 @@
],
"jsRules": {},
"rules": {
- "object-literal-sort-keys": false
+ "object-literal-sort-keys": false,
+ "max-classes-per-file": false
},
"rulesDirectory": []
}
diff --git a/gui/packages/desktop/src/renderer/components/Account.js b/gui/packages/desktop/src/renderer/components/Account.js
index a08165c1bc..0792e58343 100644
--- a/gui/packages/desktop/src/renderer/components/Account.js
+++ b/gui/packages/desktop/src/renderer/components/Account.js
@@ -3,13 +3,11 @@
import moment from 'moment';
import * as React from 'react';
import { Component, Text, View } from 'reactxp';
-import { ClipboardLabel } from '@mullvad/components';
+import { ClipboardLabel, ImageView, SettingsHeader, HeaderTitle } from '@mullvad/components';
import * as AppButton from './AppButton';
import { Layout, Container } from './Layout';
import { NavigationBar, BackBarItem } from './NavigationBar';
-import SettingsHeader, { HeaderTitle } from './SettingsHeader';
import styles from './AccountStyles';
-import Img from './Img';
import type { AccountToken } from '../lib/daemon-rpc';
@@ -65,7 +63,7 @@ export default class Account extends Component<Props> {
icon="icon-extLink"
testName="account__buymore">
<AppButton.Label>Buy more credit</AppButton.Label>
- <Img source="icon-extLink" height={16} width={16} />
+ <ImageView source="icon-extLink" height={16} width={16} />
</AppButton.GreenButton>
<AppButton.RedButton onPress={this.props.onLogout} testName="account__logout">
{'Log out'}
diff --git a/gui/packages/desktop/src/renderer/components/AdvancedSettings.js b/gui/packages/desktop/src/renderer/components/AdvancedSettings.js
index a33ca074a5..ddfcf5f2ce 100644
--- a/gui/packages/desktop/src/renderer/components/AdvancedSettings.js
+++ b/gui/packages/desktop/src/renderer/components/AdvancedSettings.js
@@ -2,6 +2,7 @@
import * as React from 'react';
import { Button, Component, Text, View } from 'reactxp';
+import { ImageView, SettingsHeader, HeaderTitle } from '@mullvad/components';
import * as Cell from './Cell';
import { Layout, Container } from './Layout';
import {
@@ -11,10 +12,9 @@ import {
BackBarItem,
TitleBarItem,
} from './NavigationBar';
-import SettingsHeader, { HeaderTitle } from './SettingsHeader';
import Switch from './Switch';
import styles from './AdvancedSettingsStyles';
-import Img from './Img';
+import { colors } from '../../config';
const MIN_MSSFIX_VALUE = 1000;
const MAX_MSSFIX_VALUE = 1450;
@@ -239,10 +239,10 @@ class Selector extends Component<SelectorProps<*>, SelectorState> {
onHoverStart={() => this.handleButtonHover(value)}
onHoverEnd={() => this.handleButtonHover(-1)}
key={value}>
- <Img
+ <ImageView
style={styles.advanced_settings__cell_icon}
source="icon-tick"
- tintColor="currentColor"
+ tintColor={colors.white}
/>
<Text style={styles.advanced_settings__cell_label}>{value}</Text>
</Button>
diff --git a/gui/packages/desktop/src/renderer/components/AdvancedSettingsStyles.js b/gui/packages/desktop/src/renderer/components/AdvancedSettingsStyles.js
index 5857ddf183..ffd2e9f64f 100644
--- a/gui/packages/desktop/src/renderer/components/AdvancedSettingsStyles.js
+++ b/gui/packages/desktop/src/renderer/components/AdvancedSettingsStyles.js
@@ -49,7 +49,6 @@ export default {
height: 24,
marginRight: 8,
flex: 0,
- color: colors.white80,
}),
advanced_settings__cell_dimmed: Styles.createViewStyle({
cursor: 'default',
diff --git a/gui/packages/desktop/src/renderer/components/AppButton.js b/gui/packages/desktop/src/renderer/components/AppButton.js
index fe1f74dc20..7e34c84803 100644
--- a/gui/packages/desktop/src/renderer/components/AppButton.js
+++ b/gui/packages/desktop/src/renderer/components/AppButton.js
@@ -2,8 +2,9 @@
import * as React from 'react';
import { Button, Text, Component } from 'reactxp';
+import { ImageView } from '@mullvad/components';
import styles from './AppButtonStyles';
-import Img from './Img';
+import { colors } from '../../config';
export class Label extends Text {}
@@ -20,12 +21,12 @@ type State = {
class BaseButton extends Component<Props, State> {
state = { hovered: false };
- textStyle = () => styles.white;
- iconStyle = () => styles.white;
- backgroundStyle = () => (this.state.hovered ? styles.white80 : styles.white);
-
+ backgroundStyle = () => {
+ throw new Error('Implement backgroundStyle in subclasses.');
+ };
onHoverStart = () => (!this.props.disabled ? this.setState({ hovered: true }) : null);
onHoverEnd = () => (!this.props.disabled ? this.setState({ hovered: false }) : null);
+
render() {
const { children, style, ...otherProps } = this.props;
return (
@@ -39,16 +40,16 @@ class BaseButton extends Component<Props, State> {
let updatedProps = {};
if (node.type === Label) {
- updatedProps = { style: [styles.label, this.textStyle()] };
+ updatedProps = { style: [styles.label] };
}
- if (node.type === Img) {
- updatedProps = { tintColor: 'currentColor', style: [styles.icon, this.iconStyle()] };
+ if (node.type === ImageView) {
+ updatedProps = { tintColor: colors.white, style: [styles.icon] };
}
return React.cloneElement(node, updatedProps);
} else {
- return <Label style={[styles.label, this.textStyle()]}>{children}</Label>;
+ return <Label style={[styles.label]}>{children}</Label>;
}
})}
</Button>
diff --git a/gui/packages/desktop/src/renderer/components/AppButtonStyles.js b/gui/packages/desktop/src/renderer/components/AppButtonStyles.js
index 6ef2bb6420..9b11375f01 100644
--- a/gui/packages/desktop/src/renderer/components/AppButtonStyles.js
+++ b/gui/packages/desktop/src/renderer/components/AppButtonStyles.js
@@ -22,12 +22,6 @@ export default {
blueHover: Styles.createViewStyle({
backgroundColor: colors.blue60,
}),
- white80: Styles.createViewStyle({
- color: colors.white80,
- }),
- white: Styles.createViewStyle({
- color: colors.white,
- }),
transparent: Styles.createViewStyle({
backgroundColor: colors.white20,
}),
@@ -46,11 +40,6 @@ export default {
right: 8,
marginLeft: 8,
}),
- iconTransparent: Styles.createViewStyle({
- position: 'absolute',
- alignSelf: 'flex-end',
- right: 42,
- }),
common: Styles.createViewStyle({
cursor: 'default',
paddingTop: 9,
@@ -63,7 +52,6 @@ export default {
alignContent: 'center',
justifyContent: 'center',
}),
-
label: Styles.createTextStyle({
alignSelf: 'center',
fontFamily: 'DINPro',
@@ -71,5 +59,6 @@ export default {
fontWeight: '900',
lineHeight: 26,
flex: 1,
+ color: colors.white,
}),
};
diff --git a/gui/packages/desktop/src/renderer/components/Cell.js b/gui/packages/desktop/src/renderer/components/Cell.js
index 969a69701f..23edeb26ac 100644
--- a/gui/packages/desktop/src/renderer/components/Cell.js
+++ b/gui/packages/desktop/src/renderer/components/Cell.js
@@ -2,7 +2,7 @@
import * as React from 'react';
import { Button, Component, Styles, Text, TextInput, Types, View } from 'reactxp';
-import PlainImg from './Img';
+import { ImageView } from '@mullvad/components';
import { colors } from '../../config';
const styles = {
@@ -84,7 +84,6 @@ const styles = {
backgroundColor: colors.blue80,
}),
icon: Styles.createViewStyle({
- color: colors.white60,
marginLeft: 8,
}),
@@ -208,18 +207,18 @@ export function SubText({ children, style, cellHoverStyle, ...otherProps }: SubT
);
}
-export type IconProps = {
- cellHoverStyle?: Types.ViewStyle,
- style?: Types.ViewStyle,
-};
-
-export function Icon({ style, cellHoverStyle, ...otherProps }: IconProps) {
+export function Icon({
+ style,
+ tintColor,
+ tintHoverColor,
+ ...otherProps
+}: React.ElementProps<typeof ImageView>) {
return (
<CellHoverContext.Consumer>
{(hovered) => (
- <PlainImg
- tintColor={'currentColor'}
- style={[styles.icon, style, hovered && cellHoverStyle]}
+ <ImageView
+ tintColor={(hovered && tintHoverColor) || tintColor || colors.white60}
+ style={[styles.icon, style]}
{...otherProps}
/>
)}
diff --git a/gui/packages/desktop/src/renderer/components/Connect.js b/gui/packages/desktop/src/renderer/components/Connect.js
index b3a60b5082..5911d1955a 100644
--- a/gui/packages/desktop/src/renderer/components/Connect.js
+++ b/gui/packages/desktop/src/renderer/components/Connect.js
@@ -3,18 +3,23 @@
import moment from 'moment';
import * as React from 'react';
import { Component, Text, View, Types } from 'reactxp';
-import { ConnectionInfo, SecuredLabel, SecuredDisplayStyle } from '@mullvad/components';
+import {
+ ConnectionInfo,
+ SecuredLabel,
+ SecuredDisplayStyle,
+ SettingsBarButton,
+ Brand,
+ HeaderBarStyle,
+ ImageView,
+} from '@mullvad/components';
import { Layout, Container, Header } from './Layout';
-import { SettingsBarButton, Brand } from './HeaderBar';
import NotificationArea from './NotificationArea';
import * as AppButton from './AppButton';
-import Img from './Img';
import Map from './Map';
import styles from './ConnectStyles';
import { NoCreditError, NoInternetError } from '../errors';
import type { TunnelState, RelayProtocol } from '../lib/daemon-rpc';
-import type { HeaderBarStyle } from './HeaderBar';
import type { ConnectionReduxState } from '../redux/connection/reducers';
import type { VersionReduxState } from '../redux/version/reducers';
@@ -63,7 +68,7 @@ export default class Connect extends Component<Props> {
return (
<View style={styles.connect}>
<View style={styles.status_icon}>
- <Img source="icon-fail" height={60} width={60} alt="" />
+ <ImageView source="icon-fail" height={60} width={60} alt="" />
</View>
<View style={styles.body}>
<View style={styles.error_title}>{title}</View>
@@ -72,7 +77,7 @@ export default class Connect extends Component<Props> {
<View>
<AppButton.GreenButton onPress={() => this.props.onExternalLink('purchase')}>
<AppButton.Label>Buy more time</AppButton.Label>
- <Img source="icon-extLink" height={16} width={16} />
+ <ImageView source="icon-extLink" height={16} width={16} />
</AppButton.GreenButton>
</View>
) : null}
@@ -162,7 +167,7 @@ export default class Connect extends Component<Props> {
{/* show spinner when connecting */}
{tunnelState === 'connecting' ? (
<View style={styles.status_icon}>
- <Img source="icon-spinner" height={60} width={60} alt="" />
+ <ImageView source="icon-spinner" height={60} width={60} alt="" />
</View>
) : null}
@@ -196,18 +201,18 @@ export default class Connect extends Component<Props> {
const { status } = this.props.connection;
switch (status.state) {
case 'disconnected':
- return 'error';
+ return HeaderBarStyle.error;
case 'connecting':
case 'connected':
case 'blocked':
- return 'success';
+ return HeaderBarStyle.success;
case 'disconnecting':
switch (status.details) {
case 'block':
case 'reconnect':
- return 'success';
+ return HeaderBarStyle.success;
case 'nothing':
- return 'error';
+ return HeaderBarStyle.error;
default:
throw new Error(`Invalid action after disconnection: ${(status.details: empty)}`);
}
@@ -286,7 +291,7 @@ class TunnelControl extends Component<TunnelControlProps, TunnelControlState> {
style={styles.switch_location_button}
onPress={this.props.onSelectLocation}>
<AppButton.Label>{this.props.selectedRelayName}</AppButton.Label>
- <Img height={12} width={7} source="icon-chevron" />
+ <ImageView height={12} width={7} source="icon-chevron" />
</AppButton.TransparentButton>
);
diff --git a/gui/packages/desktop/src/renderer/components/Img.js b/gui/packages/desktop/src/renderer/components/Img.js
deleted file mode 100644
index c39244b9c8..0000000000
--- a/gui/packages/desktop/src/renderer/components/Img.js
+++ /dev/null
@@ -1,67 +0,0 @@
-// @flow
-
-import * as React from 'react';
-import { View, Component, Types } from 'reactxp';
-
-type Props = {
- source: string,
- width?: number,
- height?: number,
- tintColor?: string,
- hoverStyle?: Types.ViewStyle,
- disabled?: boolean,
-};
-
-type State = { hovered: boolean };
-
-export default class Img extends Component<Props, State> {
- state = { hovered: false };
-
- onHoverStart = () => (!this.props.disabled ? this.setState({ hovered: true }) : null);
- onHoverEnd = () => (!this.props.disabled ? this.setState({ hovered: false }) : null);
-
- getHoverStyle = () => (this.state.hovered ? this.props.hoverStyle || null : null);
-
- render() {
- const { source, width, height, style, onMouseEnter, onMouseLeave, ...otherProps } = this.props;
- const tintColor = this.props.tintColor;
- const url = '../assets/images/' + source + '.svg';
- let image;
-
- if (tintColor) {
- const maskWidth = typeof width === 'number' ? `${width}px` : 'auto';
- const maskHeight = typeof height === 'number' ? `${height}px` : 'auto';
- image = (
- <div
- style={{
- WebkitMaskImage: `url('${url}')`,
- WebkitMaskRepeat: 'no-repeat',
- WebkitMaskSize: `${maskWidth} ${maskHeight}`,
- backgroundColor: tintColor,
- lineHeight: 0,
- }}>
- <img
- src={url}
- width={width}
- height={height}
- style={{
- visibility: 'hidden',
- }}
- />
- </div>
- );
- } else {
- image = <img src={url} width={width} height={height} />;
- }
-
- return (
- <View
- {...otherProps}
- onMouseEnter={onMouseEnter || this.onHoverStart}
- onMouseLeave={onMouseLeave || this.onHoverEnd}
- style={[style, this.getHoverStyle()]}>
- {image}
- </View>
- );
- }
-}
diff --git a/gui/packages/desktop/src/renderer/components/Launch.js b/gui/packages/desktop/src/renderer/components/Launch.js
index ef6fc851cc..cbb58b2078 100644
--- a/gui/packages/desktop/src/renderer/components/Launch.js
+++ b/gui/packages/desktop/src/renderer/components/Launch.js
@@ -2,9 +2,8 @@
import * as React from 'react';
import { Component, Styles, View, Text } from 'reactxp';
+import { ImageView, SettingsBarButton } from '@mullvad/components';
import { Layout, Container, Header } from './Layout';
-import { SettingsBarButton } from './HeaderBar';
-import Img from './Img';
import { colors } from '../../config';
const styles = {
@@ -48,7 +47,7 @@ export default class Launch extends Component<Props> {
</Header>
<Container>
<View style={styles.container} testName="headerbar__container">
- <Img height={120} width={120} source="logo-icon" style={styles.logo} />
+ <ImageView 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>
diff --git a/gui/packages/desktop/src/renderer/components/Layout.js b/gui/packages/desktop/src/renderer/components/Layout.js
index 42e96640c0..f7c87a9c08 100644
--- a/gui/packages/desktop/src/renderer/components/Layout.js
+++ b/gui/packages/desktop/src/renderer/components/Layout.js
@@ -2,7 +2,7 @@
import * as React from 'react';
import { View, Component } from 'reactxp';
-import HeaderBar from './HeaderBar';
+import { HeaderBar } from '@mullvad/components';
import styles from './LayoutStyles';
export class Header extends Component<React.ElementProps<typeof HeaderBar>> {
diff --git a/gui/packages/desktop/src/renderer/components/Login.js b/gui/packages/desktop/src/renderer/components/Login.js
index 66e699704a..c89ec100d3 100644
--- a/gui/packages/desktop/src/renderer/components/Login.js
+++ b/gui/packages/desktop/src/renderer/components/Login.js
@@ -3,9 +3,7 @@
import * as React from 'react';
import { Component, Text, TextInput, View, Animated, Styles, UserInterface } from 'reactxp';
import { Layout, Container, Header } from './Layout';
-import { SettingsBarButton, Brand } from './HeaderBar';
-import { Accordion } from '@mullvad/components';
-import Img from './Img';
+import { Accordion, ImageView, SettingsBarButton, Brand } from '@mullvad/components';
import * as Cell from './Cell';
import * as AppButton from './AppButton';
import styles from './LoginStyles';
@@ -233,7 +231,9 @@ export default class Login extends Component<Props, State> {
const statusIconPath = this._getStatusIconPath();
return (
<View style={styles.status_icon}>
- {statusIconPath ? <Img source={statusIconPath} height={48} width={48} alt="" /> : null}
+ {statusIconPath ? (
+ <ImageView source={statusIconPath} height={48} width={48} alt="" />
+ ) : null}
</View>
);
}
@@ -282,13 +282,9 @@ export default class Login extends Component<Props, State> {
}
_accountInputArrowStyles(): Array<Object> {
- const { accountToken, loginState } = this.props;
+ const { loginState } = this.props;
const classes = [styles.input_arrow];
- if (accountToken && accountToken.length >= MIN_ACCOUNT_TOKEN_LENGTH) {
- classes.push(styles.input_arrow__active);
- }
-
if (loginState === 'logging in') {
classes.push(styles.input_arrow__invisible);
}
@@ -372,12 +368,12 @@ export default class Login extends Component<Props, State> {
style={this._accountInputButtonStyles()}
onPress={this._onSubmit}
testName="account-input-button">
- <Img
+ <ImageView
style={this._accountInputArrowStyles()}
source="icon-arrow"
height={16}
width={24}
- tintColor="currentColor"
+ tintColor="rgb(255, 255, 255)"
/>
</Animated.View>
</View>
@@ -401,7 +397,7 @@ export default class Login extends Component<Props, State> {
<Text style={styles.login_footer__prompt}>{"Don't have an account number?"}</Text>
<AppButton.BlueButton onPress={this._onCreateAccount}>
<AppButton.Label>Create account</AppButton.Label>
- <Img source="icon-extLink" height={16} width={16} />
+ <ImageView source="icon-extLink" height={16} width={16} />
</AppButton.BlueButton>
</View>
);
@@ -455,10 +451,10 @@ class AccountDropdownItem extends React.Component<AccountDropdownItemProps> {
onPress={() => this.props.onSelect(this.props.value)}>
{this.props.label}
</Cell.Label>
- <Img
+ <ImageView
style={styles.account_dropdown__remove}
- hoverStyle={styles.account_dropdown__remove_hover}
- tintColor={'currentColor'}
+ tintColor={colors.blue40}
+ tintHoverColor={colors.blue}
source="icon-close-sml"
height={16}
width={16}
diff --git a/gui/packages/desktop/src/renderer/components/LoginStyles.js b/gui/packages/desktop/src/renderer/components/LoginStyles.js
index 1665b1c450..1ab3fb835a 100644
--- a/gui/packages/desktop/src/renderer/components/LoginStyles.js
+++ b/gui/packages/desktop/src/renderer/components/LoginStyles.js
@@ -70,11 +70,7 @@ export default {
justifyContent: 'center',
color: colors.blue20,
}),
- input_arrow__active: Styles.createViewStyle({
- color: colors.white,
- }),
input_arrow__invisible: Styles.createViewStyle({
- color: colors.white,
opacity: 0,
}),
account_dropdown__spacer: Styles.createViewStyle({
@@ -97,16 +93,12 @@ export default {
}),
account_dropdown__remove: Styles.createViewStyle({
justifyContent: 'center',
- color: colors.blue40,
paddingTop: 10,
paddingRight: 12,
paddingBottom: 12,
paddingLeft: 12,
marginLeft: 0,
}),
- account_dropdown__remove_hover: Styles.createViewStyle({
- color: colors.blue,
- }),
account_dropdown__label_hover: Styles.createViewStyle({
color: colors.blue,
}),
diff --git a/gui/packages/desktop/src/renderer/components/NavigationBar.js b/gui/packages/desktop/src/renderer/components/NavigationBar.js
index f85f161c5b..a4eeffb82b 100644
--- a/gui/packages/desktop/src/renderer/components/NavigationBar.js
+++ b/gui/packages/desktop/src/renderer/components/NavigationBar.js
@@ -2,7 +2,7 @@
import * as React from 'react';
import { Animated, Button, Component, Text, View, Styles, UserInterface } from 'reactxp';
-import Img from './Img';
+import { ImageView } from '@mullvad/components';
import CustomScrollbars from './CustomScrollbars';
import { colors } from '../../config';
@@ -368,7 +368,7 @@ export class CloseBarItem extends Component {
render() {
return (
<Button style={[styles.closeBarItem.default]} onPress={this.props.action}>
- <Img height={24} width={24} style={[styles.closeBarItem.icon]} source="icon-close" />
+ <ImageView height={24} width={24} style={[styles.closeBarItem.icon]} source="icon-close" />
</Button>
);
}
@@ -383,7 +383,7 @@ export class BackBarItem extends Component {
return (
<Button style={styles.backBarButton.default} onPress={this.props.action}>
<View style={styles.backBarButton.content}>
- <Img style={styles.backBarButton.icon} source="icon-back" />
+ <ImageView style={styles.backBarButton.icon} source="icon-back" />
<Text style={styles.backBarButton.label}>{this.props.title}</Text>
</View>
</Button>
diff --git a/gui/packages/desktop/src/renderer/components/NotificationBanner.js b/gui/packages/desktop/src/renderer/components/NotificationBanner.js
index a168ee0bf7..1e27712de7 100644
--- a/gui/packages/desktop/src/renderer/components/NotificationBanner.js
+++ b/gui/packages/desktop/src/renderer/components/NotificationBanner.js
@@ -2,8 +2,8 @@
import * as React from 'react';
import { Animated, View, Button, Text, Component, UserInterface, Styles, Types } from 'reactxp';
+import { ImageView } from '@mullvad/components';
import { colors } from '../../config';
-import Img from './Img';
const styles = {
collapsible: Styles.createViewStyle({
@@ -97,7 +97,7 @@ export class NotificationOpenLinkAction extends Component<{ onPress: () => void
onPress={this.props.onPress}
onHoverStart={this._onHoverStart}
onHoverEnd={this._onHoverEnd}>
- <Img
+ <ImageView
height={12}
width={12}
tintColor={this.state.hovered ? colors.white80 : colors.white60}
diff --git a/gui/packages/desktop/src/renderer/components/Preferences.js b/gui/packages/desktop/src/renderer/components/Preferences.js
index 54e32ccb60..b9f923c7e1 100644
--- a/gui/packages/desktop/src/renderer/components/Preferences.js
+++ b/gui/packages/desktop/src/renderer/components/Preferences.js
@@ -2,10 +2,10 @@
import * as React from 'react';
import { Component, View } from 'reactxp';
+import { SettingsHeader, HeaderTitle } from '@mullvad/components';
import * as Cell from './Cell';
import { Layout, Container } from './Layout';
import { NavigationBar, BackBarItem } from './NavigationBar';
-import SettingsHeader, { HeaderTitle } from './SettingsHeader';
import Switch from './Switch';
import styles from './PreferencesStyles';
diff --git a/gui/packages/desktop/src/renderer/components/SelectLocation.js b/gui/packages/desktop/src/renderer/components/SelectLocation.js
index d0e91a328b..d1933a37e5 100644
--- a/gui/packages/desktop/src/renderer/components/SelectLocation.js
+++ b/gui/packages/desktop/src/renderer/components/SelectLocation.js
@@ -3,7 +3,7 @@
import * as React from 'react';
import ReactDOM from 'react-dom';
import { View, Component } from 'reactxp';
-import { Accordion } from '@mullvad/components';
+import { Accordion, SettingsHeader, HeaderTitle, HeaderSubTitle } from '@mullvad/components';
import { Layout, Container } from './Layout';
import {
NavigationContainer,
@@ -12,7 +12,6 @@ import {
CloseBarItem,
TitleBarItem,
} from './NavigationBar';
-import SettingsHeader, { HeaderTitle, HeaderSubTitle } from './SettingsHeader';
import * as Cell from './Cell';
import styles from './SelectLocationStyles';
@@ -23,6 +22,7 @@ import type {
RelayLocationRelayRedux,
} from '../redux/settings/reducers';
import type { RelayLocation } from '../lib/daemon-rpc';
+import { colors } from '../../config';
type Props = {
relaySettings: RelaySettingsRedux,
@@ -170,7 +170,13 @@ export default class SelectLocation extends Component<Props, State> {
const statusClass = active ? styles.relay_status__active : styles.relay_status__inactive;
return isSelected ? (
- <Cell.Icon style={styles.tick_icon} source="icon-tick" height={24} width={24} />
+ <Cell.Icon
+ style={styles.tick_icon}
+ tintColor={colors.white}
+ source="icon-tick"
+ height={24}
+ width={24}
+ />
) : (
<View style={[styles.relay_status, statusClass]} />
);
@@ -216,7 +222,8 @@ export default class SelectLocation extends Component<Props, State> {
{hasChildren ? (
<Cell.Icon
style={styles.collapse_button}
- hoverStyle={styles.expand_chevron_hover}
+ tintColor={colors.white80}
+ tintHoverColor={colors.white}
onPress={handleCollapse}
source={isExpanded ? 'icon-chevron-up' : 'icon-chevron-down'}
height={24}
@@ -273,7 +280,8 @@ export default class SelectLocation extends Component<Props, State> {
{relayCity.relays.length > 1 ? (
<Cell.Icon
style={styles.collapse_button}
- hoverStyle={styles.expand_chevron_hover}
+ tintColor={colors.white80}
+ tintHoverColor={colors.white}
onPress={handleCollapse}
source={isExpanded ? 'icon-chevron-up' : 'icon-chevron-down'}
height={24}
diff --git a/gui/packages/desktop/src/renderer/components/SelectLocationStyles.js b/gui/packages/desktop/src/renderer/components/SelectLocationStyles.js
index d6d1abec65..202d2c53fe 100644
--- a/gui/packages/desktop/src/renderer/components/SelectLocationStyles.js
+++ b/gui/packages/desktop/src/renderer/components/SelectLocationStyles.js
@@ -95,7 +95,4 @@ export default {
paddingLeft: 60,
backgroundColor: colors.green,
}),
- expand_chevron_hover: Styles.createViewStyle({
- color: colors.white,
- }),
};
diff --git a/gui/packages/desktop/src/renderer/components/Settings.js b/gui/packages/desktop/src/renderer/components/Settings.js
index 82f5dacd6d..71cdd333a1 100644
--- a/gui/packages/desktop/src/renderer/components/Settings.js
+++ b/gui/packages/desktop/src/renderer/components/Settings.js
@@ -3,9 +3,9 @@
import moment from 'moment';
import * as React from 'react';
import { Component, Text, View } from 'reactxp';
+import { ImageView, SettingsHeader, HeaderTitle } from '@mullvad/components';
import * as AppButton from './AppButton';
import * as Cell from './Cell';
-import Img from './Img';
import { Layout, Container } from './Layout';
import {
NavigationBar,
@@ -14,7 +14,6 @@ import {
CloseBarItem,
TitleBarItem,
} from './NavigationBar';
-import SettingsHeader, { HeaderTitle } from './SettingsHeader';
import styles from './SettingsStyles';
import { colors } from '../../config';
@@ -136,7 +135,11 @@ export default class Settings extends Component<Props> {
: 'Update available, download to remain safe.';
icon = (
- <Img source="icon-alert" tintColor={colors.red} style={styles.settings__version_warning} />
+ <ImageView
+ source="icon-alert"
+ tintColor={colors.red}
+ style={styles.settings__version_warning}
+ />
);
footer = (
<View style={styles.settings__cell_footer}>
diff --git a/gui/packages/desktop/src/renderer/components/Support.js b/gui/packages/desktop/src/renderer/components/Support.js
index 8cbc584be7..bf9ddac8f0 100644
--- a/gui/packages/desktop/src/renderer/components/Support.js
+++ b/gui/packages/desktop/src/renderer/components/Support.js
@@ -2,12 +2,11 @@
import * as React from 'react';
import { Component, Text, View, TextInput } from 'reactxp';
+import { ImageView, SettingsHeader, HeaderTitle, HeaderSubTitle } from '@mullvad/components';
import * as AppButton from './AppButton';
import { Layout, Container } from './Layout';
import { NavigationBar, BackBarItem } from './NavigationBar';
-import SettingsHeader, { HeaderTitle, HeaderSubTitle } from './SettingsHeader';
import styles from './SupportStyles';
-import Img from './Img';
import type { AccountToken } from '../lib/daemon-rpc';
import type { SupportReportForm } from '../redux/support/actions';
@@ -248,7 +247,7 @@ export default class Support extends Component<SupportProps, SupportState> {
onPress={this.onViewLog}
testName="support__view_logs">
<AppButton.Label>View app logs</AppButton.Label>
- <Img source="icon-extLink" height={16} width={16} />
+ <ImageView source="icon-extLink" height={16} width={16} />
</AppButton.BlueButton>
<AppButton.GreenButton
disabled={!this.validate()}
@@ -266,7 +265,7 @@ export default class Support extends Component<SupportProps, SupportState> {
<View style={styles.support__form}>
<View style={styles.support__form_row}>
<View style={styles.support__status_icon}>
- <Img source="icon-spinner" height={60} width={60} alt="" />
+ <ImageView source="icon-spinner" height={60} width={60} alt="" />
</View>
<View style={styles.support__status_security__secure}>{'SECURE CONNECTION'}</View>
<Text style={styles.support__send_status}>{'Sending...'}</Text>
@@ -282,7 +281,7 @@ export default class Support extends Component<SupportProps, SupportState> {
<View style={styles.support__form}>
<View style={styles.support__form_row}>
<View style={styles.support__status_icon}>
- <Img source="icon-success" height={60} width={60} alt="" />
+ <ImageView source="icon-success" height={60} width={60} alt="" />
</View>
<Text style={styles.support__status_security__secure}>{'SECURE CONNECTION'}</Text>
<Text style={styles.support__send_status}>{'Sent'}</Text>
@@ -306,7 +305,7 @@ export default class Support extends Component<SupportProps, SupportState> {
<View style={styles.support__form}>
<View style={styles.support__form_row}>
<View style={styles.support__status_icon}>
- <Img source="icon-fail" height={60} width={60} alt="" />
+ <ImageView source="icon-fail" height={60} width={60} alt="" />
</View>
<Text style={styles.support__status_security__secure}>{'SECURE CONNECTION'}</Text>
<Text style={styles.support__send_status}>{'Failed to send'}</Text>