fix mounting and destroying issues

This commit is contained in:
vcoppe
2024-07-13 11:42:21 +02:00
parent 46bafa9fff
commit b8e03cf947
8 changed files with 92 additions and 30 deletions

View File

@@ -3,11 +3,18 @@
import ElevationProfile from '$lib/components/ElevationProfile.svelte'; import ElevationProfile from '$lib/components/ElevationProfile.svelte';
import FileList from '$lib/components/file-list/FileList.svelte'; import FileList from '$lib/components/file-list/FileList.svelte';
import GPXStatistics from '$lib/components/GPXStatistics.svelte'; import GPXStatistics from '$lib/components/GPXStatistics.svelte';
import MapComponent from '$lib/components/Map.svelte'; import Map from '$lib/components/Map.svelte';
import LayerControl from '$lib/components/layer-control/LayerControl.svelte'; import LayerControl from '$lib/components/layer-control/LayerControl.svelte';
import OpenIn from '$lib/components/embedding/OpenIn.svelte'; import OpenIn from '$lib/components/embedding/OpenIn.svelte';
import { gpxStatistics, slicedGPXStatistics, embedding, loadFile, map } from '$lib/stores'; import {
gpxStatistics,
slicedGPXStatistics,
embedding,
loadFile,
map,
updateGPXData
} from '$lib/stores';
import { onDestroy, onMount } from 'svelte'; import { onDestroy, onMount } from 'svelte';
import { fileObservers, settings, GPXStatisticsTree } from '$lib/db'; import { fileObservers, settings, GPXStatisticsTree } from '$lib/db';
import { readable } from 'svelte/store'; import { readable } from 'svelte/store';
@@ -167,6 +174,10 @@
applyOptions(); applyOptions();
} }
$: if ($fileOrder) {
updateGPXData();
}
onDestroy(() => { onDestroy(() => {
if ($distanceMarkers !== prevSettings.distanceMarkers) { if ($distanceMarkers !== prevSettings.distanceMarkers) {
$distanceMarkers = prevSettings.distanceMarkers; $distanceMarkers = prevSettings.distanceMarkers;
@@ -194,7 +205,7 @@
<div class="absolute flex flex-col h-full w-full border rounded-xl overflow-clip"> <div class="absolute flex flex-col h-full w-full border rounded-xl overflow-clip">
<div class="grow relative"> <div class="grow relative">
<MapComponent <Map
class="h-full {$fileObservers.size > 1 ? 'horizontal' : ''}" class="h-full {$fileObservers.size > 1 ? 'horizontal' : ''}"
accessToken={options.token} accessToken={options.token}
geocoder={false} geocoder={false}

View File

@@ -9,13 +9,14 @@ const { distanceMarkers, distanceUnits, currentBasemap } = settings;
export class DistanceMarkers { export class DistanceMarkers {
map: mapboxgl.Map; map: mapboxgl.Map;
updateBinded: () => void = this.update.bind(this); updateBinded: () => void = this.update.bind(this);
unsubscribes: (() => void)[] = [];
constructor(map: mapboxgl.Map) { constructor(map: mapboxgl.Map) {
this.map = map; this.map = map;
gpxStatistics.subscribe(this.updateBinded); this.unsubscribes.push(gpxStatistics.subscribe(this.updateBinded));
distanceMarkers.subscribe(this.updateBinded); this.unsubscribes.push(distanceMarkers.subscribe(this.updateBinded));
distanceUnits.subscribe(this.updateBinded); this.unsubscribes.push(distanceUnits.subscribe(this.updateBinded));
this.map.on('style.load', this.updateBinded); this.map.on('style.load', this.updateBinded);
} }
@@ -61,6 +62,10 @@ export class DistanceMarkers {
} }
} }
remove() {
this.unsubscribes.forEach(unsubscribe => unsubscribe());
}
getDistanceMarkersGeoJSON(): GeoJSON.FeatureCollection { getDistanceMarkersGeoJSON(): GeoJSON.FeatureCollection {
let statistics = get(gpxStatistics); let statistics = get(gpxStatistics);

View File

@@ -1,4 +1,4 @@
import { currentTool, Tool } from "$lib/stores"; import { currentTool, map, Tool } from "$lib/stores";
import { settings, type GPXFileWithStatistics, dbUtils } from "$lib/db"; import { settings, type GPXFileWithStatistics, dbUtils } from "$lib/db";
import { get, type Readable } from "svelte/store"; import { get, type Readable } from "svelte/store";
import mapboxgl from "mapbox-gl"; import mapboxgl from "mapbox-gl";
@@ -259,7 +259,14 @@ export class GPXLayer {
}); });
} }
updateMap(map: mapboxgl.Map) {
this.map = map;
this.map.on('style.load', this.updateBinded);
this.update();
}
remove() { remove() {
if (get(map)) {
this.map.off('click', this.fileId, this.layerOnClickBinded); this.map.off('click', this.fileId, this.layerOnClickBinded);
this.map.off('mouseenter', this.fileId, this.layerOnMouseEnterBinded); this.map.off('mouseenter', this.fileId, this.layerOnMouseEnterBinded);
this.map.off('mouseleave', this.fileId, this.layerOnMouseLeaveBinded); this.map.off('mouseleave', this.fileId, this.layerOnMouseLeaveBinded);
@@ -274,6 +281,7 @@ export class GPXLayer {
if (this.map.getSource(this.fileId)) { if (this.map.getSource(this.fileId)) {
this.map.removeSource(this.fileId); this.map.removeSource(this.fileId);
} }
}
this.markers.forEach((marker) => { this.markers.forEach((marker) => {
marker.remove(); marker.remove();

View File

@@ -5,9 +5,10 @@
import { fileObservers } from '$lib/db'; import { fileObservers } from '$lib/db';
import { DistanceMarkers } from './DistanceMarkers'; import { DistanceMarkers } from './DistanceMarkers';
import { StartEndMarkers } from './StartEndMarkers'; import { StartEndMarkers } from './StartEndMarkers';
import { onDestroy } from 'svelte';
let distanceMarkers: DistanceMarkers; let distanceMarkers: DistanceMarkers | undefined = undefined;
let startEndMarkers: StartEndMarkers; let startEndMarkers: StartEndMarkers | undefined = undefined;
$: if ($map && $fileObservers) { $: if ($map && $fileObservers) {
// remove layers for deleted files // remove layers for deleted files
@@ -15,6 +16,8 @@
if (!$fileObservers.has(fileId)) { if (!$fileObservers.has(fileId)) {
layer.remove(); layer.remove();
gpxLayers.delete(fileId); gpxLayers.delete(fileId);
} else if ($map !== layer.map) {
layer.updateMap($map);
} }
}); });
// add layers for new files // add layers for new files
@@ -26,9 +29,30 @@
} }
$: if ($map) { $: if ($map) {
if (distanceMarkers) {
distanceMarkers.remove();
}
if (startEndMarkers) {
startEndMarkers.remove();
}
distanceMarkers = new DistanceMarkers($map); distanceMarkers = new DistanceMarkers($map);
startEndMarkers = new StartEndMarkers($map); startEndMarkers = new StartEndMarkers($map);
} }
onDestroy(() => {
gpxLayers.forEach((layer) => layer.remove());
gpxLayers.clear();
if (distanceMarkers) {
distanceMarkers.remove();
distanceMarkers = undefined;
}
if (startEndMarkers) {
startEndMarkers.remove();
startEndMarkers = undefined;
}
});
</script> </script>
<WaypointPopup /> <WaypointPopup />

View File

@@ -7,6 +7,7 @@ export class StartEndMarkers {
start: mapboxgl.Marker; start: mapboxgl.Marker;
end: mapboxgl.Marker; end: mapboxgl.Marker;
updateBinded: () => void = this.update.bind(this); updateBinded: () => void = this.update.bind(this);
unsubscribes: (() => void)[] = [];
constructor(map: mapboxgl.Map) { constructor(map: mapboxgl.Map) {
this.map = map; this.map = map;
@@ -20,9 +21,9 @@ export class StartEndMarkers {
this.start = new mapboxgl.Marker({ element: startElement }); this.start = new mapboxgl.Marker({ element: startElement });
this.end = new mapboxgl.Marker({ element: endElement }); this.end = new mapboxgl.Marker({ element: endElement });
gpxStatistics.subscribe(this.updateBinded); this.unsubscribes.push(gpxStatistics.subscribe(this.updateBinded));
slicedGPXStatistics.subscribe(this.updateBinded); this.unsubscribes.push(slicedGPXStatistics.subscribe(this.updateBinded));
currentTool.subscribe(this.updateBinded); this.unsubscribes.push(currentTool.subscribe(this.updateBinded));
} }
update() { update() {
@@ -36,4 +37,11 @@ export class StartEndMarkers {
this.end.remove(); this.end.remove();
} }
} }
remove() {
this.unsubscribes.forEach(unsubscribe => unsubscribe());
this.start.remove();
this.end.remove();
}
} }

View File

@@ -54,15 +54,14 @@
if (selectedItem && selectedItem.getFileId() === fileId) { if (selectedItem && selectedItem.getFileId() === fileId) {
selectedItem = null; selectedItem = null;
} }
} else if ($map !== controls.map) {
controls.updateMap($map);
} }
}); });
// add controls for new files // add controls for new files
$fileObservers.forEach((file, fileId) => { $fileObservers.forEach((file, fileId) => {
if (!routingControls.has(fileId)) { if (!routingControls.has(fileId)) {
routingControls.set( routingControls.set(fileId, new RoutingControls($map, fileId, file, popup, popupElement));
fileId,
new RoutingControls(get(map), fileId, file, popup, popupElement)
);
} }
}); });
} }
@@ -92,6 +91,9 @@
onDestroy(() => { onDestroy(() => {
$map?.off('click', createFileWithPoint); $map?.off('click', createFileWithPoint);
routingControls.forEach((controls) => controls.destroy());
routingControls.clear();
}); });
</script> </script>

