mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-07-14 12:04:51 +00:00
Handle confirmation on popstate event if player is active in a game (#2777)
Please merge it into v29, since in that version the back navigation out of a game is currently **broken** after switching from hash-based to path-based routing via #2740 ## Description: Protect against players accidentally leaving an active game by pressing the browser back button. Uses the same confirmation dialog as the game exit button. Partially handles issue #1877 (protects against back button, not closing tab or editing the URL directly). <img width="861" height="373" alt="image" src="https://github.com/user-attachments/assets/167cc137-6df3-44a7-a594-91ffd904857d" /> Partial credit to PR #2141 ## 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: deshack_82603
This commit is contained in:
@@ -69,7 +69,7 @@ export function joinLobby(
|
||||
lobbyConfig: LobbyConfig,
|
||||
onPrestart: () => void,
|
||||
onJoin: () => void,
|
||||
): () => void {
|
||||
): (force?: boolean) => 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;
|
||||
|
||||
let hasJoined = false;
|
||||
|
||||
const onconnect = () => {
|
||||
@@ -122,9 +124,15 @@ export function joinLobby(
|
||||
terrainLoad,
|
||||
terrainMapFileLoader,
|
||||
)
|
||||
.then((r) => r.start())
|
||||
.then((r) => {
|
||||
currentGameRunner = r;
|
||||
r.start();
|
||||
})
|
||||
.catch((e) => {
|
||||
console.error("error creating client game", e);
|
||||
|
||||
currentGameRunner = null;
|
||||
|
||||
const startingModal = document.querySelector(
|
||||
"game-starting-modal",
|
||||
) as HTMLElement;
|
||||
@@ -165,9 +173,19 @@ export function joinLobby(
|
||||
}
|
||||
};
|
||||
transport.connect(onconnect, onmessage);
|
||||
return () => {
|
||||
return (force: boolean = false) => {
|
||||
if (!force && currentGameRunner?.shouldPreventWindowClose()) {
|
||||
console.log("Player is active, prevent leaving game");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
console.log("leaving game");
|
||||
|
||||
currentGameRunner = null;
|
||||
transport.leaveGame();
|
||||
|
||||
return true;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -256,6 +274,21 @@ 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
|
||||
return !!this.myPlayer?.isAlive();
|
||||
}
|
||||
|
||||
private async saveGame(update: WinUpdate) {
|
||||
if (this.myPlayer === null) {
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user