diff options
-rw-r--r-- | modern/public/index.html | 1 | ||||
-rw-r--r-- | modern/public/styles.css | 8 | ||||
-rw-r--r-- | modern/src/MainMap.js | 29 | ||||
-rw-r--r-- | modern/src/StatusView.js | 20 | ||||
-rw-r--r-- | modern/src/common/formatter.js | 1 |
5 files changed, 56 insertions, 3 deletions
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 @@ <meta name="theme-color" content="#000000"> <link rel="manifest" href="%PUBLIC_URL%/manifest.json"> <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico"> + <link rel="stylesheet" href="%PUBLIC_URL%/styles.css"> <title>Traccar</title> </head> <body style="margin: 0; padding: 0;"> 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( + <Provider store={store}> + <StatusView deviceId={feature.properties.deviceId} /> + </Provider>, + 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 ( + <> + <b>{t('deviceStatus')}:</b> {formatter(device.status, 'status')}<br /> + <b>{t('positionSpeed')}:</b> {formatter(position.speed, 'speed')}<br /> + <b>{t('positionCourse')}:</b> {formatter(position.course, 'course')}<br /> + <b>{t('positionDistance')}:</b> {formatter(position.attributes.totalDistance, 'distance')}<br /> + </> + ); +}; + +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; |