From f3024c900dffe7668b294054ee9a0345696769db Mon Sep 17 00:00:00 2001 From: Anton Tananaev Date: Sun, 13 Sep 2020 17:52:38 -0700 Subject: Implement status popup --- modern/public/index.html | 1 + modern/public/styles.css | 8 ++++++++ modern/src/MainMap.js | 29 ++++++++++++++++++++++++++--- modern/src/StatusView.js | 20 ++++++++++++++++++++ modern/src/common/formatter.js | 1 + 5 files changed, 56 insertions(+), 3 deletions(-) create mode 100644 modern/public/styles.css create mode 100644 modern/src/StatusView.js diff --git a/modern/public/index.html b/modern/public/index.html index ecded7c1..78138ed5 100644 --- a/modern/public/index.html +++ b/modern/public/index.html @@ -6,6 +6,7 @@ + Traccar diff --git a/modern/public/styles.css b/modern/public/styles.css new file mode 100644 index 00000000..60d12082 --- /dev/null +++ b/modern/public/styles.css @@ -0,0 +1,8 @@ +canvas { + outline: none; + -webkit-tap-highlight-color: rgba(255, 255, 255, 0); +} + +.mapboxgl-popup-content { + padding: 10px !important; +} diff --git a/modern/src/MainMap.js b/modern/src/MainMap.js index fadfe9e7..5ba50982 100644 --- a/modern/src/MainMap.js +++ b/modern/src/MainMap.js @@ -1,8 +1,11 @@ import React, { useRef, useLayoutEffect, useEffect, useState } from 'react'; -import { useSelector } from 'react-redux'; +import ReactDOM from 'react-dom'; +import { Provider, useSelector } from 'react-redux'; import mapboxgl from 'mapbox-gl'; import mapManager from './mapManager'; +import store from './store'; +import StatusView from './StatusView'; const MainMap = () => { const containerEl = useRef(null); @@ -22,10 +25,11 @@ const MainMap = () => { const createFeature = (state, position) => { const device = state.devices.items[position.deviceId] || null; return { + deviceId: position.deviceId, name: device ? device.name : '', } }; - + const positions = useSelector(state => ({ type: 'FeatureCollection', features: Object.values(state.positions.items).map(position => ({ @@ -54,7 +58,26 @@ const MainMap = () => { }, []); const markerClickHandler = (event) => { - // TODO + const feature = event.features[0]; + let coordinates = feature.geometry.coordinates.slice(); + while (Math.abs(event.lngLat.lng - coordinates[0]) > 180) { + coordinates[0] += event.lngLat.lng > coordinates[0] ? 360 : -360; + } + + const placeholder = document.createElement('div'); + ReactDOM.render( + + + , + placeholder); + + new mapboxgl.Popup({ + offset: 25, + anchor: 'top' + }) + .setDOMContent(placeholder) + .setLngLat(coordinates) + .addTo(mapManager.map); }; useEffect(() => { diff --git a/modern/src/StatusView.js b/modern/src/StatusView.js new file mode 100644 index 00000000..ed0149ef --- /dev/null +++ b/modern/src/StatusView.js @@ -0,0 +1,20 @@ +import t from './common/localization' +import React from 'react'; +import { useSelector } from 'react-redux'; +import formatter from './common/formatter'; + +const StatusView = (props) => { + const device = useSelector(state => state.devices.items[props.deviceId]); + const position = useSelector(state => state.positions.items[props.deviceId]); + + return ( + <> + {t('deviceStatus')}: {formatter(device.status, 'status')}
+ {t('positionSpeed')}: {formatter(position.speed, 'speed')}
+ {t('positionCourse')}: {formatter(position.course, 'course')}
+ {t('positionDistance')}: {formatter(position.attributes.totalDistance, 'distance')}
+ + ); +}; + +export default StatusView; diff --git a/modern/src/common/formatter.js b/modern/src/common/formatter.js index ce46c6cf..50841e15 100644 --- a/modern/src/common/formatter.js +++ b/modern/src/common/formatter.js @@ -8,6 +8,7 @@ const formatValue = (key, value) => { case 'longitude': return value.toFixed(5); case 'speed': + case 'course': return value.toFixed(1); default: return value; -- cgit v1.2.3