diff --git a/src/ui/admin-ui-handler.ts b/src/ui/admin-ui-handler.ts index 4ccdd9322f9..c59ff0c6dea 100644 --- a/src/ui/admin-ui-handler.ts +++ b/src/ui/admin-ui-handler.ts @@ -2,17 +2,19 @@ import BattleScene from "#app/battle-scene"; import { ModalConfig } from "./modal-ui-handler"; import { Mode } from "./ui"; import * as Utils from "../utils"; -import { FormModalUiHandler, InputFieldConfigs } from "./form-modal-ui-handler"; +import { FormModalUiHandler, InputFieldConfig } from "./form-modal-ui-handler"; import { Button } from "#app/enums/buttons"; import { TextStyle } from "./text"; export default class AdminUiHandler extends FormModalUiHandler { private adminMode: AdminMode; - private adminResult: AdminSearchInfo; // this is the username that we're looking for + private adminResult: AdminSearchInfo; private config: ModalConfig; - private readonly httpUserNotFoundErrorCode: number = 404; // this is the http response from the server when a username isn't found in the server. This has to be the same error the server is giving + private readonly buttonGap = 10; + // http response from the server when a username isn't found in the server + private readonly httpUserNotFoundErrorCode: number = 404; private readonly ERR_REQUIRED_FIELD = (field: string) => { if (field === "username") { return `${Utils.formatText(field)} is required`; @@ -20,7 +22,8 @@ export default class AdminUiHandler extends FormModalUiHandler { return `${Utils.formatText(field)} Id is required`; } }; - private readonly SUCCESS_SERVICE_MODE = (service: string, mode: string) => { // this returns a string saying whether a username has been successfully linked/unlinked to discord/google + // returns a string saying whether a username has been successfully linked/unlinked to discord/google + private readonly SUCCESS_SERVICE_MODE = (service: string, mode: string) => { return `Username and ${service} successfully ${mode.toLowerCase()}ed`; }; private readonly ERR_USERNAME_NOT_FOUND: string = "Username not found!"; @@ -30,36 +33,19 @@ export default class AdminUiHandler extends FormModalUiHandler { super(scene, mode); } - setup(): void { - super.setup(); - } - - getModalTitle(config?: ModalConfig): string { + override getModalTitle(): string { return "Admin panel"; } - getFields(config?: ModalConfig): string[] { - switch (this.adminMode) { - case AdminMode.LINK: - return [ "Username", "Discord ID" ]; - case AdminMode.SEARCH: - return [ "Username" ]; - case AdminMode.ADMIN: - return [ "Username", "Discord ID", "Google ID", "Last played", "Registered" ]; - default: - return [ "" ]; - } - } - - getWidth(config?: ModalConfig): number { + override getWidth(): number { return this.adminMode === AdminMode.ADMIN ? 180 : 160; } - getMargin(config?: ModalConfig): [number, number, number, number] { + override getMargin(): [number, number, number, number] { return [ 0, 0, 0, 0 ]; } - getButtonLabels(config?: ModalConfig): string[] { + override getButtonLabels(): string[] { switch (this.adminMode) { case AdminMode.LINK: return [ "Link Account", "Cancel" ]; @@ -72,19 +58,26 @@ export default class AdminUiHandler extends FormModalUiHandler { } } - override getInputFieldConfigs(adminResult: AdminSearchInfo): InputFieldConfigs[] { - const inputFieldConfigs: InputFieldConfigs[] = []; - adminResult = adminResult ?? { username: "", discordId: "", googleId: "", lastLoggedIn: "", registered: "" }; // we use this to check what fields we need to be locking, if any - const adminKeys = Object.keys(adminResult); - const fields = this.getFields(); - const lockedFields: string[] = [ "username", "lastLoggedIn", "registered" ]; // this is the list of fields that will always be locked when this.adminMode === AdminMode.ADMIN - fields.forEach((field, i) => { - const readOnly = (this.adminMode === AdminMode.ADMIN && (lockedFields.includes(adminKeys[i]) || adminResult[adminKeys[i]] !== "")); - inputFieldConfigs.push({ - label: field, - isReadOnly: readOnly - }); - }); + override getInputFieldConfigs(): InputFieldConfig[] { + const inputFieldConfigs: InputFieldConfig[] = []; + switch (this.adminMode) { + case AdminMode.LINK: + inputFieldConfigs.push( { label: "Username" }); + inputFieldConfigs.push( { label: "Discord ID" }); + break; + case AdminMode.SEARCH: + inputFieldConfigs.push( { label: "Username" }); + break; + case AdminMode.ADMIN: + const adminResult = this.adminResult ?? { username: "", discordId: "", googleId: "", lastLoggedIn: "", registered: "" }; + // Discord and Google ID fields that are not empty get locked, other fields are all locked + inputFieldConfigs.push( { label: "Username", isReadOnly: true }); + inputFieldConfigs.push( { label: "Discord ID", isReadOnly: adminResult.discordId !== "" }); + inputFieldConfigs.push( { label: "Google ID", isReadOnly: adminResult.googleId !== "" }); + inputFieldConfigs.push( { label: "Last played", isReadOnly: true }); + inputFieldConfigs.push( { label: "Registered", isReadOnly: true }); + break; + } return inputFieldConfigs; } @@ -103,10 +96,10 @@ export default class AdminUiHandler extends FormModalUiHandler { this.adminResult = args[2] ?? { username: "", discordId: "", googleId: "", lastLoggedIn: "", registered: "" }; // admin result, if any const isMessageError = args[3]; // is the message shown a success or error - const fields = this.getFields(); + const fields = this.getInputFieldConfigs(); const hasTitle = !!this.getModalTitle(); - this.updateFields(this.getInputFieldConfigs(this.adminResult), hasTitle); + this.updateFields(fields, hasTitle); this.updateContainer(this.config); const labels = this.getButtonLabels(); @@ -164,7 +157,11 @@ export default class AdminUiHandler extends FormModalUiHandler { showMessage(message: string, adminResult: AdminSearchInfo, isError: boolean) { this.scene.ui.setMode(Mode.ADMIN, Object.assign(this.config, { errorMessage: message?.trim() }), this.adminMode, adminResult, isError); - this.scene.ui.playError(); + if (isError) { + this.scene.ui.playError(); + } else { + this.scene.ui.playSelect(); + } } // this is used to update the fields' text when loading a new admin ui handler. It uses the adminResult to update the input text fields depending on the adminMode @@ -359,7 +356,7 @@ export function getAdminModeName(adminMode: AdminMode): string { } } -export interface AdminSearchInfo { +interface AdminSearchInfo { username: string; discordId: string; googleId: string; diff --git a/src/ui/form-modal-ui-handler.ts b/src/ui/form-modal-ui-handler.ts index 7c791f02709..9a92804fadb 100644 --- a/src/ui/form-modal-ui-handler.ts +++ b/src/ui/form-modal-ui-handler.ts @@ -29,15 +29,14 @@ export abstract class FormModalUiHandler extends ModalUiHandler { this.formLabels = []; } - abstract getFields(): string[]; - - // this function takes any args and uses it to make an array of InputFieldConfigs, which has extra support for the input text field - // It currently has support for a field's label, whether it's a password field, and whether the field should be read only, but by expanding the InputFieldConfig interface - // any extra details can be passed on to the field during creation - abstract getInputFieldConfigs(args?: any): InputFieldConfigs[]; + /** + * Get all information for each field to display in the modal + * @returns array of {@linkcode InputFieldConfig} + */ + abstract getInputFieldConfigs(): InputFieldConfig[]; getHeight(config?: ModalConfig): number { - return 20 * this.getFields().length + (this.getModalTitle() ? 26 : 0) + ((config as FormModalConfig)?.errorMessage ? 12 : 0) + this.getButtonTopMargin() + 28; + return 20 * this.getInputFieldConfigs().length + (this.getModalTitle() ? 26 : 0) + ((config as FormModalConfig)?.errorMessage ? 12 : 0) + this.getButtonTopMargin() + 28; } getReadableErrorMessage(error: string): string { @@ -66,7 +65,7 @@ export abstract class FormModalUiHandler extends ModalUiHandler { this.modalContainer.add(this.errorMessage); } - updateFields(fieldsConfig: InputFieldConfigs[], hasTitle: boolean) { + updateFields(fieldsConfig: InputFieldConfig[], hasTitle: boolean) { this.inputContainers = []; this.inputs = []; this.formLabels = []; @@ -169,7 +168,7 @@ export abstract class FormModalUiHandler extends ModalUiHandler { } } -export interface InputFieldConfigs { +export interface InputFieldConfig { label: string, isPassword?: boolean, isReadOnly?: boolean diff --git a/src/ui/login-form-ui-handler.ts b/src/ui/login-form-ui-handler.ts index 45b67fa490a..46f4881e930 100644 --- a/src/ui/login-form-ui-handler.ts +++ b/src/ui/login-form-ui-handler.ts @@ -1,4 +1,4 @@ -import { FormModalUiHandler, InputFieldConfigs } from "./form-modal-ui-handler"; +import { FormModalUiHandler, InputFieldConfig } from "./form-modal-ui-handler"; import { ModalConfig } from "./modal-ui-handler"; import * as Utils from "../utils"; import { Mode } from "./ui"; @@ -75,10 +75,6 @@ export default class LoginFormUiHandler extends FormModalUiHandler { return i18next.t("menu:login"); } - override getFields(_config?: ModalConfig): string[] { - return [ i18next.t("menu:username"), i18next.t("menu:password") ]; - } - override getWidth(_config?: ModalConfig): number { return 160; } @@ -114,15 +110,10 @@ export default class LoginFormUiHandler extends FormModalUiHandler { return super.getReadableErrorMessage(error); } - override getInputFieldConfigs(): InputFieldConfigs[] { - const inputFieldConfigs: InputFieldConfigs[] = []; - const fields = this.getFields(); - fields.forEach((field, i) => { - inputFieldConfigs.push({ - label: field, - isPassword: field.includes(i18next.t("menu:password")) || field.includes(i18next.t("menu:confirmPassword")) - }); - }); + override getInputFieldConfigs(): InputFieldConfig[] { + const inputFieldConfigs: InputFieldConfig[] = []; + inputFieldConfigs.push({ label: i18next.t("menu:username") }); + inputFieldConfigs.push({ label: i18next.t("menu:password"), isPassword: true }); return inputFieldConfigs; } diff --git a/src/ui/registration-form-ui-handler.ts b/src/ui/registration-form-ui-handler.ts index 0cf50e7d55c..ec7eb91a81c 100644 --- a/src/ui/registration-form-ui-handler.ts +++ b/src/ui/registration-form-ui-handler.ts @@ -1,4 +1,4 @@ -import { FormModalUiHandler, InputFieldConfigs } from "./form-modal-ui-handler"; +import { FormModalUiHandler, InputFieldConfig } from "./form-modal-ui-handler"; import { ModalConfig } from "./modal-ui-handler"; import * as Utils from "../utils"; import { Mode } from "./ui"; @@ -24,10 +24,6 @@ export default class RegistrationFormUiHandler extends FormModalUiHandler { return i18next.t("menu:register"); } - getFields(config?: ModalConfig): string[] { - return [ i18next.t("menu:username"), i18next.t("menu:password"), i18next.t("menu:confirmPassword") ]; - } - getWidth(config?: ModalConfig): number { return 160; } @@ -61,15 +57,11 @@ export default class RegistrationFormUiHandler extends FormModalUiHandler { return super.getReadableErrorMessage(error); } - override getInputFieldConfigs(): InputFieldConfigs[] { - const inputFieldConfigs: InputFieldConfigs[] = []; - const fields = this.getFields(); - fields.forEach((field, i) => { - inputFieldConfigs.push({ - label: field, - isPassword: field.includes(i18next.t("menu:password")) || field.includes(i18next.t("menu:confirmPassword")) - }); - }); + override getInputFieldConfigs(): InputFieldConfig[] { + const inputFieldConfigs: InputFieldConfig[] = []; + inputFieldConfigs.push({ label: i18next.t("menu:username") }); + inputFieldConfigs.push({ label: i18next.t("menu:password"), isPassword: true }); + inputFieldConfigs.push({ label: i18next.t("menu:confirmPassword"), isPassword: true }); return inputFieldConfigs; } diff --git a/src/ui/rename-form-ui-handler.ts b/src/ui/rename-form-ui-handler.ts index 2c97d8a03a1..6e4c4c6809d 100644 --- a/src/ui/rename-form-ui-handler.ts +++ b/src/ui/rename-form-ui-handler.ts @@ -1,4 +1,4 @@ -import { FormModalUiHandler, InputFieldConfigs } from "./form-modal-ui-handler"; +import { FormModalUiHandler, InputFieldConfig } from "./form-modal-ui-handler"; import { ModalConfig } from "./modal-ui-handler"; import i18next from "i18next"; import { PlayerPokemon } from "#app/field/pokemon"; @@ -8,10 +8,6 @@ export default class RenameFormUiHandler extends FormModalUiHandler { return i18next.t("menu:renamePokemon"); } - getFields(config?: ModalConfig): string[] { - return [ i18next.t("menu:nickname") ]; - } - getWidth(config?: ModalConfig): number { return 160; } @@ -33,15 +29,8 @@ export default class RenameFormUiHandler extends FormModalUiHandler { return super.getReadableErrorMessage(error); } - override getInputFieldConfigs(): InputFieldConfigs[] { - const inputFieldConfigs: InputFieldConfigs[] = []; - const fields = this.getFields(); - fields.forEach((field, i) => { - inputFieldConfigs.push({ - label: field - }); - }); - return inputFieldConfigs; + override getInputFieldConfigs(): InputFieldConfig[] { + return [{ label: i18next.t("menu:nickname") }]; } show(args: any[]): boolean { diff --git a/src/ui/test-dialogue-ui-handler.ts b/src/ui/test-dialogue-ui-handler.ts index 3edabcea824..bf0e7f6723f 100644 --- a/src/ui/test-dialogue-ui-handler.ts +++ b/src/ui/test-dialogue-ui-handler.ts @@ -1,4 +1,4 @@ -import { FormModalUiHandler, InputFieldConfigs } from "./form-modal-ui-handler"; +import { FormModalUiHandler, InputFieldConfig } from "./form-modal-ui-handler"; import { ModalConfig } from "./modal-ui-handler"; import i18next from "i18next"; import { PlayerPokemon } from "#app/field/pokemon"; @@ -43,10 +43,6 @@ export default class TestDialogueUiHandler extends FormModalUiHandler { return "Test Dialogue"; } - getFields(config?: ModalConfig): string[] { - return [ "Dialogue" ]; - } - getWidth(config?: ModalConfig): number { return 300; } @@ -68,15 +64,8 @@ export default class TestDialogueUiHandler extends FormModalUiHandler { return super.getReadableErrorMessage(error); } - override getInputFieldConfigs(): InputFieldConfigs[] { - const inputFieldConfigs: InputFieldConfigs[] = []; - const fields = this.getFields(); - fields.forEach((field, i) => { - inputFieldConfigs.push({ - label: field - }); - }); - return inputFieldConfigs; + override getInputFieldConfigs(): InputFieldConfig[] { + return [{ label: "Dialogue" }]; } show(args: any[]): boolean {