From dc1f79d090ae42f851dee61b839b16ea3dcc346b Mon Sep 17 00:00:00 2001 From: Antoine Date: Tue, 29 Jul 2025 22:24:52 +0200 Subject: [PATCH] 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 --- src/client/HostLobbyModal.ts | 8 +++-- src/client/Main.ts | 15 ++++++++-- src/client/SinglePlayerModal.ts | 8 +++-- src/client/graphics/layers/BuildMenu.ts | 2 +- src/client/graphics/layers/ChatDisplay.ts | 4 --- src/client/graphics/layers/ControlPanel.ts | 2 +- src/client/graphics/layers/EmojiTable.ts | 4 +-- src/client/graphics/layers/EventsDisplay.ts | 24 +++++++-------- src/client/graphics/layers/HeadsUpMessage.ts | 2 +- src/client/graphics/layers/Layer.ts | 10 +++---- src/client/graphics/layers/OptionsMenu.ts | 4 +-- .../graphics/layers/PlayerInfoOverlay.ts | 2 +- src/client/graphics/layers/PlayerPanel.ts | 30 +++++++++++-------- src/client/graphics/layers/TeamStats.ts | 6 ++-- tsconfig.json | 3 +- 15 files changed, 69 insertions(+), 55 deletions(-) diff --git a/src/client/HostLobbyModal.ts b/src/client/HostLobbyModal.ts index a83e1e6c7..58bfd6aba 100644 --- a/src/client/HostLobbyModal.ts +++ b/src/client/HostLobbyModal.ts @@ -154,7 +154,9 @@ export class HostLobbyModal extends LitElement {
${maps.map((mapValue) => { const mapKey = Object.keys(GameMapType).find( - (key) => GameMapType[key] === mapValue, + (key) => + GameMapType[key as keyof typeof GameMapType] === + mapValue, ); return html`

${translateText( - `difficulty.${DifficultyDescription[key]}`, + `difficulty.${DifficultyDescription[key as keyof typeof DifficultyDescription]}`, )}

@@ -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(); diff --git a/src/client/Main.ts b/src/client/Main.ts index 239f6184d..640ae8d93 100644 --- a/src/client/Main.ts +++ b/src/client/Main.ts @@ -58,6 +58,11 @@ declare global { spaNewPage: (url: string) => void; }; } + + // Extend the global interfaces to include your custom events + interface DocumentEventMap { + "join-lobby": CustomEvent; + } } 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( + "#bots-count, #private-lobby-bots-count", + ) .forEach((slider) => { updateSliderProgress(slider); slider.addEventListener("input", () => updateSliderProgress(slider)); diff --git a/src/client/SinglePlayerModal.ts b/src/client/SinglePlayerModal.ts index a1e9c1a14..69f5b23cf 100644 --- a/src/client/SinglePlayerModal.ts +++ b/src/client/SinglePlayerModal.ts @@ -67,7 +67,9 @@ export class SinglePlayerModal extends LitElement {
${maps.map((mapValue) => { const mapKey = Object.keys(GameMapType).find( - (key) => GameMapType[key] === mapValue, + (key) => + GameMapType[key as keyof typeof GameMapType] === + mapValue, ); return html`

${translateText( - `difficulty.${DifficultyDescription[key]}`, + `difficulty.${DifficultyDescription[key as keyof typeof DifficultyDescription]}`, )}

@@ -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(); diff --git a/src/client/graphics/layers/BuildMenu.ts b/src/client/graphics/layers/BuildMenu.ts index 7644347fc..9399218e9 100644 --- a/src/client/graphics/layers/BuildMenu.ts +++ b/src/client/graphics/layers/BuildMenu.ts @@ -404,7 +404,7 @@ export class BuildMenu extends LitElement implements Layer { return html`
e.preventDefault()} + @contextmenu=${(e: MouseEvent) => e.preventDefault()} > ${this.filteredBuildTable.map( (row) => html` diff --git a/src/client/graphics/layers/ChatDisplay.ts b/src/client/graphics/layers/ChatDisplay.ts index 5a880f733..941b08551 100644 --- a/src/client/graphics/layers/ChatDisplay.ts +++ b/src/client/graphics/layers/ChatDisplay.ts @@ -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[] = []; diff --git a/src/client/graphics/layers/ControlPanel.ts b/src/client/graphics/layers/ControlPanel.ts index e4ac7b286..a4197e0de 100644 --- a/src/client/graphics/layers/ControlPanel.ts +++ b/src/client/graphics/layers/ControlPanel.ts @@ -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()} >
diff --git a/src/client/graphics/layers/EmojiTable.ts b/src/client/graphics/layers/EmojiTable.ts index 0236d33fd..7a9702578 100644 --- a/src/client/graphics/layers/EmojiTable.ts +++ b/src/client/graphics/layers/EmojiTable.ts @@ -62,8 +62,8 @@ export class EmojiTable extends LitElement {
e.preventDefault()} - @wheel=${(e) => e.stopPropagation()} + @contextmenu=${(e: MouseEvent) => e.preventDefault()} + @wheel=${(e: WheelEvent) => e.stopPropagation()} >
diff --git a/src/client/graphics/layers/Layer.ts b/src/client/graphics/layers/Layer.ts index 9bfd9dc81..239937435 100644 --- a/src/client/graphics/layers/Layer.ts +++ b/src/client/graphics/layers/Layer.ts @@ -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; } diff --git a/src/client/graphics/layers/OptionsMenu.ts b/src/client/graphics/layers/OptionsMenu.ts index ed984904e..66ea8f3ae 100644 --- a/src/client/graphics/layers/OptionsMenu.ts +++ b/src/client/graphics/layers/OptionsMenu.ts @@ -14,7 +14,7 @@ const button = ({ classes = "", onClick = () => {}, title = "", - children, + children = "", }) => html` ${canTarget ? html`
${canEmbargo && other !== myPlayer ? html`