summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--app/assets/css/style.css1
-rw-r--r--app/components/Connect.css20
-rw-r--r--app/components/Connect.js22
-rw-r--r--app/components/Layout.css1
-rw-r--r--app/components/SelectLocation.css98
-rw-r--r--app/components/SelectLocation.js69
-rw-r--r--app/constants.js6
-rw-r--r--app/containers/SelectLocationPage.js19
-rw-r--r--app/routes.js2
9 files changed, 217 insertions, 21 deletions
diff --git a/app/assets/css/style.css b/app/assets/css/style.css
index 7d16da3fe3..e11777b0f2 100644
--- a/app/assets/css/style.css
+++ b/app/assets/css/style.css
@@ -4,6 +4,7 @@
@import '../../components/Login.css';
@import '../../components/Connect.css';
@import '../../components/Settings.css';
+@import '../../components/SelectLocation.css';
@import '../../components/HeaderBar.css';
@import '../../components/Layout.css';
@import '../../components/Switch.css';
diff --git a/app/components/Connect.css b/app/components/Connect.css
index 486aeccdba..be846b5b76 100644
--- a/app/components/Connect.css
+++ b/app/components/Connect.css
@@ -3,7 +3,7 @@
position: relative;
}
-.map {
+.connect__map {
position: absolute;
top: 0;
left: 0;
@@ -14,13 +14,13 @@
background-position: 0 -72px;
}
-.container {
+.connect__container {
display: flex;
flex-direction: column;
height: 100%;
}
-.connect-pane {
+.connect__footer {
display: flex;
flex-direction: column;
margin-top: auto;
@@ -28,15 +28,11 @@
z-index: 1;
}
-.connect-pane__row {
-
-}
-
-.connect-pane__row + .connect-pane__row {
+.connect__row + .connect__row{
margin-top: 16px;
}
-.connect-pane__server {
+.connect__server {
padding: 7px 12px 9px;
background-color: rgba(255,255,255,0.2);
border-radius: 4px;
@@ -45,7 +41,7 @@
align-items: center;
}
-.connect-pane__server-label {
+.connect__server-label {
font-family: "Open Sans";
font-size: 12px;
font-weight: 800;
@@ -53,7 +49,7 @@
color: rgba(255,255,255,0.8);
}
-.connect-pane__server-country {
+.connect__server-country {
margin-left: auto;
font-family: DINPro;
font-size: 20px;
@@ -62,7 +58,7 @@
color: #FFFFFF;
}
-.connect-pane__secure-button {
+.connect__secure-button {
display: block;
width:100%;
border: 0;
diff --git a/app/components/Connect.js b/app/components/Connect.js
index 81e5440ae7..efdf5a5512 100644
--- a/app/components/Connect.js
+++ b/app/components/Connect.js
@@ -7,25 +7,29 @@ export default class Connect extends Component {
this.props.router.push('/settings');
}
+ openLocationPicker() {
+ this.props.router.push('/select-location');
+ }
+
render() {
return (
<Layout>
<Header showSettings={ true } onSettings={ ::this.onSettings } />
<Container>
<div className="connect">
- <div className="map"></div>
- <div className="container">
- <div className="connect-pane">
+ <div className="connect__map"></div>
+ <div className="connect__container">
+ <div className="connect__footer">
- <div className="connect-pane__row">
- <div className="connect-pane__server">
- <div className="connect-pane__server-label">CONNECT TO</div>
- <div className="connect-pane__server-country">USA</div>
+ <div className="connect__row">
+ <div className="connect__server" onClick={ ::this.openLocationPicker }>
+ <div className="connect__server-label">CONNECT TO</div>
+ <div className="connect__server-country">USA</div>
</div>
</div>
- <div className="connect-pane__row">
- <button className="connect-pane__secure-button">Secure my connection</button>
+ <div className="connect__row">
+ <button className="connect__secure-button">Secure my connection</button>
</div>
</div>
diff --git a/app/components/Layout.css b/app/components/Layout.css
index 5d1aa92445..14acf93769 100644
--- a/app/components/Layout.css
+++ b/app/components/Layout.css
@@ -11,4 +11,5 @@
.layout__container {
flex: 1 1 100%;
background: #294D73;
+ overflow: hidden; /* needed for flex boxes with overflow: auto to work */
} \ No newline at end of file
diff --git a/app/components/SelectLocation.css b/app/components/SelectLocation.css
new file mode 100644
index 0000000000..6d6e85a0f3
--- /dev/null
+++ b/app/components/SelectLocation.css
@@ -0,0 +1,98 @@
+.select-location {
+ background: #192E45;
+ height: 100%;
+}
+
+.select-location__container {
+ display: flex;
+ flex-direction: column;
+ height: 100%;
+}
+
+.select-location__header {
+ flex: 0 0 auto;
+ padding: 40px 24px 24px;
+ position: relative; /* anchor for close button */
+}
+
+.select-location__close {
+ position: absolute;
+ display: block;
+ border: 0;
+ padding: 0;
+ margin: 0;
+ width: 24px;
+ height: 24px;
+ top: 24px;
+ left: 12px;
+ background-color: transparent;
+ background-image: url(../assets/images/icon-close.svg);
+ opacity: 0.6;
+ z-index: 1; /* part of .select-location__container convers the button */
+}
+
+.select-location__title {
+ font-family: DINPro;
+ font-size: 32px;
+ font-weight: 900;
+ line-height: 40px;
+ color: #FFFFFF;
+ margin: 0 0 8px 0;
+}
+
+.select-location__subtitle {
+ font-family: "Open Sans";
+ font-size: 15px;
+ font-weight: 600;
+ line-height: 20px;
+ color: rgba(255,255,255,0.8);
+}
+
+.select-location__list {
+ overflow: auto;
+}
+
+.select-location__separator {
+ height: 16px;
+}
+
+.select-location__cell {
+ background-color: #294D73;
+ padding: 15px 16px 15px 24px;
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+}
+
+.select-location__cell + .select-location__cell {
+ margin-top: 1px;
+}
+
+.select-location__cell-label {
+ font-family: DINPro;
+ font-size: 20px;
+ font-weight: 900;
+ line-height: 26px;
+ color: #FFFFFF;
+ flex: 1 0 auto;
+}
+
+.select-location__cell-icon {
+ width: 24px;
+ height: 24px;
+ flex: 0 0 auto;
+ margin-right: 8px;
+}
+
+.select-location__cell-value {
+ flex: 0 0 auto;
+}
+
+.select-location__cell-footer {
+ padding: 8px 24px 24px;
+ font-family: "Open Sans";
+ font-size: 15px;
+ font-weight: 600;
+ line-height: 20px;
+ color: rgba(255,255,255,0.8);
+}
diff --git a/app/components/SelectLocation.js b/app/components/SelectLocation.js
new file mode 100644
index 0000000000..fc8ec7da25
--- /dev/null
+++ b/app/components/SelectLocation.js
@@ -0,0 +1,69 @@
+import React, { Component, PropTypes } from 'react';
+import { Layout, Container, Header } from './Layout';
+import { servers } from '../constants';
+
+export default class SelectLocation extends Component {
+
+ static propTypes = {
+ updateSettings: PropTypes.func.isRequired
+ }
+
+ onClose() {
+ this.props.router.push('/connect');
+ }
+
+ handleServer(name) {
+
+ }
+
+ handleFastest() {
+
+ }
+
+ handleNearest() {
+
+ }
+
+ render() {
+ return (
+ <Layout>
+ <Header hidden={ true } style={ Header.Style.defaultDark } />
+ <Container>
+ <div className="select-location">
+ <button className="select-location__close" onClick={ ::this.onClose } />
+ <div className="select-location__container">
+ <div className="select-location__header">
+ <h2 className="select-location__title">Select location</h2>
+ <div className="select-location__subtitle">
+ While connected, your real location is masked with a private and secure location in the selected region
+ </div>
+ </div>
+
+ <div className="select-location__list">
+ <div>
+ <div className="select-location__cell" onClick={ ::this.handleFastest }>
+ <img className="select-location__cell-icon" src="./assets/images/icon-fastest.svg" />
+ <div className="select-location__cell-label">Fastest</div>
+ </div>
+ <div className="select-location__cell" onClick={ ::this.handleNearest }>
+ <img className="select-location__cell-icon" src="./assets/images/icon-nearest.svg" />
+ <div className="select-location__cell-label">Nearest</div>
+ </div>
+ <div className="select-location__separator"></div>
+
+ {
+ servers.map((name) => (
+ <div className="select-location__cell" key={name}>
+ <div className="select-location__cell-label">{ name }</div>
+ </div>))
+ }
+
+ </div>
+ </div>
+ </div>
+ </div>
+ </Container>
+ </Layout>
+ );
+ }
+}
diff --git a/app/constants.js b/app/constants.js
index e8ae43fa4d..75b29e1e3e 100644
--- a/app/constants.js
+++ b/app/constants.js
@@ -9,5 +9,11 @@ module.exports = {
guides: 'https://mullvad.net/guides/',
supportEmail: 'mailto:support@mullvad.net'
},
+ servers: [
+ 'Canada', 'Canada (Quebec)', 'Denmark', 'Germany',
+ 'Lithuania', 'The Netherlands', 'Norway', 'Romania',
+ 'Singapore', 'Spain', 'Sweden', 'Switzerland',
+ 'United Kingdom', 'USA'
+ ],
LoginState
};
diff --git a/app/containers/SelectLocationPage.js b/app/containers/SelectLocationPage.js
new file mode 100644
index 0000000000..0610bc300b
--- /dev/null
+++ b/app/containers/SelectLocationPage.js
@@ -0,0 +1,19 @@
+import { connect } from 'react-redux';
+import { bindActionCreators } from 'redux';
+import SelectLocation from '../components/SelectLocation';
+import connectActions from '../actions/connect';
+import settingsActions from '../actions/settings';
+
+const mapStateToProps = (state) => {
+ return state;
+};
+
+const mapDispatchToProps = (dispatch, props) => {
+ const user = bindActionCreators(connectActions, dispatch);
+ const settings = bindActionCreators(settingsActions, dispatch);
+ return {
+ updateSettings: settings.updateSettings
+ };
+};
+
+export default connect(mapStateToProps, mapDispatchToProps)(SelectLocation);
diff --git a/app/routes.js b/app/routes.js
index cff78c9d65..8ce2e06433 100644
--- a/app/routes.js
+++ b/app/routes.js
@@ -5,11 +5,13 @@ import App from './containers/App';
import LoginPage from './containers/LoginPage';
import ConnectPage from './containers/ConnectPage';
import SettingsPage from './containers/SettingsPage';
+import SelectLocationPage from './containers/SelectLocationPage';
export default (
<Route path="/" component={ App }>
<IndexRoute component={ LoginPage } />
<Route path="connect" component={ ConnectPage } />
<Route path="settings" component={ SettingsPage } />
+ <Route path="select-location" component={ SelectLocationPage } />
</Route>
);