diff options
| author | Andrej Mihajlov <and@mullvad.net> | 2018-01-29 16:13:42 +0100 |
|---|---|---|
| committer | Andrej Mihajlov <and@mullvad.net> | 2018-01-29 16:13:42 +0100 |
| commit | aeb2f9b733e7b11cadb79c114debe5d5e4bdda30 (patch) | |
| tree | 9fffb4c0fe7042262dfe2be6c85f9b30591b9bc8 /app/components/Map.js | |
| parent | 2ab013667c028a2e75017080d8cffd37a3a6141d (diff) | |
| parent | a5eda4cef865005a13a751c32d42acafcc49a59c (diff) | |
| download | mullvadvpn-aeb2f9b733e7b11cadb79c114debe5d5e4bdda30.tar.xz mullvadvpn-aeb2f9b733e7b11cadb79c114debe5d5e4bdda30.zip | |
Merge branch 'svg-maps'
Diffstat (limited to 'app/components/Map.js')
| -rw-r--r-- | app/components/Map.js | 114 |
1 files changed, 81 insertions, 33 deletions
diff --git a/app/components/Map.js b/app/components/Map.js index 337d5c812b..d416b77961 100644 --- a/app/components/Map.js +++ b/app/components/Map.js @@ -1,51 +1,99 @@ // @flow -import React, { Component } from 'react'; -import ReactMapboxGl, { Marker } from 'react-mapbox-gl'; -import { mapbox as mapboxConfig } from '../config'; -import cheapRuler from 'cheap-ruler'; +import React from 'react'; +import { Component, View } from 'reactxp'; -import type { Coordinate2d } from '../types'; +import SvgMap from './SvgMap'; -const ReactMap = ReactMapboxGl({ - accessToken: mapboxConfig.accessToken, - attributionControl: false, - interactive: false, -}); +export type MapProps = { + center: [number, number], // longitude, latitude + offset: [number, number], // offset [x, y] from the center of the map + zoomLevel: 'high' | 'medium' | 'low', + showMarker: boolean, + markerStyle: 'secure' | 'unsecure', + style: Object, +}; -export default class Map extends Component { - props: { - animate: boolean, - location: Coordinate2d, - altitude: number, - markerImagePath: string, +type MapState = { + bounds: { + width: number, + height: number } +}; + +export default class Map extends Component { + + props: MapProps; + + state: MapState = { + bounds: { + width: 0, + height: 0, + }, + }; render() { + const { width, height } = this.state.bounds; + const readyToRenderTheMap = (width > 0 && height > 0); + return ( + <View style={ this.props.style } onLayout={ this._onLayout }> + { readyToRenderTheMap && ( + <SvgMap width={ width } + height={ height } + center={ this.props.center } + offset={ this.props.offset } + zoomLevel={ this._zoomLevel(this.props.zoomLevel) } + showMarker={ this.props.showMarker } + markerImagePath={ this._markerImage(this.props.markerStyle) } /> + ) } + </View> + ); + } + + shouldComponentUpdate(nextProps: MapProps, nextState: MapState) { + const oldProps = this.props; + const oldState = this.state; + return ( + oldProps.center[0] !== nextProps.center[0] || + oldProps.center[1] !== nextProps.center[1] || - const mapBounds = this.calculateMapBounds(this.props.location, this.props.altitude); + oldProps.offset[0] !== nextProps.offset[0] || + oldProps.offset[1] !== nextProps.offset[1] || - const mapBoundsOptions = { offset: [0, -113], animate: this.props.animate }; + oldProps.zoomLevel !== nextProps.zoomLevel || + oldProps.showMarker !== nextProps.showMarker || + oldProps.markerStyle !== nextProps.markerStyle || - return <ReactMap style={ mapboxConfig.styleURL } - containerStyle={{ height: '100%' }} - fitBounds={ mapBounds } - fitBoundsOptions={ mapBoundsOptions }> + oldState.bounds.width !== nextState.bounds.width || + oldState.bounds.height !== nextState.bounds.height + ); + } - <Marker coordinates={ this.convertToMapCoordinate(this.props.location) } offset={ [0, -10] }> - <img src={ this.props.markerImagePath } /> - </Marker> - </ReactMap>; + _onLayout = (layoutInfo) => { + this.setState({ + bounds: { + width: layoutInfo.width, + height: layoutInfo.height, + } + }); } - calculateMapBounds(center: Coordinate2d, altitude: number): [Coordinate2d, Coordinate2d] { - const bounds = cheapRuler(center[0], 'meters').bufferPoint(center, altitude); - // convert [lat,lng] bounds to [lng,lat] - return [ [bounds[1], bounds[0]], [bounds[3], bounds[2]] ]; + // TODO: Remove zoom level in favor of center + coordinate span + _zoomLevel(variant: $PropertyType<MapProps, 'zoomLevel'>) { + switch(variant) { + case 'high': return 1; + case 'medium': return 20; + case 'low': return 40; + } } - convertToMapCoordinate(pos: Coordinate2d): Coordinate2d { - // convert [lat,lng] bounds to [lng,lat] - return [pos[1], pos[0]]; + _markerImage(style: $PropertyType<MapProps, 'markerStyle'>) { + switch(style) { + case 'secure': + return './assets/images/location-marker-secure.svg'; + case 'unsecure': + return './assets/images/location-marker-unsecure.svg'; + } } + } |
