summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--app/app.js20
-rw-r--r--app/assets/css/global.css11
-rw-r--r--app/components/HeaderBar.css61
-rw-r--r--app/components/HeaderBar.js55
-rw-r--r--app/components/HeaderBarStyles.js46
-rw-r--r--app/components/Img.android.js8
-rw-r--r--app/components/Img.js13
-rw-r--r--app/components/WindowChrome.css7
-rw-r--r--app/containers/AccountPage.js4
-rw-r--r--app/containers/ConnectPage.js4
-rw-r--r--app/containers/LoginPage.js6
-rw-r--r--app/containers/SettingsPage.js8
-rw-r--r--app/index.html4
-rw-r--r--app/index.js7
-rw-r--r--app/lib/backend.js1
-rw-r--r--app/lib/exit.android.js5
-rw-r--r--app/lib/exit.js5
-rw-r--r--app/lib/linking.android.js6
-rw-r--r--app/lib/linking.js6
-rw-r--r--package.json1
21 files changed, 178 insertions, 101 deletions
diff --git a/.gitignore b/.gitignore
index 5da2ccb7c4..f9d3de0c13 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,3 +3,4 @@ dist
build
.DS_Store
*.log
+*.lock
diff --git a/app/app.js b/app/app.js
index a10d0da07c..a5392a49c3 100644
--- a/app/app.js
+++ b/app/app.js
@@ -2,6 +2,7 @@
import React from 'react';
import ReactDOM from 'react-dom';
+import { Component} from 'reactxp';
import { Provider } from 'react-redux';
import { ConnectedRouter } from 'react-router-redux';
import { createMemoryHistory } from 'history';
@@ -104,11 +105,14 @@ function getRootElement() {
}
-ReactDOM.render(
- <Provider store={ store }>
- <ConnectedRouter history={ memoryHistory }>
- { makeRoutes(store.getState, { backend }) }
- </ConnectedRouter>
- </Provider>,
- getRootElement()
-);
+export default class App extends Component{
+ render() {
+ return (
+ <Provider store={ store }>
+ <ConnectedRouter history={ memoryHistory }>
+ { makeRoutes(store.getState, { backend }) }
+ </ConnectedRouter>
+ </Provider>
+ );
+ }
+}
diff --git a/app/assets/css/global.css b/app/assets/css/global.css
index f724a6b5ff..f571b16355 100644
--- a/app/assets/css/global.css
+++ b/app/assets/css/global.css
@@ -8,6 +8,8 @@ html {
-webkit-font-smoothing: antialiased;
user-select: none;
cursor: default;
+ height: 100%;
+ width: 100%;
}
img {
@@ -16,4 +18,13 @@ img {
body {
font-family: -apple-system, BlinkMacSystemFont, sans-serif;
+ height: 100%;
+ width: 100%;
+ display: flex;
+}
+
+#app {
+ height: 100%;
+ width: 100%;
+ display: flex;
}
diff --git a/app/components/HeaderBar.css b/app/components/HeaderBar.css
deleted file mode 100644
index 9fcc65047b..0000000000
--- a/app/components/HeaderBar.css
+++ /dev/null
@@ -1,61 +0,0 @@
-.headerbar {
- padding: 12px;
- background-color: #294D73;
- transition: 0.5s background-color ease-in-out;
-}
-
-/* macOS app runs as menubar app so add extra padding */
-.headerbar--darwin {
- padding-top: 24px;
-}
-
-.headerbar--hidden {
- padding: 24px 0 0 0;
-}
-
-.headerbar--style-defaultDark {
- background-color: #192E45;
-}
-
-.headerbar--style-error {
- background-color: #D0021B;
-}
-
-.headerbar--style-success {
- background-color: #44AD4D;
-}
-
-.headerbar__container {
- display: flex;
- flex-direction: row;
- align-items: center;
-}
-
-.headerbar__title {
- font-family: DINPro;
- font-size: 24px;
- font-weight: 900;
- line-height: 30px;
- letter-spacing: -0.5px;
- color: rgba(255,255,255,0.6);
- display: inline-block;
- vertical-align: middle;
- margin-left: 8px;
-}
-
-.headerbar__logo {
- height: 50px;
- display: inline-block;
- vertical-align: middle;
-}
-
-.headerbar__settings {
- display: block;
- border: 0;
- padding: 0;
- margin: 0 0 0 auto;
- width: 24px;
- height: 24px;
- background-color: transparent;
- background-image: url(../assets/images/icon-settings.svg);
-}
diff --git a/app/components/HeaderBar.js b/app/components/HeaderBar.js
index 26e937ad23..0960954d58 100644
--- a/app/components/HeaderBar.js
+++ b/app/components/HeaderBar.js
@@ -1,6 +1,16 @@
// @flow
-import React, { Component } from 'react';
-import { If, Then } from 'react-if';
+import React from 'react';
+import {
+ Component,
+ Text,
+ Button,
+ Image,
+ View
+} from 'reactxp';
+
+import Img from './Img';
+
+import styles from './HeaderBarStyles';
export type HeaderBarStyle = 'default' | 'defaultDark' | 'error' | 'success';
export type HeaderBarProps = {
@@ -19,33 +29,34 @@ export default class HeaderBar extends Component {
onSettings: null
};
- render(): React.Element<*> {
+ render() {
let containerClass = [
- 'headerbar',
- 'headerbar--' + process.platform,
- 'headerbar--style-' + this.props.style
+ styles['headerbar'],
+ styles['headerbar__' + process.platform],
+ styles['headerbar__style_' + this.props.style]
];
if(this.props.hidden) {
- containerClass.push('headerbar--hidden');
+ containerClass.push(styles['headerbar__hidden']);
}
return (
- <div className={ containerClass.join(' ') }>
- <If condition={ !this.props.hidden }>
- <Then>
- <div className="headerbar__container">
- <img className="headerbar__logo" src="./assets/images/logo-icon.svg" />
- <h2 className="headerbar__title">MULLVAD VPN</h2>
- <If condition={ !!this.props.showSettings }>
- <Then>
- <button className="headerbar__settings" onClick={ this.props.onSettings } />
- </Then>
- </If>
- </div>
- </Then>
- </If>
- </div>
+ <View style={ containerClass }>
+ {!this.props.hidden ?
+ <View style={styles.headerbar__container}>
+ <Img style={ styles.headerbar__logo } source='logo-icon'/>
+ <Text style={styles.headerbar__title}>MULLVAD VPN</Text>
+ </View>
+ : null}
+
+ {!!this.props.showSettings ?
+ <View style={styles.headerbar__settings}>
+ <Button onPress={ this.props.onSettings }>
+ <Img style={ styles.headerbar__settings } source='icon-settings'/>
+ </Button>
+ </View>
+ : null}
+ </View>
);
}
}
diff --git a/app/components/HeaderBarStyles.js b/app/components/HeaderBarStyles.js
new file mode 100644
index 0000000000..c2f86c2dc9
--- /dev/null
+++ b/app/components/HeaderBarStyles.js
@@ -0,0 +1,46 @@
+import { Styles } from 'reactxp';
+
+const styles = {
+ headerbar:Styles.createViewStyle({
+ padding: 12,
+ backgroundColor: '#294D73',
+ flexDirection: 'row',
+ justifyContent: 'space-between',
+ alignItems: 'center',
+}),headerbar__hidden: Styles.createViewStyle({
+ paddingTop: 0,
+ paddingBottom: 0,
+ paddingLeft: 0,
+ paddingRight: 0,
+}),headerbar__style_defaultDark: Styles.createViewStyle({
+ backgroundColor: '#192E45',
+}),headerbar__style_error: Styles.createViewStyle({
+ backgroundColor: '#D0021B',
+}),headerbar__style_success: Styles.createViewStyle({
+ backgroundColor: '#44AD4D',
+}),headerbar__container: Styles.createViewStyle({
+ display: 'flex',
+ flexDirection: 'row',
+ alignItems: 'center',
+}),headerbar__title: Styles.createTextStyle({
+ fontFamily: 'DINPro',
+ fontSize: 24,
+ fontWeight: '900',
+ lineHeight: 30,
+ letterSpacing: -0.5,
+ color: 'rgba(255,255,255,0.6)',
+ marginLeft: 8,
+}),headerbar__logo: Styles.createViewStyle({
+ height: 50,
+ width: 50,
+}),headerbar__settings: Styles.createViewStyle({
+ width: 24,
+ height: 24,
+ backgroundColor: 'transparent',
+ marginLeft: -6, //Because of button.css, when removed remove this
+ marginTop: -1, //Because of button.css, when removed remove this
+})
+};
+
+
+module.exports = styles; \ No newline at end of file
diff --git a/app/components/Img.android.js b/app/components/Img.android.js
new file mode 100644
index 0000000000..25e5e474c9
--- /dev/null
+++ b/app/components/Img.android.js
@@ -0,0 +1,8 @@
+import React from 'react';
+import { Image, Component } from 'reactxp';
+
+export default class Img extends Component {
+ render(): React.Element<*> {
+ return (<Image style={ this.props.style } source={ this.props.source }/>);
+ }
+} \ No newline at end of file
diff --git a/app/components/Img.js b/app/components/Img.js
new file mode 100644
index 0000000000..c82d96c1be
--- /dev/null
+++ b/app/components/Img.js
@@ -0,0 +1,13 @@
+import React from 'react';
+import { View, Component } from 'reactxp';
+
+export default class Img extends Component {
+ render(): React.Element<*> {
+
+ const url = "./assets/images/" + this.props.source + ".svg";
+
+ const style = this.props.style;
+
+ return (<View style={ style }> <img src={ url } /> </View>);
+ }
+} \ No newline at end of file
diff --git a/app/components/WindowChrome.css b/app/components/WindowChrome.css
index 8f3fcdb52c..b2206d9095 100644
--- a/app/components/WindowChrome.css
+++ b/app/components/WindowChrome.css
@@ -3,4 +3,11 @@
-webkit-mask:
url(../assets/images/app-triangle.svg) 50% 0% no-repeat,
url(../assets/images/app-header-backdrop.svg) no-repeat;
+}
+
+.window-chrome {
+ flex: 1 1 auto;
+ height: 100%;
+ width: 100%;
+ display: flex;
} \ No newline at end of file
diff --git a/app/containers/AccountPage.js b/app/containers/AccountPage.js
index f5d31e5bc0..ae992bc12a 100644
--- a/app/containers/AccountPage.js
+++ b/app/containers/AccountPage.js
@@ -5,8 +5,8 @@ import { bindActionCreators } from 'redux';
import { push } from 'react-router-redux';
import Account from '../components/Account';
import accountActions from '../redux/account/actions';
-import { shell } from 'electron';
import { links } from '../config';
+import Linking from '../lib/linking';
import type { ReduxState, ReduxDispatch } from '../redux/store';
import type { SharedRouteProps } from '../routes';
@@ -22,7 +22,7 @@ const mapDispatchToProps = (dispatch: ReduxDispatch, props: SharedRouteProps) =>
onClose: () => {
pushHistory('/settings');
},
- onBuyMore: () => shell.openExternal(links['purchase'])
+ onBuyMore: () => Linking(links['purchase'])
};
};
diff --git a/app/containers/ConnectPage.js b/app/containers/ConnectPage.js
index ca64c6725a..1694e84556 100644
--- a/app/containers/ConnectPage.js
+++ b/app/containers/ConnectPage.js
@@ -3,10 +3,10 @@
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { push } from 'react-router-redux';
-import { shell } from 'electron';
import { links } from '../config';
import Connect from '../components/Connect';
import connectActions from '../redux/connection/actions';
+import Linking from '../lib/linking';
import type { ReduxState, ReduxDispatch } from '../redux/store';
import type { SharedRouteProps } from '../routes';
@@ -40,7 +40,7 @@ const mapDispatchToProps = (dispatch: ReduxDispatch, props: SharedRouteProps) =>
onDisconnect: () => {
disconnect(backend);
},
- onExternalLink: (type) => shell.openExternal(links[type]),
+ onExternalLink: (type) => Linking(links[type]),
getServerInfo: (relayLocation) => backend.serverInfo(relayLocation),
};
};
diff --git a/app/containers/LoginPage.js b/app/containers/LoginPage.js
index c6c7d3a7e2..16703fdc0c 100644
--- a/app/containers/LoginPage.js
+++ b/app/containers/LoginPage.js
@@ -1,12 +1,16 @@
+<<<<<<< HEAD
// @flow
import { shell } from 'electron';
+=======
+>>>>>>> Reactxp starter pack
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { push } from 'react-router-redux';
import Login from '../components/Login';
import accountActions from '../redux/account/actions';
import { links } from '../config';
+import Linking from '../lib/linking';
import type { ReduxState, ReduxDispatch } from '../redux/store';
import type { SharedRouteProps } from '../routes';
@@ -26,7 +30,7 @@ const mapDispatchToProps = (dispatch: ReduxDispatch, props: SharedRouteProps) =>
onFirstChangeAfterFailure: () => {
resetLoginError();
},
- onExternalLink: (type) => shell.openExternal(links[type]),
+ onExternalLink: (type) => Linking(links[type]),
onAccountTokenChange: (token) => {
updateAccountToken(token);
},
diff --git a/app/containers/SettingsPage.js b/app/containers/SettingsPage.js
index dcd1d121bb..8d41efd4d9 100644
--- a/app/containers/SettingsPage.js
+++ b/app/containers/SettingsPage.js
@@ -4,8 +4,10 @@ import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { push } from 'react-router-redux';
import Settings from '../components/Settings';
-import { remote, shell } from 'electron';
+import settingsActions from '../redux/settings/actions';
import { links } from '../config';
+import Linking from '../lib/linking';
+import Exit from '../lib/exit';
import type { ReduxState, ReduxDispatch } from '../redux/store';
import type { SharedRouteProps } from '../routes';
@@ -14,12 +16,12 @@ const mapStateToProps = (state: ReduxState) => state;
const mapDispatchToProps = (dispatch: ReduxDispatch, _props: SharedRouteProps) => {
const { push: pushHistory } = bindActionCreators({ push }, dispatch);
return {
- onQuit: () => remote.app.quit(),
+ onQuit: () => Exit(),
onClose: () => pushHistory('/connect'),
onViewAccount: () => pushHistory('/settings/account'),
onViewSupport: () => pushHistory('/settings/support'),
onViewAdvancedSettings: () => pushHistory('/settings/advanced'),
- onExternalLink: (type) => shell.openExternal(links[type]),
+ onExternalLink: (type) => Linking(links[type]),
};
};
diff --git a/app/index.html b/app/index.html
index e0ac17cd31..d653380431 100644
--- a/app/index.html
+++ b/app/index.html
@@ -5,8 +5,8 @@
<link rel="stylesheet" href="./assets/css/style.css" />
</head>
<body>
- <div id="app"></div>
- <script src="./app.js" data-container="#app"></script>
+ <div id="app" class="app-container"></div>
+ <script src="./index.js" data-container="#app"></script>
<script>
if (process.env.BROWSER_SYNC_CLIENT_URL) {
const current = document.currentScript;
diff --git a/app/index.js b/app/index.js
new file mode 100644
index 0000000000..3f17282c34
--- /dev/null
+++ b/app/index.js
@@ -0,0 +1,7 @@
+import React from 'react';
+import RX from 'reactxp';
+import App from './app';
+
+RX.App.initialize(true, true);
+RX.UserInterface.setMainView(<App />);
+RX.UserInterface.useCustomScrollbars(true);
diff --git a/app/lib/backend.js b/app/lib/backend.js
index b76b3b3749..a68c2309e7 100644
--- a/app/lib/backend.js
+++ b/app/lib/backend.js
@@ -8,6 +8,7 @@ import accountActions from '../redux/account/actions';
import connectionActions from '../redux/connection/actions';
import settingsActions from '../redux/settings/actions';
import { push } from 'react-router-redux';
+import { defaultServer } from '../config';
import type { ReduxStore } from '../redux/store';
import type { AccountToken, BackendState, RelayLocation, RelaySettingsUpdate } from './ipc-facade';
diff --git a/app/lib/exit.android.js b/app/lib/exit.android.js
new file mode 100644
index 0000000000..2dbcf80413
--- /dev/null
+++ b/app/lib/exit.android.js
@@ -0,0 +1,5 @@
+import { BackHandler } from 'react-native';
+
+module.exports = function () {
+ BackHandler.exitApp();
+}
diff --git a/app/lib/exit.js b/app/lib/exit.js
new file mode 100644
index 0000000000..cf87680b32
--- /dev/null
+++ b/app/lib/exit.js
@@ -0,0 +1,5 @@
+import { remote } from 'electron';
+
+module.exports = function () {
+ remote.app.quit();
+}
diff --git a/app/lib/linking.android.js b/app/lib/linking.android.js
new file mode 100644
index 0000000000..ec99b85997
--- /dev/null
+++ b/app/lib/linking.android.js
@@ -0,0 +1,6 @@
+import { Linking } from 'react-native';
+
+var open = (link) => {
+ Linking.openURL(link);
+};
+export default open;
diff --git a/app/lib/linking.js b/app/lib/linking.js
new file mode 100644
index 0000000000..1d7a0a8d0a
--- /dev/null
+++ b/app/lib/linking.js
@@ -0,0 +1,6 @@
+import { shell } from 'electron';
+
+var open = (link) => {
+ shell.openExternal(link);
+};
+export default open; \ No newline at end of file
diff --git a/package.json b/package.json
index f84cc878c8..06da9d4634 100644
--- a/package.json
+++ b/package.json
@@ -29,6 +29,7 @@
"react-router": "^4.1.1",
"react-router-redux": "5.0.0-alpha.6",
"react-transition-group": "^1.2.0",
+ "reactxp": "^0.46.5",
"redux": "^3.0.0",
"redux-thunk": "^2.2.0",
"shell-escape": "^0.2.0",