3 Commits

Author SHA1 Message Date
vcoppe
467cb2e589 update extension api 2025-11-25 19:18:54 +01:00
vcoppe
f13d8c1e22 New translations en.json (Chinese Simplified) (#280) 2025-11-25 18:23:13 +01:00
vcoppe
e230d55b82 fix cloning 2025-11-25 18:22:51 +01:00
5 changed files with 54 additions and 9 deletions

View File

@@ -17,6 +17,9 @@ import {
import { immerable, isDraft, original, freeze } from 'immer'; import { immerable, isDraft, original, freeze } from 'immer';
function cloneJSON<T>(obj: T): T { function cloneJSON<T>(obj: T): T {
if (obj === undefined) {
return undefined;
}
if (obj === null || typeof obj !== 'object') { if (obj === null || typeof obj !== 'object') {
return null; return null;
} }

View File

@@ -85,7 +85,7 @@
{:else if anySelectedLayer(node[id])} {:else if anySelectedLayer(node[id])}
<CollapsibleTreeNode {id}> <CollapsibleTreeNode {id}>
{#snippet trigger()} {#snippet trigger()}
<span>{i18n._(`layers.label.${id}`)}</span> <span>{i18n._(`layers.label.${id}`, id)}</span>
{/snippet} {/snippet}
{#snippet content()} {#snippet content()}
<div class="ml-2"> <div class="ml-2">

View File

@@ -8,6 +8,7 @@ import { map } from '$lib/components/map/map';
const { currentOverlays, previousOverlays, selectedOverlayTree } = settings; const { currentOverlays, previousOverlays, selectedOverlayTree } = settings;
export type CustomOverlay = { export type CustomOverlay = {
extensionName: string;
id: string; id: string;
name: string; name: string;
tileUrls: string[]; tileUrls: string[];
@@ -46,8 +47,16 @@ export class ExtensionAPI {
} }
addOrUpdateOverlay(overlay: CustomOverlay) { addOrUpdateOverlay(overlay: CustomOverlay) {
if (!overlay.id || !overlay.name || !overlay.tileUrls || overlay.tileUrls.length === 0) { if (
throw new Error('Overlay must have an id, name, and at least one tile URL.'); !overlay.extensionName ||
!overlay.id ||
!overlay.name ||
!overlay.tileUrls ||
overlay.tileUrls.length === 0
) {
throw new Error(
'Overlay must have an extensionName, id, name, and at least one tile URL.'
);
} }
overlay.id = this.getOverlayId(overlay.id); overlay.id = this.getOverlayId(overlay.id);
@@ -75,10 +84,17 @@ export class ExtensionAPI {
], ],
}; };
overlayTree.overlays.world[overlay.id] = true; if (!overlayTree.overlays.hasOwnProperty(overlay.extensionName)) {
overlayTree.overlays[overlay.extensionName] = {};
}
overlayTree.overlays[overlay.extensionName][overlay.id] = true;
selectedOverlayTree.update((selected) => { selectedOverlayTree.update((selected) => {
selected.overlays.world[overlay.id] = true; if (!selected.overlays.hasOwnProperty(overlay.extensionName)) {
selected.overlays[overlay.extensionName] = {};
}
selected.overlays[overlay.extensionName][overlay.id] = true;
return selected; return selected;
}); });
@@ -94,7 +110,10 @@ export class ExtensionAPI {
} }
currentOverlays.update((current) => { currentOverlays.update((current) => {
current.overlays.world[overlay.id] = show; if (!current.overlays.hasOwnProperty(overlay.extensionName)) {
current.overlays[overlay.extensionName] = {};
}
current.overlays[overlay.extensionName][overlay.id] = show;
return current; return current;
}); });
} }
@@ -133,6 +152,29 @@ export class ExtensionAPI {
}); });
} }
updateOverlaysOrder(ids: string[]) {
ids = ids.map((id) => this.getOverlayId(id));
selectedOverlayTree.update((selected) => {
let isSelected: Record<string, boolean> = {};
ids.forEach((id) => {
const overlay = get(this._overlays).get(id);
if (
overlay &&
selected.overlays.hasOwnProperty(overlay.extensionName) &&
selected.overlays[overlay.extensionName].hasOwnProperty(id)
) {
isSelected[id] = selected.overlays[overlay.extensionName][id];
delete selected.overlays[overlay.extensionName][id];
}
});
Object.entries(isSelected).forEach(([id, value]) => {
const overlay = get(this._overlays).get(id)!;
selected.overlays[overlay.extensionName][id] = value;
});
return selected;
});
}
isLayerFromExtension = derived(this._overlays, ($overlays) => { isLayerFromExtension = derived(this._overlays, ($overlays) => {
return (id: string) => $overlays.has(id); return (id: string) => $overlays.has(id);
}); });

View File

@@ -14,7 +14,7 @@ class Locale {
private _isLoadingInitial = $state(true); private _isLoadingInitial = $state(true);
private _isLoading = $state(true); private _isLoading = $state(true);
private dictionary: Dictionary = $state({}); private dictionary: Dictionary = $state({});
private _t = $derived((key: string) => { private _t = $derived((key: string, fallback?: string) => {
const keys = key.split('.'); const keys = key.split('.');
let value: string | Dictionary = this.dictionary; let value: string | Dictionary = this.dictionary;
@@ -22,7 +22,7 @@ class Locale {
if (value && typeof value === 'object' && k in value) { if (value && typeof value === 'object' && k in value) {
value = value[k]; value = value[k];
} else { } else {
return key; return fallback || key;
} }
} }

View File

@@ -28,7 +28,7 @@
"undo": "撤销", "undo": "撤销",
"redo": "恢复", "redo": "恢复",
"delete": "删除", "delete": "删除",
"delete_all": "Delete all", "delete_all": "",
"select_all": "全选", "select_all": "全选",
"view": "显示", "view": "显示",
"elevation_profile": "海拔剖面图", "elevation_profile": "海拔剖面图",