Files
OpenFrontIO/src/client/graphics/layers/ReplayPanel.ts
T
Evan 62299c9714 standardize UI colors to fit brand guidelines (#3754)
## Description:

We have brand colors:

<img width="738" height="900" alt="Screenshot 2026-04-25 at 12 52 29 PM"
src="https://github.com/user-attachments/assets/aac69e87-91f2-4c3f-9f1e-f69f48f5943e"
/>

So update the homepage & in-game UI to use those colors:

<img width="1185" height="946" alt="Screenshot 2026-04-25 at 12 51
06 PM"
src="https://github.com/user-attachments/assets/89a0b12c-2db1-43d4-9500-fcf405c0f7ff"
/>

Also updated buttons to use the o-button element

## 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
- [x] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced

## Please put your Discord username so you can be contacted if a bug or
regression is found:

evan
2026-04-25 13:53:21 -06:00

113 lines
3.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { html, LitElement } from "lit";
import { customElement, property, state } from "lit/decorators.js";
import { EventBus } from "../../../core/EventBus";
import { GameView } from "../../../core/game/GameView";
import { ReplaySpeedChangeEvent } from "../../InputHandler";
import {
defaultReplaySpeedMultiplier,
ReplaySpeedMultiplier,
} from "../../utilities/ReplaySpeedMultiplier";
import { translateText } from "../../Utils";
import { Layer } from "./Layer";
export class ShowReplayPanelEvent {
constructor(
public visible: boolean = true,
public isSingleplayer: boolean = false,
) {}
}
@customElement("replay-panel")
export class ReplayPanel extends LitElement implements Layer {
public game: GameView | undefined;
public eventBus: EventBus | undefined;
@property({ type: Boolean })
visible: boolean = false;
@state()
private _replaySpeedMultiplier: number = defaultReplaySpeedMultiplier;
@property({ type: Boolean })
isSingleplayer = false;
createRenderRoot() {
return this; // Enable Tailwind CSS
}
init() {
if (this.eventBus) {
this.eventBus.on(ShowReplayPanelEvent, (event: ShowReplayPanelEvent) => {
this.visible = event.visible;
this.isSingleplayer = event.isSingleplayer;
});
this.eventBus.on(
ReplaySpeedChangeEvent,
(event: ReplaySpeedChangeEvent) => {
this._replaySpeedMultiplier = event.replaySpeedMultiplier;
this.requestUpdate();
},
);
}
}
getTickIntervalMs() {
return 1000;
}
tick() {
if (!this.visible) return;
this.requestUpdate();
}
onReplaySpeedChange(value: ReplaySpeedMultiplier) {
this._replaySpeedMultiplier = value;
this.eventBus?.emit(new ReplaySpeedChangeEvent(value));
}
renderLayer(_ctx: CanvasRenderingContext2D) {}
shouldTransform() {
return false;
}
render() {
if (!this.visible) return html``;
return html`
<div
class="p-2 bg-gray-800/92 backdrop-blur-sm shadow-xs min-[1200px]:rounded-lg rounded-l-lg"
@contextmenu=${(e: Event) => e.preventDefault()}
>
<label class="block mb-2 text-white" translate="no">
${this.game?.config()?.isReplay()
? translateText("replay_panel.replay_speed")
: translateText("replay_panel.game_speed")}
</label>
<div class="grid grid-cols-4 gap-2">
${this.renderSpeedButton(ReplaySpeedMultiplier.slow, "×0.5")}
${this.renderSpeedButton(ReplaySpeedMultiplier.normal, "×1")}
${this.renderSpeedButton(ReplaySpeedMultiplier.fast, "×2")}
${this.renderSpeedButton(
ReplaySpeedMultiplier.fastest,
translateText("replay_panel.fastest_game_speed"),
)}
</div>
</div>
`;
}
private renderSpeedButton(value: ReplaySpeedMultiplier, label: string) {
const backgroundColor =
this._replaySpeedMultiplier === value ? "bg-malibu-blue" : "";
return html`
<button
class="py-0.5 px-1 text-sm text-white rounded-sm border transition border-gray-500 ${backgroundColor} hover:border-gray-200"
@click=${() => this.onReplaySpeedChange(value)}
>
${label}
</button>
`;
}
}