feat(ui): Phase 29 map visibility toggles
Tests · Go / test (push) Successful in 2m31s
Tests · UI / test (push) Failing after 8m7s

Adds the gear-icon popover on the map view with per-game persistence
of every category toggle plus the wrap-mode radio. Hide-by-id and
visibility-fog facilities land on the renderer so every flip applies
within one frame without a Pixi remount; the wrap-mode toggle keeps
its existing remount + camera-preserve path. A new server-side turn
force-resets every flag to defaults so a hidden category never makes
the player miss the next turn's news.

Also fixes the FligthDistance → FlightDistance typo in pkg/calc/race.go
(plus the single Go caller); the TS side keeps duplicating the formula
until a race-level WASM bridge lands.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Ilia Denisov
2026-05-19 21:33:53 +02:00
parent 65c0fbb87d
commit 2bd1b54936
32 changed files with 3046 additions and 63 deletions
+53
View File
@@ -280,3 +280,56 @@ describe("hitTest — empty results and scale", () => {
expect(ids(wFar, "torus", cam05, cursorOver(500, 500, cam05))).toBe(null);
});
});
describe("hitTest — Phase 29 hiddenIds parameter", () => {
const cam = camAt(500, 500);
test("a hidden primitive is skipped entirely", () => {
const w = new World(1000, 1000, [
point(1, 500, 500),
point(2, 500, 500, { priority: -1 }),
]);
// Without filtering, primitive 1 wins (higher priority).
expect(hitTest(w, cam, VP, cursorOver(500, 500, cam), "torus")?.primitive.id)
.toBe(1);
// With 1 hidden, the cursor falls through to primitive 2.
expect(
hitTest(
w,
cam,
VP,
cursorOver(500, 500, cam),
"torus",
new Set([1]),
)?.primitive.id,
).toBe(2);
});
test("hiding every match returns null", () => {
const w = new World(1000, 1000, [point(1, 500, 500)]);
expect(
hitTest(
w,
cam,
VP,
cursorOver(500, 500, cam),
"torus",
new Set([1]),
),
).toBeNull();
});
test("an empty hidden set is equivalent to omitting the parameter", () => {
const w = new World(1000, 1000, [point(1, 500, 500)]);
const a = hitTest(w, cam, VP, cursorOver(500, 500, cam), "torus");
const b = hitTest(
w,
cam,
VP,
cursorOver(500, 500, cam),
"torus",
new Set(),
);
expect(a?.primitive.id).toBe(1);
expect(b?.primitive.id).toBe(1);
});
});