diff --git a/apps/client/src/widgets/collections/geomap/index.tsx b/apps/client/src/widgets/collections/geomap/index.tsx
index cc17d5691..4651abddb 100644
--- a/apps/client/src/widgets/collections/geomap/index.tsx
+++ b/apps/client/src/widgets/collections/geomap/index.tsx
@@ -1,11 +1,11 @@
import Map from "./map";
import "./index.css";
import { ViewModeProps } from "../interface";
-import { useNoteLabel, useNoteLabelBoolean, useNoteProperty, useSpacedUpdate, useTriliumEvent } from "../../react/hooks";
+import { useNoteBlob, useNoteLabel, useNoteLabelBoolean, useNoteProperty, useSpacedUpdate, useTriliumEvent } from "../../react/hooks";
import { DEFAULT_MAP_LAYER_NAME } from "./map_layer";
-import { divIcon, LatLng, LeafletMouseEvent } from "leaflet";
+import { divIcon, GPXOptions, LatLng, LeafletMouseEvent } from "leaflet";
import { useCallback, useEffect, useMemo, useState } from "preact/hooks";
-import Marker from "./marker";
+import Marker, { GpxTrack } from "./marker";
import froca from "../../../services/froca";
import FNote from "../../../entities/fnote";
import markerIcon from "leaflet/dist/images/marker-icon.png";
@@ -15,6 +15,7 @@ import { createNewNote, moveMarker } from "./api";
import openContextMenu, { openMapContextMenu } from "./context_menu";
import toast from "../../../services/toast";
import { t } from "../../../services/i18n";
+import server from "../../../services/server";
const DEFAULT_COORDINATES: [number, number] = [3.878638227135724, 446.6630455551659];
const DEFAULT_ZOOM = 2;
@@ -99,7 +100,11 @@ export default function GeoView({ note, noteIds, viewConfig, saveConfig }: ViewM
onContextMenu={onContextMenu}
scale={hasScale}
>
- {notes.map(note => )}
+ {notes.map(note => (
+ note.mime !== "application/gpx+xml"
+ ?
+ :
+ ))}
);
@@ -148,6 +153,39 @@ function NoteMarker({ note, editable }: { note: FNote, editable: boolean }) {
/>
}
+function NoteGpxTrack({ note }: { note: FNote }) {
+ const [ xmlString, setXmlString ] = useState();
+ const blob = useNoteBlob(note);
+
+ useEffect(() => {
+ server.get(`notes/${note.noteId}/open`, undefined, true).then(xmlResponse => {
+ if (xmlResponse instanceof Uint8Array) {
+ setXmlString(new TextDecoder().decode(xmlResponse));
+ } else {
+ setXmlString(xmlResponse);
+ }
+ });
+ }, [ blob ]);
+
+ // React to changes
+ const color = useNoteLabel(note, "color");
+ const iconClass = useNoteLabel(note, "iconClass");
+
+ const options = useMemo(() => ({
+ markers: {
+ startIcon: buildIcon(note.getIcon(), note.getColorClass(), note.title),
+ endIcon: buildIcon("bxs-flag-checkered"),
+ wptIcons: {
+ "": buildIcon("bx bx-pin")
+ }
+ },
+ polyline_options: {
+ color: note.getLabelValue("color") ?? "blue"
+ }
+ }), [ color, iconClass ]);
+ return xmlString &&
+}
+
function buildIcon(bxIconClass: string, colorClass?: string, title?: string, noteIdLink?: string) {
let html = /*html*/`\
diff --git a/apps/client/src/widgets/collections/geomap/marker.tsx b/apps/client/src/widgets/collections/geomap/marker.tsx
index 7f9a7cda9..2a2142d1c 100644
--- a/apps/client/src/widgets/collections/geomap/marker.tsx
+++ b/apps/client/src/widgets/collections/geomap/marker.tsx
@@ -1,6 +1,7 @@
import { useContext, useEffect } from "preact/hooks";
import { ParentMap } from "./map";
-import { DivIcon, Icon, LatLng, Marker as LeafletMarker, LeafletMouseEvent, marker, MarkerOptions } from "leaflet";
+import { DivIcon, GPX, GPXOptions, Icon, LatLng, Marker as LeafletMarker, LeafletMouseEvent, marker, MarkerOptions } from "leaflet";
+import "leaflet-gpx";
export interface MarkerProps {
coordinates: [ number, number ];
@@ -53,3 +54,18 @@ export default function Marker({ coordinates, icon, draggable, onClick, onDragge
return ()
}
+
+export function GpxTrack({ gpxXmlString, options }: { gpxXmlString: string, options: GPXOptions }) {
+ const parentMap = useContext(ParentMap);
+
+ useEffect(() => {
+ if (!parentMap) return;
+
+ const track = new GPX(gpxXmlString, options);
+ track.addTo(parentMap);
+
+ return () => track.removeFrom(parentMap);
+ }, [ parentMap, gpxXmlString, options ]);
+
+ return ;
+}
diff --git a/apps/client/src/widgets/view_widgets/geo_view/index.ts b/apps/client/src/widgets/view_widgets/geo_view/index.ts
index a9bf023f3..46f535afe 100644
--- a/apps/client/src/widgets/view_widgets/geo_view/index.ts
+++ b/apps/client/src/widgets/view_widgets/geo_view/index.ts
@@ -83,18 +83,6 @@ export default class GeoView extends ViewMode {
this.currentMarkerData = {};
const notes = await this.parentNote.getSubtreeNotes();
const draggable = !this.isReadOnly;
- for (const childNote of notes) {
- if (childNote.mime === "application/gpx+xml") {
- const track = await processNoteWithGpxTrack(this.map, childNote);
- this.currentTrackData[childNote.noteId] = track;
- continue;
- }
-
- if (latLng) {
- const marker = processNoteWithMarker(this.map, childNote, latLng, draggable);
- this.currentMarkerData[childNote.noteId] = marker;
- }
- }
}
#changeState(newState: State) {
diff --git a/apps/client/src/widgets/view_widgets/geo_view/markers.ts b/apps/client/src/widgets/view_widgets/geo_view/markers.ts
deleted file mode 100644
index 0e8e9f4f1..000000000
--- a/apps/client/src/widgets/view_widgets/geo_view/markers.ts
+++ /dev/null
@@ -1,38 +0,0 @@
-import { marker, latLng, divIcon, Map, type Marker } from "leaflet";
-import type FNote from "../../../entities/fnote.js";
-import openContextMenu from "./context_menu.js";
-import server from "../../../services/server.js";
-import { moveMarker } from "./editing.js";
-import L from "leaflet";
-
-let gpxLoaded = false;
-
-export async function processNoteWithGpxTrack(map: Map, note: FNote) {
- if (!gpxLoaded) {
- const GPX = await import("leaflet-gpx");
- gpxLoaded = true;
- }
-
- const xmlResponse = await server.get(`notes/${note.noteId}/open`, undefined, true);
- let stringResponse: string;
- if (xmlResponse instanceof Uint8Array) {
- stringResponse = new TextDecoder().decode(xmlResponse);
- } else {
- stringResponse = xmlResponse;
- }
-
- const track = new L.GPX(stringResponse, {
- markers: {
- startIcon: buildIcon(note.getIcon(), note.getColorClass(), note.title),
- endIcon: buildIcon("bxs-flag-checkered"),
- wptIcons: {
- "": buildIcon("bx bx-pin")
- }
- },
- polyline_options: {
- color: note.getLabelValue("color") ?? "blue"
- }
- });
- track.addTo(map);
- return track;
-}