Pause replay or SP game when opening Settings modal (#1530)

## Description:

Since the in-game Settings became their own modal in v24, it blocks game
control but the game goes on in the background. On mobile it is full
screen so you don't even notice the game still playing in the
background.

Of course players understand that a Multiplayer game will move on. But
for Single Player, the game mode played by beginners too, you'd expect
the game to be paused and are surprised when it isn't. Same goes for
Replays.

This PR fixes it:

- Pause when opening the in-game Settings modal during replay or single
player game.
- Unpause again when closing the Settings modal (if not already paused
before opening the Settings).
- The icon for pause/unpause isn't switched in GameRightSideBar during
this, as the sidebar is blurred in the background anyway.

## 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
- [ ] I have read and accepted the CLA agreement (only required once).

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

tryout33

---------

Co-authored-by: Drills Kibo <59177241+drillskibo@users.noreply.github.com>
This commit is contained in:
VariableVince
2025-08-11 19:29:27 +02:00
committed by evanpelle
parent e027983f41
commit ef4bb4feaa
2 changed files with 25 additions and 3 deletions
@@ -99,7 +99,9 @@ export class GameRightSidebar extends LitElement implements Layer {
}
private onSettingsButtonClick() {
this.eventBus.emit(new ShowSettingsModalEvent(true));
this.eventBus.emit(
new ShowSettingsModalEvent(true, this._isSinglePlayer, this.isPaused),
);
}
render() {
+22 -2
View File
@@ -1,5 +1,5 @@
import { html, LitElement } from "lit";
import { customElement, query, state } from "lit/decorators.js";
import { customElement, property, query, state } from "lit/decorators.js";
import structureIcon from "../../../../resources/images/CityIconWhite.svg";
import darkModeIcon from "../../../../resources/images/DarkModeIconWhite.svg";
import emojiIcon from "../../../../resources/images/EmojiIconWhite.svg";
@@ -12,11 +12,16 @@ import treeIcon from "../../../../resources/images/TreeIconWhite.svg";
import { EventBus } from "../../../core/EventBus";
import { UserSettings } from "../../../core/game/UserSettings";
import { AlternateViewEvent, RefreshGraphicsEvent } from "../../InputHandler";
import { PauseGameEvent } from "../../Transport";
import { translateText } from "../../Utils";
import { Layer } from "./Layer";
export class ShowSettingsModalEvent {
constructor(public readonly isVisible: boolean = true) {}
constructor(
public readonly isVisible: boolean = true,
public readonly shouldPause: boolean = false,
public readonly isPaused: boolean = false,
) {}
}
@customElement("settings-modal")
@@ -33,9 +38,18 @@ export class SettingsModal extends LitElement implements Layer {
@query(".modal-overlay")
private modalOverlay!: HTMLElement;
@property({ type: Boolean })
shouldPause = false;
@property({ type: Boolean })
wasPausedWhenOpened = false;
init() {
this.eventBus.on(ShowSettingsModalEvent, (event) => {
this.isVisible = event.isVisible;
this.shouldPause = event.shouldPause;
this.wasPausedWhenOpened = event.isPaused;
this.pauseGame(true);
});
}
@@ -81,6 +95,12 @@ export class SettingsModal extends LitElement implements Layer {
this.isVisible = false;
document.body.style.overflow = "";
this.requestUpdate();
this.pauseGame(false);
}
private pauseGame(pause: boolean) {
if (this.shouldPause && !this.wasPausedWhenOpened)
this.eventBus.emit(new PauseGameEvent(pause));
}
private onTerrainButtonClick() {