mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-07-16 23:00:52 +00:00
## Description: Replaces the "Highlight small players" on/off toggle with a **0-500% Strength slider** controlling the glow's **width** (0 = off, 100% = the previous default). - `UserSettings`: `highlightSmallPlayers()`/toggle → `highlightGlowStrength()`/set, float-backed, clamped to [0, 5]. - `SmallPlayerGlowPass` takes the strength via a setter (pushed by `ClientGameRunner` on the settings-changed event), so it stays a pure consumer and the slider still updates live while the settings modal has the sim paused. Width = a non-linear blur-iteration count; intensity compensated so wider stays about as bright. - `MapRenderer` persists the strength across a WebGL context restore. - `SettingsModal`: the toggle row becomes a range input. Behavior note: with the toggle gone the glow **defaults ON at 100%** (old toggle defaulted OFF); can default to 0 (opt-in) if preferred. ## Please complete the following: - [x] I have added screenshots for all UI updates - [x] I process any text displayed to the user through translateText() and I've added it to the en.json file - [x] I have added relevant tests to the test directory
89 lines
3.2 KiB
TypeScript
89 lines
3.2 KiB
TypeScript
import { EFFECTS_KEY, UserSettings } from "../src/core/game/UserSettings";
|
|
|
|
describe("UserSettings effect selection", () => {
|
|
beforeEach(() => {
|
|
localStorage.clear();
|
|
// UserSettings keeps a static in-memory cache; reset it too so each test
|
|
// reads fresh from the (cleared) localStorage.
|
|
(
|
|
UserSettings as unknown as { cache: Map<string, string | null> }
|
|
).cache.clear();
|
|
});
|
|
|
|
it("sets and reads a per-effectType selection", () => {
|
|
const s = new UserSettings();
|
|
s.setSelectedEffectName("transportShipTrail", "spectrum");
|
|
expect(s.getSelectedEffectName("transportShipTrail")).toBe("spectrum");
|
|
});
|
|
|
|
it("returns null when nothing is selected", () => {
|
|
expect(
|
|
new UserSettings().getSelectedEffectName("transportShipTrail"),
|
|
).toBeNull();
|
|
});
|
|
|
|
it("clearing the last selection removes the storage key", () => {
|
|
const s = new UserSettings();
|
|
s.setSelectedEffectName("transportShipTrail", "spectrum");
|
|
s.setSelectedEffectName("transportShipTrail", undefined);
|
|
expect(s.getSelectedEffectName("transportShipTrail")).toBeNull();
|
|
expect(localStorage.getItem(EFFECTS_KEY)).toBeNull();
|
|
});
|
|
|
|
it("clearing one effectType leaves other types intact", () => {
|
|
const s = new UserSettings();
|
|
// Seed two types directly (only one real effectType exists today).
|
|
localStorage.setItem(
|
|
EFFECTS_KEY,
|
|
JSON.stringify({ transportShipTrail: "spectrum", future: "x" }),
|
|
);
|
|
s.setSelectedEffectName("transportShipTrail", undefined);
|
|
expect(s.getSelectedEffects()).toEqual({ future: "x" });
|
|
});
|
|
|
|
it("returns an empty map for a corrupt blob", () => {
|
|
localStorage.setItem(EFFECTS_KEY, "not json");
|
|
expect(new UserSettings().getSelectedEffects()).toEqual({});
|
|
});
|
|
|
|
it("keeps per-nukeType nuke-explosion slots independent", () => {
|
|
const s = new UserSettings();
|
|
s.setSelectedEffectName("atom", "atom_boom");
|
|
s.setSelectedEffectName("hydro", "hydro_boom");
|
|
expect(s.getSelectedEffectName("atom")).toBe("atom_boom");
|
|
expect(s.getSelectedEffectName("hydro")).toBe("hydro_boom");
|
|
// Clearing one bomb's slot leaves the others intact.
|
|
s.setSelectedEffectName("atom", undefined);
|
|
expect(s.getSelectedEffectName("atom")).toBeNull();
|
|
expect(s.getSelectedEffectName("hydro")).toBe("hydro_boom");
|
|
});
|
|
});
|
|
|
|
describe("UserSettings highlight glow strength", () => {
|
|
beforeEach(() => {
|
|
localStorage.clear();
|
|
(
|
|
UserSettings as unknown as { cache: Map<string, string | null> }
|
|
).cache.clear();
|
|
});
|
|
|
|
it("defaults to 1 (100%, on)", () => {
|
|
expect(new UserSettings().highlightGlowStrength()).toBe(1);
|
|
});
|
|
|
|
it("persists a set value, including 0 (off)", () => {
|
|
const s = new UserSettings();
|
|
s.setHighlightGlowStrength(2.5);
|
|
expect(s.highlightGlowStrength()).toBe(2.5);
|
|
s.setHighlightGlowStrength(0);
|
|
expect(s.highlightGlowStrength()).toBe(0);
|
|
});
|
|
|
|
it("shares state across instances via the static cache", () => {
|
|
// The settings modal and the renderer's frame builder each hold their own
|
|
// UserSettings; a change in one must be visible to the other.
|
|
new UserSettings().setHighlightGlowStrength(3);
|
|
expect(new UserSettings().highlightGlowStrength()).toBe(3);
|
|
});
|
|
});
|