[UI/UX] Fix overlapping in login screen (#6885)

* add method to disable interactivity

* add and fix comments
This commit is contained in:
Fabi 2025-12-22 04:14:33 +01:00 committed by GitHub
parent d9ddf6f24b
commit 350bd34793
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 61 additions and 0 deletions

View File

@ -1,4 +1,5 @@
import { globalScene } from "#app/global-scene";
import type { LoginRegisterInfoContainerUiHandler } from "#ui/login-register-info-container-ui-handler";
import type { SettingsDisplayUiHandler } from "#ui/settings-display-ui-handler";
import i18next from "i18next";
@ -8,6 +9,8 @@ const cancelHandler = () => {
// Reset the cursor to the current language, if in the settings menu
if (handler && typeof (handler as SettingsDisplayUiHandler).setOptionCursor === "function") {
(handler as SettingsDisplayUiHandler).setOptionCursor(-1, 0, true);
} else if (handler && typeof (handler as LoginRegisterInfoContainerUiHandler).setInteractive === "function") {
(handler as LoginRegisterInfoContainerUiHandler).setInteractive(true);
}
};

View File

@ -7,6 +7,7 @@ import type { ModalConfig } from "#ui/modal-ui-handler";
import { fixedInt } from "#utils/common";
import i18next from "i18next";
import JSZip from "jszip";
import type InputText from "phaser3-rex-plugins/plugins/inputtext";
interface BuildInteractableImageOpts {
scale?: number;
@ -36,6 +37,7 @@ export abstract class LoginRegisterInfoContainerUiHandler extends FormModalUiHan
private saveDownloadImage: Phaser.GameObjects.Image;
private changeLanguageImage: Phaser.GameObjects.Image;
private infoContainer: Phaser.GameObjects.Container;
private lastFocusedInput: InputText | null = null;
public override getReadableErrorMessage(error: string): string {
if (!error) {
@ -109,6 +111,7 @@ export abstract class LoginRegisterInfoContainerUiHandler extends FormModalUiHan
this.changeLanguageImage //
.setPositionRelative(this.infoContainer, 40, 0)
.on("pointerdown", () => {
this.setInteractive(false);
globalScene.ui.setOverlayMode(UiMode.OPTION_SELECT, {
options: languageOptions,
maxOptions: 7,
@ -154,6 +157,7 @@ export abstract class LoginRegisterInfoContainerUiHandler extends FormModalUiHan
const handler = () => {
globalScene.ui.revertMode();
this.infoContainer.disableInteractive();
this.setInteractive(true);
return true;
};
@ -162,6 +166,7 @@ export abstract class LoginRegisterInfoContainerUiHandler extends FormModalUiHan
}
globalScene.ui.setOverlayMode(UiMode.OPTION_SELECT, { options, delay: 1000 });
this.setInteractive(false);
this.infoContainer.setInteractive(
new Phaser.Geom.Rectangle(0, 0, globalScene.game.canvas.width, globalScene.game.canvas.height),
Phaser.Geom.Rectangle.Contains,
@ -230,4 +235,45 @@ export abstract class LoginRegisterInfoContainerUiHandler extends FormModalUiHan
return img;
}
/**
* Enable or disable interactivity on all interactive objects.
* @param active - Whether to enable or disable interactivity
*/
public setInteractive(active: boolean): void {
const objects = [...this.buttonBgs, this.usernameInfoImage, this.saveDownloadImage, this.changeLanguageImage];
for (const obj of objects) {
if (active) {
obj.setInteractive();
} else {
obj.disableInteractive();
if (obj instanceof Phaser.GameObjects.Image) {
obj.clearTint();
}
}
}
this.setInteractiveInputs(active);
this.setMouseCursorStyle("default");
}
/**
* Enable or disable interactivity on all input fields.
* @param active - Whether to enable or disable interactivity
*/
private setInteractiveInputs(active: boolean): void {
if (active) {
// `setFocus` doesn't focus without a timeout
setTimeout(() => {
this.lastFocusedInput?.setFocus();
this.lastFocusedInput = null;
}, 50);
} else {
this.lastFocusedInput = this.inputs.find(input => input.isFocused) ?? null;
}
for (const input of this.inputs) {
(input.node as HTMLInputElement).disabled = !active;
}
}
}

View File

@ -56,6 +56,18 @@ export abstract class OAuthProvidersUiHandler extends LoginRegisterInfoContainer
this.getUi().add(this.externalPartyContainer);
}
public override setInteractive(active: boolean): void {
super.setInteractive(active);
const externalPartyIcons = this.externalPartyContainer.list.filter(obj => obj instanceof Phaser.GameObjects.Image);
for (const obj of externalPartyIcons) {
if (active) {
obj.setInteractive();
} else {
obj.disableInteractive();
}
}
}
protected processExternalProvider(): void {
const titleX = 22;
this.externalPartyTitle