mirror of
https://github.com/gpxstudio/gpx.studio.git
synced 2026-10-19 17:22:12 +00:00
fix popups
This commit is contained in:
1 parent
017d8521d6
commit
543fecadb8
25 files changed
+1242
-225
No files matched your search
@@ -2,14 +2,13 @@
|
||||
import { Button } from '$lib/components/ui/button';
|
||||
import { ClipboardCopy } from '@lucide/svelte';
|
||||
import { i18n } from '$lib/i18n.svelte';
|
||||
import type { Coordinates } from 'gpx';
|
||||
|
||||
let {
|
||||
coordinates,
|
||||
onCopy = () => {},
|
||||
class: className = '',
|
||||
}: {
|
||||
coordinates: Coordinates;
|
||||
coordinates: { lng: number; lat: number };
|
||||
onCopy?: () => void;
|
||||
class?: string;
|
||||
} = $props();
|
||||
@@ -20,7 +19,7 @@
|
||||
variant="outline"
|
||||
onclick={() => {
|
||||
navigator.clipboard.writeText(
|
||||
`${coordinates.lat.toFixed(6)}, ${coordinates.lon.toFixed(6)}`
|
||||
`${coordinates.lat.toFixed(6)}, ${coordinates.lng.toFixed(6)}`
|
||||
);
|
||||
onCopy();
|
||||
}}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
<script lang="ts">
|
||||
import type { TrackPoint } from 'gpx';
|
||||
import { Button } from '$lib/components/ui/button';
|
||||
import CopyCoordinates from '$lib/components/map/gpx-layer/CopyCoordinates.svelte';
|
||||
import * as Card from '$lib/components/ui/card';
|
||||
@@ -7,18 +6,17 @@
|
||||
import { Compass, Earth, Mountain, Timer } from '@lucide/svelte';
|
||||
import { i18n } from '$lib/i18n.svelte';
|
||||
import type { PopupItem } from '$lib/components/map/map-popup';
|
||||
import type { TrackpointDetails } from '$lib/engine';
|
||||
import { map } from '$lib/components/map/map';
|
||||
|
||||
let { trackpoint }: { trackpoint: PopupItem<TrackPoint> } = $props();
|
||||
let { trackpoint }: { trackpoint: PopupItem<Pick<TrackpointDetails, 'lng' | 'lat'> & Partial<TrackpointDetails>> } = $props();
|
||||
</script>
|
||||
|
||||
<Card.Root class="border-none shadow-md text-base p-2">
|
||||
<Card.Content class="flex flex-col p-0 text-xs gap-1">
|
||||
<div class="flex flex-row items-center gap-1">
|
||||
<Compass size="14" />
|
||||
{trackpoint.item.getLatitude().toFixed(6)}° {trackpoint.item
|
||||
.getLongitude()
|
||||
.toFixed(6)}°
|
||||
{trackpoint.item.lat.toFixed(6)}° {trackpoint.item.lng.toFixed(6)}°
|
||||
</div>
|
||||
{#if trackpoint.item.ele !== undefined}
|
||||
<div class="flex flex-row items-center gap-1">
|
||||
@@ -26,14 +24,14 @@
|
||||
<WithUnits value={trackpoint.item.ele} type="elevation" />
|
||||
</div>
|
||||
{/if}
|
||||
{#if trackpoint.item.time}
|
||||
{#if trackpoint.item.time !== undefined}
|
||||
<div class="flex flex-row items-center gap-1">
|
||||
<Timer size="14" />
|
||||
{i18n.df.format(trackpoint.item.time)}
|
||||
{i18n.df.format(new Date(trackpoint.item.time))}
|
||||
</div>
|
||||
{/if}
|
||||
<CopyCoordinates
|
||||
coordinates={trackpoint.item.attributes}
|
||||
coordinates={trackpoint.item}
|
||||
onCopy={() => trackpoint.hide?.()}
|
||||
class="mt-0.5"
|
||||
/>
|
||||
@@ -41,7 +39,7 @@
|
||||
<Button
|
||||
variant="outline"
|
||||
class="justify-start"
|
||||
href={`https://www.openstreetmap.org/edit?#map=${(($map?.getZoom() ?? 17) + 1).toFixed(0)}/${trackpoint.item.getLatitude().toFixed(5)}/${trackpoint.item.getLongitude().toFixed(5)}`}
|
||||
href={`https://www.openstreetmap.org/edit?#map=${(($map?.getZoom() ?? 17) + 1).toFixed(0)}/${trackpoint.item.lat.toFixed(5)}/${trackpoint.item.lng.toFixed(5)}`}
|
||||
target="_blank"
|
||||
>
|
||||
<Earth size="14" />
|
||||
|
||||
@@ -9,21 +9,23 @@
|
||||
import { getSymbolKey, symbols } from '$lib/assets/symbols';
|
||||
import { i18n } from '$lib/i18n.svelte';
|
||||
import sanitizeHtml from 'sanitize-html';
|
||||
import type { Waypoint } from 'gpx';
|
||||
import { ScrollArea } from '$lib/components/ui/scroll-area/index.js';
|
||||
import { fileActions } from '$lib/logic/file-actions';
|
||||
import type { PopupItem } from '$lib/components/map/map-popup';
|
||||
import { selection } from '$lib/logic/selection';
|
||||
import { ListFileItem } from '$lib/components/file-list/file-list';
|
||||
import { engine, type WaypointDetails } from '$lib/engine';
|
||||
import { hasSelectionWithin } from '$lib/selection-helpers';
|
||||
|
||||
let {
|
||||
waypoint,
|
||||
}: {
|
||||
waypoint: PopupItem<Waypoint>;
|
||||
waypoint: PopupItem<WaypointDetails>;
|
||||
} = $props();
|
||||
|
||||
const { selection } = engine;
|
||||
|
||||
let selected = $derived(
|
||||
waypoint.fileId ? $selection.hasAnyChildren(new ListFileItem(waypoint.fileId)) : false
|
||||
waypoint.fileId
|
||||
? hasSelectionWithin($selection, { type: 'file', fileId: waypoint.fileId })
|
||||
: false
|
||||
);
|
||||
let symbolKey = $derived(waypoint ? getSymbolKey(waypoint.item.sym) : undefined);
|
||||
|
||||
@@ -44,9 +46,9 @@
|
||||
<Card.Root class="border-none shadow-md text-base p-2 max-w-[50dvw] gap-0">
|
||||
<Card.Header class="p-0 gap-0">
|
||||
<Card.Title class="text-md">
|
||||
{#if waypoint.item.link && waypoint.item.link.attributes && waypoint.item.link.attributes.href}
|
||||
<a href={waypoint.item.link.attributes.href} target="_blank">
|
||||
{waypoint.item.name ?? waypoint.item.link.attributes.href}
|
||||
{#if waypoint.item.link?.href}
|
||||
<a href={waypoint.item.link.href} target="_blank">
|
||||
{waypoint.item.name ?? waypoint.item.link.href}
|
||||
<ExternalLink size="12" class="inline-block mb-1.5" />
|
||||
</a>
|
||||
{:else}
|
||||
@@ -68,13 +70,9 @@
|
||||
</span>
|
||||
<Dot size="16" />
|
||||
{/if}
|
||||
{waypoint.item.getLatitude().toFixed(6)}° {waypoint.item
|
||||
.getLongitude()
|
||||
.toFixed(6)}°
|
||||
{#if waypoint.item.ele !== undefined}
|
||||
<Dot size="16" />
|
||||
<WithUnits value={waypoint.item.ele} type="elevation" />
|
||||
{/if}
|
||||
{waypoint.item.lat.toFixed(6)}° {waypoint.item.lng.toFixed(6)}°
|
||||
<Dot size="16" />
|
||||
<WithUnits value={waypoint.item.ele} type="elevation" />
|
||||
</div>
|
||||
<ScrollArea class="flex flex-col max-h-[30dvh]">
|
||||
{#if waypoint.item.desc}
|
||||
@@ -85,13 +83,13 @@
|
||||
{/if}
|
||||
</ScrollArea>
|
||||
<div class="mt-2 flex flex-col gap-1">
|
||||
<CopyCoordinates coordinates={waypoint.item.attributes} />
|
||||
<CopyCoordinates coordinates={waypoint.item} />
|
||||
{#if $currentTool === Tool.WAYPOINT && selected}
|
||||
<Button
|
||||
variant="outline"
|
||||
onclick={() => {
|
||||
if (waypoint.fileId) {
|
||||
fileActions.deleteWaypoint(waypoint.fileId, waypoint.item._data.index);
|
||||
engine.deleteWaypoint(waypoint.fileId, waypoint.item.id);
|
||||
waypoint.hide?.();
|
||||
}
|
||||
}}
|
||||
|
||||
@@ -8,7 +8,8 @@ import maplibregl, {
|
||||
} from 'maplibre-gl';
|
||||
import { map } from '$lib/components/map/map';
|
||||
import { waypointPopup, trackpointPopup } from './gpx-layer-popup';
|
||||
import { getClosestLinePoint, getElevation, loadSVGIcon } from '$lib/utils';
|
||||
import { closestPointIndex } from '$lib/closest-point';
|
||||
import { getElevation, loadSVGIcon } from '$lib/utils';
|
||||
import { selectedWaypoint } from '$lib/components/toolbar/tools/waypoint/waypoint';
|
||||
import { MapPin, Square } from 'lucide-static';
|
||||
import { getSymbolKey, symbols } from '$lib/assets/symbols';
|
||||
@@ -18,7 +19,6 @@ import { isCovered, hasSelectionWithin, type FileTreeNode } from '$lib/selection
|
||||
import { isSegmentHidden, isWaypointHidden } from '$lib/file-visibility';
|
||||
import { settings } from '$lib/logic/settings';
|
||||
import { currentTool, Tool } from '$lib/components/toolbar/tools';
|
||||
import { fileActionManager } from '$lib/logic/file-action-manager';
|
||||
import { fileActions } from '$lib/logic/file-actions';
|
||||
import { splitAs } from '$lib/components/toolbar/tools/scissors/scissors';
|
||||
import { mapCursor, MapCursorState } from '$lib/logic/map-cursor';
|
||||
@@ -398,18 +398,18 @@ export class GPXLayer {
|
||||
|
||||
layerOnMouseMove(e: any) {
|
||||
if (e.originalEvent.shiftKey) {
|
||||
let trackIndex = e.features[0].properties.trackIndex;
|
||||
let segmentIndex = e.features[0].properties.segmentIndex;
|
||||
|
||||
// TODO needs the trackpoints of the previous implementation (see oldFile)
|
||||
// const file = null;
|
||||
// if (file) {
|
||||
// const closest = getClosestLinePoint(
|
||||
// file.trk[trackIndex].trkseg[segmentIndex].trkpt,
|
||||
// { lat: e.lngLat.lat, lon: e.lngLat.lng }
|
||||
// );
|
||||
// trackpointPopup?.setItem({ item: closest, fileId: this.fileId });
|
||||
// }
|
||||
const { segmentId } = e.features[0].properties;
|
||||
const lngLat = { lng: e.lngLat.lng, lat: e.lngLat.lat };
|
||||
const index = closestPointIndex(engine.segmentCoordinates(segmentId), lngLat);
|
||||
const trackpoint =
|
||||
index === undefined ? undefined : engine.trackpoint(this.fileId, segmentId, index);
|
||||
if (trackpoint) {
|
||||
trackpointPopup?.setItem({
|
||||
item: trackpoint,
|
||||
kind: 'trackpoint',
|
||||
fileId: this.fileId,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -471,15 +471,18 @@ export class GPXLayer {
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO the popup needs the waypoint of the previous implementation (see oldFile)
|
||||
// let waypoint = this.oldFile?.wpt[e.features![0].properties!.waypointIndex];
|
||||
// if (waypoint) {
|
||||
// waypointPopup?.setItem({ item: waypoint, fileId: this.fileId });
|
||||
// }
|
||||
this.showWaypointPopup(e.features![0].properties!.waypointId);
|
||||
|
||||
mapCursor.notify(MapCursorState.WAYPOINT_HOVER, true);
|
||||
}
|
||||
|
||||
showWaypointPopup(waypointId: string) {
|
||||
const waypoint = engine.waypoint(this.fileId, waypointId);
|
||||
if (waypoint) {
|
||||
waypointPopup?.setItem({ item: waypoint, kind: 'waypoint', fileId: this.fileId });
|
||||
}
|
||||
}
|
||||
|
||||
waypointLayerOnMouseLeave() {
|
||||
mapCursor.notify(MapCursorState.WAYPOINT_HOVER, false);
|
||||
}
|
||||
@@ -487,19 +490,14 @@ export class GPXLayer {
|
||||
waypointLayerOnClick(e: MapLayerMouseEvent) {
|
||||
e.preventDefault();
|
||||
|
||||
const { waypointIndex, waypointId } = e.features![0].properties!;
|
||||
// TODO the popup and the waypoint tool need the waypoint of the previous implementation
|
||||
const { waypointId } = e.features![0].properties!;
|
||||
if (get(currentTool) === Tool.WAYPOINT) {
|
||||
if (this.selected) {
|
||||
if (e.originalEvent.shiftKey) {
|
||||
// TODO
|
||||
// fileActions.deleteWaypoint(this.fileId, waypointIndex);
|
||||
engine.deleteWaypoint(this.fileId, waypointId);
|
||||
} else {
|
||||
engine.selectWaypoints(this.fileId, [waypointId]);
|
||||
// TODO
|
||||
// if (waypoint) {
|
||||
// selectedWaypoint.set([waypoint, this.fileId]);
|
||||
// }
|
||||
selectedWaypoint.set({ fileId: this.fileId, id: waypointId });
|
||||
}
|
||||
} else {
|
||||
if (get(treeFileView)) {
|
||||
@@ -507,10 +505,7 @@ export class GPXLayer {
|
||||
} else {
|
||||
engine.select([this.fileId]);
|
||||
}
|
||||
// TODO
|
||||
// if (waypoint) {
|
||||
// selectedWaypoint.set([waypoint, this.fileId]);
|
||||
// }
|
||||
selectedWaypoint.set({ fileId: this.fileId, id: waypointId });
|
||||
}
|
||||
} else {
|
||||
if (get(treeFileView)) {
|
||||
@@ -524,10 +519,7 @@ export class GPXLayer {
|
||||
if (!this.selected) {
|
||||
engine.select([this.fileId]);
|
||||
}
|
||||
// TODO
|
||||
// if (waypoint) {
|
||||
// waypointPopup?.setItem({ item: waypoint, fileId: this.fileId });
|
||||
// }
|
||||
this.showWaypointPopup(waypointId);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -622,23 +614,27 @@ export class GPXLayer {
|
||||
return;
|
||||
}
|
||||
|
||||
// the dragged waypoint, as it is in the features of the source
|
||||
const waypointId =
|
||||
this.currentWaypointData?.features[this.draggedWaypointIndex].properties?.waypointId;
|
||||
getElevation([
|
||||
{
|
||||
lat: e.lngLat.lat,
|
||||
lon: e.lngLat.lng,
|
||||
},
|
||||
]).then((ele) => {
|
||||
]).then(async (ele) => {
|
||||
if (this.draggedWaypointIndex === null) {
|
||||
return;
|
||||
}
|
||||
fileActionManager.applyToFile(this.fileId, (file) => {
|
||||
let wpt = file.wpt[this.draggedWaypointIndex!];
|
||||
wpt.setCoordinates({
|
||||
lat: e.lngLat.lat,
|
||||
lon: e.lngLat.lng,
|
||||
});
|
||||
wpt.ele = ele[0];
|
||||
});
|
||||
if (waypointId) {
|
||||
await engine.moveWaypoint(
|
||||
this.fileId,
|
||||
waypointId,
|
||||
e.lngLat.lng,
|
||||
e.lngLat.lat,
|
||||
ele[0]
|
||||
);
|
||||
}
|
||||
this.draggedWaypointIndex = null;
|
||||
});
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user