mirror of
https://github.com/pagefaultgames/pokerogue.git
synced 2025-08-25 00:39:27 +02:00
autocomplete for rename funcionally, and translate integration i18n for helpEmojiList
This commit is contained in:
parent
d1ab218044
commit
4eeb20184b
@ -50,6 +50,7 @@
|
||||
"choosePokemon": "Wähle ein Pokémon.",
|
||||
"renamePokemon": "Pokémon umbennenen",
|
||||
"rename": "Umbenennen",
|
||||
"renameHelpEmoji": "Use \"/\" to access emoji library and enter a number to choose an emoji\n(e.g. \"/1\" for the first emoji)",
|
||||
"nickname": "Spitzname",
|
||||
"errorServerDown": "Ups! Es gab einen Fehler beim Versuch\nden Server zu kontaktieren\nLasse dieses Fenster offen\nDu wirst automatisch neu verbunden."
|
||||
}
|
@ -50,6 +50,7 @@
|
||||
"choosePokemon": "Choose a Pokémon.",
|
||||
"renamePokemon": "Rename Pokémon",
|
||||
"rename": "Rename",
|
||||
"renameHelpEmoji": "Use \"/\" to access emoji library and enter a number to choose an emoji\n(e.g. \"/1\" for the first emoji)",
|
||||
"nickname": "Nickname",
|
||||
"errorServerDown": "Oops! There was an issue contacting the server.\n\nYou may leave this window open,\nthe game will automatically reconnect."
|
||||
}
|
@ -50,6 +50,7 @@
|
||||
"choosePokemon": "Elige un Pokémon.",
|
||||
"renamePokemon": "Renombrar Pokémon.",
|
||||
"rename": "Renombrar",
|
||||
"renameHelpEmoji": "Use \"/\" to access emoji library and enter a number to choose an emoji\n(e.g. \"/1\" for the first emoji)",
|
||||
"nickname": "Apodo",
|
||||
"errorServerDown": "¡Ups! Ha habido un problema al contactar con el servidor.\n\nPuedes mantener esta ventana abierta, el juego se reconectará automáticamente."
|
||||
}
|
||||
|
@ -50,6 +50,7 @@
|
||||
"choosePokemon": "Sélectionnez un Pokémon.",
|
||||
"renamePokemon": "Renommer le Pokémon",
|
||||
"rename": "Renommer",
|
||||
"renameHelpEmoji": "Use \"/\" to access emoji library and enter a number to choose an emoji\n(e.g. \"/1\" for the first emoji)",
|
||||
"nickname": "Surnom",
|
||||
"errorServerDown": "Oupsi ! Un problème de connexion au serveur est survenu.\n\nVous pouvez garder cette fenêtre ouverte,\nle jeu se reconnectera automatiquement."
|
||||
}
|
||||
|
@ -50,6 +50,7 @@
|
||||
"choosePokemon": "Scegli un Pokémon.",
|
||||
"renamePokemon": "Rinomina un Pokémon",
|
||||
"rename": "Rinomina",
|
||||
"renameHelpEmoji": "Use \"/\" to access emoji library and enter a number to choose an emoji\n(e.g. \"/1\" for the first emoji)",
|
||||
"nickname": "Nickname",
|
||||
"errorServerDown": "Poffarbacco! C'è stato un errore nella comunicazione col server.\n\nPuoi lasciare questa finestra aperta,\nil gioco si riconnetterà automaticamente."
|
||||
}
|
@ -50,6 +50,7 @@
|
||||
"choosePokemon": "포켓몬을 선택하세요.",
|
||||
"renamePokemon": "포켓몬의 닉네임은?",
|
||||
"rename": "닉네임 바꾸기",
|
||||
"renameHelpEmoji": "Use \"/\" to access emoji library and enter a number to choose an emoji\n(e.g. \"/1\" for the first emoji)",
|
||||
"nickname": "닉네임",
|
||||
"errorServerDown": "서버 연결 중 문제가 발생했습니다.\n\n이 창을 종료하지 않고 두면,\n게임은 자동으로 재접속됩니다."
|
||||
}
|
||||
|
@ -50,6 +50,7 @@
|
||||
"choosePokemon": "Escolha um Pokémon.",
|
||||
"renamePokemon": "Renomear Pokémon",
|
||||
"rename": "Renomear",
|
||||
"renameHelpEmoji": "Use \"/\" to access emoji library and enter a number to choose an emoji\n(e.g. \"/1\" for the first emoji)",
|
||||
"nickname": "Apelido",
|
||||
"errorServerDown": "Opa! Não foi possível conectar-se ao servidor.\n\nVocê pode deixar essa janela aberta,\npois o jogo irá se reconectar automaticamente."
|
||||
}
|
@ -50,6 +50,7 @@
|
||||
"choosePokemon": "选择一只宝可梦。",
|
||||
"renamePokemon": "给宝可梦起名",
|
||||
"rename": "起名",
|
||||
"renameHelpEmoji": "Use \"/\" to access emoji library and enter a number to choose an emoji\n(e.g. \"/1\" for the first emoji)",
|
||||
"nickname": "昵称",
|
||||
"errorServerDown": "糟糕!访问服务器时发生了错误。\n\n你可以保持页面开启,\n游戏会自动重新连接。"
|
||||
}
|
113
src/ui/autocomplete-ui-handler.ts
Normal file
113
src/ui/autocomplete-ui-handler.ts
Normal file
@ -0,0 +1,113 @@
|
||||
import { Button } from "#enums/buttons";
|
||||
import BattleScene from "../battle-scene";
|
||||
import AbstractOptionSelectUiHandler from "./abstact-option-select-ui-handler";
|
||||
import { Mode } from "./ui";
|
||||
import InputText from "phaser3-rex-plugins/plugins/inputtext";
|
||||
// import * as Utils from "#app/utils";
|
||||
|
||||
export default class AutoCompleteUiHandler extends AbstractOptionSelectUiHandler {
|
||||
modalContainer: Phaser.GameObjects.Container;
|
||||
inputContainer: Phaser.GameObjects.Container;
|
||||
handlerKeyDown: (inputObject: InputText, evt: KeyboardEvent) => void;
|
||||
|
||||
|
||||
constructor(scene: BattleScene, mode: Mode = Mode.OPTION_SELECT, ...args) {
|
||||
super(scene, mode);
|
||||
this.config = {
|
||||
options: []
|
||||
};
|
||||
this.handlerKeyDown = (inputObject, evt) => {
|
||||
// Don't move inputText cursor
|
||||
if (["arrowup"].some((key) => key === (evt.code || evt.key).toLowerCase())) {
|
||||
evt.preventDefault();
|
||||
this.processInput(Button.UP);
|
||||
} else if (["arrowdown"].some((key) => key === (evt.code || evt.key).toLowerCase())) {
|
||||
evt.preventDefault();
|
||||
this.processInput(Button.DOWN);
|
||||
}
|
||||
|
||||
// Revert Mode when not press...
|
||||
if (!["enter", "arrowup", "arrowdown"].some((key) => (evt.code || evt.key).toLowerCase().includes(key))) {
|
||||
this.scene.ui.revertMode();
|
||||
}
|
||||
|
||||
// Recovery focus
|
||||
if (["escape"].some((key) => key === (evt.code || evt.key).toLowerCase())) {
|
||||
const recoveryFocus = () => (inputObject.setFocus(), inputObject.off("blur", recoveryFocus));
|
||||
inputObject.on("blur", recoveryFocus);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
getWindowWidth(): integer {
|
||||
return 0;
|
||||
}
|
||||
|
||||
show(args: any[]): boolean {
|
||||
if (args[0].modalContainer && args[0].inputContainer && args[0].inputContainer.list.some((el) => el instanceof InputText)) {
|
||||
const { modalContainer, inputContainer } = args[0];
|
||||
args[0].options?.forEach((opt)=>{
|
||||
const originalHandler = opt.handler;
|
||||
opt.handler = () => {
|
||||
if (originalHandler()) {
|
||||
ui.revertMode();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
});
|
||||
this.modalContainer = modalContainer;
|
||||
this.inputContainer = inputContainer;
|
||||
const input = args[0].inputContainer.list.find((el) => el instanceof InputText);
|
||||
const ui = this.getUi();
|
||||
|
||||
const originalsEvents = input.listeners("keydown");
|
||||
for (let i = 0; i < originalsEvents?.length; i++) {
|
||||
input.off("keydown", originalsEvents[i]);
|
||||
}
|
||||
|
||||
const handlerBlur = () => {
|
||||
ui.revertMode();
|
||||
input.off("blur", handlerBlur);
|
||||
};
|
||||
const handlerPointerUp = () => {
|
||||
ui.revertMode();
|
||||
this.modalContainer.off("pointerup", handlerPointerUp);
|
||||
};
|
||||
|
||||
input.on("blur", handlerBlur);
|
||||
input.on("keydown", this.handlerKeyDown);
|
||||
this.modalContainer.on("pointerup", handlerPointerUp);
|
||||
|
||||
for (let i = 0; i < originalsEvents?.length; i++) {
|
||||
input.on("keydown", originalsEvents[i]);
|
||||
}
|
||||
|
||||
const show = super.show(args);
|
||||
this.setupOptions();
|
||||
|
||||
return show;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected setupOptions() {
|
||||
super.setupOptions();
|
||||
if (this.modalContainer) {
|
||||
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 {
|
||||
super.clear();
|
||||
const input = this.inputContainer.list.find((el) => el instanceof InputText);
|
||||
input?.off("keydown", this.handlerKeyDown);
|
||||
}
|
||||
}
|
@ -4,10 +4,17 @@ import i18next from "i18next";
|
||||
import { PlayerPokemon } from "#app/field/pokemon.js";
|
||||
import { Mode } from "./ui";
|
||||
import { OptionSelectConfig, OptionSelectItem } from "./abstact-option-select-ui-handler";
|
||||
import { addWindow } from "./ui-theme";
|
||||
import { addTextObject, getTextStyleOptions, TextStyle } from "./text";
|
||||
import InputText from "phaser3-rex-plugins/plugins/inputtext";
|
||||
import BattleScene from "#app/battle-scene.js";
|
||||
import AutoCompleteUiHandler from "./autocomplete-ui-handler";
|
||||
|
||||
const emojiAvailable = ["♪", "★", "♥", "♣"];
|
||||
const emojiAvailable = ["♪", "★", "♥", "♣", "☻", "ª", "☼", "►", "♫", "←", "→"];
|
||||
|
||||
export default class RenameFormUiHandler extends FormModalUiHandler {
|
||||
protected autocomplete: AutoCompleteUiHandler;
|
||||
|
||||
getModalTitle(config?: ModalConfig): string {
|
||||
return i18next.t("menu:renamePokemon");
|
||||
}
|
||||
@ -37,38 +44,31 @@ export default class RenameFormUiHandler extends FormModalUiHandler {
|
||||
return super.getReadableErrorMessage(error);
|
||||
}
|
||||
|
||||
show(args: any[]): boolean {
|
||||
const ui = this.getUi();
|
||||
const input = this.inputs[0];
|
||||
input.node.addEventListener("keydown",(e:KeyboardEvent)=>{
|
||||
if (e.key === "/") {
|
||||
const emojiOptions = emojiAvailable.map((emoji): OptionSelectItem => {
|
||||
return {
|
||||
label: emoji,
|
||||
handler: ()=> {
|
||||
ui.revertMode();
|
||||
return true;
|
||||
},
|
||||
keepOpen: true
|
||||
};
|
||||
});
|
||||
const modalOptions: OptionSelectConfig = {
|
||||
xOffset: 98,
|
||||
yOffset: 48 / 2,
|
||||
options: emojiOptions
|
||||
};
|
||||
this.scene.ui.setOverlayMode(Mode.MENU_OPTION_SELECT, modalOptions);
|
||||
// input.setText(input.text + emojiAvailable[0]);
|
||||
} else if (input.cursorPosition === (input.text.split("").findIndex((value) => value === "/"))) {
|
||||
// input.setData("filter", )
|
||||
console.log(input.text[input.text.split("").findIndex((value) => value === "/")]);
|
||||
} else if (e.code === "Escape" && ui.getMode() === Mode.MENU_OPTION_SELECT) {
|
||||
e.preventDefault();
|
||||
ui.revertMode();
|
||||
console.log(e, input);
|
||||
}
|
||||
setup(): void {
|
||||
super.setup();
|
||||
const helpEmojiListContainer = this.scene.add.container(0, this.getHeight());
|
||||
const helpEmojiListBg = addWindow(this.scene, 0, 0, this.getWidth(), 52);
|
||||
helpEmojiListContainer.add(helpEmojiListBg);
|
||||
const scale = getTextStyleOptions(TextStyle.WINDOW, (this.scene as BattleScene).uiTheme).scale ?? 0.1666666667;
|
||||
|
||||
const helpEmojiListText = addTextObject(this.scene, 8, 8, i18next.t("menu:renameHelpEmoji"), TextStyle.TOOLTIP_CONTENT, {
|
||||
fontSize: "80px",
|
||||
});
|
||||
helpEmojiListText.setWordWrapWidth(this.modalContainer.getBounds().width * 0.95);
|
||||
const height = ((Math.min((helpEmojiListText.getWrappedText(helpEmojiListText.text) || []).length, 99)) * 96 * scale) + helpEmojiListText.y;
|
||||
helpEmojiListBg.setSize(helpEmojiListBg.width, height);
|
||||
|
||||
helpEmojiListContainer.add(helpEmojiListText);
|
||||
|
||||
this.modalContainer.add(helpEmojiListContainer);
|
||||
}
|
||||
|
||||
show(args: any[]): boolean {
|
||||
if (super.show(args)) {
|
||||
const ui = this.getUi();
|
||||
const input = this.inputs[0];
|
||||
|
||||
// rename config
|
||||
const config = args[0] as ModalConfig;
|
||||
if (args[1] && typeof (args[1] as PlayerPokemon).getNameToRender === "function") {
|
||||
this.inputs[0].text = (args[1] as PlayerPokemon).getNameToRender();
|
||||
@ -76,11 +76,103 @@ export default class RenameFormUiHandler extends FormModalUiHandler {
|
||||
this.inputs[0].text = args[1];
|
||||
}
|
||||
this.submitAction = (_) => {
|
||||
this.sanitizeInputs();
|
||||
const sanitizedName = btoa(unescape(encodeURIComponent(this.inputs[0].text)));
|
||||
config.buttonActions[0](sanitizedName);
|
||||
return true;
|
||||
if (ui.getMode() === Mode.RENAME_POKEMON) {
|
||||
this.sanitizeInputs();
|
||||
const sanitizedName = btoa(unescape(encodeURIComponent(this.inputs[0].text)));
|
||||
config.buttonActions[0](sanitizedName);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
const originalCancel = config.buttonActions[1];
|
||||
config.buttonActions[1] = ()=>{
|
||||
if (ui.getMode() === Mode.RENAME_POKEMON) {
|
||||
originalCancel();
|
||||
}
|
||||
};
|
||||
|
||||
const maxEmojis = 6;
|
||||
|
||||
const emojiOptions = emojiAvailable.map((emoji, index): OptionSelectItem => {
|
||||
return {
|
||||
label: `${emoji} /${index + 1}`,
|
||||
handler: ()=> {
|
||||
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 textBeforeCursor = texto.substring(0, input.cursorPosition);
|
||||
const textAfterCursor = texto.substring(input.cursorPosition);
|
||||
|
||||
const exactlyCommand = textBeforeCursor.lastIndexOf(command);
|
||||
if (exactlyCommand !== -1) {
|
||||
const textReplace = textBeforeCursor.substring(0, exactlyCommand) + emoji + textAfterCursor;
|
||||
input.setText(textReplace);
|
||||
input.setCursorPosition(exactlyCommand + emoji.length);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
interface OptionSelectConfigAC extends OptionSelectConfig {
|
||||
inputContainer: Phaser.GameObjects.Container;
|
||||
modalContainer: Phaser.GameObjects.Container;
|
||||
}
|
||||
|
||||
const modalOptions = {
|
||||
options: emojiOptions,
|
||||
modalContainer: this.modalContainer,
|
||||
inputContainer: this.inputContainers[0],
|
||||
maxOptions: 5
|
||||
};
|
||||
|
||||
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) {
|
||||
ui.setOverlayMode(Mode.AUTO_COMPLETE, modalOptions);
|
||||
}
|
||||
|
||||
if (input.text.split("").filter((char) => emojiAvailable.some((em) => em === char)).length > maxEmojis) {
|
||||
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("");
|
||||
|
||||
const texto = input.text;
|
||||
const textBeforeCursor = texto.substring(0, input.cursorPosition);
|
||||
const textAfterCursor = texto.substring(input.cursorPosition);
|
||||
|
||||
const exactlyCommand = textBeforeCursor.lastIndexOf(command);
|
||||
if (exactlyCommand !== -1 && evt.data) {
|
||||
const textReplace = textBeforeCursor.substring(0, exactlyCommand) + textAfterCursor;
|
||||
if (textReplace !== input.text) {
|
||||
input.setText(textReplace);
|
||||
input.setCursorPosition(exactlyCommand);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (evt.data && input.text.split("").filter((char) => emojiAvailable.some((em) => em === char)).length < maxEmojis) {
|
||||
if (evt.data === "/") {
|
||||
ui.setOverlayMode(Mode.AUTO_COMPLETE, modalOptions);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
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 false;
|
||||
|
@ -48,6 +48,7 @@ import BgmBar from "#app/ui/bgm-bar";
|
||||
import RenameFormUiHandler from "./rename-form-ui-handler";
|
||||
import RunHistoryUiHandler from "./run-history-ui-handler";
|
||||
import RunInfoUiHandler from "./run-info-ui-handler";
|
||||
import AutoCompleteUiHandler from "./autocomplete-ui-handler";
|
||||
|
||||
export enum Mode {
|
||||
MESSAGE,
|
||||
@ -88,6 +89,7 @@ export enum Mode {
|
||||
RENAME_POKEMON,
|
||||
RUN_HISTORY,
|
||||
RUN_INFO,
|
||||
AUTO_COMPLETE,
|
||||
}
|
||||
|
||||
const transitionModes = [
|
||||
@ -124,7 +126,8 @@ const noTransitionModes = [
|
||||
Mode.SESSION_RELOAD,
|
||||
Mode.UNAVAILABLE,
|
||||
Mode.OUTDATED,
|
||||
Mode.RENAME_POKEMON
|
||||
Mode.RENAME_POKEMON,
|
||||
Mode.AUTO_COMPLETE
|
||||
];
|
||||
|
||||
export default class UI extends Phaser.GameObjects.Container {
|
||||
@ -188,6 +191,7 @@ export default class UI extends Phaser.GameObjects.Container {
|
||||
new RenameFormUiHandler(scene),
|
||||
new RunHistoryUiHandler(scene),
|
||||
new RunInfoUiHandler(scene),
|
||||
new AutoCompleteUiHandler(scene),
|
||||
];
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user