mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-21 09:30:45 +00:00
Fix all strict errors in /client (#1489)
## Description: Second PR to fix issues in order to enable strict mode. ## Specifics 1. Most important change: Turned off errors for Class variables not initialized in constructor. I've noticed that pretty much all Classes in the project have at least one occurence of that issue. And fixing it properly would require a large refactor across the whole project. So disabling the rule seems like a good solution in this case. #1075 ## 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 - [x] I have read and accepted the CLA aggreement (only required once). ## Please put your Discord username so you can be contacted if a bug or regression is found: azlod
This commit is contained in:
@@ -154,7 +154,9 @@ export class HostLobbyModal extends LitElement {
|
||||
<div class="flex flex-row flex-wrap justify-center gap-4">
|
||||
${maps.map((mapValue) => {
|
||||
const mapKey = Object.keys(GameMapType).find(
|
||||
(key) => GameMapType[key] === mapValue,
|
||||
(key) =>
|
||||
GameMapType[key as keyof typeof GameMapType] ===
|
||||
mapValue,
|
||||
);
|
||||
return html`
|
||||
<div
|
||||
@@ -214,7 +216,7 @@ export class HostLobbyModal extends LitElement {
|
||||
></difficulty-display>
|
||||
<p class="option-card-title">
|
||||
${translateText(
|
||||
`difficulty.${DifficultyDescription[key]}`,
|
||||
`difficulty.${DifficultyDescription[key as keyof typeof DifficultyDescription]}`,
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
@@ -589,7 +591,7 @@ export class HostLobbyModal extends LitElement {
|
||||
|
||||
await this.putGameConfig();
|
||||
console.log(
|
||||
`Starting private game with map: ${GameMapType[this.selectedMap]} ${this.useRandomMap ? " (Randomly selected)" : ""}`,
|
||||
`Starting private game with map: ${GameMapType[this.selectedMap as keyof typeof GameMapType]} ${this.useRandomMap ? " (Randomly selected)" : ""}`,
|
||||
);
|
||||
this.close();
|
||||
const config = await getServerConfigFromClient();
|
||||
|
||||
+12
-3
@@ -58,6 +58,11 @@ declare global {
|
||||
spaNewPage: (url: string) => void;
|
||||
};
|
||||
}
|
||||
|
||||
// Extend the global interfaces to include your custom events
|
||||
interface DocumentEventMap {
|
||||
"join-lobby": CustomEvent<JoinLobbyEvent>;
|
||||
}
|
||||
}
|
||||
|
||||
export interface JoinLobbyEvent {
|
||||
@@ -383,14 +388,18 @@ class Client {
|
||||
window.addEventListener("popstate", onHashUpdate);
|
||||
window.addEventListener("hashchange", onHashUpdate);
|
||||
|
||||
function updateSliderProgress(slider) {
|
||||
function updateSliderProgress(slider: HTMLInputElement) {
|
||||
const percent =
|
||||
((slider.value - slider.min) / (slider.max - slider.min)) * 100;
|
||||
((Number(slider.value) - Number(slider.min)) /
|
||||
(Number(slider.max) - Number(slider.min))) *
|
||||
100;
|
||||
slider.style.setProperty("--progress", `${percent}%`);
|
||||
}
|
||||
|
||||
document
|
||||
.querySelectorAll("#bots-count, #private-lobby-bots-count")
|
||||
.querySelectorAll<HTMLInputElement>(
|
||||
"#bots-count, #private-lobby-bots-count",
|
||||
)
|
||||
.forEach((slider) => {
|
||||
updateSliderProgress(slider);
|
||||
slider.addEventListener("input", () => updateSliderProgress(slider));
|
||||
|
||||
@@ -67,7 +67,9 @@ export class SinglePlayerModal extends LitElement {
|
||||
<div class="flex flex-row flex-wrap justify-center gap-4">
|
||||
${maps.map((mapValue) => {
|
||||
const mapKey = Object.keys(GameMapType).find(
|
||||
(key) => GameMapType[key] === mapValue,
|
||||
(key) =>
|
||||
GameMapType[key as keyof typeof GameMapType] ===
|
||||
mapValue,
|
||||
);
|
||||
return html`
|
||||
<div
|
||||
@@ -129,7 +131,7 @@ export class SinglePlayerModal extends LitElement {
|
||||
></difficulty-display>
|
||||
<p class="option-card-title">
|
||||
${translateText(
|
||||
`difficulty.${DifficultyDescription[key]}`,
|
||||
`difficulty.${DifficultyDescription[key as keyof typeof DifficultyDescription]}`,
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
@@ -389,7 +391,7 @@ export class SinglePlayerModal extends LitElement {
|
||||
}
|
||||
|
||||
console.log(
|
||||
`Starting single player game with map: ${GameMapType[this.selectedMap]}${this.useRandomMap ? " (Randomly selected)" : ""}`,
|
||||
`Starting single player game with map: ${GameMapType[this.selectedMap as keyof typeof GameMapType]}${this.useRandomMap ? " (Randomly selected)" : ""}`,
|
||||
);
|
||||
const clientID = generateID();
|
||||
const gameID = generateID();
|
||||
|
||||
@@ -404,7 +404,7 @@ export class BuildMenu extends LitElement implements Layer {
|
||||
return html`
|
||||
<div
|
||||
class="build-menu ${this._hidden ? "hidden" : ""}"
|
||||
@contextmenu=${(e) => e.preventDefault()}
|
||||
@contextmenu=${(e: MouseEvent) => e.preventDefault()}
|
||||
>
|
||||
${this.filteredBuildTable.map(
|
||||
(row) => html`
|
||||
|
||||
@@ -26,10 +26,6 @@ export class ChatDisplay extends LitElement implements Layer {
|
||||
|
||||
private active: boolean = false;
|
||||
|
||||
private updateMap = new Map([
|
||||
[GameUpdateType.DisplayEvent, (u) => this.onDisplayMessageEvent(u)],
|
||||
]);
|
||||
|
||||
@state() private _hidden: boolean = false;
|
||||
@state() private newEvents: number = 0;
|
||||
@state() private chatEvents: ChatEvent[] = [];
|
||||
|
||||
@@ -214,7 +214,7 @@ export class ControlPanel extends LitElement implements Layer {
|
||||
class="${this._isVisible
|
||||
? "w-full sm:max-w-[320px] text-sm sm:text-base bg-gray-800/70 p-2 pr-3 sm:p-4 shadow-lg sm:rounded-lg backdrop-blur"
|
||||
: "hidden"}"
|
||||
@contextmenu=${(e) => e.preventDefault()}
|
||||
@contextmenu=${(e: MouseEvent) => e.preventDefault()}
|
||||
>
|
||||
<div class="block bg-black/30 text-white mb-4 p-2 rounded">
|
||||
<div class="flex justify-between mb-1">
|
||||
|
||||
@@ -62,8 +62,8 @@ export class EmojiTable extends LitElement {
|
||||
<div
|
||||
class="bg-slate-800 max-w-[95vw] max-h-[95vh] pt-[15px] pb-[15px] fixed flex flex-col -translate-x-1/2 -translate-y-1/2
|
||||
items-center rounded-[10px] z-[9999] top-[50%] left-[50%] justify-center"
|
||||
@contextmenu=${(e) => e.preventDefault()}
|
||||
@wheel=${(e) => e.stopPropagation()}
|
||||
@contextmenu=${(e: MouseEvent) => e.preventDefault()}
|
||||
@wheel=${(e: WheelEvent) => e.stopPropagation()}
|
||||
>
|
||||
<!-- Close button -->
|
||||
<button
|
||||
|
||||
@@ -142,20 +142,20 @@ export class EventsDisplay extends LitElement implements Layer {
|
||||
this.requestUpdate();
|
||||
}
|
||||
|
||||
private updateMap = new Map([
|
||||
[GameUpdateType.DisplayEvent, (u) => this.onDisplayMessageEvent(u)],
|
||||
[GameUpdateType.DisplayChatEvent, (u) => this.onDisplayChatEvent(u)],
|
||||
[GameUpdateType.AllianceRequest, (u) => this.onAllianceRequestEvent(u)],
|
||||
private updateMap = [
|
||||
[GameUpdateType.DisplayEvent, this.onDisplayMessageEvent.bind(this)],
|
||||
[GameUpdateType.DisplayChatEvent, this.onDisplayChatEvent.bind(this)],
|
||||
[GameUpdateType.AllianceRequest, this.onAllianceRequestEvent.bind(this)],
|
||||
[
|
||||
GameUpdateType.AllianceRequestReply,
|
||||
(u) => this.onAllianceRequestReplyEvent(u),
|
||||
this.onAllianceRequestReplyEvent.bind(this),
|
||||
],
|
||||
[GameUpdateType.BrokeAlliance, (u) => this.onBrokeAllianceEvent(u)],
|
||||
[GameUpdateType.TargetPlayer, (u) => this.onTargetPlayerEvent(u)],
|
||||
[GameUpdateType.Emoji, (u) => this.onEmojiMessageEvent(u)],
|
||||
[GameUpdateType.UnitIncoming, (u) => this.onUnitIncomingEvent(u)],
|
||||
[GameUpdateType.AllianceExpired, (u) => this.onAllianceExpiredEvent(u)],
|
||||
]);
|
||||
[GameUpdateType.BrokeAlliance, this.onBrokeAllianceEvent.bind(this)],
|
||||
[GameUpdateType.TargetPlayer, this.onTargetPlayerEvent.bind(this)],
|
||||
[GameUpdateType.Emoji, this.onEmojiMessageEvent.bind(this)],
|
||||
[GameUpdateType.UnitIncoming, this.onUnitIncomingEvent.bind(this)],
|
||||
[GameUpdateType.AllianceExpired, this.onAllianceExpiredEvent.bind(this)],
|
||||
] as const;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
@@ -189,7 +189,7 @@ export class EventsDisplay extends LitElement implements Layer {
|
||||
const updates = this.game.updatesSinceLastTick();
|
||||
if (updates) {
|
||||
for (const [ut, fn] of this.updateMap) {
|
||||
updates[ut]?.forEach(fn);
|
||||
updates[ut]?.forEach(fn as (event: unknown) => void);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ export class HeadsUpMessage extends LitElement implements Layer {
|
||||
w-full justify-evenly h-8 lg:h-10 md:top-[70px] left-0 lg:left-4
|
||||
bg-opacity-60 bg-gray-900 rounded-md lg:rounded-lg
|
||||
backdrop-blur-md text-white text-md lg:text-xl p-1 lg:p-2"
|
||||
@contextmenu=${(e) => e.preventDefault()}
|
||||
@contextmenu=${(e: MouseEvent) => e.preventDefault()}
|
||||
>
|
||||
${translateText("heads_up_message.choose_spawn")}
|
||||
</div>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
export interface Layer {
|
||||
init?();
|
||||
tick?();
|
||||
renderLayer?(context: CanvasRenderingContext2D);
|
||||
shouldTransform?(): boolean;
|
||||
redraw?(): void;
|
||||
init?: () => void;
|
||||
tick?: () => void;
|
||||
renderLayer?: (context: CanvasRenderingContext2D) => void;
|
||||
shouldTransform?: () => boolean;
|
||||
redraw?: () => void;
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ const button = ({
|
||||
classes = "",
|
||||
onClick = () => {},
|
||||
title = "",
|
||||
children,
|
||||
children = "",
|
||||
}) => html`
|
||||
<button
|
||||
class="flex items-center justify-center p-1
|
||||
@@ -167,7 +167,7 @@ export class OptionsMenu extends LitElement implements Layer {
|
||||
return html`
|
||||
<div
|
||||
class="top-0 lg:top-4 right-0 lg:right-4 z-50 pointer-events-auto"
|
||||
@contextmenu=${(e) => e.preventDefault()}
|
||||
@contextmenu=${(e: MouseEvent) => e.preventDefault()}
|
||||
>
|
||||
<div
|
||||
class="bg-opacity-60 bg-gray-900 p-1 lg:p-2 rounded-es-sm lg:rounded-lg backdrop-blur-md"
|
||||
|
||||
@@ -340,7 +340,7 @@ export class PlayerInfoOverlay extends LitElement implements Layer {
|
||||
return html`
|
||||
<div
|
||||
class="block lg:flex fixed top-[150px] right-0 w-full z-50 flex-col max-w-[180px]"
|
||||
@contextmenu=${(e) => e.preventDefault()}
|
||||
@contextmenu=${(e: MouseEvent) => e.preventDefault()}
|
||||
>
|
||||
<div
|
||||
class="bg-gray-800/70 backdrop-blur-sm shadow-xs rounded-lg shadow-lg transition-all duration-300 text-white text-lg md:text-base ${containerClasses}"
|
||||
|
||||
@@ -162,10 +162,10 @@ export class PlayerPanel extends LitElement implements Layer {
|
||||
return this;
|
||||
}
|
||||
|
||||
private ctModal;
|
||||
private ctModal: ChatModal;
|
||||
|
||||
init() {
|
||||
this.eventBus.on(MouseUpEvent, (e: MouseEvent) => this.hide());
|
||||
this.eventBus.on(MouseUpEvent, () => this.hide());
|
||||
|
||||
this.ctModal = document.querySelector("chat-modal") as ChatModal;
|
||||
}
|
||||
@@ -234,8 +234,8 @@ export class PlayerPanel extends LitElement implements Layer {
|
||||
return html`
|
||||
<div
|
||||
class="fixed inset-0 flex items-center justify-center z-[1001] pointer-events-none overflow-auto"
|
||||
@contextmenu=${(e) => e.preventDefault()}
|
||||
@wheel=${(e) => e.stopPropagation()}
|
||||
@contextmenu=${(e: MouseEvent) => e.preventDefault()}
|
||||
@wheel=${(e: MouseEvent) => e.stopPropagation()}
|
||||
>
|
||||
<div
|
||||
class="pointer-events-auto max-h-[90vh] overflow-y-auto min-w-[240px] w-auto px-4 py-2"
|
||||
@@ -364,7 +364,8 @@ export class PlayerPanel extends LitElement implements Layer {
|
||||
<!-- Action buttons -->
|
||||
<div class="flex justify-center gap-2">
|
||||
<button
|
||||
@click=${(e) => this.handleChat(e, myPlayer, other)}
|
||||
@click=${(e: MouseEvent) =>
|
||||
this.handleChat(e, myPlayer, other)}
|
||||
class="w-10 h-10 flex items-center justify-center
|
||||
bg-opacity-50 bg-gray-700 hover:bg-opacity-70
|
||||
text-white rounded-lg transition-colors"
|
||||
@@ -373,7 +374,8 @@ export class PlayerPanel extends LitElement implements Layer {
|
||||
</button>
|
||||
${canTarget
|
||||
? html`<button
|
||||
@click=${(e) => this.handleTargetClick(e, other)}
|
||||
@click=${(e: MouseEvent) =>
|
||||
this.handleTargetClick(e, other)}
|
||||
class="w-10 h-10 flex items-center justify-center
|
||||
bg-opacity-50 bg-gray-700 hover:bg-opacity-70
|
||||
text-white rounded-lg transition-colors"
|
||||
@@ -383,7 +385,7 @@ export class PlayerPanel extends LitElement implements Layer {
|
||||
: ""}
|
||||
${canBreakAlliance
|
||||
? html`<button
|
||||
@click=${(e) =>
|
||||
@click=${(e: MouseEvent) =>
|
||||
this.handleBreakAllianceClick(e, myPlayer, other)}
|
||||
class="w-10 h-10 flex items-center justify-center
|
||||
bg-opacity-50 bg-gray-700 hover:bg-opacity-70
|
||||
@@ -398,7 +400,7 @@ export class PlayerPanel extends LitElement implements Layer {
|
||||
: ""}
|
||||
${canSendAllianceRequest
|
||||
? html`<button
|
||||
@click=${(e) =>
|
||||
@click=${(e: MouseEvent) =>
|
||||
this.handleAllianceClick(e, myPlayer, other)}
|
||||
class="w-10 h-10 flex items-center justify-center
|
||||
bg-opacity-50 bg-gray-700 hover:bg-opacity-70
|
||||
@@ -409,7 +411,7 @@ export class PlayerPanel extends LitElement implements Layer {
|
||||
: ""}
|
||||
${canDonate
|
||||
? html`<button
|
||||
@click=${(e) =>
|
||||
@click=${(e: MouseEvent) =>
|
||||
this.handleDonateTroopClick(e, myPlayer, other)}
|
||||
class="w-10 h-10 flex items-center justify-center
|
||||
bg-opacity-50 bg-gray-700 hover:bg-opacity-70
|
||||
@@ -424,7 +426,7 @@ export class PlayerPanel extends LitElement implements Layer {
|
||||
: ""}
|
||||
${canDonate
|
||||
? html`<button
|
||||
@click=${(e) =>
|
||||
@click=${(e: MouseEvent) =>
|
||||
this.handleDonateGoldClick(e, myPlayer, other)}
|
||||
class="w-10 h-10 flex items-center justify-center
|
||||
bg-opacity-50 bg-gray-700 hover:bg-opacity-70
|
||||
@@ -435,7 +437,8 @@ export class PlayerPanel extends LitElement implements Layer {
|
||||
: ""}
|
||||
${canSendEmoji
|
||||
? html`<button
|
||||
@click=${(e) => this.handleEmojiClick(e, myPlayer, other)}
|
||||
@click=${(e: MouseEvent) =>
|
||||
this.handleEmojiClick(e, myPlayer, other)}
|
||||
class="w-10 h-10 flex items-center justify-center
|
||||
bg-opacity-50 bg-gray-700 hover:bg-opacity-70
|
||||
text-white rounded-lg transition-colors"
|
||||
@@ -446,7 +449,8 @@ export class PlayerPanel extends LitElement implements Layer {
|
||||
</div>
|
||||
${canEmbargo && other !== myPlayer
|
||||
? html`<button
|
||||
@click=${(e) => this.handleEmbargoClick(e, myPlayer, other)}
|
||||
@click=${(e: MouseEvent) =>
|
||||
this.handleEmbargoClick(e, myPlayer, other)}
|
||||
class="w-100 h-10 flex items-center justify-center
|
||||
bg-opacity-50 bg-gray-700 hover:bg-opacity-70
|
||||
text-white rounded-lg transition-colors"
|
||||
@@ -456,7 +460,7 @@ export class PlayerPanel extends LitElement implements Layer {
|
||||
: ""}
|
||||
${!canEmbargo && other !== myPlayer
|
||||
? html`<button
|
||||
@click=${(e) =>
|
||||
@click=${(e: MouseEvent) =>
|
||||
this.handleStopEmbargoClick(e, myPlayer, other)}
|
||||
class="w-100 h-10 flex items-center justify-center
|
||||
bg-opacity-50 bg-gray-700 hover:bg-opacity-70
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { LitElement, html } from "lit";
|
||||
import { customElement, property } from "lit/decorators.js";
|
||||
import { EventBus } from "../../../core/EventBus";
|
||||
import { GameMode } from "../../../core/game/Game";
|
||||
import { GameMode, Team } from "../../../core/game/Game";
|
||||
import { GameView, PlayerView } from "../../../core/game/GameView";
|
||||
import { renderNumber, translateText } from "../../Utils";
|
||||
import { Layer } from "./Layer";
|
||||
@@ -47,7 +47,7 @@ export class TeamStats extends LitElement implements Layer {
|
||||
|
||||
private updateTeamStats() {
|
||||
const players = this.game.playerViews();
|
||||
const grouped: Record<number, PlayerView[]> = {};
|
||||
const grouped: Record<Team, PlayerView[]> = {};
|
||||
|
||||
for (const player of players) {
|
||||
const team = player.team();
|
||||
@@ -102,7 +102,7 @@ export class TeamStats extends LitElement implements Layer {
|
||||
.visible
|
||||
? ""
|
||||
: "hidden"}"
|
||||
@contextmenu=${(e) => e.preventDefault()}
|
||||
@contextmenu=${(e: MouseEvent) => e.preventDefault()}
|
||||
>
|
||||
<div
|
||||
class="grid w-full"
|
||||
|
||||
+2
-1
@@ -20,7 +20,8 @@
|
||||
"experimentalDecorators": true,
|
||||
"resolveJsonModule": true,
|
||||
"strictNullChecks": true,
|
||||
"useDefineForClassFields": false
|
||||
"useDefineForClassFields": false,
|
||||
"strictPropertyInitialization": false
|
||||
},
|
||||
"include": [
|
||||
"src/**/*",
|
||||
|
||||
Reference in New Issue
Block a user