Give the SCUM live map the full width and add catalog icon pickers

- Drop the live-map stat strip and the half-width detail column: the map board now spans the row, is taller, and the selected point renders as a compact strip under it.
- Fit the map filters into a single row with small layer chips, and switch the board between terrain, topo and night base layers plus the extracted building-zone overlay.
- Add a searchable SCUM catalog picker with icons for gift items and event produces, show gift item and vehicle icons in the lists, and keep the picker grid closed until it is opened so no icon is requested up front.
This commit is contained in:
npc0-hue
2026-09-16 07:58:48 +08:00
parent 839aff35ed
commit c959a5bc03
5 changed files with 154 additions and 17 deletions
+27 -1
View File
@@ -291,7 +291,33 @@ describe("SCUM plugin feature module", () => {
expect(view.elements.find((element) => element.label === "SCUM 地图图层")?.style?.backgroundImage).toContain("scum-map-terrain-4096.webp");
expect(view.inputs.map((input) => input.label)).toEqual(expect.arrayContaining(["启用自定义地图", "地图中心 X", "地图中心 Y", "地图宽度公里", "地图高度公里"]));
const vehicleView = renderAndCollect({ pageKey: "live-map", pageTitle: "实时地图", data: { ...surfaceData, players: [], mapPoints: [], flags: [], mapRegions: [] } });
expect(vehicleView.texts).toEqual(expect.arrayContaining(["锁 已上锁", "scum-user-1", "76561198000000001"]));
expect(vehicleView.texts).toEqual(expect.arrayContaining(["BPC_Laika_C · unknown · 已上锁 · 访问 unknown", "scum-user-1", "76561198000000001"]));
});
it("keeps the live map full width with one compact filter row", () => {
const view = renderAndCollect({ pageKey: "live-map", pageTitle: "实时地图" });
expect(view.texts).not.toContain("载具目录");
expect(view.texts).not.toContain("地图点");
expect(view.texts.some((text) => /^\d+ \/ \d+ 个可见点$/.test(text))).toBe(true);
for (const layer of ["地形", "等高线", "夜间", "建筑区"]) expect(view.texts).toContain(layer);
expect(view.buttons.map((button) => button.label)).toEqual(expect.arrayContaining(["地形", "等高线", "夜间"]));
expect(view.inputs.map((input) => input.label)).toEqual(expect.arrayContaining(["筛选地图点"]));
expect(pageSource).toContain('new URL("../assets/map/scum-map-building-zones-4096.png", import.meta.url).href');
expect(pageSource).toContain("mapBoardStyle(baseLayer, zonesOverlay)");
});
it("keeps the extracted icon catalog closed until an editor asks for it", () => {
const gifts = renderAndCollect({ pageKey: "gifts", pageTitle: "礼包管理" });
expect(gifts.texts).toContain("从 SCUM 目录选择礼包物品");
expect(gifts.inputs.map((input) => input.label)).not.toContain("搜索礼包物品");
const workflows = renderAndCollect({ pageKey: "workflows", pageTitle: "活动管理" });
expect(workflows.texts).toContain("从 SCUM 目录选择物品");
expect(workflows.inputs.map((input) => input.label)).not.toContain("搜索生成物品");
});
it("loads the vehicle icon for trajectory rows and gift items", () => {
expect(pageSource).toContain('trajectoryVehicleIcon(row) ? e("img", { className: "scum-catalog-icon"');
expect(pageSource).toContain("catalogIconStrip(e, giftCatalogIcons(gift))");
});
it("deduplicates map entities, keeps every point, and computes custom map bounds", async () => {