ui/phase-13: planet inspector — read-only

Plumbs the map → inspector pathway: a click on a planet selects it
through the new SelectionStore, the sidebar Inspector tab swaps
its empty-state copy for a per-kind read-only field set, and a
mobile-only bottom-sheet mirrors the same content over the map.
Field projection in api/game-state.ts now surfaces every documented
planet field.
This commit is contained in:
Ilia Denisov
2026-05-09 08:29:03 +02:00
parent a3fdcfe9c5
commit 6364bba6fd
19 changed files with 1440 additions and 75 deletions
+46 -2
View File
@@ -1,9 +1,15 @@
// Typed wrapper around `GalaxyClient.executeCommand("user.games.report",
// ...)`. The signed-gRPC wire shape is the FlatBuffers
// `report.GameReportRequest` for the request and `report.Report` for
// the response (see `pkg/schema/fbs/report.fbs`). Phase 11 only
// surfaces the planet subset of the response — full ship / fleet /
// the response (see `pkg/schema/fbs/report.fbs`). Full ship / fleet /
// science decoding lands in Phases 17-22.
//
// Phase 13 expanded the per-planet projection so the inspector can
// render every documented field without a second round-trip. Each
// planet field is optional: the FBS schema carries different field
// sets for `LocalPlanet`, `OtherPlanet`, `UninhabitedPlanet`, and
// `UnidentifiedPlanet`, and the wrapper preserves that nullability
// instead of inventing zero values.
import { Builder, ByteBuffer } from "flatbuffers";
@@ -37,6 +43,16 @@ export interface ReportPlanet {
owner: string | null;
size: number | null;
resources: number | null;
// Engine field naming carries history: `capital` ($) is the
// industry stockpile, `material` (M) is the materials stockpile.
// `pkg/model/report/planet.go` is the source of truth for these.
industryStockpile: number | null;
materialsStockpile: number | null;
industry: number | null;
population: number | null;
colonists: number | null;
production: string | null;
freeIndustry: number | null;
}
export interface GameReport {
@@ -85,6 +101,13 @@ function decodeReport(report: Report): GameReport {
owner: null,
size: p.size(),
resources: p.resources(),
industryStockpile: p.capital(),
materialsStockpile: p.material(),
industry: p.industry(),
population: p.population(),
colonists: p.colonists(),
production: p.production() ?? null,
freeIndustry: p.freeIndustry(),
});
}
@@ -100,6 +123,13 @@ function decodeReport(report: Report): GameReport {
owner: p.owner() ?? null,
size: p.size(),
resources: p.resources(),
industryStockpile: p.capital(),
materialsStockpile: p.material(),
industry: p.industry(),
population: p.population(),
colonists: p.colonists(),
production: p.production() ?? null,
freeIndustry: p.freeIndustry(),
});
}
@@ -115,6 +145,13 @@ function decodeReport(report: Report): GameReport {
owner: null,
size: p.size(),
resources: p.resources(),
industryStockpile: p.capital(),
materialsStockpile: p.material(),
industry: null,
population: null,
colonists: null,
production: null,
freeIndustry: null,
});
}
@@ -130,6 +167,13 @@ function decodeReport(report: Report): GameReport {
owner: null,
size: null,
resources: null,
industryStockpile: null,
materialsStockpile: null,
industry: null,
population: null,
colonists: null,
production: null,
freeIndustry: null,
});
}