diff --git a/src/client/ClientGameRunner.ts b/src/client/ClientGameRunner.ts index c3c093426d..3585d051e0 100644 --- a/src/client/ClientGameRunner.ts +++ b/src/client/ClientGameRunner.ts @@ -69,7 +69,7 @@ export function joinLobby( lobbyConfig: LobbyConfig, onPrestart: () => void, onJoin: () => void, -): () => void { +): () => boolean { console.log( `joining lobby: gameID: ${lobbyConfig.gameID}, clientID: ${lobbyConfig.clientID}`, ); @@ -79,6 +79,8 @@ export function joinLobby( const transport = new Transport(lobbyConfig, eventBus); + let currentGameRunner: ClientGameRunner | null = null; + const onconnect = () => { console.log(`Joined game lobby ${lobbyConfig.gameID}`); transport.joinGame(0); @@ -113,7 +115,10 @@ export function joinLobby( userSettings, terrainLoad, terrainMapFileLoader, - ).then((r) => r.start()); + ).then((r) => { + currentGameRunner = r; + r.start(); + }); } if (message.type === "error") { if (message.error === "full-lobby") { @@ -139,8 +144,13 @@ export function joinLobby( }; transport.connect(onconnect, onmessage); return () => { + if (currentGameRunner && currentGameRunner.shouldPreventWindowClose()) { + return false; + } console.log("leaving game"); + currentGameRunner = null; transport.leaveGame(); + return true; }; } @@ -230,6 +240,24 @@ export class ClientGameRunner { this.lastMessageTime = Date.now(); } + /** + * Determines whether window closing should be prevented. + * + * Used to show a confirmation dialog when the user attempts to close + * the window or navigate away during an active game session. + * + * @returns {boolean} `true` if the window close should be prevented + * (when the player is alive in the game), `false` otherwise + * (when the player is not alive or doesn't exist) + */ + public shouldPreventWindowClose(): boolean { + // Show confirmation dialog if player is alive in the game + if (this.myPlayer && this.myPlayer.isAlive()) { + return true; + } + return false; + } + private saveGame(update: WinUpdate) { if (this.myPlayer === null) { return; diff --git a/src/client/Main.ts b/src/client/Main.ts index 6425c137f4..accaf9ea62 100644 --- a/src/client/Main.ts +++ b/src/client/Main.ts @@ -89,7 +89,7 @@ export interface JoinLobbyEvent { } class Client { - private gameStop: (() => void) | null = null; + private gameStop: (() => boolean) | null = null; private eventBus: EventBus = new EventBus(); private usernameInput: UsernameInput | null = null; @@ -150,11 +150,13 @@ class Client { this.publicLobby = document.querySelector("public-lobby") as PublicLobby; - window.addEventListener("beforeunload", () => { - console.log("Browser is closing"); - if (this.gameStop !== null) { - this.gameStop(); + window.addEventListener("beforeunload", (e) => { + if (this.gameStop && !this.gameStop()) { + e.preventDefault(); + e.returnValue = ""; + return ""; } + console.log("Browser is closing"); }); const gutterAds = document.querySelector("gutter-ads");