update extension api

This commit is contained in:
vcoppe
2025-11-12 14:48:17 +01:00
parent 110f23bdf1
commit 0eca588280
2 changed files with 43 additions and 43 deletions

View File

@@ -1,6 +1,6 @@
import { settings } from '$lib/logic/settings'; import { settings } from '$lib/logic/settings';
import { derived, get, writable, type Writable } from 'svelte/store'; import { derived, get, writable, type Writable } from 'svelte/store';
import { isSelected, remove, removeByPrefix, toggle } from './utils'; import { isSelected, remove, removeAll } from './utils';
import { overlays, overlayTree } from '$lib/assets/layers'; import { overlays, overlayTree } from '$lib/assets/layers';
import { browser } from '$app/environment'; import { browser } from '$app/environment';
import { map } from '$lib/components/map/map'; import { map } from '$lib/components/map/map';
@@ -29,19 +29,30 @@ export class ExtensionAPI {
} }
ensureLoaded(): Promise<void> { ensureLoaded(): Promise<void> {
return new Promise((resolve) => { let unsubscribe: () => void;
const promise = new Promise<void>((resolve) => {
map.onLoad(() => { map.onLoad(() => {
resolve(); unsubscribe = currentOverlays.subscribe((current) => {
if (current) {
resolve();
}
});
}); });
}); });
promise.finally(() => {
unsubscribe?.();
});
return promise;
} }
addOrUpdateOverlay(overlay: CustomOverlay) { addOrUpdateOverlay(overlay: CustomOverlay) {
if (!overlay.id || !overlay.tileUrls || overlay.tileUrls.length === 0) { if (!overlay.id || !overlay.name || !overlay.tileUrls || overlay.tileUrls.length === 0) {
throw new Error('Overlay must have an id and at least one tile URL.'); throw new Error('Overlay must have an id, name, and at least one tile URL.');
} }
overlay.id = this.getOverlayId(overlay.id); overlay.id = this.getOverlayId(overlay.id);
let show = get(this._overlays).get(overlay.id) === undefined;
this._overlays.update(($overlays) => { this._overlays.update(($overlays) => {
$overlays.set(overlay.id, overlay); $overlays.set(overlay.id, overlay);
return $overlays; return $overlays;
@@ -75,6 +86,7 @@ export class ExtensionAPI {
const current = get(currentOverlays); const current = get(currentOverlays);
if (current && isSelected(current, overlay.id)) { if (current && isSelected(current, overlay.id)) {
show = true;
try { try {
get(map)?.removeImport(overlay.id); get(map)?.removeImport(overlay.id);
} catch (e) { } catch (e) {
@@ -83,35 +95,38 @@ export class ExtensionAPI {
} }
currentOverlays.update((current) => { currentOverlays.update((current) => {
current.overlays.world[overlay.id] = true; current.overlays.world[overlay.id] = show;
return current; return current;
}); });
} }
removeOverlaysWithPrefix(prefix: string) { filterOverlays(ids: string[]) {
prefix = this.getOverlayId(prefix); ids = ids.map((id) => this.getOverlayId(id));
const idsToRemove = Array.from(get(this._overlays).keys()).filter(
(id) => !ids.includes(id)
);
currentOverlays.update((current) => { currentOverlays.update((current) => {
removeByPrefix(current, prefix); removeAll(current, idsToRemove);
return current; return current;
}); });
previousOverlays.update((previous) => { previousOverlays.update((previous) => {
removeByPrefix(previous, prefix); removeAll(previous, idsToRemove);
return previous; return previous;
}); });
selectedOverlayTree.update((overlayTree) => { selectedOverlayTree.update((selected) => {
removeByPrefix(overlayTree, prefix); removeAll(selected, idsToRemove);
return overlayTree; return selected;
}); });
Object.keys(overlays).forEach((id) => { Object.keys(overlays).forEach((id) => {
if (id.startsWith(prefix)) { if (idsToRemove.includes(id)) {
delete overlays[id]; delete overlays[id];
} }
}); });
removeByPrefix(overlayTree, prefix); removeAll(overlayTree, idsToRemove);
this._overlays.update(($overlays) => { this._overlays.update(($overlays) => {
$overlays.forEach((_, id) => { $overlays.forEach((_, id) => {
if (id.startsWith(prefix)) { if (idsToRemove.includes(id)) {
$overlays.delete(id); $overlays.delete(id);
} }
}); });
@@ -119,21 +134,6 @@ export class ExtensionAPI {
}); });
} }
toggleOverlay(id: string) {
id = this.getOverlayId(id);
currentOverlays.update((overlays) => {
toggle(overlays, id);
return overlays;
});
if (!isSelected(get(selectedOverlayTree), id)) {
selectedOverlayTree.update((overlays) => {
toggle(overlays, id);
return overlays;
});
}
}
isLayerFromExtension = derived(this._overlays, ($overlays) => { isLayerFromExtension = derived(this._overlays, ($overlays) => {
return (id: string) => $overlays.has(id); return (id: string) => $overlays.has(id);
}); });
@@ -148,23 +148,23 @@ export class ExtensionAPI {
private destroy() { private destroy() {
const ids = Array.from(get(this._overlays).keys()); const ids = Array.from(get(this._overlays).keys());
currentOverlays.update((overlays) => { currentOverlays.update((current) => {
ids.forEach((id) => { ids.forEach((id) => {
remove(overlays, id); remove(current, id);
}); });
return overlays; return current;
}); });
previousOverlays.update((overlays) => { previousOverlays.update((previous) => {
ids.forEach((id) => { ids.forEach((id) => {
remove(overlays, id); remove(previous, id);
}); });
return overlays; return previous;
}); });
selectedOverlayTree.update((overlays) => { selectedOverlayTree.update((selected) => {
ids.forEach((id) => { ids.forEach((id) => {
remove(overlays, id); remove(selected, id);
}); });
return overlays; return selected;
}); });
} }
} }

View File

@@ -66,12 +66,12 @@ export function remove(node: LayerTreeType, id: string) {
return node; return node;
} }
export function removeByPrefix(node: LayerTreeType, prefix: string) { export function removeAll(node: LayerTreeType, ids: string[]) {
Object.keys(node).forEach((key) => { Object.keys(node).forEach((key) => {
if (key.startsWith(prefix)) { if (ids.includes(key)) {
delete node[key]; delete node[key];
} else if (typeof node[key] !== 'boolean') { } else if (typeof node[key] !== 'boolean') {
removeByPrefix(node[key], prefix); removeAll(node[key], ids);
} }
}); });
return node; return node;