diff --git a/package.json b/package.json
index 4099d308..6c201e3c 100644
--- a/package.json
+++ b/package.json
@@ -30,6 +30,7 @@
"evergreen-ui": "^6.10.3",
"geodesy": "^2.4.0",
"immer": "^9.0.15",
+ "mapbox-gl": "npm:empty-npm-package@1.0.0",
"maplibre-gl": "^2.3.0",
"modern-css-reset": "^1.4.0",
"prettier": "^2.7.1",
@@ -38,6 +39,7 @@
"react-hook-form": "^7.34.2",
"react-icons": "^4.4.0",
"react-json-pretty": "^2.2.0",
+ "react-map-gl": "^7.0.19",
"react-qrcode-logo": "^2.8.0",
"rfc4648": "^1.5.2",
"zustand": "4.1.0"
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 29ef71d7..725c8507 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -20,6 +20,7 @@ specifiers:
geodesy: ^2.4.0
gzipper: ^7.1.0
immer: ^9.0.15
+ mapbox-gl: npm:empty-npm-package@1.0.0
maplibre-gl: ^2.3.0
modern-css-reset: ^1.4.0
prettier: ^2.7.1
@@ -28,6 +29,7 @@ specifiers:
react-hook-form: ^7.34.2
react-icons: ^4.4.0
react-json-pretty: ^2.2.0
+ react-map-gl: ^7.0.19
react-qrcode-logo: ^2.8.0
rfc4648: ^1.5.2
rollup-plugin-visualizer: ^5.7.1
@@ -49,6 +51,7 @@ dependencies:
evergreen-ui: 6.10.3_biqbaboplfbrettd7655fr4n2y
geodesy: 2.4.0
immer: 9.0.15
+ mapbox-gl: /empty-npm-package/1.0.0
maplibre-gl: 2.3.0
modern-css-reset: 1.4.0
prettier: 2.7.1
@@ -57,6 +60,7 @@ dependencies:
react-hook-form: 7.34.2_react@18.2.0
react-icons: 4.4.0_react@18.2.0
react-json-pretty: 2.2.0_biqbaboplfbrettd7655fr4n2y
+ react-map-gl: 7.0.19_6eczaga5xxiwzxtfiyk6fioasq
react-qrcode-logo: 2.8.0_biqbaboplfbrettd7655fr4n2y
rfc4648: 1.5.2
zustand: 4.1.0_immer@9.0.15+react@18.2.0
@@ -739,6 +743,12 @@ packages:
resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==}
dev: false
+ /@types/mapbox-gl/2.7.5:
+ resolution: {integrity: sha512-T8gACm3oGKMlBo2l/9vnKEAxgCc0g2mr8g6dI1d3ZO6EzRe7JALBONlWRmc7SOHV79kiarkcdLdDVEnfd+jilA==}
+ dependencies:
+ '@types/geojson': 7946.0.10
+ dev: false
+
/@types/mapbox__point-geometry/0.1.2:
resolution: {integrity: sha512-D0lgCq+3VWV85ey1MZVkE8ZveyuvW5VAfuahVTQRpXFQTxw03SuIf1/K4UQ87MMIXVKzpFjXFiFMZzLj2kU+iA==}
dev: false
@@ -1342,6 +1352,10 @@ packages:
resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
dev: true
+ /empty-npm-package/1.0.0:
+ resolution: {integrity: sha512-q4Mq/+XO7UNDdMiPpR/LIBIW1Zl4V0Z6UT9aKGqIAnBCtCb3lvZJM1KbDbdzdC8fKflwflModfjR29Nt0EpcwA==}
+ dev: false
+
/encoding/0.1.13:
resolution: {integrity: sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==}
dependencies:
@@ -2982,6 +2996,17 @@ packages:
react-dom: 18.2.0_react@18.2.0
dev: false
+ /react-map-gl/7.0.19_6eczaga5xxiwzxtfiyk6fioasq:
+ resolution: {integrity: sha512-s3E8aU6BursSDVwzQZbzdDzDRUX4kdfRqZODYvkdDbInr3RzaNdlbhJ5tojXKWOonsxV6wt+Acv9JCaOMKaf0A==}
+ peerDependencies:
+ mapbox-gl: '*'
+ react: '>=16.3.0'
+ dependencies:
+ '@types/mapbox-gl': 2.7.5
+ mapbox-gl: /empty-npm-package/1.0.0
+ react: 18.2.0
+ dev: false
+
/react-qrcode-logo/2.8.0_biqbaboplfbrettd7655fr4n2y:
resolution: {integrity: sha512-dbEgjsg6C4tK6+oGmCRDlJ7urQAWqybaGBLJtp8Z6ZYvVUP302HBXk/F7VRk54yWTwzlHwig3VK6HMKCha2YFw==}
peerDependencies:
diff --git a/src/App.tsx b/src/App.tsx
index 9c4d22ad..2dee6056 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -1,6 +1,7 @@
import type React from "react";
import { Pane } from "evergreen-ui";
+import { MapProvider } from "react-map-gl";
import { AppLayout } from "@components/layout/AppLayout.js";
@@ -10,7 +11,9 @@ export const App = (): JSX.Element => {
return (
-
+
+
+
);
diff --git a/src/core/stores/deviceStore.ts b/src/core/stores/deviceStore.ts
index 7af9a7b1..d6621e34 100644
--- a/src/core/stores/deviceStore.ts
+++ b/src/core/stores/deviceStore.ts
@@ -44,10 +44,10 @@ export interface Device {
activePage: Page;
peerInfoOpen: boolean;
activePeer: number;
+ waypoints: Protobuf.Location[];
setReady(ready: boolean): void;
setStatus: (status: Types.DeviceStatusEnum) => void;
- addChannel: (channel: Channel) => void;
setConfig: (config: Protobuf.Config) => void;
setModuleConfig: (config: Protobuf.ModuleConfig) => void;
setHardware: (hardware: Protobuf.MyNodeInfo) => void;
@@ -55,6 +55,8 @@ export interface Device {
setActivePage: (page: Page) => void;
setPeerInfoOpen: (open: boolean) => void;
setActivePeer: (peer: number) => void;
+ addChannel: (channel: Channel) => void;
+ addWaypoint: (waypoint: Protobuf.Location) => void;
addNodeInfo: (nodeInfo: Types.NodeInfoPacket) => void;
addUser: (user: Types.UserPacket) => void;
addPosition: (position: Types.PositionPacket) => void;
@@ -92,6 +94,7 @@ export const useDeviceStore = create((set, get) => ({
activePage: "messages",
peerInfoOpen: false,
activePeer: 0,
+ waypoints: [],
setReady: (ready: boolean) => {
set(
@@ -113,25 +116,6 @@ export const useDeviceStore = create((set, get) => ({
})
);
},
- addChannel: (channel: Channel) => {
- set(
- produce((draft) => {
- const device = draft.devices.get(id);
- if (device) {
- const channelIndex = device.channels.findIndex(
- (c) => c.config.index === channel.config.index
- );
- if (channelIndex !== -1) {
- const messages = device.channels[channelIndex].messages;
- device.channels[channelIndex] = channel;
- device.channels[channelIndex].messages = messages;
- } else {
- device.channels.push(channel);
- }
- }
- })
- );
- },
setConfig: (config: Protobuf.Config) => {
set(
produce((draft) => {
@@ -257,6 +241,43 @@ export const useDeviceStore = create((set, get) => ({
})
);
},
+ addChannel: (channel: Channel) => {
+ set(
+ produce((draft) => {
+ const device = draft.devices.get(id);
+ if (device) {
+ const channelIndex = device.channels.findIndex(
+ (c) => c.config.index === channel.config.index
+ );
+ if (channelIndex !== -1) {
+ const messages = device.channels[channelIndex].messages;
+ device.channels[channelIndex] = channel;
+ device.channels[channelIndex].messages = messages;
+ } else {
+ device.channels.push(channel);
+ }
+ }
+ })
+ );
+ },
+ addWaypoint: (waypoint: Protobuf.Location) => {
+ set(
+ produce((draft) => {
+ const device = draft.devices.get(id);
+ if (device) {
+ const waypointIndex = device.waypoints.findIndex(
+ (wp) => wp.id === waypoint.id
+ );
+
+ if (waypointIndex !== -1) {
+ device.waypoints[waypointIndex] = waypoint;
+ } else {
+ device.waypoints.push(waypoint);
+ }
+ }
+ })
+ );
+ },
addNodeInfo: (nodeInfo) => {
set(
produce((draft) => {
diff --git a/src/core/subscriptions.ts b/src/core/subscriptions.ts
index 0ee1af33..07a136bb 100644
--- a/src/core/subscriptions.ts
+++ b/src/core/subscriptions.ts
@@ -71,5 +71,8 @@ export const subscribeAll = (device: Device, connection: IConnection) => {
? new Date(messagePacket.packet.rxTime * 1000)
: new Date(),
});
+ if (messagePacket.location) {
+ device.addWaypoint(messagePacket.location);
+ }
});
};
diff --git a/src/pages/Map/index.tsx b/src/pages/Map/index.tsx
index 6eb75249..8fbcd29c 100644
--- a/src/pages/Map/index.tsx
+++ b/src/pages/Map/index.tsx
@@ -1,49 +1,44 @@
import type React from "react";
-import { useEffect, useMemo, useRef } from "react";
+import { useRef } from "react";
-import { majorScale, Pane } from "evergreen-ui";
-import { Marker } from "maplibre-gl";
+import { majorScale, MapMarkerIcon, Pane } from "evergreen-ui";
+import maplibregl from "maplibre-gl";
+import Map, { Marker } from "react-map-gl";
-import { useCreateMapbox } from "@app/core/providers/useCreateMapbox.js";
import { useDevice } from "@core/providers/useDevice.js";
+import { Hashicon } from "@emeraldpay/hashicon-react";
export const MapPage = (): JSX.Element => {
- const { nodes } = useDevice();
+ const { nodes, waypoints } = useDevice();
- const nodeMarkers = useMemo(() => new Map(), []);
+ // const nodeMarkers = useMemo(() => new Map(), []);
const ref = useRef(null);
- const map = useCreateMapbox({
- ref,
- style:
- "https://raw.githubusercontent.com/hc-oss/maplibre-gl-styles/master/styles/osm-mapnik/v8/default.json",
- });
-
- useEffect(() => {
- nodes.map((n) => {
- if (n.data.position?.longitudeI && n.data.position?.latitudeI && map) {
- if (nodeMarkers.has(n.data.num)) {
- nodeMarkers
- .get(n.data.num)
- ?.setLngLat([
- n.data.position?.longitudeI / 1e7,
- n.data.position?.latitudeI / 1e7,
- ]);
- } else {
- nodeMarkers.set(
- n.data.num,
- new Marker()
- .setLngLat([
- n.data.position?.longitudeI / 1e7,
- n.data.position?.latitudeI / 1e7,
- ])
- .addTo(map)
- );
- }
- }
- });
- }, [map, nodeMarkers, nodes]);
+ // useEffect(() => {
+ // nodes.map((n) => {
+ // if (n.data.position?.longitudeI && n.data.position?.latitudeI && map) {
+ // if (nodeMarkers.has(n.data.num)) {
+ // nodeMarkers
+ // .get(n.data.num)
+ // ?.setLngLat([
+ // n.data.position?.longitudeI / 1e7,
+ // n.data.position?.latitudeI / 1e7,
+ // ]);
+ // } else {
+ // nodeMarkers.set(
+ // n.data.num,
+ // new Marker()
+ // .setLngLat([
+ // n.data.position?.longitudeI / 1e7,
+ // n.data.position?.latitudeI / 1e7,
+ // ])
+ // .addTo(map)
+ // );
+ // }
+ // }
+ // });
+ // }, [map, nodeMarkers, nodes]);
return (
{
gap={majorScale(2)}
overflow="hidden"
>
-
+
);
};