mirror of
https://github.com/zadam/trilium.git
synced 2025-11-01 20:19:05 +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 Map from "./map";
|
||||||
import "./index.css";
|
import "./index.css";
|
||||||
import { ViewModeProps } from "../interface";
|
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 { 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 { useCallback, useEffect, useMemo, useState } from "preact/hooks";
|
||||||
import Marker from "./marker";
|
import Marker, { GpxTrack } from "./marker";
|
||||||
import froca from "../../../services/froca";
|
import froca from "../../../services/froca";
|
||||||
import FNote from "../../../entities/fnote";
|
import FNote from "../../../entities/fnote";
|
||||||
import markerIcon from "leaflet/dist/images/marker-icon.png";
|
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 openContextMenu, { openMapContextMenu } from "./context_menu";
|
||||||
import toast from "../../../services/toast";
|
import toast from "../../../services/toast";
|
||||||
import { t } from "../../../services/i18n";
|
import { t } from "../../../services/i18n";
|
||||||
|
import server from "../../../services/server";
|
||||||
|
|
||||||
const DEFAULT_COORDINATES: [number, number] = [3.878638227135724, 446.6630455551659];
|
const DEFAULT_COORDINATES: [number, number] = [3.878638227135724, 446.6630455551659];
|
||||||
const DEFAULT_ZOOM = 2;
|
const DEFAULT_ZOOM = 2;
|
||||||
@ -99,7 +100,11 @@ export default function GeoView({ note, noteIds, viewConfig, saveConfig }: ViewM
|
|||||||
onContextMenu={onContextMenu}
|
onContextMenu={onContextMenu}
|
||||||
scale={hasScale}
|
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>
|
</Map>
|
||||||
</div>
|
</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) {
|
function buildIcon(bxIconClass: string, colorClass?: string, title?: string, noteIdLink?: string) {
|
||||||
let html = /*html*/`\
|
let html = /*html*/`\
|
||||||
<img class="icon" src="${markerIcon}" />
|
<img class="icon" src="${markerIcon}" />
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import { useContext, useEffect } from "preact/hooks";
|
import { useContext, useEffect } from "preact/hooks";
|
||||||
import { ParentMap } from "./map";
|
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 {
|
export interface MarkerProps {
|
||||||
coordinates: [ number, number ];
|
coordinates: [ number, number ];
|
||||||
@ -53,3 +54,18 @@ export default function Marker({ coordinates, icon, draggable, onClick, onDragge
|
|||||||
|
|
||||||
return (<div />)
|
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 = {};
|
this.currentMarkerData = {};
|
||||||
const notes = await this.parentNote.getSubtreeNotes();
|
const notes = await this.parentNote.getSubtreeNotes();
|
||||||
const draggable = !this.isReadOnly;
|
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) {
|
#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