aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--modern/public/index.html1
-rw-r--r--modern/public/styles.css8
-rw-r--r--modern/src/MainMap.js29
-rw-r--r--modern/src/StatusView.js20
-rw-r--r--modern/src/common/formatter.js1
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;