diff options
| author | Andrej Mihajlov <and@codeispoetry.ru> | 2017-02-20 13:48:37 +0000 |
|---|---|---|
| committer | Andrej Mihajlov <and@codeispoetry.ru> | 2017-02-20 13:48:37 +0000 |
| commit | 348ef1448cb30d7a83f970fe55d50e27e8b33806 (patch) | |
| tree | 9fb19674175be7f2040eb3d590ea1760b7213235 /app | |
| parent | 02f8a846a2300cadce24ec52d24d10d837be57b0 (diff) | |
| download | mullvadvpn-348ef1448cb30d7a83f970fe55d50e27e8b33806.tar.xz mullvadvpn-348ef1448cb30d7a83f970fe55d50e27e8b33806.zip | |
Add location picker
Diffstat (limited to 'app')
| -rw-r--r-- | app/assets/css/style.css | 1 | ||||
| -rw-r--r-- | app/components/Connect.css | 20 | ||||
| -rw-r--r-- | app/components/Connect.js | 22 | ||||
| -rw-r--r-- | app/components/Layout.css | 1 | ||||
| -rw-r--r-- | app/components/SelectLocation.css | 98 | ||||
| -rw-r--r-- | app/components/SelectLocation.js | 69 | ||||
| -rw-r--r-- | app/constants.js | 6 | ||||
| -rw-r--r-- | app/containers/SelectLocationPage.js | 19 | ||||
| -rw-r--r-- | app/routes.js | 2 |
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> ); |
