Refactored code and fixed bugs

This commit is contained in:
Adrian 2024-09-18 16:56:21 -04:00
parent 4eeb20184b
commit 0b6a732f83
2 changed files with 112 additions and 78 deletions

View File

@ -1,21 +1,25 @@
import { Button } from "#enums/buttons"; import { Button } from "#enums/buttons";
import BattleScene from "../battle-scene"; import BattleScene from "../battle-scene";
import AbstractOptionSelectUiHandler from "./abstact-option-select-ui-handler"; import AbstractOptionSelectUiHandler, { OptionSelectConfig } from "./abstact-option-select-ui-handler";
import { Mode } from "./ui"; import { Mode } from "./ui";
import InputText from "phaser3-rex-plugins/plugins/inputtext"; import InputText from "phaser3-rex-plugins/plugins/inputtext";
// import * as Utils from "#app/utils";
export interface OptionSelectConfigAC extends OptionSelectConfig {
inputContainer: Phaser.GameObjects.Container;
modalContainer: Phaser.GameObjects.Container;
maxOptionsReverse?: number;
reverse?: true;
}
export default class AutoCompleteUiHandler extends AbstractOptionSelectUiHandler { export default class AutoCompleteUiHandler extends AbstractOptionSelectUiHandler {
modalContainer: Phaser.GameObjects.Container; modalContainer: Phaser.GameObjects.Container;
inputContainer: Phaser.GameObjects.Container; inputContainer: Phaser.GameObjects.Container;
handlerKeyDown: (inputObject: InputText, evt: KeyboardEvent) => void; handlerKeyDown: (inputObject: InputText, evt: KeyboardEvent) => void;
reverse?: true;
constructor(scene: BattleScene, mode: Mode = Mode.AUTO_COMPLETE) {
constructor(scene: BattleScene, mode: Mode = Mode.OPTION_SELECT, ...args) {
super(scene, mode); super(scene, mode);
this.config = {
options: []
};
this.handlerKeyDown = (inputObject, evt) => { this.handlerKeyDown = (inputObject, evt) => {
// Don't move inputText cursor // Don't move inputText cursor
if (["arrowup"].some((key) => key === (evt.code || evt.key).toLowerCase())) { if (["arrowup"].some((key) => key === (evt.code || evt.key).toLowerCase())) {
@ -37,6 +41,7 @@ export default class AutoCompleteUiHandler extends AbstractOptionSelectUiHandler
inputObject.on("blur", recoveryFocus); inputObject.on("blur", recoveryFocus);
} }
}; };
} }
getWindowWidth(): integer { getWindowWidth(): integer {
@ -45,9 +50,12 @@ export default class AutoCompleteUiHandler extends AbstractOptionSelectUiHandler
show(args: any[]): boolean { show(args: any[]): boolean {
if (args[0].modalContainer && args[0].inputContainer && args[0].inputContainer.list.some((el) => el instanceof InputText)) { if (args[0].modalContainer && args[0].inputContainer && args[0].inputContainer.list.some((el) => el instanceof InputText)) {
const { modalContainer, inputContainer } = args[0]; const { modalContainer, inputContainer, reverse } = args[0] as OptionSelectConfigAC;
args[0].options?.forEach((opt)=>{ const newArgs = JSON.parse(JSON.stringify(args));
const originalHandler = opt.handler; this.reverse = reverse;
newArgs[0].options?.forEach((opt, index)=>{
const originalHandler = args[0].options[index].handler;
opt.handler = () => { opt.handler = () => {
if (originalHandler()) { if (originalHandler()) {
ui.revertMode(); ui.revertMode();
@ -83,10 +91,21 @@ export default class AutoCompleteUiHandler extends AbstractOptionSelectUiHandler
input.on("keydown", originalsEvents[i]); input.on("keydown", originalsEvents[i]);
} }
const show = super.show(args); if (this.reverse && newArgs[0].maxOptionsReverse) {
this.setupOptions(); newArgs[0].maxOptions = newArgs[0].maxOptionsReverse;
}
return show; if (this.reverse) {
newArgs[0].options.reverse();
}
if (super.show(newArgs)) {
if (this.reverse) {
this.processInput(Button.UP);
}
return true;
}
} }
return false; return false;
} }
@ -94,17 +113,14 @@ export default class AutoCompleteUiHandler extends AbstractOptionSelectUiHandler
protected setupOptions() { protected setupOptions() {
super.setupOptions(); super.setupOptions();
if (this.modalContainer) { if (this.modalContainer) {
if (this.reverse) {
this.optionSelectContainer.setPositionRelative(this.modalContainer, this.optionSelectBg.width + this.inputContainer.x, this.inputContainer.y);
return;
}
this.optionSelectContainer.setPositionRelative(this.modalContainer, this.optionSelectBg.width + this.inputContainer.x, this.optionSelectBg.height + this.inputContainer.y + (this.inputContainer.list.find((el) => el instanceof Phaser.GameObjects.NineSlice)?.height ?? 0)); this.optionSelectContainer.setPositionRelative(this.modalContainer, this.optionSelectBg.width + this.inputContainer.x, this.optionSelectBg.height + this.inputContainer.y + (this.inputContainer.list.find((el) => el instanceof Phaser.GameObjects.NineSlice)?.height ?? 0));
} }
} }
// processInput(button: Button): boolean {
// if (button !== Button.CANCEL) {
// return super.processInput(button);
// }
// return false;
// }
clear(): void { clear(): void {
super.clear(); super.clear();
const input = this.inputContainer.list.find((el) => el instanceof InputText); const input = this.inputContainer.list.find((el) => el instanceof InputText);

View File

@ -3,14 +3,14 @@ import { ModalConfig } from "./modal-ui-handler";
import i18next from "i18next"; import i18next from "i18next";
import { PlayerPokemon } from "#app/field/pokemon.js"; import { PlayerPokemon } from "#app/field/pokemon.js";
import { Mode } from "./ui"; import { Mode } from "./ui";
import { OptionSelectConfig, OptionSelectItem } from "./abstact-option-select-ui-handler"; import { OptionSelectItem } from "./abstact-option-select-ui-handler";
import { addWindow } from "./ui-theme"; import { addWindow } from "./ui-theme";
import { addTextObject, getTextStyleOptions, TextStyle } from "./text"; import { addTextObject, getTextStyleOptions, TextStyle } from "./text";
import InputText from "phaser3-rex-plugins/plugins/inputtext"; import InputText from "phaser3-rex-plugins/plugins/inputtext";
import BattleScene from "#app/battle-scene.js"; import BattleScene from "#app/battle-scene.js";
import AutoCompleteUiHandler from "./autocomplete-ui-handler"; import AutoCompleteUiHandler, { OptionSelectConfigAC } from "./autocomplete-ui-handler";
const emojiAvailable = ["♪", "★", "♥", "♣", "☻", "ª", "☼", "►", "♫", "←", "→"]; const emojiAvailable = ["♪", "★", "♥", "♣", "☻", "ª", "☼", "►", "♫", "←", "→", "↩", "↪"];
export default class RenameFormUiHandler extends FormModalUiHandler { export default class RenameFormUiHandler extends FormModalUiHandler {
protected autocomplete: AutoCompleteUiHandler; protected autocomplete: AutoCompleteUiHandler;
@ -90,89 +90,107 @@ export default class RenameFormUiHandler extends FormModalUiHandler {
} }
}; };
// emoji list config
const maxEmojis = 6; const maxEmojis = 6;
const emojiOptions = emojiAvailable.map((emoji, index): OptionSelectItem => { const modalOptions: OptionSelectConfigAC = {
return { options: emojiAvailable.map((emoji, index): OptionSelectItem => {
label: `${emoji} /${index + 1}`, return {
handler: ()=> { label: `${emoji} /${index + 1}`,
const command = input.text.split("").filter((_, i) => i >= (input.text.split("").filter((_, i) => i < input.cursorPosition).lastIndexOf("/")) && i < input.cursorPosition).join(""); handler: ()=> {
// Retrieve the exact command, as it can be either "/", or "/n"
const command = input.text.split("").filter((_, i) => i >= (input.text.split("").filter((_, i) => i < input.cursorPosition).lastIndexOf("/")) && i < input.cursorPosition).join("");
const texto = input.text; const texto = input.text;
const textBeforeCursor = texto.substring(0, input.cursorPosition); const textBeforeCursor = texto.substring(0, input.cursorPosition);
const textAfterCursor = texto.substring(input.cursorPosition); const textAfterCursor = texto.substring(input.cursorPosition);
const exactlyCommand = textBeforeCursor.lastIndexOf(command); const exactlyCommand = textBeforeCursor.lastIndexOf(command);
if (exactlyCommand !== -1) { if (exactlyCommand !== -1) {
const textReplace = textBeforeCursor.substring(0, exactlyCommand) + emoji + textAfterCursor; const textReplace = textBeforeCursor.substring(0, exactlyCommand) + emoji + textAfterCursor;
input.setText(textReplace); input.setText(textReplace);
input.setCursorPosition(exactlyCommand + emoji.length); input.setCursorPosition(exactlyCommand + emoji.length);
return true; return true;
} }
return false; return false;
}, },
}; };
}); }),
interface OptionSelectConfigAC extends OptionSelectConfig {
inputContainer: Phaser.GameObjects.Container;
modalContainer: Phaser.GameObjects.Container;
}
const modalOptions = {
options: emojiOptions,
modalContainer: this.modalContainer, modalContainer: this.modalContainer,
inputContainer: this.inputContainers[0], inputContainer: this.inputContainers[0],
maxOptions: 5 maxOptions: 5
}; };
input.on("textchange", (inputObject:InputText, evt:InputEvent) => { input.on("textchange", (inputObject:InputText, evt:InputEvent) => {
if (input.text.split("").filter((char) => emojiAvailable.some((em) => em === char)).length < maxEmojis && input.text.split("").some((char, i) => char === "/" && i + 1 === input.cursorPosition) && input.text.length < input.maxLength) { // If deleting and currently positioned at "/", display the list of emojis
if (
!evt.data &&
input.text.split("").filter((char) => emojiAvailable.some((em) => em === char)).length < maxEmojis &&
input.text.split("").some((char, i) => char === "/" && i + 1 === input.cursorPosition)
) {
ui.setOverlayMode(Mode.AUTO_COMPLETE, modalOptions); ui.setOverlayMode(Mode.AUTO_COMPLETE, modalOptions);
} }
if (input.text.split("").filter((char) => emojiAvailable.some((em) => em === char)).length > maxEmojis) { const getDisallowedEmojis = (text) => {
const command = input.text.split("").filter((_, i) => evt.data && i >= (input.text.split("").filter((_, i) => i < input.cursorPosition).lastIndexOf(evt.data)) && i < input.cursorPosition).join(""); return text.split("").filter((char) => {
const isEmoji = !char.match(/[\u0000-\u00ff]/);
const isAllowedEmoji = emojiAvailable.includes(char);
return isEmoji && !isAllowedEmoji;
});
};
// Remove disallowed emojis.
while (getDisallowedEmojis(input.text).length > 0) {
const disallowedEmojis = getDisallowedEmojis(input.text);
const lastDisallowedEmojiIndex = input.text.lastIndexOf(disallowedEmojis[0]);
if (lastDisallowedEmojiIndex !== -1) {
const textBeforeCursor = input.text.substring(0, lastDisallowedEmojiIndex);
const textAfterCursor = input.text.substring(lastDisallowedEmojiIndex + 1);
const newText = textBeforeCursor + textAfterCursor;
if (newText !== input.text) {
input.setText(newText);
input.setCursorPosition(lastDisallowedEmojiIndex);
}
}
}
// If the number of available emojis exceeds the maximum allowed number of emojis..
//.. Delete any attempt to insert another one.
if (evt.data && input.text.split("").filter((char) => emojiAvailable.some((em) => em === char)).length > maxEmojis) {
const texto = input.text; const texto = input.text;
const textBeforeCursor = texto.substring(0, input.cursorPosition); const textBeforeCursor = texto.substring(0, input.cursorPosition);
const textAfterCursor = texto.substring(input.cursorPosition); const textAfterCursor = texto.substring(input.cursorPosition);
const exactlyCommand = textBeforeCursor.lastIndexOf(command); const exactlyEmoji = textBeforeCursor.lastIndexOf(evt.data);
if (exactlyCommand !== -1 && evt.data) { if (exactlyEmoji !== -1) {
const textReplace = textBeforeCursor.substring(0, exactlyCommand) + textAfterCursor; const textReplace = textBeforeCursor.substring(0, exactlyEmoji) + textAfterCursor;
if (textReplace !== input.text) { if (textReplace !== input.text) {
input.setText(textReplace); input.setText(textReplace);
input.setCursorPosition(exactlyCommand); input.setCursorPosition(exactlyEmoji);
} }
} }
} }
// If the number of available emojis has been reached, do not display the list of emojis
if (evt.data && input.text.split("").filter((char) => emojiAvailable.some((em) => em === char)).length < maxEmojis) { if (evt.data && input.text.split("").filter((char) => emojiAvailable.some((em) => em === char)).length < maxEmojis) {
if (evt.data === "/") {
ui.setOverlayMode(Mode.AUTO_COMPLETE, modalOptions); // Retrieve the exact command, as it can be either "/", or "/n"
const command = input.text.split("").filter((_, i, arr) => arr.includes("/") && i >= (input.text.split("").filter((_, i) => i < input.cursorPosition).lastIndexOf("/")) && i < input.cursorPosition).join("");
if (modalOptions.options.some((opt) => opt.label.includes(command))) {
const filterOptions = {
...modalOptions,
options: modalOptions.options.filter((opt) => opt.label.includes(command))
};
this.scene.ui.setOverlayMode(Mode.AUTO_COMPLETE, filterOptions);
} }
} }
}); });
input.on("keydown", (inputObject:InputText, evt:KeyboardEvent)=>{
const command = input.text.split("").filter((_, i) => i >= (input.text.split("").filter((_, i) => i < input.cursorPosition).lastIndexOf("/")) && i < input.cursorPosition).join("");
if (!isNaN(parseInt(evt.key))) {
input.setData("filter", input.getData("filter") ? input.getData("filter").toString().concat(evt.key) : evt.key.toString());
} else {
input.setData("filter");
}
if (command.includes("/") && emojiOptions.some((_, i) => (i + 1).toString().includes(input.getData("filter")))) {
const filterOptions: OptionSelectConfigAC = {
options: emojiOptions.filter((_, i) => (i + 1).toString().includes(input.getData("filter"))),
modalContainer: this.modalContainer,
inputContainer: this.inputContainers[0],
maxOptions: 5
};
this.scene.ui.setOverlayMode(Mode.AUTO_COMPLETE, filterOptions);
}
});
return true; return true;
} }
return false; return false;