From f07607fb6244820dd78cdfd5d88b39833141db13 Mon Sep 17 00:00:00 2001 From: selankon Date: Fri, 13 Dec 2024 11:30:42 +0100 Subject: [PATCH 1/5] chore(locate): deprecate locate plugin Merge locate plugin with mesh wide page --- plugins/lime-plugin-locate/index.ts | 8 - plugins/lime-plugin-locate/locate.stories.js | 948 ------------------ .../src/communityGeoJSON.spec.js | 219 ---- .../src/communityGeoJSON.ts | 121 --- plugins/lime-plugin-locate/src/locateMenu.js | 12 - plugins/lime-plugin-locate/src/locatePage.tsx | 239 ----- .../src/containers/LocateNode.tsx | 71 ++ .../src/containers/Map.tsx | 19 +- .../src/containers}/style.less | 6 +- .../src/hooks/useLocateNode.tsx | 38 + .../src/lib}/leafletUtils.ts | 2 +- .../src/locateApi.js | 3 - .../src/locateNodeQueries.tsx} | 26 +- .../src/meshWidePage.tsx | 21 +- src/config.ts | 2 - 15 files changed, 149 insertions(+), 1586 deletions(-) delete mode 100644 plugins/lime-plugin-locate/index.ts delete mode 100644 plugins/lime-plugin-locate/locate.stories.js delete mode 100644 plugins/lime-plugin-locate/src/communityGeoJSON.spec.js delete mode 100644 plugins/lime-plugin-locate/src/communityGeoJSON.ts delete mode 100755 plugins/lime-plugin-locate/src/locateMenu.js delete mode 100644 plugins/lime-plugin-locate/src/locatePage.tsx create mode 100644 plugins/lime-plugin-mesh-wide/src/containers/LocateNode.tsx rename plugins/{lime-plugin-locate/src => lime-plugin-mesh-wide/src/containers}/style.less (90%) create mode 100644 plugins/lime-plugin-mesh-wide/src/hooks/useLocateNode.tsx rename plugins/{lime-plugin-locate/src => lime-plugin-mesh-wide/src/lib}/leafletUtils.ts (98%) rename plugins/{lime-plugin-locate => lime-plugin-mesh-wide}/src/locateApi.js (74%) rename plugins/{lime-plugin-locate/src/locateQueries.tsx => lime-plugin-mesh-wide/src/locateNodeQueries.tsx} (74%) diff --git a/plugins/lime-plugin-locate/index.ts b/plugins/lime-plugin-locate/index.ts deleted file mode 100644 index fc2045db2..000000000 --- a/plugins/lime-plugin-locate/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { LocateMenu } from "./src/locateMenu"; -import Locate from "./src/locatePage"; - -export default { - name: "Locate", - page: Locate, - menu: LocateMenu, -} as LimePlugin; diff --git a/plugins/lime-plugin-locate/locate.stories.js b/plugins/lime-plugin-locate/locate.stories.js deleted file mode 100644 index 550dd5fe6..000000000 --- a/plugins/lime-plugin-locate/locate.stories.js +++ /dev/null @@ -1,948 +0,0 @@ -import { action } from "@storybook/addon-actions"; - -import { LocatePage } from "./src/locatePage"; - -export default { - title: "Containers/Map", - component: LocatePage, -}; - -const actions = { - loadLocation: action("loadLocation"), - loadLocationLinks: action("loadLocationLinks"), -}; - -export const nodeAndCommunityNotLocated = () => ( - -); - -export const nodeNotLocatedcommunityLocated = () => ( - -); - -export const nodeLocated = () => ( - -); - -export const edittingLocation = () => ( - -); - -export const submittingLocation = () => ( - -); - -export const withCommunityData = () => { - const nodesData = { - result: { - "ql-male": { - bleachTTL: 26, - data: { - hostname: "ql-male", - coordinates: { - lon: "-64.423605501652", - lat: "-31.816965261909", - }, - macs: [ - "a0:f3:c1:86:31:d2", - "a0:f3:c1:86:31:d3", - "a2:f3:c1:86:31:d2", - ], - links: [ - "c0:4a:00:fc:55:41", - "02:11:4e:2f:63:52", - "c0:4a:00:fc:55:40", - ], - }, - author: "ql-male", - }, - "si-radio": { - bleachTTL: 29, - data: { - links: [ - "", - "a8:40:41:1c:84:20", - "14:cc:20:ad:b0:d9", - "c0:4a:00:b6:9a:b1", - "a0:f3:c1:86:31:8a", - ], - coordinates: { lon: "-64.39613", lat: "-31.82090" }, - macs: [ - "a8:40:41:1c:83:e5", - "a8:40:41:1c:83:ed", - "a8:40:41:1c:85:9c", - ], - hostname: "si-radio", - }, - author: "si-radio", - }, - "si-claudio": { - bleachTTL: 29, - data: { - links: [ - "c0:4a:00:b6:9a:b2", - "a8:40:41:1c:84:16", - "c0:4a:00:b6:9a:b1", - "a8:40:41:1c:85:50", - "a0:f3:c1:86:31:a0", - "14:cc:20:75:c0:04", - "14:cc:20:75:d5:1c", - "14:cc:20:75:be:21", - ], - coordinates: { - lon: "-64.394447446680999292", - lat: "-31.820718688547000141", - }, - macs: ["64:70:02:4e:cd:0a", "64:70:02:4e:cd:0b"], - hostname: "si-claudio", - }, - author: "si-claudio", - }, - "si-frigo-bbone": { - bleachTTL: 30, - data: { - links: ["02:ce:56:aa:83:51", ""], - coordinates: { lon: "-64.39963", lat: "-31.79972" }, - macs: ["c0:4a:00:fc:38:e0", "c0:4a:00:fc:38:e1"], - hostname: "si-frigo-bbone", - }, - author: "si-frigo-bbone", - }, - "si-marcelo": { - bleachTTL: 29, - data: { - links: [ - "14:cc:20:75:d5:1d", - "a8:40:41:1c:84:16", - "a8:40:41:1c:84:28", - "c0:4a:00:b6:9a:b2", - "14:cc:20:75:c0:05", - "14:cc:20:75:c0:04", - "14:cc:20:75:d5:1c", - "c0:4a:00:b6:9a:b1", - "a8:40:41:1c:85:50", - "a8:40:41:1c:85:9c", - ], - coordinates: { lon: "-64.3909722", lat: "-31.8212500" }, - macs: ["14:cc:20:75:be:21", "14:cc:20:75:be:22"], - hostname: "si-marcelo", - }, - author: "si-marcelo", - }, - "ql-quinteros": { - bleachTTL: 28, - data: { - links: [ - "c0:4a:00:fc:55:40", - "c0:4a:00:fc:39:c0", - "64:66:b3:87:4e:d0", - "a8:40:41:1c:85:3c", - "a0:f3:c1:86:32:10", - "a0:f3:c1:85:fb:42", - "14:cc:20:ad:b2:11", - "14:cc:20:ad:b2:12", - "a8:40:41:1c:84:18", - "a0:f3:c1:85:fb:43", - "c0:4a:00:fc:55:41", - "64:66:b3:87:4e:d1", - ], - coordinates: { lon: "FIXME", lat: "FIXME" }, - macs: [ - "64:70:02:4e:cc:e2", - "64:70:02:4e:cc:e3", - "66:70:02:4e:cc:e2", - ], - hostname: "ql-quinteros", - }, - author: "ql-quinteros", - }, - "ql-silviak": { - bleachTTL: 28, - data: { - links: [ - "64:70:02:4e:cc:e3", - "c0:4a:00:fc:39:c1", - "64:70:02:4e:cc:e2", - "c0:4a:00:fc:39:c0", - ], - coordinates: { - lon: "-64.43105399608612", - lat: "-31.80852738456711", - }, - macs: [ - "64:66:b3:87:4e:d0", - "64:66:b3:87:4e:d1", - "66:66:b3:87:4e:d0", - ], - hostname: "ql-silviak", - }, - author: "ql-silviak", - }, - "ql-guilleolsina": { - bleachTTL: 29, - data: { - links: ["c0:4a:00:fc:3a:bf", "c0:4a:00:fc:3a:be"], - coordinates: { - lon: "-64.409050063109", - lat: "-31.803118109088", - }, - macs: [ - "a0:f3:c1:86:30:70", - "a0:f3:c1:86:30:71", - "a2:f3:c1:86:30:70", - ], - hostname: "ql-guilleolsina", - }, - author: "ql-guilleolsina", - }, - "ql-flor": { - bleachTTL: 30, - data: { - hostname: "ql-flor", - coordinates: { - lon: "-64.41371777735", - lat: "-31.798914449176", - }, - macs: ["14:cc:20:ad:b0:82", "14:cc:20:ad:b0:83"], - links: [ - "a0:f3:c1:48:cf:ed", - "14:cc:20:ad:b0:92", - "c0:4a:00:fc:3a:bf", - "c0:4a:00:fc:3a:be", - ], - }, - author: "ql-flor", - }, - "ql-b6aa8e": { - bleachTTL: 29, - data: { - hostname: "ql-b6aa8e", - coordinates: { lon: "FIXME", lat: "FIXME" }, - macs: [ - "c0:4a:00:b6:aa:8f", - "c0:4a:00:b6:aa:90", - "c2:4a:00:b6:aa:8f", - "c6:4a:00:b6:aa:8f", - ], - links: [], - }, - author: "ql-b6aa8e", - }, - "rl-tanque": { - bleachTTL: 29, - data: { - links: ["a8:40:41:1c:84:20", "", ""], - coordinates: { lon: "-64.385388", lat: "-31.837376" }, - macs: [ - "a8:40:41:1c:83:e3", - "a8:40:41:1c:83:eb", - "a8:40:41:1c:85:a4", - "aa:40:41:1c:83:e3", - "aa:40:41:1c:83:eb", - "aa:40:41:1c:85:a4", - ], - hostname: "rl-tanque", - }, - author: "rl-tanque", - }, - "si-tato": { - bleachTTL: 29, - data: { - links: [ - "c0:4a:00:b6:9a:b2", - "a8:40:41:1c:84:16", - "14:cc:20:75:be:22", - "14:cc:20:75:d5:1c", - "14:cc:20:75:be:21", - "c0:4a:00:b6:9a:b1", - "a8:40:41:1c:85:50", - "a0:f3:c1:86:31:a0", - "64:70:02:4e:cd:0a", - "a8:40:41:1c:85:9c", - ], - coordinates: { lon: "-64.39182", lat: "-31.82069" }, - macs: ["14:cc:20:75:c0:04", "14:cc:20:75:c0:05"], - hostname: "si-tato", - }, - author: "si-tato", - }, - "si-manu": { - bleachTTL: 29, - data: { - hostname: "si-manu", - coordinates: { lon: "-64.40564", lat: "-31.80858" }, - macs: ["14:cc:20:ad:b0:1c", "14:cc:20:ad:b0:1d"], - links: [ - "a8:40:41:1c:84:28", - "a0:f3:c1:6c:32:75", - "a0:f3:c1:6c:32:74", - "c0:4a:00:fc:41:54", - "a8:40:41:1c:85:44", - "14:cc:20:ad:aa:16", - ], - }, - author: "si-manu", - }, - "ql-margayorlando": { - bleachTTL: 28, - data: { - hostname: "ql-margayorlando", - coordinates: { - lon: "-64.425031334974", - lat: "-31.808832376861", - }, - macs: [ - "c0:4a:00:fc:55:40", - "c0:4a:00:fc:55:41", - "c2:4a:00:fc:55:40", - ], - links: [ - "64:70:02:4e:cc:e3", - "02:11:4e:2f:63:52", - "c0:4a:00:b6:b6:c8", - "c0:4a:00:b6:b6:c7", - "a8:40:41:1c:85:3c", - "c0:4a:00:fc:39:c0", - "a0:f3:c1:86:31:d2", - "64:70:02:4e:cc:e2", - "a0:f3:c1:86:32:10", - "a0:f3:c1:46:28:36", - ], - }, - author: "ql-margayorlando", - }, - "si-cantor": { - bleachTTL: 26, - data: { - hostname: "si-cantor", - coordinates: { - lon: "-64.400667250156", - lat: "-31.810159405843", - }, - macs: ["a0:f3:c1:86:31:8a", "a0:f3:c1:86:31:8b"], - links: [ - "c0:4a:00:fc:41:55", - "c0:4a:00:fc:41:54", - "a8:40:41:1c:85:9c", - ], - }, - author: "si-cantor", - }, - "ql-chanxs": { - bleachTTL: 26, - data: { - links: [ - "c0:4a:00:40:42:8d", - "a0:f3:c1:86:32:11", - "c0:4a:00:40:42:8c", - "a0:f3:c1:86:32:10", - ], - coordinates: { lon: "-64.43163", lat: "-31.80267" }, - macs: [ - "e8:94:f6:bb:c3:51", - "e8:94:f6:bb:c3:52", - "ea:94:f6:bb:c3:51", - ], - hostname: "ql-chanxs", - }, - author: "ql-chanxs", - }, - "ql-coqui": { - bleachTTL: 29, - data: { - hostname: "ql-coqui", - coordinates: { - lon: "-64.413126350261", - lat: "-31.802707653379", - }, - macs: [ - "64:70:02:3d:84:f8", - "64:70:02:3d:84:f9", - "66:70:02:3d:84:f8", - ], - links: [ - "14:cc:20:ad:b0:92", - "c0:4a:00:fc:3a:bf", - "14:cc:20:ad:b0:91", - "c0:4a:00:fc:3a:be", - "64:66:b3:87:4b:38", - "a0:f3:c1:48:cf:ec", - ], - }, - author: "ql-coqui", - }, - "ql-nicojesigioia": { - bleachTTL: 30, - data: { - links: ["a8:40:41:1c:83:f8", ""], - coordinates: { lon: "-64.42818", lat: "-31.81317" }, - macs: [ - "a8:40:41:1c:83:f1", - "a8:40:41:1c:84:07", - "a8:40:41:1c:85:d8", - "aa:40:41:1c:85:d8", - ], - hostname: "ql-nicojesigioia", - }, - author: "ql-nicojesigioia", - }, - "ql-marisa": { - bleachTTL: 28, - data: { - hostname: "ql-marisa", - coordinates: { lon: "-64.43389", lat: "-31.80343" }, - macs: ["a0:f3:c1:86:32:10", "a0:f3:c1:86:32:11"], - links: [ - "e8:94:f6:bb:c3:52", - "a8:40:41:1c:84:18", - "c0:4a:00:fc:55:40", - "e8:94:f6:bb:c3:51", - "a8:40:41:1c:85:3c", - "64:70:02:4e:cc:e2", - "14:cc:20:ad:b2:11", - "a0:f3:c1:85:fb:42", - ], - }, - author: "ql-marisa", - }, - "ql-ipet265": { - bleachTTL: 30, - data: { - links: [ - "a0:f3:c1:48:cf:ed", - "64:66:b3:87:4b:39", - "64:70:02:3d:84:f9", - "14:cc:20:ad:b0:83", - "c0:4a:00:fc:3a:bf", - "64:70:02:3d:84:f8", - "a0:f3:c1:48:cf:ec", - "c0:4a:00:fc:3a:be", - ], - coordinates: { - lon: "-64.413958505606004223", - lat: "-31.804002555867000979", - }, - macs: [ - "14:cc:20:ad:b0:91", - "14:cc:20:ad:b0:92", - "16:cc:20:ad:b0:91", - ], - hostname: "ql-ipet265", - }, - author: "ql-ipet265", - }, - "si-giordano": { - bleachTTL: 27, - data: { - links: [ - "a0:f3:c1:86:31:8b", - "a8:40:41:1c:84:28", - "a0:f3:c1:86:31:8a", - "14:cc:20:ad:b0:1c", - "14:cc:20:ad:aa:16", - "a8:40:41:1c:85:9c", - ], - coordinates: { lon: "-64.39912", lat: "-31.80916" }, - macs: ["c0:4a:00:fc:41:54", "c0:4a:00:fc:41:55"], - hostname: "si-giordano", - }, - author: "si-giordano", - }, - "ql-irene": { - bleachTTL: 29, - data: { - links: [ - "14:cc:20:ad:ae:e5", - "14:cc:20:ad:b0:92", - "c0:4a:00:fc:3a:bf", - "64:70:02:3d:84:f9", - "a0:f3:c1:48:cf:ed", - "14:cc:20:ad:ae:e4", - "c0:4a:00:fc:3a:be", - "64:70:02:3d:84:f8", - ], - coordinates: { lon: "-64.41682", lat: "-31.80584" }, - macs: [ - "64:66:b3:87:4b:38", - "64:66:b3:87:4b:39", - "66:66:b3:87:4b:38", - "66:66:b3:87:4b:39", - ], - hostname: "ql-irene", - }, - author: "ql-irene", - }, - "ql-bety": { - bleachTTL: 28, - data: { - hostname: "ql-bety", - coordinates: { lon: "-64.4318056", lat: "-31.8068056" }, - macs: ["14:cc:20:ad:b2:11", "14:cc:20:ad:b2:12"], - links: [ - "64:70:02:4e:cc:e3", - "64:70:02:4e:cc:e2", - "a8:40:41:1c:85:3c", - "c0:4a:00:fc:39:c0", - ], - }, - author: "ql-bety", - }, - "ql-lauraymario": { - bleachTTL: 28, - data: { - hostname: "ql-lauraymario", - coordinates: { lon: "-64.42696", lat: "-31.80462" }, - macs: [ - "c4:e9:84:f9:af:fc", - "c4:e9:84:f9:af:fd", - "c6:e9:84:f9:af:fc", - ], - links: [ - "a8:40:41:1c:84:18", - "c0:4a:00:fc:39:c1", - "a8:40:41:1c:85:3c", - "c0:4a:00:fc:39:c0", - ], - }, - author: "ql-lauraymario", - }, - "ql-graciela": { - bleachTTL: 29, - data: { - hostname: "ql-graciela", - coordinates: { lon: "-64.42705", lat: "-31.80873" }, - macs: [ - "a8:40:41:1c:84:05", - "a8:40:41:1c:84:18", - "a8:40:41:1c:85:3c", - ], - links: [ - "c4:e9:84:f9:af:fd", - "a0:f3:c1:86:32:11", - "c0:4a:00:fc:39:c1", - "64:70:02:4e:cc:e3", - "14:cc:20:ad:b2:12", - "64:70:02:d1:88:74", - "c4:e9:84:f9:af:fc", - "a0:f3:c1:86:32:10", - "c0:4a:00:fc:39:c0", - "64:70:02:4e:cc:e2", - "a0:f3:c1:85:fb:42", - ], - }, - author: "ql-graciela", - }, - "ql-guillermina": { - bleachTTL: 28, - data: { - links: [ - "64:70:02:4e:cc:e3", - "a8:40:41:1c:84:18", - "64:70:02:4e:cc:e2", - "c0:4a:00:fc:39:c0", - "a0:f3:c1:86:32:10", - "a8:40:41:1c:85:3c", - ], - coordinates: { lon: "-64.43215", lat: "-31.80964" }, - macs: ["a0:f3:c1:85:fb:42", "a0:f3:c1:85:fb:43"], - hostname: "ql-guillermina", - }, - author: "ql-guillermina", - }, - "si-nestor": { - bleachTTL: 29, - data: { - links: [ - "14:cc:20:75:c0:05", - "c0:4a:00:b6:9a:b2", - "a8:40:41:1c:84:28", - "a8:40:41:1c:84:20", - "14:cc:20:75:be:21", - "14:cc:20:75:c0:04", - "14:cc:20:75:d5:1c", - "c0:4a:00:b6:9a:b1", - ], - coordinates: { lon: "-64.39240", lat: "-31.82056" }, - macs: [ - "a8:40:41:1c:84:16", - "a8:40:41:1c:84:1a", - "a8:40:41:1c:85:50", - ], - hostname: "si-nestor", - }, - author: "si-nestor", - }, - "ql-esteban": { - bleachTTL: 30, - data: { - hostname: "ql-esteban", - coordinates: { - lon: "-64.41600680351257", - lat: "-31.801688993108318", - }, - macs: ["a0:f3:c1:48:cf:ec", "a0:f3:c1:48:cf:ed"], - links: [ - "14:cc:20:ad:b0:83", - "64:70:02:3d:8a:e5", - "14:cc:20:ad:b0:92", - "c0:4a:00:fc:3a:bf", - "64:66:b3:87:4b:39", - "a0:f3:c1:86:30:71", - "64:70:02:3d:8a:e4", - "14:cc:20:ad:b0:91", - "64:70:02:3d:84:f8", - "c0:4a:00:fc:3a:be", - "14:cc:20:ad:b0:82", - "a0:f3:c1:86:30:70", - "64:66:b3:87:4b:38", - ], - }, - author: "ql-esteban", - }, - "ql-irenecasa": { - bleachTTL: 25, - data: { - links: ["64:66:b3:87:4b:39", "64:66:b3:87:4b:38"], - coordinates: { lon: "-64.41609", lat: "-31.80461" }, - macs: [ - "14:cc:20:ad:ae:e4", - "14:cc:20:ad:ae:e5", - "16:cc:20:ad:ae:e4", - "16:cc:20:ad:ae:e5", - ], - hostname: "ql-irenecasa", - }, - author: "ql-irenecasa", - }, - "si-mario": { - bleachTTL: 29, - data: { - hostname: "si-mario", - coordinates: { lon: "-64.40331", lat: "-31.80399" }, - macs: ["a0:f3:c1:6c:32:74", "a0:f3:c1:6c:32:75"], - links: [ - "a8:40:41:1c:84:28", - "a8:40:41:1c:85:44", - "14:cc:20:ad:b0:1c", - ], - }, - author: "si-mario", - }, - "ql-czuk": { - bleachTTL: 30, - data: { - links: [ - "64:66:b3:87:4b:39", - "64:70:02:3d:84:f9", - "14:cc:20:ad:b0:83", - "a0:f3:c1:48:cf:ed", - "a0:f3:c1:86:30:71", - "14:cc:20:ad:b0:92", - "14:cc:20:ad:b0:82", - "64:66:b3:87:4b:38", - "64:70:02:3d:84:f8", - "a0:f3:c1:86:30:70", - "a0:f3:c1:48:cf:ec", - "14:cc:20:ad:b0:91", - ], - coordinates: { lon: "-64.41506", lat: "-31.80137" }, - macs: ["c0:4a:00:fc:3a:be", "c0:4a:00:fc:3a:bf"], - hostname: "ql-czuk", - }, - author: "ql-czuk", - }, - "ql-gioiajesinico": { - bleachTTL: 29, - data: { - links: [""], - coordinates: { lon: "-64.42813", lat: "-31.81314" }, - macs: ["e8:de:27:91:60:6d", "ea:de:27:91:60:6d"], - hostname: "ql-gioiajesinico", - }, - author: "ql-gioiajesinico", - }, - "si-pablo": { - bleachTTL: 28, - data: { - hostname: "si-pablo", - coordinates: { lon: "-64.40452", lat: "-31.80978" }, - macs: [ - "14:cc:20:ad:aa:16", - "14:cc:20:ad:aa:17", - "16:cc:20:ad:aa:16", - ], - links: [ - "a8:40:41:1c:84:28", - "c0:4a:00:fc:41:54", - "14:cc:20:ad:b0:1c", - "a8:40:41:1c:85:44", - ], - }, - author: "si-pablo", - }, - "ql-graciela-bbone": { - bleachTTL: 30, - data: { - links: ["02:ce:56:aa:83:52", "a8:40:41:1c:83:f1"], - coordinates: { lon: "-64.42703", lat: "-31.80874" }, - macs: [ - "a8:40:41:1c:83:dd", - "a8:40:41:1c:83:f8", - "a8:40:41:1c:85:a8", - ], - hostname: "ql-graciela-bbone", - }, - author: "ql-graciela-bbone", - }, - "si-soniam": { - bleachTTL: 29, - data: { - links: [ - "a8:40:41:1c:84:16", - "14:cc:20:75:c0:05", - "a0:f3:c1:86:31:a1", - "64:70:02:4e:cd:0b", - "a0:f3:c1:86:31:a0", - "14:cc:20:75:c0:04", - "14:cc:20:75:be:21", - "a8:40:41:1c:85:50", - "64:70:02:4e:cd:0a", - "14:cc:20:75:d5:1c", - ], - coordinates: { lon: "-64.39345", lat: "-31.82057" }, - macs: ["c0:4a:00:b6:9a:b1", "c0:4a:00:b6:9a:b2"], - hostname: "si-soniam", - }, - author: "si-soniam", - }, - "si-frigorifico": { - bleachTTL: 30, - data: { - hostname: "si-frigorifico", - coordinates: { lon: "-64.39950", lat: "-31.79970" }, - macs: [ - "a8:40:41:1c:84:20", - "a8:40:41:1c:84:28", - "a8:40:41:1c:85:44", - ], - links: [ - "a8:40:41:1c:83:eb", - "a8:40:41:1c:84:1a", - "a8:40:41:1c:83:e5", - "a0:f3:c1:6c:32:75", - "14:cc:20:ad:b0:1d", - "14:cc:20:ad:b0:1c", - "a0:f3:c1:6c:32:74", - "a8:40:41:1c:85:9c", - ], - }, - author: "si-frigorifico", - }, - "si-bel-mar": { - bleachTTL: 28, - data: { - links: [ - "14:cc:20:75:be:22", - "a8:40:41:1c:84:28", - "c0:4a:00:fc:55:82", - "14:cc:20:75:be:21", - "a8:40:41:1c:85:50", - "a8:40:41:1c:85:44", - ], - coordinates: { lon: "-64.39031", lat: "-31.82131" }, - macs: ["14:cc:20:75:d5:1c", "14:cc:20:75:d5:1d"], - hostname: "si-bel-mar", - }, - author: "si-bel-mar", - }, - "ql-cesarylucia": { - bleachTTL: 25, - data: { - hostname: "ql-cesarylucia", - coordinates: { lon: "-64.42450", lat: "-31.81799" }, - macs: [ - "a0:f3:c1:46:28:36", - "a0:f3:c1:46:28:37", - "a2:f3:c1:46:28:36", - ], - links: [ - "02:11:4e:2f:63:52", - "c0:4a:00:fc:55:40", - "a8:40:41:1c:85:3c", - ], - }, - author: "ql-cesarylucia", - }, - "ql-espacioabierto": { - bleachTTL: 29, - data: { - links: ["a0:f3:c1:48:cf:ed", "a0:f3:c1:48:cf:ec"], - coordinates: { lon: "-64.41756", lat: "-31.80264" }, - macs: [ - "64:70:02:3d:8a:e4", - "64:70:02:3d:8a:e5", - "66:70:02:3d:8a:e4", - ], - hostname: "ql-espacioabierto", - }, - author: "ql-espacioabierto", - }, - "ql-ale": { - bleachTTL: 27, - data: { - hostname: "ql-ale", - coordinates: { lon: "-64.42530", lat: "-31.81378" }, - macs: [ - "c0:4a:00:b6:b6:c7", - "c0:4a:00:b6:b6:c8", - "c2:4a:00:b6:b6:c7", - ], - links: ["c0:4a:00:fc:55:41", "c0:4a:00:fc:55:40"], - }, - author: "ql-ale", - }, - "ql-oncelotes": { - bleachTTL: 28, - data: { - links: [ - "a0:f3:c1:86:31:d3", - "c0:4a:00:fc:55:41", - "a8:40:41:1c:84:05", - ], - coordinates: { lon: "-64.42398", lat: "-31.81424" }, - macs: ["02:11:4e:2f:63:51", "02:11:4e:2f:63:52"], - hostname: "ql-oncelotes", - }, - author: "ql-oncelotes", - }, - "si-sonia": { - bleachTTL: 29, - data: { - hostname: "si-sonia", - coordinates: { - lon: "-64.388400000000004297", - lat: "-31.821400000000000574", - }, - macs: ["c0:4a:00:fc:55:82", "c0:4a:00:fc:55:83"], - links: ["a8:40:41:1c:84:28", "14:cc:20:75:d5:1c"], - }, - author: "si-sonia", - }, - "ql-jorgeortiz": { - bleachTTL: 28, - data: { - links: [ - "c0:4a:00:fc:55:40", - "64:66:b3:87:4e:d0", - "a8:40:41:1c:85:3c", - "64:70:02:4e:cc:e2", - "a0:f3:c1:85:fb:42", - "c4:e9:84:f9:af:fc", - "a8:40:41:1c:84:18", - "64:66:b3:87:4e:d1", - "c4:e9:84:f9:af:fd", - ], - coordinates: { - lon: "-64.430179595947", - lat: "-31.804784567677", - }, - macs: [ - "c0:4a:00:fc:39:c0", - "c0:4a:00:fc:39:c1", - "c2:4a:00:fc:39:c0", - ], - hostname: "ql-jorgeortiz", - }, - author: "ql-jorgeortiz", - }, - "si-andrea": { - bleachTTL: 27, - data: { - hostname: "si-andrea", - coordinates: { lon: "-64.40097", lat: "-31.81854" }, - macs: ["14:cc:20:ad:b0:d9", "14:cc:20:ad:b0:da"], - links: [ - "a8:40:41:1c:84:28", - "a8:40:41:1c:85:9c", - "a8:40:41:1c:85:44", - ], - }, - author: "si-andrea", - }, - "ql-anaymarcos": { - bleachTTL: 28, - data: { - links: ["a8:40:41:1c:84:05"], - coordinates: { lon: "-64.42695", lat: "-31.81300" }, - macs: ["64:70:02:d1:88:74"], - hostname: "ql-anaymarcos", - }, - author: "ql-anaymarcos", - }, - "si-monica": { - bleachTTL: 29, - data: { - links: [ - "c0:4a:00:b6:9a:b2", - "14:cc:20:75:c0:04", - "c0:4a:00:b6:9a:b1", - "64:70:02:4e:cd:0a", - ], - coordinates: { lon: "-64.39372", lat: "-31.81995" }, - macs: ["a0:f3:c1:86:31:a0", "a0:f3:c1:86:31:a1"], - hostname: "si-monica", - }, - author: "si-monica", - }, - }, - }; - return ( - - ); -}; diff --git a/plugins/lime-plugin-locate/src/communityGeoJSON.spec.js b/plugins/lime-plugin-locate/src/communityGeoJSON.spec.js deleted file mode 100644 index ad4feada2..000000000 --- a/plugins/lime-plugin-locate/src/communityGeoJSON.spec.js +++ /dev/null @@ -1,219 +0,0 @@ -/* eslint jest/expect-expect: ["error", { "assertFunctionNames": ["expect", "compareGeoJsons"] }] */ -import { getCommunityGeoJSON } from "./communityGeoJSON"; - -const getMockedNodesData = jest.fn(() => ({ - host1: { - bleachTTL: 29, - data: { - hostname: "host1", - coordinates: { - lon: "-64.42818", - lat: "-31.81317", - }, - macs: [ - "a0:f3:c1:86:31:d2", - "a0:f3:c1:86:31:d3", - "a2:f3:c1:86:31:d2", - ], - links: ["a0:f3:c1:46:28:37", "a8:40:41:1c:85:44"], - }, - author: "host1", - }, - host2: { - bleachTTL: 30, - data: { - links: [ - "a0:f3:c1:86:31:d2", - // Link to host3, but host3 doenst link host2 - "a8:40:41:1c:84:20", - ], - coordinates: { - lon: "-64.42450", - lat: "-31.81799", - }, - macs: [ - "a0:f3:c1:46:28:36", - "a0:f3:c1:46:28:37", - "a2:f3:c1:46:28:36", - ], - hostname: "host2", - }, - author: "host2", - }, - host3: { - bleachTTL: 30, - data: { - hostname: "host3", - coordinates: { - lon: "-64.39950", - lat: "-31.79970", - }, - macs: [ - "a8:40:41:1c:84:20", - "a8:40:41:1c:84:28", - "a8:40:41:1c:85:44", - ], - links: ["a0:f3:c1:86:31:d3"], - }, - author: "host3", - }, -})); - -function compareGeoJsons(a, b) { - expect(a.type).toEqual(b.type); - expect(a.features.length).toEqual(b.features.length); - const resultFeatures = a.features; - for (const feature of b.features) { - expect(resultFeatures).toContainEqual(feature); - } -} - -test("getCommunityGeoJSON returns a well formed geo JSON", () => { - const nodesData = getMockedNodesData(); - const geoJSON = getCommunityGeoJSON(nodesData); - const expected = { - type: "FeatureCollection", - features: [ - { - type: "Feature", - geometry: { - type: "Point", - coordinates: [-64.42818, -31.81317], - }, - properties: { name: "host1" }, - }, - { - type: "Feature", - geometry: { type: "Point", coordinates: [-64.4245, -31.81799] }, - properties: { name: "host2" }, - }, - { - type: "Feature", - geometry: { type: "Point", coordinates: [-64.3995, -31.7997] }, - properties: { name: "host3" }, - }, - // Note: coordinates list is expected to be sorted to simplify testing - { - type: "Feature", - geometry: { - type: "LineString", - coordinates: [ - [-64.42818, -31.81317], - [-64.4245, -31.81799], - ].sort(), - }, - }, - { - type: "Feature", - geometry: { - type: "LineString", - coordinates: [ - [-64.42818, -31.81317], - [-64.3995, -31.7997], - ].sort(), - }, - }, - ], - }; - compareGeoJsons(geoJSON, expected); -}); - -test("getCommunityGeoJSON ignore nodes without coordinates and their links", () => { - let nodesData = getMockedNodesData(); - nodesData.host2.data.coordinates = { lat: "FIXME", lon: "FIXME" }; - const geoJSON = getCommunityGeoJSON(nodesData); - const expected = { - type: "FeatureCollection", - features: [ - { - type: "Feature", - geometry: { - type: "Point", - coordinates: [-64.42818, -31.81317], - }, - properties: { name: "host1" }, - }, - { - type: "Feature", - geometry: { type: "Point", coordinates: [-64.3995, -31.7997] }, - properties: { name: "host3" }, - }, - // Note: coordinates list is expected to be sorted to simplify testing - { - type: "Feature", - geometry: { - type: "LineString", - coordinates: [ - [-64.42818, -31.81317], - [-64.3995, -31.7997], - ].sort(), - }, - }, - ], - }; - compareGeoJsons(geoJSON, expected); -}); - -test("getCommunityGeoJSON ignore nodes without mac addresses", () => { - let nodesData = getMockedNodesData(); - nodesData.host2.data.macs = []; - const geoJSON = getCommunityGeoJSON(nodesData); - const expected = { - type: "FeatureCollection", - features: [ - { - type: "Feature", - geometry: { - type: "Point", - coordinates: [-64.42818, -31.81317], - }, - properties: { name: "host1" }, - }, - { - type: "Feature", - geometry: { type: "Point", coordinates: [-64.3995, -31.7997] }, - properties: { name: "host3" }, - }, - // Note: coordinates list is expected to be sorted to simplify testing - { - type: "Feature", - geometry: { - type: "LineString", - coordinates: [ - [-64.42818, -31.81317], - [-64.3995, -31.7997], - ].sort(), - }, - }, - ], - }; - compareGeoJsons(geoJSON, expected); -}); - -test("getCommunityGeoJSON doesnt return geo points in keepClean coordinates", () => { - let nodesData = getMockedNodesData(); - nodesData.host2.data.macs = []; - const geoJSON = getCommunityGeoJSON(nodesData, [-64.42818, -31.81317]); - const expected = { - type: "FeatureCollection", - features: [ - { - type: "Feature", - geometry: { type: "Point", coordinates: [-64.3995, -31.7997] }, - properties: { name: "host3" }, - }, - // Note: coordinates list is expected to be sorted to simplify testing - { - type: "Feature", - geometry: { - type: "LineString", - coordinates: [ - [-64.42818, -31.81317], - [-64.3995, -31.7997], - ].sort(), - }, - }, - ], - }; - compareGeoJsons(geoJSON, expected); -}); diff --git a/plugins/lime-plugin-locate/src/communityGeoJSON.ts b/plugins/lime-plugin-locate/src/communityGeoJSON.ts deleted file mode 100644 index 046f51c63..000000000 --- a/plugins/lime-plugin-locate/src/communityGeoJSON.ts +++ /dev/null @@ -1,121 +0,0 @@ -import type { GeoJsonObject } from "geojson"; - -interface NodeData { - [key: string]: { - bleachTTL: number; - data: { - hostname: string; - coordinates: { - lon: string; - lat: string; - }; - macs: string[]; - links: string[]; - }; - author: string; - }; -} - -const isObject = (obj) => typeof obj === "object" && obj !== null; -const coordsToPoint = (coordinates, properties = {}) => ({ - type: "Feature", - geometry: { - type: "Point", - coordinates: [Number(coordinates.lon), Number(coordinates.lat)], - }, - properties, -}); - -const coordspairToLineString = (coordinates) => ({ - type: "Feature", - geometry: { - type: "LineString", - coordinates, - }, -}); - -const pointIsIn = (lat, lon, point) => { - const pointLat = point.geometry.coordinates[1]; - const pointLon = point.geometry.coordinates[0]; - return Number(pointLat) === Number(lat) && Number(pointLon) === Number(lon); -}; - -const removeDuplicates = (collection, getIdentifier) => { - const identifierState = {}; - return collection.filter((value) => { - const identifier = String(getIdentifier(value)); - if (identifierState[identifier]) { - return false; - } - identifierState[identifier] = true; - return true; - }); -}; - -export function getCommunityGeoJSON( - nodesData: NodeData, - keepClean = null -): GeoJsonObject { - // nodes: {..., {hostname, coordinates, macs, links}} Nodes with potential links - const nodes = Object.values(nodesData) - .map((nodeData) => nodeData.data) - .filter((n) => isObject(n)) // Filter completely corrupted nodes - .filter( - (n) => - !isNaN(Number(n.coordinates.lat)) || - !isNaN(Number(n.coordinates.lon)) - ) // Filter nodes without coordinates - .filter((n) => n.macs.length); // Filter nodes without a macs list - - // geomac: {mac: [lat, lon]} Coordinates for each mac address - const geomac_ = nodes.map((node) => - node.macs.map((mac) => [ - mac, - [Number(node.coordinates.lon), Number(node.coordinates.lat)], - ]) - ); - const geomac = Object.fromEntries(geomac_.flat()); - - const macLinks_ = nodes.map((node) => - node.macs.map((mac) => [mac, node.links]) - ); - const macLinks = Object.fromEntries(macLinks_.flat()); - - // geolink: [..., [[lat,lon], [lat,lon]]] All links as pair of coordinates - let geolinks = nodes - .map((node) => - node.links - .filter((mac) => mac in geomac) - //Keep only links if both nodes say there is a link - .filter((mac) => - node.macs.some( - (node_mac) => macLinks[mac].indexOf(node_mac) != -1 - ) - ) - .map((mac) => [geomac[node.macs[0]], geomac[mac]].sort()) - ) - .flat(); - geolinks = removeDuplicates(geolinks, (l) => `${l[0]},${l[1]}`); - - // nodefeatures: [..., GeoJSONFeature:Point] All nodes to be shown - let nodefeatures = nodes.map((node) => - coordsToPoint(node.coordinates, { name: node.hostname }) - ); - if (keepClean) { - const [lon, lat] = keepClean; - nodefeatures = nodefeatures.filter( - (point) => !pointIsIn(lat, lon, point) - ); - } - - // linksfeatures: [..., GeoJSONFeature:LineString] - const linksfeatures = geolinks.map(coordspairToLineString); - - const features = [...nodefeatures, ...linksfeatures]; - - const geoJSON = { - type: "FeatureCollection", - features, - }; - return geoJSON as GeoJsonObject; -} diff --git a/plugins/lime-plugin-locate/src/locateMenu.js b/plugins/lime-plugin-locate/src/locateMenu.js deleted file mode 100755 index 1a389c660..000000000 --- a/plugins/lime-plugin-locate/src/locateMenu.js +++ /dev/null @@ -1,12 +0,0 @@ -import { Trans } from "@lingui/macro"; - -import { PinIcon } from "components/icons/teenny/pin"; - -export const LocateMenu = () => ( - - - - Locate - - -); diff --git a/plugins/lime-plugin-locate/src/locatePage.tsx b/plugins/lime-plugin-locate/src/locatePage.tsx deleted file mode 100644 index cc65c67fa..000000000 --- a/plugins/lime-plugin-locate/src/locatePage.tsx +++ /dev/null @@ -1,239 +0,0 @@ -import { Trans } from "@lingui/macro"; -import L, { LatLngExpression, icon } from "leaflet"; -import { useEffect, useRef, useState } from "preact/hooks"; -import { LayersControl, MapContainer, Marker, TileLayer } from "react-leaflet"; - -import { Loading } from "components/loading"; - -import { - useChangeLocation, - useLoadLeaflet, - useLocation, - useNodesandlinks, -} from "plugins/lime-plugin-locate/src/locateQueries"; - -import { useBoardData } from "utils/queries"; - -import { getCommunityGeoJSON } from "./communityGeoJSON"; -import { homeIcon } from "./leafletUtils"; -import style from "./style.less"; - -const openStreetMapTileString = "http://{s}.tile.osm.org/{z}/{x}/{y}.png"; -const openStreetMapAttribution = - '© OpenStreetMap contributors'; - -const gmSatellite = "https://{s}.google.com/vt/lyrs=s&x={x}&y={y}&z={z}"; -const gmHybrid = "https://{s}.google.com/vt/lyrs=s,h&x={x}&y={y}&z={z}"; -const gmSubdomains = ["mt0", "mt1", "mt2", "mt3"]; - -function getCommunityLayer(nodeHostname, stationLat, stationLon, nodesData) { - /** Create a Leaflet layer with community nodes and links to be added to the map*/ - if (nodesData[nodeHostname]) { - nodesData[nodeHostname].data.coordinates = { - lat: stationLat, - lon: stationLon, - }; - } - // Get community GeoJSON, filter out nodes in same location as station host. - const geoJSON = getCommunityGeoJSON(nodesData, [stationLon, stationLat]); - return L.geoJSON(geoJSON, { - onEachFeature: (feature, layer) => { - if (feature.properties && feature.properties.name) { - layer.bindTooltip(feature.properties.name).openTooltip(); - } - }, - }); -} - -export const LocatePage = () => { - const { data: boardData } = useBoardData(); - const { - isError: isAssetError, - isFetchedAfterMount: assetsLoaded, - isLoading: isLoadingAssets, - } = useLoadLeaflet({ - refetchOnWindowFocus: false, - }); - - const { - data: nodeLocation, - isLoading: isLoadingLocation, - isFetched: locationLoaded, - } = useLocation({ - enabled: assetsLoaded, - }); - - const { data: nodesData } = useNodesandlinks({ - enabled: locationLoaded, - }); - - const { mutate: changeLocation, isLoading: submitting } = useChangeLocation( - { - onSettled: () => { - toogleEdition(); - }, - } - ); - - const loading = isLoadingLocation || isLoadingAssets; - const isCommunityLocation = nodeLocation.default; - const stationLat = - nodeLocation.location.lat !== "FIXME" - ? nodeLocation.location.lat - : null; - const stationLon = - nodeLocation.location.lon !== "FIXME" - ? nodeLocation.location.lon - : null; - const hasLocation = stationLat && !isCommunityLocation; - - const [editting, setEditting] = useState(false); - const [nodeMarker, setNodeMarker] = useState(null); - const [communityLayer, setCommunityLayer] = useState(null); - - const mapRef = useRef(); - - // Set map position when map is available or location gets updated - useEffect(() => { - function updateNodeMarker(lat, lon) { - setNodeMarker([lat, lon]); - } - const mapInstance = mapRef.current; - - if (!loading && mapInstance && stationLat) { - mapInstance.setView([+stationLat, +stationLon], 13); - updateNodeMarker(stationLat, stationLon); - } - }, [stationLat, stationLon, loading]); - - // Center the map on the node also when editting is turned on - useEffect(() => { - const map = mapRef.current; - if (map && stationLat) { - editting && map.setView([+stationLat, +stationLon], 13); - } - }, [mapRef, editting, stationLat, stationLon]); - - function onConfirmLocation() { - const position = mapRef.current.getCenter(); - changeLocation({ lat: position.lat, lon: position.lng }); - if (communityLayer) { - // Hide the community view, to avoid outdated links - toogleCommunityLayer(); - } - } - - function toogleCommunityLayer() { - if (communityLayer) { - mapRef.current.removeLayer(communityLayer); - setCommunityLayer(null); - } else { - const layer = getCommunityLayer( - boardData.hostname, - stationLat, - stationLon, - nodesData - ); - layer.addTo(mapRef.current); - setCommunityLayer(layer); - } - } - - function isReady() { - return !loading && typeof stationLat !== "undefined"; - } - - function toogleEdition() { - setEditting(!editting); - } - - if (isAssetError) { - return ( -
- Cannot load map, check your internet connection -
- ); - } - - return ( - <> - {(!isReady() || submitting) && ( -
- -
- )} - {isReady() && ( - - - - - - - - - - - - - {nodeMarker && ( - - )} - {editting && ( -
- )} - - )} - {isReady() && ( -
- {editting && ( - - )} - {!editting && ( - - )} - - -
- )} - - ); -}; - -export default LocatePage; diff --git a/plugins/lime-plugin-mesh-wide/src/containers/LocateNode.tsx b/plugins/lime-plugin-mesh-wide/src/containers/LocateNode.tsx new file mode 100644 index 000000000..3ffe656bb --- /dev/null +++ b/plugins/lime-plugin-mesh-wide/src/containers/LocateNode.tsx @@ -0,0 +1,71 @@ +import { Trans } from "@lingui/macro"; + +import style from "plugins/lime-plugin-mesh-wide/src/containers/style.less"; +import { useLocateNode } from "plugins/lime-plugin-mesh-wide/src/hooks/useLocateNode"; +import { + getLocationQueryKey, + useChangeLocation, + useLocation, +} from "plugins/lime-plugin-mesh-wide/src/locateNodeQueries"; + +import queryCache from "utils/queryCache"; + +const LocateNode = ({}) => { + const { editingLocation, setEditingLocation, mapRef } = useLocateNode(); + + const { data: nodeLocation, isLoading } = useLocation({}); + + const { mutate: changeLocation, isLoading: submitting } = useChangeLocation( + { + onSettled: () => { + queryCache.invalidateQueries(getLocationQueryKey); + toogleEdition(); + }, + } + ); + + let stationLat = null; + if (nodeLocation.location.lat !== "FIXME") + stationLat = nodeLocation.location.lat; + let stationLon = null; + if (nodeLocation.location.lon !== "FIXME") { + stationLon = nodeLocation.location.lon; + } + + const hasLocation = stationLat && stationLon; + const loaded = !isLoading && typeof stationLat !== "undefined"; + + const toogleEdition = () => { + setEditingLocation((prev) => !prev); + }; + + const confirmLocation = async () => { + const position = mapRef.current.getCenter(); + changeLocation({ lat: position.lat, lon: position.lng }); + }; + + if (!loaded) { + return null; + } + + return ( +
+ {editingLocation && ( + + )} + +
+ ); +}; + +export default LocateNode; diff --git a/plugins/lime-plugin-mesh-wide/src/containers/Map.tsx b/plugins/lime-plugin-mesh-wide/src/containers/Map.tsx index 2da02c117..f797f8260 100644 --- a/plugins/lime-plugin-mesh-wide/src/containers/Map.tsx +++ b/plugins/lime-plugin-mesh-wide/src/containers/Map.tsx @@ -1,6 +1,5 @@ -import L from "leaflet"; import { ComponentChildren } from "preact"; -import { useEffect, useRef } from "preact/hooks"; +import { useEffect } from "preact/hooks"; import { LayerGroup, LayersControl, @@ -10,16 +9,18 @@ import { import { MeshWideMapTypes } from "components/shared-state/SharedStateTypes"; -import { - useLoadLeaflet, - useLocation, -} from "plugins/lime-plugin-locate/src/locateQueries"; import { BabelLinksLayer, BatmanLinksLayer, WifiLinksLayer, } from "plugins/lime-plugin-mesh-wide/src/containers/MapLayers/LinksLayers"; import NodesLayer from "plugins/lime-plugin-mesh-wide/src/containers/MapLayers/NodesLayer"; +import style from "plugins/lime-plugin-mesh-wide/src/containers/style.less"; +import { useLocateNode } from "plugins/lime-plugin-mesh-wide/src/hooks/useLocateNode"; +import { + useLoadLeaflet, + useLocation, +} from "plugins/lime-plugin-mesh-wide/src/locateNodeQueries"; import { useSelectedMapFeature } from "plugins/lime-plugin-mesh-wide/src/meshWideQueries"; const openStreetMapTileString = "https://{s}.tile.osm.org/{z}/{x}/{y}.png"; @@ -50,7 +51,8 @@ export const MeshWideMap = ({ enabled: !!leafletData, }); - const mapRef = useRef(); + const { mapRef, editingLocation } = useLocateNode(); + const loading = assetsLoading || isLoadingLocation; useEffect(() => { @@ -129,6 +131,9 @@ export const MeshWideMap = ({ ) )} + {editingLocation && ( +
+ )} ); }; diff --git a/plugins/lime-plugin-locate/src/style.less b/plugins/lime-plugin-mesh-wide/src/containers/style.less similarity index 90% rename from plugins/lime-plugin-locate/src/style.less rename to plugins/lime-plugin-mesh-wide/src/containers/style.less index 5a6fc9ec4..bd2328b39 100644 --- a/plugins/lime-plugin-locate/src/style.less +++ b/plugins/lime-plugin-mesh-wide/src/containers/style.less @@ -1,8 +1,4 @@ -.mapContainer { - width: 100vw; - height: ~"calc(100vh - 56px)"; -} - +// Styles for locate node. Inherited from old implementation .locationMarker { width: 10px; height: 10px; diff --git a/plugins/lime-plugin-mesh-wide/src/hooks/useLocateNode.tsx b/plugins/lime-plugin-mesh-wide/src/hooks/useLocateNode.tsx new file mode 100644 index 000000000..9d067eb54 --- /dev/null +++ b/plugins/lime-plugin-mesh-wide/src/hooks/useLocateNode.tsx @@ -0,0 +1,38 @@ +import L from "leaflet"; +import { ComponentChildren, createContext } from "preact"; +import { useContext, useRef, useState } from "preact/hooks"; + +const LocateNodeContext = createContext< + ReturnType | undefined +>(undefined); + +export const LocateNodeProvider = ({ + children, +}: { + children: ComponentChildren; +}) => { + const locateNode = useLocateNodeProvider(); + return ( + + {children} + + ); +}; + +const useLocateNodeProvider = () => { + const [editingLocation, setEditingLocation] = useState(false); + // MapRef is stored on here but should be moved to a more general place if used further + const mapRef = useRef(); + + return { editingLocation, setEditingLocation, mapRef }; +}; + +export const useLocateNode = () => { + const context = useContext(LocateNodeContext); + if (context === null) { + throw new Error( + "useLocateNode must be used within a LocateNodeProvider" + ); + } + return context; +}; diff --git a/plugins/lime-plugin-locate/src/leafletUtils.ts b/plugins/lime-plugin-mesh-wide/src/lib/leafletUtils.ts similarity index 98% rename from plugins/lime-plugin-locate/src/leafletUtils.ts rename to plugins/lime-plugin-mesh-wide/src/lib/leafletUtils.ts index e0aa70f07..7022b75b0 100644 --- a/plugins/lime-plugin-locate/src/leafletUtils.ts +++ b/plugins/lime-plugin-mesh-wide/src/lib/leafletUtils.ts @@ -1,4 +1,4 @@ -import { DivIconOptions, IconOptions } from "leaflet"; +import { IconOptions } from "leaflet"; const leafletVersion = "1.9.3"; diff --git a/plugins/lime-plugin-locate/src/locateApi.js b/plugins/lime-plugin-mesh-wide/src/locateApi.js similarity index 74% rename from plugins/lime-plugin-locate/src/locateApi.js rename to plugins/lime-plugin-mesh-wide/src/locateApi.js index 3e2d54288..3a61484aa 100644 --- a/plugins/lime-plugin-locate/src/locateApi.js +++ b/plugins/lime-plugin-mesh-wide/src/locateApi.js @@ -2,9 +2,6 @@ import api from "utils/uhttpd.service"; export const getLocation = () => api.call("lime-location", "get", {}); -export const getNodesandlinks = async () => - api.call("lime-location", "all_nodes_and_links", {}); - export const changeLocation = async (location) => { return await api.call("lime-location", "set", { lat: location.lat.toFixed(5), diff --git a/plugins/lime-plugin-locate/src/locateQueries.tsx b/plugins/lime-plugin-mesh-wide/src/locateNodeQueries.tsx similarity index 74% rename from plugins/lime-plugin-locate/src/locateQueries.tsx rename to plugins/lime-plugin-mesh-wide/src/locateNodeQueries.tsx index 45c1f399a..0acd02aca 100644 --- a/plugins/lime-plugin-locate/src/locateQueries.tsx +++ b/plugins/lime-plugin-mesh-wide/src/locateNodeQueries.tsx @@ -1,11 +1,10 @@ import { useMutation, useQuery } from "@tanstack/react-query"; -import { loadLeafLet } from "plugins/lime-plugin-locate/src/leafletUtils"; +import { loadLeafLet } from "plugins/lime-plugin-mesh-wide/src/lib/leafletUtils"; import { changeLocation, getLocation, - getNodesandlinks, -} from "plugins/lime-plugin-locate/src/locateApi"; +} from "plugins/lime-plugin-mesh-wide/src/locateApi"; import queryCache from "utils/queryCache"; @@ -17,8 +16,9 @@ export interface INodeLocation { default: boolean; } +export const getLocationQueryKey = ["lime-location", "get"]; export function useLocation(params) { - return useQuery(["lime-location", "get"], getLocation, { + return useQuery(getLocationQueryKey, getLocation, { placeholderData: { default: false, location: { @@ -30,15 +30,15 @@ export function useLocation(params) { }); } -export function useNodesandlinks(params) { - return useQuery( - ["lime-location", "all_nodes_and_links"], - getNodesandlinks, - { - ...params, - } - ); -} +// export function useNodesandlinks(params) { +// return useQuery( +// ["lime-location", "all_nodes_and_links"], +// getNodesandlinks, +// { +// ...params, +// } +// ); +// } interface IChangeUserParams { lat: number; diff --git a/plugins/lime-plugin-mesh-wide/src/meshWidePage.tsx b/plugins/lime-plugin-mesh-wide/src/meshWidePage.tsx index 27e368f2b..dbc362bb6 100644 --- a/plugins/lime-plugin-mesh-wide/src/meshWidePage.tsx +++ b/plugins/lime-plugin-mesh-wide/src/meshWidePage.tsx @@ -3,16 +3,18 @@ import React from "react"; import Loading from "components/loading"; -import { useLoadLeaflet } from "plugins/lime-plugin-locate/src/locateQueries"; import { FloatingAlert } from "plugins/lime-plugin-mesh-wide/src/components/Map/FloatingAlert"; +import LocateNode from "plugins/lime-plugin-mesh-wide/src/containers/LocateNode"; import { MeshWideMap } from "plugins/lime-plugin-mesh-wide/src/containers/Map"; import { SelectedFeatureBottomSheet } from "plugins/lime-plugin-mesh-wide/src/containers/SelectedFeatureBottomSheet"; +import { LocateNodeProvider } from "plugins/lime-plugin-mesh-wide/src/hooks/useLocateNode"; import { BabelLinksProvider, BatmanLinksProvider, MeshWideLinksProvider, } from "plugins/lime-plugin-mesh-wide/src/hooks/useLocatedLinks"; import { NodesProvider } from "plugins/lime-plugin-mesh-wide/src/hooks/useNodes"; +import { useLoadLeaflet } from "plugins/lime-plugin-mesh-wide/src/locateNodeQueries"; const MeshWide = () => { const { @@ -46,6 +48,7 @@ const MeshWide = () => { + ); }; @@ -53,13 +56,15 @@ const MeshWide = () => { const MeshWidePage = () => { return ( - - - - - - - + + + + + + + + + ); }; diff --git a/src/config.ts b/src/config.ts index 9e0e6f8b2..473ef659f 100644 --- a/src/config.ts +++ b/src/config.ts @@ -2,7 +2,6 @@ import Align from "plugins/lime-plugin-align"; import ChangeNode from "plugins/lime-plugin-changeNode"; import Fbw from "plugins/lime-plugin-fbw"; import Firmware from "plugins/lime-plugin-firmware"; -import Locate from "plugins/lime-plugin-locate"; import MeshWide from "plugins/lime-plugin-mesh-wide"; import MeshConfigPage from "plugins/lime-plugin-mesh-wide-config"; import MeshUpgrade from "plugins/lime-plugin-mesh-wide-upgrade"; @@ -18,7 +17,6 @@ import Rx from "plugins/lime-plugin-rx"; export const plugins: LimePlugin[] = [ Rx, Align, - Locate, MeshWide, Metrics, Notes, From 78caa170b6302d7b4d822c5b6f110bd35a2697ab Mon Sep 17 00:00:00 2001 From: selankon Date: Fri, 13 Dec 2024 11:40:18 +0100 Subject: [PATCH 2/5] chore(locate): hide edit location when feature selected --- plugins/lime-plugin-mesh-wide/src/containers/LocateNode.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/plugins/lime-plugin-mesh-wide/src/containers/LocateNode.tsx b/plugins/lime-plugin-mesh-wide/src/containers/LocateNode.tsx index 3ffe656bb..efaa9fd2d 100644 --- a/plugins/lime-plugin-mesh-wide/src/containers/LocateNode.tsx +++ b/plugins/lime-plugin-mesh-wide/src/containers/LocateNode.tsx @@ -7,11 +7,13 @@ import { useChangeLocation, useLocation, } from "plugins/lime-plugin-mesh-wide/src/locateNodeQueries"; +import { useSelectedMapFeature } from "plugins/lime-plugin-mesh-wide/src/meshWideQueries"; import queryCache from "utils/queryCache"; const LocateNode = ({}) => { const { editingLocation, setEditingLocation, mapRef } = useLocateNode(); + const { data: selectedMapFeature } = useSelectedMapFeature(); const { data: nodeLocation, isLoading } = useLocation({}); @@ -44,7 +46,7 @@ const LocateNode = ({}) => { changeLocation({ lat: position.lat, lon: position.lng }); }; - if (!loaded) { + if (!loaded || selectedMapFeature) { return null; } From 3f298ac98df2a458447eb84566477557bfb99549 Mon Sep 17 00:00:00 2001 From: selankon Date: Fri, 13 Dec 2024 12:18:35 +0100 Subject: [PATCH 3/5] chore(locate): show location edition state --- .../src/containers/LocateNode.tsx | 54 +++++++++++++++---- 1 file changed, 45 insertions(+), 9 deletions(-) diff --git a/plugins/lime-plugin-mesh-wide/src/containers/LocateNode.tsx b/plugins/lime-plugin-mesh-wide/src/containers/LocateNode.tsx index efaa9fd2d..2fb75164d 100644 --- a/plugins/lime-plugin-mesh-wide/src/containers/LocateNode.tsx +++ b/plugins/lime-plugin-mesh-wide/src/containers/LocateNode.tsx @@ -1,4 +1,9 @@ import { Trans } from "@lingui/macro"; +import { useMemo, useState } from "preact/hooks"; + +import Loading from "components/loading"; +import { usePublishAll } from "components/shared-state/SharedStateQueries"; +import { sharedStateQueries } from "components/shared-state/SharedStateQueriesKeys"; import style from "plugins/lime-plugin-mesh-wide/src/containers/style.less"; import { useLocateNode } from "plugins/lime-plugin-mesh-wide/src/hooks/useLocateNode"; @@ -8,23 +13,45 @@ import { useLocation, } from "plugins/lime-plugin-mesh-wide/src/locateNodeQueries"; import { useSelectedMapFeature } from "plugins/lime-plugin-mesh-wide/src/meshWideQueries"; +import { useNodeStatus } from "plugins/lime-plugin-rx/src/rxQueries"; import queryCache from "utils/queryCache"; const LocateNode = ({}) => { const { editingLocation, setEditingLocation, mapRef } = useLocateNode(); const { data: selectedMapFeature } = useSelectedMapFeature(); + const { data: nodeLocation, isLoading: isLoadingNodeLocation } = + useLocation({}); + const [isLoading, setIsLoading] = useState(false); - const { data: nodeLocation, isLoading } = useLocation({}); + // Code to force to update shared state with new location + const { data: node } = useNodeStatus(); + const ip = useMemo(() => { + if (!node) return null; + return node?.ips + .find((ip) => ip.version === "4") + ?.address?.split("/")[0]; + }, [node]); + const { mutateAsync: publishAll } = usePublishAll({ + ip, + }); - const { mutate: changeLocation, isLoading: submitting } = useChangeLocation( - { - onSettled: () => { - queryCache.invalidateQueries(getLocationQueryKey); - toogleEdition(); - }, + const onNewLocationSet = async () => { + try { + await queryCache.invalidateQueries(getLocationQueryKey); + await publishAll({ ip }); + await queryCache.invalidateQueries( + sharedStateQueries.getFromSharedState("node_info") + ); + } finally { + toogleEdition(); + setIsLoading(false); } - ); + }; + + const { mutate: changeLocation } = useChangeLocation({ + onSettled: onNewLocationSet, + }); let stationLat = null; if (nodeLocation.location.lat !== "FIXME") @@ -35,13 +62,14 @@ const LocateNode = ({}) => { } const hasLocation = stationLat && stationLon; - const loaded = !isLoading && typeof stationLat !== "undefined"; + const loaded = !isLoadingNodeLocation && typeof stationLat !== "undefined"; const toogleEdition = () => { setEditingLocation((prev) => !prev); }; const confirmLocation = async () => { + setIsLoading(true); const position = mapRef.current.getCenter(); changeLocation({ lat: position.lat, lon: position.lng }); }; @@ -50,6 +78,14 @@ const LocateNode = ({}) => { return null; } + if (isLoading) { + return ( +
+ +
+ ); + } + return (
{editingLocation && ( From 1a77935c2a8b74bb0b38b0e56bfbd456e491a0b1 Mon Sep 17 00:00:00 2001 From: selankon Date: Wed, 18 Dec 2024 09:48:07 +0100 Subject: [PATCH 4/5] chore(rx): change map page link --- plugins/lime-plugin-rx/src/sections/internetPath.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/lime-plugin-rx/src/sections/internetPath.tsx b/plugins/lime-plugin-rx/src/sections/internetPath.tsx index 6d51cf256..57c9875c4 100644 --- a/plugins/lime-plugin-rx/src/sections/internetPath.tsx +++ b/plugins/lime-plugin-rx/src/sections/internetPath.tsx @@ -124,7 +124,7 @@ export const InternetPath = () => { -
From 598aa8f7b58e77a7644411791ae9c27192b486be Mon Sep 17 00:00:00 2001 From: selankon Date: Wed, 18 Dec 2024 10:15:21 +0100 Subject: [PATCH 5/5] chore(locate): implement satellite layers control --- .../src/containers/Map.tsx | 94 ++++++++++++------- .../src/containers/style.less | 1 + .../src/locateNodeQueries.tsx | 10 -- .../src/meshWidePage.tsx | 2 - 4 files changed, 63 insertions(+), 44 deletions(-) diff --git a/plugins/lime-plugin-mesh-wide/src/containers/Map.tsx b/plugins/lime-plugin-mesh-wide/src/containers/Map.tsx index f797f8260..973162ddd 100644 --- a/plugins/lime-plugin-mesh-wide/src/containers/Map.tsx +++ b/plugins/lime-plugin-mesh-wide/src/containers/Map.tsx @@ -9,6 +9,7 @@ import { import { MeshWideMapTypes } from "components/shared-state/SharedStateTypes"; +import LocateNode from "plugins/lime-plugin-mesh-wide/src/containers/LocateNode"; import { BabelLinksLayer, BatmanLinksLayer, @@ -27,6 +28,10 @@ const openStreetMapTileString = "https://{s}.tile.osm.org/{z}/{x}/{y}.png"; const openStreetMapAttribution = '© OpenStreetMap contributors'; +const gmSatellite = "https://{s}.google.com/vt/lyrs=s&x={x}&y={y}&z={z}"; +const gmHybrid = "https://{s}.google.com/vt/lyrs=s,h&x={x}&y={y}&z={z}"; +const gmSubdomains = ["mt0", "mt1", "mt2", "mt3"]; + interface ILayersChecked { nodes?: boolean; wifiLinks?: boolean; @@ -34,12 +39,7 @@ interface ILayersChecked { babelLinks?: boolean; } -export const MeshWideMap = ({ - nodes = true, - wifiLinks = true, - batmanLinks = false, - babelLinks = false, -}: ILayersChecked) => { +export const MeshWideMap = (layers: ILayersChecked) => { const { data: selectedMapFeature, setData: setSelectedMapFeature } = useSelectedMapFeature(); @@ -83,6 +83,34 @@ export const MeshWideMap = ({ } }, [loading, nodeLocation]); + return ( + + + + + + {editingLocation && ( +
+ )} + + ); +}; + +const LayersControlMeshWide = ({ + nodes = true, + wifiLinks = true, + batmanLinks = false, + babelLinks = false, +}: ILayersChecked) => { // @ts-ignore const mapSupportedLayers: Record< keyof MeshWideMapTypes, @@ -107,33 +135,35 @@ export const MeshWideMap = ({ }; return ( - + + {Object.values(mapSupportedLayers).map( + ({ name, layer, checked }, k) => ( + + {layer} + + ) + )} + + ); +}; + +const LayersControlMaps = () => ( + + - - {Object.values(mapSupportedLayers).map( - ({ name, layer, checked }, k) => ( - - {layer} - - ) - )} - - {editingLocation && ( -
- )} - - ); -}; + + + + + + + + +); diff --git a/plugins/lime-plugin-mesh-wide/src/containers/style.less b/plugins/lime-plugin-mesh-wide/src/containers/style.less index bd2328b39..d5d965405 100644 --- a/plugins/lime-plugin-mesh-wide/src/containers/style.less +++ b/plugins/lime-plugin-mesh-wide/src/containers/style.less @@ -23,6 +23,7 @@ button { min-width: 60%; background-color: white; + font-size: 15px; } } diff --git a/plugins/lime-plugin-mesh-wide/src/locateNodeQueries.tsx b/plugins/lime-plugin-mesh-wide/src/locateNodeQueries.tsx index 0acd02aca..c4a9e4d44 100644 --- a/plugins/lime-plugin-mesh-wide/src/locateNodeQueries.tsx +++ b/plugins/lime-plugin-mesh-wide/src/locateNodeQueries.tsx @@ -30,16 +30,6 @@ export function useLocation(params) { }); } -// export function useNodesandlinks(params) { -// return useQuery( -// ["lime-location", "all_nodes_and_links"], -// getNodesandlinks, -// { -// ...params, -// } -// ); -// } - interface IChangeUserParams { lat: number; lon: number; diff --git a/plugins/lime-plugin-mesh-wide/src/meshWidePage.tsx b/plugins/lime-plugin-mesh-wide/src/meshWidePage.tsx index dbc362bb6..88038e406 100644 --- a/plugins/lime-plugin-mesh-wide/src/meshWidePage.tsx +++ b/plugins/lime-plugin-mesh-wide/src/meshWidePage.tsx @@ -4,7 +4,6 @@ import React from "react"; import Loading from "components/loading"; import { FloatingAlert } from "plugins/lime-plugin-mesh-wide/src/components/Map/FloatingAlert"; -import LocateNode from "plugins/lime-plugin-mesh-wide/src/containers/LocateNode"; import { MeshWideMap } from "plugins/lime-plugin-mesh-wide/src/containers/Map"; import { SelectedFeatureBottomSheet } from "plugins/lime-plugin-mesh-wide/src/containers/SelectedFeatureBottomSheet"; import { LocateNodeProvider } from "plugins/lime-plugin-mesh-wide/src/hooks/useLocateNode"; @@ -48,7 +47,6 @@ const MeshWide = () => { - ); };