mirror of
https://github.com/gpxstudio/gpx.studio.git
synced 2025-09-01 08:12:32 +00:00
progress
This commit is contained in:
@@ -2,15 +2,41 @@
|
||||
import { ScrollArea } from '$lib/components/ui/scroll-area/index';
|
||||
import FileListNode from './FileListNode.svelte';
|
||||
|
||||
import { fileObservers } from '$lib/db';
|
||||
import { fileObservers, settings } from '$lib/db';
|
||||
import { setContext } from 'svelte';
|
||||
import { ListRootItem } from './FileList';
|
||||
import { ListFileItem, ListRootItem } from './FileList';
|
||||
import { selection } from './Selection';
|
||||
|
||||
export let orientation: 'vertical' | 'horizontal';
|
||||
export let recursive = false;
|
||||
|
||||
setContext('orientation', orientation);
|
||||
setContext('recursive', recursive);
|
||||
|
||||
const { verticalFileView } = settings;
|
||||
|
||||
verticalFileView.subscribe(($vertical) => {
|
||||
if ($vertical) {
|
||||
selection.update(($selection) => {
|
||||
$selection.forEach((item) => {
|
||||
if ($selection.hasAnyChildren(item, false)) {
|
||||
$selection.toggle(item);
|
||||
}
|
||||
});
|
||||
return $selection;
|
||||
});
|
||||
} else {
|
||||
selection.update(($selection) => {
|
||||
$selection.forEach((item) => {
|
||||
if (!(item instanceof ListFileItem)) {
|
||||
$selection.toggle(item);
|
||||
$selection.set(new ListFileItem(item.getFileId()), true);
|
||||
}
|
||||
});
|
||||
return $selection;
|
||||
});
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
<ScrollArea
|
||||
|
@@ -49,7 +49,7 @@
|
||||
}}
|
||||
on:mouseenter={() => {
|
||||
if (item instanceof ListWaypointItem) {
|
||||
let layer = get(gpxLayers).get(item.getFileId());
|
||||
let layer = gpxLayers.get(item.getFileId());
|
||||
let fileStore = get(fileObservers).get(item.getFileId());
|
||||
if (layer && fileStore) {
|
||||
let waypoint = get(fileStore)?.file.wpt[item.getWaypointIndex()];
|
||||
@@ -61,7 +61,7 @@
|
||||
}}
|
||||
on:mouseleave={() => {
|
||||
if (item instanceof ListWaypointItem) {
|
||||
let layer = get(gpxLayers).get(item.getFileId());
|
||||
let layer = gpxLayers.get(item.getFileId());
|
||||
if (layer) {
|
||||
layer.hideWaypointPopup();
|
||||
}
|
||||
|
@@ -87,7 +87,7 @@ export function applyToOrderedSelectedItemsFromFile(callback: (fileId: string, l
|
||||
} else if (a instanceof ListWaypointItem && b instanceof ListWaypointItem) {
|
||||
return b.getWaypointIndex() - a.getWaypointIndex();
|
||||
}
|
||||
return 0;
|
||||
return b.level - a.level;
|
||||
});
|
||||
|
||||
callback(fileId, level, items);
|
||||
|
@@ -14,11 +14,7 @@ export class DistanceMarkers {
|
||||
|
||||
gpxStatistics.subscribe(this.updateBinded);
|
||||
distanceMarkers.subscribe(this.updateBinded);
|
||||
distanceUnits.subscribe(() => {
|
||||
if (get(distanceMarkers)) {
|
||||
this.update();
|
||||
}
|
||||
});
|
||||
distanceUnits.subscribe(this.updateBinded);
|
||||
}
|
||||
|
||||
update() {
|
||||
|
@@ -1,14 +1,15 @@
|
||||
import { map, currentTool, Tool } from "$lib/stores";
|
||||
import { settings, type GPXFileWithStatistics } from "$lib/db";
|
||||
import { settings, type GPXFileWithStatistics, dbUtils } from "$lib/db";
|
||||
import { get, type Readable } from "svelte/store";
|
||||
import mapboxgl from "mapbox-gl";
|
||||
import { currentWaypoint, waypointPopup } from "./WaypointPopup";
|
||||
import { addSelectItem, selectItem, selection } from "$lib/components/file-list/Selection";
|
||||
import { ListTrackSegmentItem, type ListItem, ListWaypointItem, ListWaypointsItem, ListTrackItem, ListFileItem, ListRootItem } from "$lib/components/file-list/FileList";
|
||||
import type { Waypoint } from "gpx";
|
||||
import { produce } from "immer";
|
||||
|
||||
let defaultWeight = 5;
|
||||
let defaultOpacity = 0.7;
|
||||
let defaultOpacity = 0.6;
|
||||
|
||||
const colors = [
|
||||
'#ff0000',
|
||||
@@ -48,7 +49,8 @@ export class GPXLayer {
|
||||
file: Readable<GPXFileWithStatistics | undefined>;
|
||||
layerColor: string;
|
||||
markers: mapboxgl.Marker[] = [];
|
||||
selected: ListItem[] = [];
|
||||
selected: boolean = false;
|
||||
draggable: boolean;
|
||||
unsubscribe: Function[] = [];
|
||||
|
||||
updateBinded: () => void = this.update.bind(this);
|
||||
@@ -61,16 +63,26 @@ export class GPXLayer {
|
||||
this.layerColor = getColor();
|
||||
this.unsubscribe.push(file.subscribe(this.updateBinded));
|
||||
this.unsubscribe.push(selection.subscribe($selection => {
|
||||
let selected = $selection.getChild(fileId)?.getSelected() || [];
|
||||
if (selected.length !== this.selected.length || selected.some((item, index) => item !== this.selected[index])) {
|
||||
this.selected = selected;
|
||||
let newSelected = $selection.hasAnyChildren(new ListFileItem(this.fileId));
|
||||
if (this.selected || newSelected) {
|
||||
this.selected = newSelected;
|
||||
this.update();
|
||||
if (this.selected.length > 0) {
|
||||
this.moveToFront();
|
||||
}
|
||||
}
|
||||
if (newSelected) {
|
||||
this.moveToFront();
|
||||
}
|
||||
}));
|
||||
this.unsubscribe.push(directionMarkers.subscribe(this.updateBinded));
|
||||
this.unsubscribe.push(currentTool.subscribe(tool => {
|
||||
if (tool === Tool.WAYPOINT && !this.draggable) {
|
||||
this.draggable = true;
|
||||
this.markers.forEach(marker => marker.setDraggable(true));
|
||||
} else if (tool !== Tool.WAYPOINT && this.draggable) {
|
||||
this.draggable = false;
|
||||
this.markers.forEach(marker => marker.setDraggable(false));
|
||||
}
|
||||
}));
|
||||
this.draggable = get(currentTool) === Tool.WAYPOINT;
|
||||
|
||||
this.map.on('style.load', this.updateBinded);
|
||||
}
|
||||
@@ -144,30 +156,67 @@ export class GPXLayer {
|
||||
}
|
||||
|
||||
let markerIndex = 0;
|
||||
file.wpt.forEach((waypoint) => { // Update markers
|
||||
if (markerIndex < this.markers.length) {
|
||||
this.markers[markerIndex].setLngLat(waypoint.getCoordinates());
|
||||
Object.defineProperty(this.markers[markerIndex], '_waypoint', { value: waypoint, writable: true });
|
||||
} else {
|
||||
let marker = new mapboxgl.Marker().setLngLat(waypoint.getCoordinates());
|
||||
Object.defineProperty(marker, '_waypoint', { value: waypoint, writable: true });
|
||||
marker.getElement().addEventListener('mouseover', (e) => {
|
||||
this.showWaypointPopup(marker._waypoint);
|
||||
e.stopPropagation();
|
||||
});
|
||||
marker.getElement().addEventListener('mouseout', () => {
|
||||
this.hideWaypointPopup();
|
||||
});
|
||||
marker.getElement().addEventListener('click', (e) => {
|
||||
if (get(verticalFileView)) {
|
||||
selectItem(new ListWaypointItem(this.fileId, marker._waypoint._data.index));
|
||||
|
||||
if (get(selection).hasAnyChildren(new ListFileItem(this.fileId))) {
|
||||
file.wpt.forEach((waypoint) => { // Update markers
|
||||
if (markerIndex < this.markers.length) {
|
||||
this.markers[markerIndex].setLngLat(waypoint.getCoordinates());
|
||||
Object.defineProperty(this.markers[markerIndex], '_waypoint', { value: waypoint, writable: true });
|
||||
} else {
|
||||
let marker = new mapboxgl.Marker({
|
||||
draggable: this.draggable
|
||||
}).setLngLat(waypoint.getCoordinates());
|
||||
Object.defineProperty(marker, '_waypoint', { value: waypoint, writable: true });
|
||||
let dragEndTimestamp = 0;
|
||||
marker.getElement().addEventListener('mouseover', (e) => {
|
||||
if (marker._isDragging) {
|
||||
return;
|
||||
}
|
||||
this.showWaypointPopup(marker._waypoint);
|
||||
e.stopPropagation();
|
||||
}
|
||||
});
|
||||
this.markers.push(marker);
|
||||
}
|
||||
markerIndex++;
|
||||
});
|
||||
});
|
||||
marker.getElement().addEventListener('mouseout', () => {
|
||||
this.hideWaypointPopup();
|
||||
});
|
||||
marker.getElement().addEventListener('click', (e) => {
|
||||
if (dragEndTimestamp && Date.now() - dragEndTimestamp < 1000) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((e.shiftKey || e.ctrlKey || e.metaKey) && get(selection).hasAnyChildren(new ListWaypointsItem(this.fileId), false)) {
|
||||
addSelectItem(new ListWaypointItem(this.fileId, marker._waypoint._data.index));
|
||||
} else {
|
||||
selectItem(new ListWaypointItem(this.fileId, marker._waypoint._data.index));
|
||||
}
|
||||
if (!get(verticalFileView) && !get(selection).has(new ListFileItem(this.fileId))) {
|
||||
addSelectItem(new ListFileItem(this.fileId));
|
||||
}
|
||||
e.stopPropagation();
|
||||
});
|
||||
marker.on('dragstart', () => {
|
||||
this.map.getCanvas().style.cursor = 'grabbing';
|
||||
marker.getElement().style.cursor = 'grabbing';
|
||||
this.hideWaypointPopup();
|
||||
});
|
||||
marker.on('dragend', (e) => {
|
||||
this.map.getCanvas().style.cursor = '';
|
||||
marker.getElement().style.cursor = '';
|
||||
dbUtils.applyToFile(this.fileId, (file) => {
|
||||
return produce(file, (draft) => {
|
||||
let latLng = marker.getLngLat();
|
||||
draft.wpt[marker._waypoint._data.index].setCoordinates({
|
||||
lat: latLng.lat,
|
||||
lon: latLng.lng
|
||||
});
|
||||
});
|
||||
});
|
||||
dragEndTimestamp = Date.now()
|
||||
});
|
||||
this.markers.push(marker);
|
||||
}
|
||||
markerIndex++;
|
||||
});
|
||||
}
|
||||
|
||||
while (markerIndex < this.markers.length) { // Remove extra markers
|
||||
this.markers.pop()?.remove();
|
||||
@@ -249,7 +298,7 @@ export class GPXLayer {
|
||||
let waypoint = get(currentWaypoint);
|
||||
if (waypoint) {
|
||||
let marker = this.markers[waypoint._data.index];
|
||||
marker.togglePopup();
|
||||
marker.getPopup()?.remove();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -281,7 +330,7 @@ export class GPXLayer {
|
||||
}
|
||||
if (get(selection).hasAnyParent(new ListTrackSegmentItem(this.fileId, trackIndex, segmentIndex)) || get(selection).hasAnyChildren(new ListWaypointsItem(this.fileId), true)) {
|
||||
feature.properties.weight = feature.properties.weight + 2;
|
||||
feature.properties.opacity = (feature.properties.opacity + 1) / 2;
|
||||
feature.properties.opacity = (feature.properties.opacity + 2) / 3;
|
||||
}
|
||||
feature.properties.trackIndex = trackIndex;
|
||||
feature.properties.segmentIndex = segmentIndex;
|
||||
|
@@ -9,21 +9,18 @@
|
||||
let distanceMarkers: DistanceMarkers;
|
||||
|
||||
$: if ($map && $fileObservers) {
|
||||
gpxLayers.update(($layers) => {
|
||||
// remove layers for deleted files
|
||||
$layers.forEach((layer, fileId) => {
|
||||
if (!$fileObservers.has(fileId)) {
|
||||
layer.remove();
|
||||
$layers.delete(fileId);
|
||||
}
|
||||
});
|
||||
// add layers for new files
|
||||
$fileObservers.forEach((file, fileId) => {
|
||||
if (!$layers.has(fileId)) {
|
||||
$layers.set(fileId, new GPXLayer(get(map), fileId, file));
|
||||
}
|
||||
});
|
||||
return $layers;
|
||||
// remove layers for deleted files
|
||||
gpxLayers.forEach((layer, fileId) => {
|
||||
if (!$fileObservers.has(fileId)) {
|
||||
layer.remove();
|
||||
gpxLayers.delete(fileId);
|
||||
}
|
||||
});
|
||||
// add layers for new files
|
||||
$fileObservers.forEach((file, fileId) => {
|
||||
if (!gpxLayers.has(fileId)) {
|
||||
gpxLayers.set(fileId, new GPXLayer(get(map), fileId, file));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
@@ -1,7 +1,5 @@
|
||||
<script lang="ts">
|
||||
import { Tool } from '$lib/stores';
|
||||
import Routing from '$lib/components/toolbar/tools/routing/Routing.svelte';
|
||||
import Waypoint from '$lib/components/toolbar/tools/waypoint/Waypoint.svelte';
|
||||
import ToolbarItem from './ToolbarItem.svelte';
|
||||
import {
|
||||
Group,
|
||||
@@ -11,11 +9,11 @@
|
||||
Ungroup,
|
||||
MapPin,
|
||||
Palette,
|
||||
FolderTree,
|
||||
Filter
|
||||
} from 'lucide-svelte';
|
||||
|
||||
import { _ } from 'svelte-i18n';
|
||||
import ToolbarItemMenu from './ToolbarItemMenu.svelte';
|
||||
</script>
|
||||
|
||||
<div class="absolute top-0 bottom-0 left-0 z-20 flex flex-col justify-center pointer-events-none">
|
||||
@@ -27,6 +25,10 @@
|
||||
<Pencil slot="icon" size="18" />
|
||||
<span slot="tooltip">{$_('toolbar.routing.tooltip')}</span>
|
||||
</ToolbarItem>
|
||||
<ToolbarItem tool={Tool.WAYPOINT}>
|
||||
<MapPin slot="icon" size="18" />
|
||||
<span slot="tooltip">{$_('toolbar.waypoint_tooltip')}</span>
|
||||
</ToolbarItem>
|
||||
<ToolbarItem tool={Tool.TIME}>
|
||||
<CalendarClock slot="icon" size="18" />
|
||||
<span slot="tooltip">{$_('toolbar.time_tooltip')}</span>
|
||||
@@ -39,10 +41,6 @@
|
||||
<Ungroup slot="icon" size="18" />
|
||||
<span slot="tooltip">{$_('toolbar.extract_tooltip')}</span>
|
||||
</ToolbarItem>
|
||||
<ToolbarItem tool={Tool.WAYPOINT}>
|
||||
<MapPin slot="icon" size="18" />
|
||||
<span slot="tooltip">{$_('toolbar.waypoint_tooltip')}</span>
|
||||
</ToolbarItem>
|
||||
<ToolbarItem tool={Tool.REDUCE}>
|
||||
<Filter slot="icon" size="18" />
|
||||
<span slot="tooltip">{$_('toolbar.reduce_tooltip')}</span>
|
||||
@@ -56,7 +54,6 @@
|
||||
<span slot="tooltip">{$_('toolbar.style_tooltip')}</span>
|
||||
</ToolbarItem>
|
||||
</div>
|
||||
<Routing />
|
||||
<Waypoint />
|
||||
<ToolbarItemMenu />
|
||||
</div>
|
||||
</div>
|
||||
|
@@ -1,20 +1,39 @@
|
||||
<script lang="ts">
|
||||
import { type Tool, currentTool } from '$lib/stores';
|
||||
import { Tool, currentTool } from '$lib/stores';
|
||||
import { flyAndScale } from '$lib/utils';
|
||||
import * as Card from '$lib/components/ui/card';
|
||||
import Routing from '$lib/components/toolbar/tools/routing/Routing.svelte';
|
||||
import Waypoint from '$lib/components/toolbar/tools/waypoint/Waypoint.svelte';
|
||||
import RoutingControlPopup from '$lib/components/toolbar/tools/routing/RoutingControlPopup.svelte';
|
||||
import { onMount } from 'svelte';
|
||||
import mapboxgl from 'mapbox-gl';
|
||||
|
||||
export let tool: Tool;
|
||||
export let active = false;
|
||||
let popupElement: HTMLElement;
|
||||
let popup: mapboxgl.Popup;
|
||||
|
||||
$: active = $currentTool === tool;
|
||||
onMount(() => {
|
||||
popup = new mapboxgl.Popup({
|
||||
closeButton: false,
|
||||
maxWidth: undefined
|
||||
});
|
||||
popup.setDOMContent(popupElement);
|
||||
popupElement.classList.remove('hidden');
|
||||
});
|
||||
</script>
|
||||
|
||||
{#if active}
|
||||
<div in:flyAndScale={{ x: -2, y: 0, duration: 100 }} class="translate-x-1 h-full">
|
||||
{#if $currentTool !== null}
|
||||
<div
|
||||
in:flyAndScale={{ x: -2, y: 0, duration: 100 }}
|
||||
class="translate-x-1 h-full {$$props.class ?? ''}"
|
||||
>
|
||||
<div class="rounded-md shadow-md pointer-events-auto">
|
||||
<Card.Root class="border-none">
|
||||
<Card.Content class="p-3 flex flex-col gap-3">
|
||||
<slot />
|
||||
<Card.Content class="p-3">
|
||||
{#if $currentTool === Tool.ROUTING}
|
||||
<Routing {popup} {popupElement} />
|
||||
{:else if $currentTool === Tool.WAYPOINT}
|
||||
<Waypoint />
|
||||
{/if}
|
||||
</Card.Content>
|
||||
</Card.Root>
|
||||
</div>
|
||||
@@ -23,8 +42,10 @@
|
||||
|
||||
<svelte:window
|
||||
on:keydown={(e) => {
|
||||
if (active && e.key === 'Escape') {
|
||||
if ($currentTool && e.key === 'Escape') {
|
||||
currentTool.set(null);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
|
||||
<RoutingControlPopup bind:element={popupElement} />
|
||||
|
@@ -1,5 +1,4 @@
|
||||
<script lang="ts">
|
||||
import ToolbarItemMenu from '$lib/components/toolbar/ToolbarItemMenu.svelte';
|
||||
import * as Select from '$lib/components/ui/select';
|
||||
import { Switch } from '$lib/components/ui/switch';
|
||||
import { Label } from '$lib/components/ui/label/index.js';
|
||||
@@ -18,26 +17,22 @@
|
||||
RouteOff
|
||||
} from 'lucide-svelte';
|
||||
|
||||
import { map, Tool } from '$lib/stores';
|
||||
import { map, routingControls } from '$lib/stores';
|
||||
import { dbUtils, settings } from '$lib/db';
|
||||
import { brouterProfiles, routingProfileSelectItem } from './Routing';
|
||||
|
||||
import { _ } from 'svelte-i18n';
|
||||
import { get } from 'svelte/store';
|
||||
import { RoutingControls } from './RoutingControls';
|
||||
import RoutingControlPopup from './RoutingControlPopup.svelte';
|
||||
import { onMount } from 'svelte';
|
||||
import mapboxgl from 'mapbox-gl';
|
||||
import { fileObservers } from '$lib/db';
|
||||
import { slide } from 'svelte/transition';
|
||||
import { selection } from '$lib/components/file-list/Selection';
|
||||
import { ListRootItem, type ListItem } from '$lib/components/file-list/FileList';
|
||||
|
||||
let routingControls: Map<string, RoutingControls> = new Map();
|
||||
let popupElement: HTMLElement;
|
||||
let popup: mapboxgl.Popup | null = null;
|
||||
export let popup: mapboxgl.Popup;
|
||||
export let popupElement: HTMLElement;
|
||||
let selectedItem: ListItem | null = null;
|
||||
let active = false;
|
||||
|
||||
const { privateRoads, routing } = settings;
|
||||
|
||||
@@ -65,18 +60,9 @@
|
||||
}
|
||||
|
||||
$: validSelection = $selection.hasAnyChildren(new ListRootItem(), true, ['waypoints']);
|
||||
|
||||
onMount(() => {
|
||||
popup = new mapboxgl.Popup({
|
||||
closeButton: false,
|
||||
maxWidth: undefined
|
||||
});
|
||||
popup.setDOMContent(popupElement);
|
||||
popupElement.classList.remove('hidden');
|
||||
});
|
||||
</script>
|
||||
|
||||
<ToolbarItemMenu tool={Tool.ROUTING} bind:active>
|
||||
<div class=" flex flex-col gap-3">
|
||||
<Tooltip>
|
||||
<div slot="data" class="w-full flex flex-row justify-between items-center gap-2">
|
||||
<Label for="routing" class="flex flex-row gap-1">
|
||||
@@ -91,6 +77,7 @@
|
||||
</div>
|
||||
<span slot="tooltip">{$_('toolbar.routing.use_routing_tooltip')}</span>
|
||||
</Tooltip>
|
||||
|
||||
{#if $routing}
|
||||
<div class="flex flex-col gap-3" in:slide>
|
||||
<div class="w-full flex flex-row justify-between items-center gap-2">
|
||||
@@ -177,6 +164,4 @@
|
||||
<div>{$_('toolbar.routing.help')}</div>
|
||||
{/if}
|
||||
</Help>
|
||||
</ToolbarItemMenu>
|
||||
|
||||
<RoutingControlPopup bind:element={popupElement} />
|
||||
</div>
|
||||
|
@@ -165,6 +165,9 @@ export class RoutingControls {
|
||||
});
|
||||
marker.getElement().addEventListener('click', (e) => {
|
||||
e.stopPropagation();
|
||||
if (marker === this.temporaryAnchor.marker) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (Date.now() - lastDragEvent < 100) { // Prevent click event during drag
|
||||
return;
|
||||
|
@@ -1,19 +1,35 @@
|
||||
<script lang="ts">
|
||||
import ToolbarItemMenu from '$lib/components/toolbar/ToolbarItemMenu.svelte';
|
||||
import * as Alert from '$lib/components/ui/alert';
|
||||
import { CircleHelp } from 'lucide-svelte';
|
||||
import { selection } from '$lib/components/file-list/Selection';
|
||||
import { Tool } from '$lib/stores';
|
||||
|
||||
import type { Waypoint } from 'gpx';
|
||||
import { _ } from 'svelte-i18n';
|
||||
import { ListWaypointItem } from '$lib/components/file-list/FileList';
|
||||
import { fileObservers } from '$lib/db';
|
||||
import { get } from 'svelte/store';
|
||||
|
||||
$: $selection.forEach((item) => {
|
||||
// todo
|
||||
});
|
||||
let waypoint: Waypoint | undefined = undefined;
|
||||
|
||||
$: if ($selection) {
|
||||
waypoint = undefined;
|
||||
$selection.forEach((item) => {
|
||||
if (item instanceof ListWaypointItem) {
|
||||
if (waypoint) return;
|
||||
let fileStore = get(fileObservers).get(item.getFileId());
|
||||
if (fileStore) {
|
||||
waypoint = get(fileStore)?.file.wpt[item.getWaypointIndex()];
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<ToolbarItemMenu tool={Tool.WAYPOINT}>
|
||||
<div class="w-full flex flex-row justify-between items-center gap-2">todo</div>
|
||||
<div class="flex flex-col gap-3 max-w-96">
|
||||
{#if waypoint}
|
||||
<span>{waypoint.name}</span>
|
||||
<span>{waypoint.desc ?? ''}</span>
|
||||
<span>{waypoint.cmt ?? ''}</span>
|
||||
{/if}
|
||||
|
||||
<Alert.Root class="max-w-64">
|
||||
<CircleHelp size="16" />
|
||||
@@ -21,4 +37,4 @@
|
||||
<div>{$_('toolbar.waypoint.help')}</div>
|
||||
</Alert.Description>
|
||||
</Alert.Root>
|
||||
</ToolbarItemMenu>
|
||||
</div>
|
||||
|
@@ -488,10 +488,6 @@ export const dbUtils = {
|
||||
}
|
||||
});
|
||||
});
|
||||
selection.update(($selection) => {
|
||||
$selection.clear();
|
||||
return $selection;
|
||||
});
|
||||
},
|
||||
deleteAllFiles: () => {
|
||||
applyGlobal((draft) => {
|
||||
|
@@ -6,8 +6,9 @@ import { tick } from 'svelte';
|
||||
import { _ } from 'svelte-i18n';
|
||||
import type { GPXLayer } from '$lib/components/gpx-layer/GPXLayer';
|
||||
import { settings, dbUtils, fileObservers } from './db';
|
||||
import { selection } from '$lib/components/file-list/Selection';
|
||||
import { selectFile, selection } from '$lib/components/file-list/Selection';
|
||||
import { ListFileItem, ListWaypointItem } from '$lib/components/file-list/FileList';
|
||||
import type { RoutingControls } from '$lib/components/toolbar/tools/routing/RoutingControls';
|
||||
|
||||
export const map = writable<mapboxgl.Map | null>(null);
|
||||
export const selectFiles = writable<{ [key: string]: (fileId?: string) => void }>({});
|
||||
@@ -113,15 +114,15 @@ export function updateTargetMapBounds(bounds: {
|
||||
});
|
||||
}
|
||||
|
||||
export const gpxLayers: Writable<Map<string, GPXLayer>> = writable(new Map());
|
||||
export const gpxLayers: Map<string, GPXLayer> = new Map();
|
||||
export const routingControls: Map<string, RoutingControls> = new Map();
|
||||
|
||||
export enum Tool {
|
||||
ROUTING,
|
||||
WAYPOINT,
|
||||
TIME,
|
||||
REVERSE,
|
||||
MERGE,
|
||||
EXTRACT,
|
||||
WAYPOINT,
|
||||
REDUCE,
|
||||
CLEAN,
|
||||
STYLE
|
||||
@@ -192,11 +193,7 @@ function selectFileWhenLoaded(fileId: string) {
|
||||
const unsubscribe = fileObservers.subscribe((files) => {
|
||||
if (files.has(fileId)) {
|
||||
tick().then(() => {
|
||||
selection.update(($selection) => {
|
||||
$selection.clear();
|
||||
$selection.toggle(new ListFileItem(fileId));
|
||||
return $selection;
|
||||
});
|
||||
selectFile(fileId);
|
||||
});
|
||||
unsubscribe();
|
||||
}
|
||||
|
Reference in New Issue
Block a user