mirror of
https://github.com/zadam/trilium.git
synced 2025-11-01 12:09:02 +01:00
refactor(react/collections): reintroduce gpx tracks
This commit is contained in:
parent
ec378a8fc5
commit
b25f3094b7
@ -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 => <NoteMarker note={note} editable={!isReadOnly} />)}
|
||||
{notes.map(note => (
|
||||
note.mime !== "application/gpx+xml"
|
||||
? <NoteMarker note={note} editable={!isReadOnly} />
|
||||
: <NoteGpxTrack note={note} />
|
||||
))}
|
||||
</Map>
|
||||
</div>
|
||||
);
|
||||
@ -148,6 +153,39 @@ function NoteMarker({ note, editable }: { note: FNote, editable: boolean }) {
|
||||
/>
|
||||
}
|
||||
|
||||
function NoteGpxTrack({ note }: { note: FNote }) {
|
||||
const [ xmlString, setXmlString ] = useState<string>();
|
||||
const blob = useNoteBlob(note);
|
||||
|
||||
useEffect(() => {
|
||||
server.get<string | Uint8Array>(`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<GPXOptions>(() => ({
|
||||
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 && <GpxTrack gpxXmlString={xmlString} options={options} />
|
||||
}
|
||||
|
||||
function buildIcon(bxIconClass: string, colorClass?: string, title?: string, noteIdLink?: string) {
|
||||
let html = /*html*/`\
|
||||
<img class="icon" src="${markerIcon}" />
|
||||
|
||||
@ -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 (<div />)
|
||||
}
|
||||
|
||||
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 <div />;
|
||||
}
|
||||
|
||||
@ -83,18 +83,6 @@ export default class GeoView extends ViewMode<MapData> {
|
||||
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) {
|
||||
|
||||
@ -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<string | Uint8Array>(`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;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user