feat: add map
This commit is contained in:
parent
e66db03704
commit
019e5019c8
@ -1 +1,5 @@
|
|||||||
|
npmScopes:
|
||||||
|
"here":
|
||||||
|
npmRegistryServer: "https://repo.platform.here.com/artifactory/api/npm/maps-api-for-javascript/"
|
||||||
|
|
||||||
yarnPath: .yarn/releases/yarn-4.0.2.cjs
|
yarnPath: .yarn/releases/yarn-4.0.2.cjs
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
"preview": "vite preview"
|
"preview": "vite preview"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@here/maps-api-for-javascript": "^1.49.1",
|
||||||
"@snort/shared": "^1.0.10",
|
"@snort/shared": "^1.0.10",
|
||||||
"@snort/system": "^1.1.8",
|
"@snort/system": "^1.1.8",
|
||||||
"@snort/system-react": "^1.1.8",
|
"@snort/system-react": "^1.1.8",
|
||||||
|
55
src/element/map.tsx
Normal file
55
src/element/map.tsx
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
import H from '@here/maps-api-for-javascript';
|
||||||
|
import { useEffect, useRef } from 'react';
|
||||||
|
|
||||||
|
export function HereMap(props: { zoom?: number, markers?: Array<{ lat: number, lng: number }>, center?: { lat: number, lng: number } }) {
|
||||||
|
const mapRef = useRef(null);
|
||||||
|
const map = useRef<H.Map>(null);
|
||||||
|
const platform = useRef<H.service.Platform>(null)
|
||||||
|
|
||||||
|
useEffect(
|
||||||
|
() => {
|
||||||
|
if (!map.current) {
|
||||||
|
platform.current = new H.service.Platform({ apikey: "5uZZsWJdVyMSDTjjNJNyUgKq_bKv2rVVZWAXnfmgttQ" });
|
||||||
|
|
||||||
|
const rasterTileService = platform.current.getRasterTileService({
|
||||||
|
queryParams: {
|
||||||
|
style: "explore.night",
|
||||||
|
size: 512,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const rasterTileProvider = new H.service.rasterTile.Provider(
|
||||||
|
rasterTileService
|
||||||
|
);
|
||||||
|
const rasterTileLayer = new H.map.layer.TileLayer(rasterTileProvider);
|
||||||
|
|
||||||
|
const newMap = new H.Map(mapRef.current!, rasterTileLayer, {
|
||||||
|
engineType: H.Map.EngineType.WEBGL,
|
||||||
|
pixelRatio: window.devicePixelRatio,
|
||||||
|
center: props.center ?? { lat: 0, lng: 0 },
|
||||||
|
zoom: props.zoom ?? 2,
|
||||||
|
});
|
||||||
|
|
||||||
|
new H.mapevents.Behavior(
|
||||||
|
new H.mapevents.MapEvents(newMap)
|
||||||
|
);
|
||||||
|
map.current = newMap;
|
||||||
|
}
|
||||||
|
}, [props]
|
||||||
|
);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (map.current) {
|
||||||
|
map.current.setCenter(props.center ?? { lat: 0, lng: 0 });
|
||||||
|
map.current.setZoom(props.zoom ?? 2);
|
||||||
|
map.current.removeObjects(map.current.getObjects());
|
||||||
|
for (const mrk of props.markers ?? []) {
|
||||||
|
const m = new H.map.Marker(mrk);
|
||||||
|
map.current.addObject(m);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [map, props])
|
||||||
|
|
||||||
|
// Return a div element to hold the map
|
||||||
|
return <div style={{ width: "100%", height: "300px" }} className="rounded-xl overflow-hidden" ref={mapRef} />;
|
||||||
|
|
||||||
|
}
|
@ -13,7 +13,9 @@ export default function RelayItem({ relay, index }: { relay: Relay, index: numbe
|
|||||||
const u = new URL(relay.url);
|
const u = new URL(relay.url);
|
||||||
|
|
||||||
return <div className="p-3 rounded-xl bg-slate-800 flex flex-col gap-2 cursor-pointer select-none hover:bg-slate-700 animate" onClick={() => {
|
return <div className="p-3 rounded-xl bg-slate-800 flex flex-col gap-2 cursor-pointer select-none hover:bg-slate-700 animate" onClick={() => {
|
||||||
navigate(`/r/${encodeURIComponent(relay.url)}`);
|
navigate(`/r/${encodeURIComponent(relay.url)}`, {
|
||||||
|
state: relay
|
||||||
|
});
|
||||||
}}>
|
}}>
|
||||||
<div className="text-lg flex gap-2 items-center">
|
<div className="text-lg flex gap-2 items-center">
|
||||||
<div className="text-slate-400 text-xl">#{index + 1}</div>
|
<div className="text-slate-400 text-xl">#{index + 1}</div>
|
||||||
|
@ -1,40 +1,47 @@
|
|||||||
import { NoteCollection, RequestBuilder } from "@snort/system";
|
import { NoteCollection, RequestBuilder } from "@snort/system";
|
||||||
import { SnortContext, useRequestBuilder } from "@snort/system-react";
|
import { SnortContext, useRequestBuilder } from "@snort/system-react";
|
||||||
import { useContext, useEffect, useMemo } from "react";
|
import { useContext, useEffect, useMemo } from "react";
|
||||||
import { useParams } from "react-router-dom"
|
import { useLocation } from "react-router-dom"
|
||||||
import { SimpleEvent } from "../element/event";
|
import { SimpleEvent } from "../element/event";
|
||||||
import { sanitizeRelayUrl } from "@snort/shared";
|
import { sanitizeRelayUrl } from "@snort/shared";
|
||||||
|
import { HereMap } from "../element/map";
|
||||||
|
import { Relay } from "../api";
|
||||||
|
|
||||||
export function RelayDetailPage() {
|
export function RelayDetailPage() {
|
||||||
const { relay } = useParams();
|
const { state } = useLocation() as { state: Relay };
|
||||||
const system = useContext(SnortContext);
|
const system = useContext(SnortContext);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (relay) {
|
if (state) {
|
||||||
system.ConnectToRelay(relay, {
|
system.ConnectToRelay(state.url, {
|
||||||
read: true,
|
read: true,
|
||||||
write: false
|
write: false
|
||||||
});
|
});
|
||||||
return () => system.DisconnectRelay(relay);
|
return () => system.DisconnectRelay(state.url);
|
||||||
}
|
}
|
||||||
}, [system, relay]);
|
}, [system, state]);
|
||||||
|
|
||||||
const sub = useMemo(() => {
|
const sub = useMemo(() => {
|
||||||
if (relay) {
|
if (state) {
|
||||||
const rb = new RequestBuilder(`events:${relay}`);
|
const rb = new RequestBuilder(`events:${state.url}`);
|
||||||
rb.withOptions({ leaveOpen: true })
|
rb.withOptions({ leaveOpen: true })
|
||||||
rb.withFilter().limit(10).relay(relay);
|
rb.withFilter().limit(10).relay(state.url);
|
||||||
return rb;
|
return rb;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}, [relay]);
|
}, [state]);
|
||||||
const events = useRequestBuilder(NoteCollection, sub);
|
const events = useRequestBuilder(NoteCollection, sub);
|
||||||
|
|
||||||
|
const pos = { lat: state.lat ?? 0, lng: state.lon ?? 0 };
|
||||||
return <div className="flex flex-col gap-5">
|
return <div className="flex flex-col gap-5">
|
||||||
<h1>{relay}</h1>
|
<h1>{state.url}</h1>
|
||||||
|
<HereMap
|
||||||
|
center={pos}
|
||||||
|
zoom={6}
|
||||||
|
markers={[pos]} />
|
||||||
<div>
|
<div>
|
||||||
<pre className="bg-slate-800 rounded-xl p-3">
|
<pre className="bg-slate-800 rounded-xl p-3">
|
||||||
{JSON.stringify(system.Sockets.find(a => a.address === sanitizeRelayUrl(relay!)!)?.info, undefined, 2)}
|
{JSON.stringify(system.Sockets.find(a => a.address === sanitizeRelayUrl(state.url!)!)?.info, undefined, 2)}
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
<h2>Latest Events</h2>
|
<h2>Latest Events</h2>
|
||||||
|
@ -2,6 +2,7 @@ import { useEffect, useState } from "react";
|
|||||||
import { Relay, SnortApi } from "../api";
|
import { Relay, SnortApi } from "../api";
|
||||||
import RelayItem from "../element/relay";
|
import RelayItem from "../element/relay";
|
||||||
import { useLocation } from "react-router-dom";
|
import { useLocation } from "react-router-dom";
|
||||||
|
import { HereMap } from "../element/map";
|
||||||
|
|
||||||
export default function RelayListPage() {
|
export default function RelayListPage() {
|
||||||
const { state } = useLocation();
|
const { state } = useLocation();
|
||||||
@ -19,6 +20,7 @@ export default function RelayListPage() {
|
|||||||
}, [state]);
|
}, [state]);
|
||||||
|
|
||||||
return <div className="flex flex-col gap-2">
|
return <div className="flex flex-col gap-2">
|
||||||
|
{relays && <HereMap center={{ lat: state?.lat ?? 40, lng: state?.lon ?? 0 }} zoom={state ? 5 : 2} markers={relays?.map(a => ({ lat: a.lat!, lng: a.lon! }))} />}
|
||||||
{relays?.map((a, i) => <RelayItem relay={a} index={i} key={a.url} />)}
|
{relays?.map((a, i) => <RelayItem relay={a} index={i} key={a.url} />)}
|
||||||
</div>;
|
</div>;
|
||||||
}
|
}
|
@ -486,6 +486,13 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
|
"@here/maps-api-for-javascript@npm:^1.49.1":
|
||||||
|
version: 1.49.1
|
||||||
|
resolution: "@here/maps-api-for-javascript@npm:1.49.1::__archiveUrl=https%3A%2F%2Frepo.platform.here.com%2Fartifactory%2Fapi%2Fnpm%2Fmaps-api-for-javascript%2F-%2F%40here%2Fmaps-api-for-javascript-1.49.1.tgz"
|
||||||
|
checksum: a7f76456b0556eb2421a8f4c0e7bdefdd1a22a2cb8b0811a0434d1ed1433138f86f4d606cfcc8bb55a964b53ed16c4d74de0b9f075b4df30ced2aec1698cd83d
|
||||||
|
languageName: node
|
||||||
|
linkType: hard
|
||||||
|
|
||||||
"@humanwhocodes/config-array@npm:^0.11.13":
|
"@humanwhocodes/config-array@npm:^0.11.13":
|
||||||
version: 0.11.13
|
version: 0.11.13
|
||||||
resolution: "@humanwhocodes/config-array@npm:0.11.13"
|
resolution: "@humanwhocodes/config-array@npm:0.11.13"
|
||||||
@ -3009,6 +3016,7 @@ __metadata:
|
|||||||
version: 0.0.0-use.local
|
version: 0.0.0-use.local
|
||||||
resolution: "relays@workspace:."
|
resolution: "relays@workspace:."
|
||||||
dependencies:
|
dependencies:
|
||||||
|
"@here/maps-api-for-javascript": "npm:^1.49.1"
|
||||||
"@snort/shared": "npm:^1.0.10"
|
"@snort/shared": "npm:^1.0.10"
|
||||||
"@snort/system": "npm:^1.1.8"
|
"@snort/system": "npm:^1.1.8"
|
||||||
"@snort/system-react": "npm:^1.1.8"
|
"@snort/system-react": "npm:^1.1.8"
|
||||||
|
Loading…
Reference in New Issue
Block a user