View File

@@ -135,6 +135,10 @@ export class RoutingControls {
this.fileUnsubscribe(); this.fileUnsubscribe();
} }
updateMap(map: mapboxgl.Map) {
this.map = map;
}
createAnchor(point: TrackPoint, segment: TrackSegment, trackIndex: number, segmentIndex: number): AnchorWithMarker { createAnchor(point: TrackPoint, segment: TrackSegment, trackIndex: number, segmentIndex: number): AnchorWithMarker {
let element = document.createElement('div'); let element = document.createElement('div');
element.className = `h-3 w-3 rounded-full bg-white border-2 border-black cursor-pointer`; element.className = `h-3 w-3 rounded-full bg-white border-2 border-black cursor-pointer`;

View File

@@ -20,7 +20,7 @@ export const selectFiles = writable<{ [key: string]: (fileId?: string) => void }
export const gpxStatistics: Writable<GPXStatistics> = writable(new GPXStatistics()); export const gpxStatistics: Writable<GPXStatistics> = writable(new GPXStatistics());
export const slicedGPXStatistics: Writable<[GPXStatistics, number, number] | undefined> = writable(undefined); export const slicedGPXStatistics: Writable<[GPXStatistics, number, number] | undefined> = writable(undefined);
function updateGPXData() { export function updateGPXData() {
let statistics = new GPXStatistics(); let statistics = new GPXStatistics();
applyToOrderedSelectedItemsFromFile((fileId, level, items) => { applyToOrderedSelectedItemsFromFile((fileId, level, items) => {
let stats = getStatistics(fileId); let stats = getStatistics(fileId);