show a message when asking for confirmation in settings

This commit is contained in:
Moka 2024-11-19 20:41:56 +01:00
parent a9ba3e56ac
commit 341332c55d
3 changed files with 84 additions and 56 deletions

View File

@ -730,16 +730,15 @@ export class GameData {
* Saves a setting to localStorage * Saves a setting to localStorage
* @param setting string ideally of SettingKeys * @param setting string ideally of SettingKeys
* @param valueIndex index of the setting's option * @param valueIndex index of the setting's option
* @param fromSettings whether the function was called from the settings menu
* @returns true * @returns true
*/ */
public saveSetting(setting: string, valueIndex: integer, fromSettings?: boolean): boolean { public saveSetting(setting: string, valueIndex: integer): boolean {
let settings: object = {}; let settings: object = {};
if (localStorage.hasOwnProperty("settings")) { if (localStorage.hasOwnProperty("settings")) {
settings = JSON.parse(localStorage.getItem("settings")!); // TODO: is this bang correct? settings = JSON.parse(localStorage.getItem("settings")!); // TODO: is this bang correct?
} }
setSetting(this.scene, setting, valueIndex, fromSettings); setSetting(this.scene, setting, valueIndex);
settings[setting] = valueIndex; settings[setting] = valueIndex;
settings["gameVersion"] = this.scene.game.config.gameVersion; settings["gameVersion"] = this.scene.game.config.gameVersion;

View File

@ -1,16 +1,15 @@
import { Mode } from "#app/ui/ui"; import { Mode } from "#app/ui/ui";
import i18next from "i18next"; import i18next from "i18next";
import BattleScene from "../../battle-scene"; import BattleScene from "#app/battle-scene";
import { hasTouchscreen } from "../../touch-controls"; import { hasTouchscreen } from "#app/touch-controls";
import { updateWindowType } from "../../ui/ui-theme"; import { updateWindowType } from "#app/ui/ui-theme";
import { CandyUpgradeNotificationChangedEvent } from "../../events/battle-scene"; import { CandyUpgradeNotificationChangedEvent } from "#app/events/battle-scene";
import SettingsUiHandler from "#app/ui/settings/settings-ui-handler"; import SettingsUiHandler from "#app/ui/settings/settings-ui-handler";
import { EaseType } from "#enums/ease-type"; import { EaseType } from "#enums/ease-type";
import { MoneyFormat } from "#enums/money-format"; import { MoneyFormat } from "#enums/money-format";
import { PlayerGender } from "#enums/player-gender"; import { PlayerGender } from "#enums/player-gender";
import { getIsInitialized, initI18n } from "#app/plugins/i18n"; import { getIsInitialized, initI18n } from "#app/plugins/i18n";
import { ShopCursorTarget } from "#app/enums/shop-cursor-target"; import { ShopCursorTarget } from "#app/enums/shop-cursor-target";
import { OptionSelectConfig } from "#app/ui/abstact-option-select-ui-handler";
function getTranslation(key: string): string { function getTranslation(key: string): string {
if (!getIsInitialized()) { if (!getIsInitialized()) {
@ -45,6 +44,7 @@ const OFF_ON: SettingOption[] = [
label: i18next.t("settings:on") label: i18next.t("settings:on")
} }
]; ];
const AUTO_DISABLED: SettingOption[] = [ const AUTO_DISABLED: SettingOption[] = [
{ {
value: "Auto", value: "Auto",
@ -56,6 +56,19 @@ const AUTO_DISABLED: SettingOption[] = [
} }
]; ];
const TOUCH_CONTROLS_OPTIONS: SettingOption[] = [
{
value: "Auto",
label: i18next.t("settings:auto")
},
{
value: "Disabled",
label: i18next.t("settings:disabled"),
needConfirmation: true,
confirmationMessage: i18next.t("settings:confirmDisableTouch")
}
];
const SHOP_CURSOR_TARGET_OPTIONS: SettingOption[] = [ const SHOP_CURSOR_TARGET_OPTIONS: SettingOption[] = [
{ {
value: "Rewards", value: "Rewards",
@ -101,7 +114,9 @@ export enum SettingType {
type SettingOption = { type SettingOption = {
value: string, value: string,
label: string label: string,
needConfirmation?: boolean,
confirmationMessage?: string
}; };
export interface Setting { export interface Setting {
@ -355,7 +370,7 @@ export const Setting: Array<Setting> = [
{ {
key: SettingKeys.Touch_Controls, key: SettingKeys.Touch_Controls,
label: i18next.t("settings:touchControls"), label: i18next.t("settings:touchControls"),
options: AUTO_DISABLED, options: TOUCH_CONTROLS_OPTIONS,
default: 0, default: 0,
type: SettingType.GENERAL, type: SettingType.GENERAL,
isHidden: () => !hasTouchscreen() isHidden: () => !hasTouchscreen()
@ -698,11 +713,9 @@ export function resetSettings(scene: BattleScene) {
* @param scene current BattleScene * @param scene current BattleScene
* @param setting string ideally from SettingKeys * @param setting string ideally from SettingKeys
* @param value value to update setting with * @param value value to update setting with
* @param fromSettings whether the function was called from the settings menu, meaning it is possible
* to access the handler and add extra interactions for the player
* @returns true if successful, false if not * @returns true if successful, false if not
*/ */
export function setSetting(scene: BattleScene, setting: string, value: integer, fromSettings?: boolean): boolean { export function setSetting(scene: BattleScene, setting: string, value: integer): boolean {
const index: number = settingIndex(setting); const index: number = settingIndex(setting);
if (index === -1) { if (index === -1) {
return false; return false;
@ -836,43 +849,10 @@ export function setSetting(scene: BattleScene, setting: string, value: integer,
} }
break; break;
case SettingKeys.Touch_Controls: case SettingKeys.Touch_Controls:
const setTouchControlsVisibility = (scene: BattleScene) => { scene.enableTouchControls = Setting[index].options[value].value !== "Disabled" && hasTouchscreen();
const touchControls = document.getElementById("touchControls"); const touchControls = document.getElementById("touchControls");
if (touchControls) { if (touchControls) {
touchControls.classList.toggle("visible", scene.enableTouchControls); touchControls.classList.toggle("visible", scene.enableTouchControls);
}
};
if (fromSettings && Setting[index].options[value].value === "Disabled") {
const optionsConfig: OptionSelectConfig = {
yOffset: 24,
delay: 1000,
options: [
{
label: i18next.t("settings:disableTouchControls"),
handler: () => {
scene.ui.revertMode();
scene.enableTouchControls = false;
setTouchControlsVisibility(scene);
return true;
}
},
{
label: i18next.t("settings:cancel"),
handler: () => {
scene.ui.revertMode();
// Put the option cursor back to "Auto" and save that
(scene.ui.getHandler() as SettingsUiHandler).setOptionCursor(-1, 0, true);
return true;
}
}
]
};
// Player moved to the "Disabled" option, show a confirmation window, with a 1s delay before being able to confirm
scene.ui.setOverlayMode(Mode.OPTION_SELECT, optionsConfig);
} else {
scene.enableTouchControls = Setting[index].options[value].value !== "Disabled" && hasTouchscreen();
setTouchControlsVisibility(scene);
} }
break; break;
case SettingKeys.Vibration: case SettingKeys.Vibration:
@ -883,7 +863,7 @@ export function setSetting(scene: BattleScene, setting: string, value: integer,
break; break;
case SettingKeys.Language: case SettingKeys.Language:
if (value) { if (value) {
if (fromSettings) { if (scene.ui) {
const cancelHandler = () => { const cancelHandler = () => {
scene.ui.revertMode(); scene.ui.revertMode();
(scene.ui.getHandler() as SettingsUiHandler).setOptionCursor(-1, 0, true); (scene.ui.getHandler() as SettingsUiHandler).setOptionCursor(-1, 0, true);

View File

@ -1,7 +1,7 @@
import BattleScene from "#app/battle-scene"; import BattleScene from "#app/battle-scene";
import { TextStyle, addTextObject } from "#app/ui/text"; import { TextStyle, addTextObject } from "#app/ui/text";
import { Mode } from "#app/ui/ui"; import { Mode } from "#app/ui/ui";
import UiHandler from "#app/ui/ui-handler"; import MessageUiHandler from "#app/ui/message-ui-handler";
import { addWindow } from "#app/ui/ui-theme"; import { addWindow } from "#app/ui/ui-theme";
import { ScrollBar } from "#app/ui/scroll-bar"; import { ScrollBar } from "#app/ui/scroll-bar";
import { Button } from "#enums/buttons"; import { Button } from "#enums/buttons";
@ -14,9 +14,10 @@ import i18next from "i18next";
/** /**
* Abstract class for handling UI elements related to settings. * Abstract class for handling UI elements related to settings.
*/ */
export default class AbstractSettingsUiHandler extends UiHandler { export default class AbstractSettingsUiHandler extends MessageUiHandler {
private settingsContainer: Phaser.GameObjects.Container; private settingsContainer: Phaser.GameObjects.Container;
private optionsContainer: Phaser.GameObjects.Container; private optionsContainer: Phaser.GameObjects.Container;
private messageBoxContainer: Phaser.GameObjects.Container;
private navigationContainer: NavigationMenu; private navigationContainer: NavigationMenu;
private scrollCursor: number; private scrollCursor: number;
@ -134,6 +135,22 @@ export default class AbstractSettingsUiHandler extends UiHandler {
this.scrollBar = new ScrollBar(this.scene, this.optionsBg.width - 9, this.optionsBg.y + 5, 4, this.optionsBg.height - 11, this.rowsToDisplay); this.scrollBar = new ScrollBar(this.scene, this.optionsBg.width - 9, this.optionsBg.y + 5, 4, this.optionsBg.height - 11, this.rowsToDisplay);
this.scrollBar.setTotalRows(this.settings.length); this.scrollBar.setTotalRows(this.settings.length);
// Single-line message box
this.messageBoxContainer = this.scene.add.container(0, this.scene.scaledCanvas.height);
this.messageBoxContainer.setName("settings-message-box");
this.messageBoxContainer.setVisible(false);
const settingsMessageBox = addWindow(this.scene, 0, -1, this.scene.scaledCanvas.width - 2, 28);
settingsMessageBox.setOrigin(0, 1);
this.messageBoxContainer.add(settingsMessageBox);
const messageText = addTextObject(this.scene, 8, -8, "", TextStyle.WINDOW);
messageText.setOrigin(0, 1);
messageText.setName("settings-message");
this.messageBoxContainer.add(messageText);
this.message = messageText;
this.settingsContainer.add(this.optionsBg); this.settingsContainer.add(this.optionsBg);
this.settingsContainer.add(this.scrollBar); this.settingsContainer.add(this.scrollBar);
this.settingsContainer.add(this.navigationContainer); this.settingsContainer.add(this.navigationContainer);
@ -143,6 +160,7 @@ export default class AbstractSettingsUiHandler extends UiHandler {
this.settingsContainer.add(iconCancel); this.settingsContainer.add(iconCancel);
this.settingsContainer.add(actionText); this.settingsContainer.add(actionText);
this.settingsContainer.add(cancelText); this.settingsContainer.add(cancelText);
this.settingsContainer.add(this.messageBoxContainer);
ui.add(this.settingsContainer); ui.add(this.settingsContainer);
@ -350,9 +368,34 @@ export default class AbstractSettingsUiHandler extends UiHandler {
newValueLabel.setShadowColor(this.getTextColor(TextStyle.SETTINGS_SELECTED, true)); newValueLabel.setShadowColor(this.getTextColor(TextStyle.SETTINGS_SELECTED, true));
if (save) { if (save) {
this.scene.gameData.saveSetting(setting.key, cursor, true); const saveSetting = () => {
if (this.reloadSettings.includes(setting)) { this.scene.gameData.saveSetting(setting.key, cursor);
this.reloadRequired = true; if (setting.requireReload) {
this.reloadRequired = true;
}
};
// For settings that ask for confirmation
if (setting.options[cursor].needConfirmation) {
const confirmUpdateSetting = () => {
this.scene.ui.revertMode();
this.showText("");
saveSetting();
};
const cancelUpdateSetting = () => {
this.scene.ui.revertMode();
this.showText("");
// Put the cursor back to its previous position without saving or asking for confirmation again
this.setOptionCursor(settingIndex, lastCursor, false);
};
const confirmationMessage = setting.options[cursor].confirmationMessage ?? i18next.t("settings:defaultConfirmMessage");
this.scene.ui.showText(confirmationMessage, null, () => {
const yOffset = 48 - this.messageBoxContainer.getAt(0).height;
this.scene.ui.setOverlayMode(Mode.CONFIRM, confirmUpdateSetting, cancelUpdateSetting, null, null, yOffset, 1000);
});
} else {
saveSetting();
} }
} }
@ -419,4 +462,10 @@ export default class AbstractSettingsUiHandler extends UiHandler {
} }
this.cursorObj = null; this.cursorObj = null;
} }
showText(text: string, delay?: integer, callback?: Function, callbackDelay?: integer, prompt?: boolean, promptDelay?: integer) {
console.log("HELLO");
this.messageBoxContainer.setVisible(!!text?.length);
super.showText(text, delay, callback, callbackDelay, prompt, promptDelay);
}
} }