Merge pull request #3 from MokaStitcher/admin

Cleanup FormUiHandler a little
This commit is contained in:
Opaque02 2024-10-19 19:00:03 +10:00 committed by GitHub
commit 65c3748f95
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 64 additions and 107 deletions

View File

@ -2,17 +2,19 @@ import BattleScene from "#app/battle-scene";
import { ModalConfig } from "./modal-ui-handler"; import { ModalConfig } from "./modal-ui-handler";
import { Mode } from "./ui"; import { Mode } from "./ui";
import * as Utils from "../utils"; 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 { Button } from "#app/enums/buttons";
import { TextStyle } from "./text"; import { TextStyle } from "./text";
export default class AdminUiHandler extends FormModalUiHandler { export default class AdminUiHandler extends FormModalUiHandler {
private adminMode: AdminMode; private adminMode: AdminMode;
private adminResult: AdminSearchInfo; // this is the username that we're looking for private adminResult: AdminSearchInfo;
private config: ModalConfig; 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; 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) => { private readonly ERR_REQUIRED_FIELD = (field: string) => {
if (field === "username") { if (field === "username") {
return `${Utils.formatText(field)} is required`; return `${Utils.formatText(field)} is required`;
@ -20,7 +22,8 @@ export default class AdminUiHandler extends FormModalUiHandler {
return `${Utils.formatText(field)} Id is required`; 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`; return `Username and ${service} successfully ${mode.toLowerCase()}ed`;
}; };
private readonly ERR_USERNAME_NOT_FOUND: string = "Username not found!"; private readonly ERR_USERNAME_NOT_FOUND: string = "Username not found!";
@ -30,36 +33,19 @@ export default class AdminUiHandler extends FormModalUiHandler {
super(scene, mode); super(scene, mode);
} }
setup(): void { override getModalTitle(): string {
super.setup();
}
getModalTitle(config?: ModalConfig): string {
return "Admin panel"; return "Admin panel";
} }
getFields(config?: ModalConfig): string[] { override getWidth(): number {
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 {
return this.adminMode === AdminMode.ADMIN ? 180 : 160; 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 ]; return [ 0, 0, 0, 0 ];
} }
getButtonLabels(config?: ModalConfig): string[] { override getButtonLabels(): string[] {
switch (this.adminMode) { switch (this.adminMode) {
case AdminMode.LINK: case AdminMode.LINK:
return [ "Link Account", "Cancel" ]; return [ "Link Account", "Cancel" ];
@ -72,19 +58,26 @@ export default class AdminUiHandler extends FormModalUiHandler {
} }
} }
override getInputFieldConfigs(adminResult: AdminSearchInfo): InputFieldConfigs[] { override getInputFieldConfigs(): InputFieldConfig[] {
const inputFieldConfigs: InputFieldConfigs[] = []; const inputFieldConfigs: InputFieldConfig[] = [];
adminResult = adminResult ?? { username: "", discordId: "", googleId: "", lastLoggedIn: "", registered: "" }; // we use this to check what fields we need to be locking, if any switch (this.adminMode) {
const adminKeys = Object.keys(adminResult); case AdminMode.LINK:
const fields = this.getFields(); inputFieldConfigs.push( { label: "Username" });
const lockedFields: string[] = [ "username", "lastLoggedIn", "registered" ]; // this is the list of fields that will always be locked when this.adminMode === AdminMode.ADMIN inputFieldConfigs.push( { label: "Discord ID" });
fields.forEach((field, i) => { break;
const readOnly = (this.adminMode === AdminMode.ADMIN && (lockedFields.includes(adminKeys[i]) || adminResult[adminKeys[i]] !== "")); case AdminMode.SEARCH:
inputFieldConfigs.push({ inputFieldConfigs.push( { label: "Username" });
label: field, break;
isReadOnly: readOnly 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; 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 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 isMessageError = args[3]; // is the message shown a success or error
const fields = this.getFields(); const fields = this.getInputFieldConfigs();
const hasTitle = !!this.getModalTitle(); const hasTitle = !!this.getModalTitle();
this.updateFields(this.getInputFieldConfigs(this.adminResult), hasTitle); this.updateFields(fields, hasTitle);
this.updateContainer(this.config); this.updateContainer(this.config);
const labels = this.getButtonLabels(); const labels = this.getButtonLabels();
@ -164,7 +157,11 @@ export default class AdminUiHandler extends FormModalUiHandler {
showMessage(message: string, adminResult: AdminSearchInfo, isError: boolean) { 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.setMode(Mode.ADMIN, Object.assign(this.config, { errorMessage: message?.trim() }), this.adminMode, adminResult, isError);
if (isError) {
this.scene.ui.playError(); 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 // 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; username: string;
discordId: string; discordId: string;
googleId: string; googleId: string;

View File

@ -29,15 +29,14 @@ export abstract class FormModalUiHandler extends ModalUiHandler {
this.formLabels = []; this.formLabels = [];
} }
abstract getFields(): string[]; /**
* Get all information for each field to display in the modal
// this function takes any args and uses it to make an array of InputFieldConfigs, which has extra support for the input text field * @returns array of {@linkcode InputFieldConfig}
// 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(): InputFieldConfig[];
abstract getInputFieldConfigs(args?: any): InputFieldConfigs[];
getHeight(config?: ModalConfig): number { 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 { getReadableErrorMessage(error: string): string {
@ -66,7 +65,7 @@ export abstract class FormModalUiHandler extends ModalUiHandler {
this.modalContainer.add(this.errorMessage); this.modalContainer.add(this.errorMessage);
} }
updateFields(fieldsConfig: InputFieldConfigs[], hasTitle: boolean) { updateFields(fieldsConfig: InputFieldConfig[], hasTitle: boolean) {
this.inputContainers = []; this.inputContainers = [];
this.inputs = []; this.inputs = [];
this.formLabels = []; this.formLabels = [];
@ -169,7 +168,7 @@ export abstract class FormModalUiHandler extends ModalUiHandler {
} }
} }
export interface InputFieldConfigs { export interface InputFieldConfig {
label: string, label: string,
isPassword?: boolean, isPassword?: boolean,
isReadOnly?: boolean isReadOnly?: boolean

View File

@ -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 { ModalConfig } from "./modal-ui-handler";
import * as Utils from "../utils"; import * as Utils from "../utils";
import { Mode } from "./ui"; import { Mode } from "./ui";
@ -75,10 +75,6 @@ export default class LoginFormUiHandler extends FormModalUiHandler {
return i18next.t("menu:login"); return i18next.t("menu:login");
} }
override getFields(_config?: ModalConfig): string[] {
return [ i18next.t("menu:username"), i18next.t("menu:password") ];
}
override getWidth(_config?: ModalConfig): number { override getWidth(_config?: ModalConfig): number {
return 160; return 160;
} }
@ -114,15 +110,10 @@ export default class LoginFormUiHandler extends FormModalUiHandler {
return super.getReadableErrorMessage(error); return super.getReadableErrorMessage(error);
} }
override getInputFieldConfigs(): InputFieldConfigs[] { override getInputFieldConfigs(): InputFieldConfig[] {
const inputFieldConfigs: InputFieldConfigs[] = []; const inputFieldConfigs: InputFieldConfig[] = [];
const fields = this.getFields(); inputFieldConfigs.push({ label: i18next.t("menu:username") });
fields.forEach((field, i) => { inputFieldConfigs.push({ label: i18next.t("menu:password"), isPassword: true });
inputFieldConfigs.push({
label: field,
isPassword: field.includes(i18next.t("menu:password")) || field.includes(i18next.t("menu:confirmPassword"))
});
});
return inputFieldConfigs; return inputFieldConfigs;
} }

View File

@ -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 { ModalConfig } from "./modal-ui-handler";
import * as Utils from "../utils"; import * as Utils from "../utils";
import { Mode } from "./ui"; import { Mode } from "./ui";
@ -24,10 +24,6 @@ export default class RegistrationFormUiHandler extends FormModalUiHandler {
return i18next.t("menu:register"); 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 { getWidth(config?: ModalConfig): number {
return 160; return 160;
} }
@ -61,15 +57,11 @@ export default class RegistrationFormUiHandler extends FormModalUiHandler {
return super.getReadableErrorMessage(error); return super.getReadableErrorMessage(error);
} }
override getInputFieldConfigs(): InputFieldConfigs[] { override getInputFieldConfigs(): InputFieldConfig[] {
const inputFieldConfigs: InputFieldConfigs[] = []; const inputFieldConfigs: InputFieldConfig[] = [];
const fields = this.getFields(); inputFieldConfigs.push({ label: i18next.t("menu:username") });
fields.forEach((field, i) => { inputFieldConfigs.push({ label: i18next.t("menu:password"), isPassword: true });
inputFieldConfigs.push({ inputFieldConfigs.push({ label: i18next.t("menu:confirmPassword"), isPassword: true });
label: field,
isPassword: field.includes(i18next.t("menu:password")) || field.includes(i18next.t("menu:confirmPassword"))
});
});
return inputFieldConfigs; return inputFieldConfigs;
} }

View File

@ -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 { ModalConfig } from "./modal-ui-handler";
import i18next from "i18next"; import i18next from "i18next";
import { PlayerPokemon } from "#app/field/pokemon"; import { PlayerPokemon } from "#app/field/pokemon";
@ -8,10 +8,6 @@ export default class RenameFormUiHandler extends FormModalUiHandler {
return i18next.t("menu:renamePokemon"); return i18next.t("menu:renamePokemon");
} }
getFields(config?: ModalConfig): string[] {
return [ i18next.t("menu:nickname") ];
}
getWidth(config?: ModalConfig): number { getWidth(config?: ModalConfig): number {
return 160; return 160;
} }
@ -33,15 +29,8 @@ export default class RenameFormUiHandler extends FormModalUiHandler {
return super.getReadableErrorMessage(error); return super.getReadableErrorMessage(error);
} }
override getInputFieldConfigs(): InputFieldConfigs[] { override getInputFieldConfigs(): InputFieldConfig[] {
const inputFieldConfigs: InputFieldConfigs[] = []; return [{ label: i18next.t("menu:nickname") }];
const fields = this.getFields();
fields.forEach((field, i) => {
inputFieldConfigs.push({
label: field
});
});
return inputFieldConfigs;
} }
show(args: any[]): boolean { show(args: any[]): boolean {

View File

@ -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 { ModalConfig } from "./modal-ui-handler";
import i18next from "i18next"; import i18next from "i18next";
import { PlayerPokemon } from "#app/field/pokemon"; import { PlayerPokemon } from "#app/field/pokemon";
@ -43,10 +43,6 @@ export default class TestDialogueUiHandler extends FormModalUiHandler {
return "Test Dialogue"; return "Test Dialogue";
} }
getFields(config?: ModalConfig): string[] {
return [ "Dialogue" ];
}
getWidth(config?: ModalConfig): number { getWidth(config?: ModalConfig): number {
return 300; return 300;
} }
@ -68,15 +64,8 @@ export default class TestDialogueUiHandler extends FormModalUiHandler {
return super.getReadableErrorMessage(error); return super.getReadableErrorMessage(error);
} }
override getInputFieldConfigs(): InputFieldConfigs[] { override getInputFieldConfigs(): InputFieldConfig[] {
const inputFieldConfigs: InputFieldConfigs[] = []; return [{ label: "Dialogue" }];
const fields = this.getFields();
fields.forEach((field, i) => {
inputFieldConfigs.push({
label: field
});
});
return inputFieldConfigs;
} }
show(args: any[]): boolean { show(args: any[]): boolean {