doc and mini-refactor

This commit is contained in:
Adrian 2024-09-21 09:51:58 -04:00
parent 4bc465a964
commit e2da67f302
18 changed files with 151 additions and 150 deletions

View File

@ -6,6 +6,12 @@ export default [
"☻",
"♀",
"♂",
"$",
"¢",
"£",
"¥",
"€",
"₽",
// "☼",
// "ª",
// "►",
@ -21,10 +27,6 @@ export default [
// "®",
// "℗",
// "™",
// "$",
// "¢",
// "£",
// "¥",
// "↖",
// "↗",
// "↙",

View File

@ -50,6 +50,7 @@
"choosePokemon": "Elegir un Pokémon.",
"renamePokemon": "Rebatejar Pokémon",
"rename": "Rebatejar",
"renameHelpEmoji": "Use \"/\" to access emoji library and enter a number to choose an emoji\n(e.g. \"/1\" for the first emoji, max. 6)",
"nickname": "Sobrenom",
"errorServerDown": "Vaja! S'ha produït un problema en contactar amb el servidor.\n\nPots deixar aquesta pestanya oberta,\nel joc es tornarà a connectar automàticament."
}

View File

@ -50,7 +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)",
"renameHelpEmoji": "Use \"/\" to access emoji library and enter a number to choose an emoji\n(e.g. \"/1\" for the first emoji, max. 6)",
"nickname": "Spitzname",
"errorServerDown": "Ups! Es gab einen Fehler beim Versuch\nden Server zu kontaktieren\nLasse dieses Fenster offen\nDu wirst automatisch neu verbunden.",
"noSaves": "Du hast keine gespeicherten Dateien!",

View File

@ -50,7 +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)",
"renameHelpEmoji": "Use \"/\" to access emoji library and enter a number to choose an emoji\n(e.g. \"/1\" for the first emoji, max. 6)",
"nickname": "Nickname",
"errorServerDown": "Oops! There was an issue contacting the server.\n\nYou may leave this window open,\nthe game will automatically reconnect.",
"noSaves": "You don't have any save files on record!",

View File

@ -50,7 +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)",
"renameHelpEmoji": "Use \"/\" to access emoji library and enter a number to choose an emoji\n(e.g. \"/1\" for the first emoji, max. 6)",
"nickname": "Apodo",
"errorServerDown": "¡Ups! Ha habido un problema al contactar con el servidor.\n\nPuedes mantener esta ventana abierta,\nel juego se reconectará automáticamente.",
"noSaves": "No tienes ninguna partida guardada registrada!",

View File

@ -50,7 +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)",
"renameHelpEmoji": "Use \"/\" to access emoji library and enter a number to choose an emoji\n(e.g. \"/1\" for the first emoji, max. 6)",
"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.",
"noSaves": "Vous navez aucune sauvegarde enregistrée !",

View File

@ -50,7 +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)",
"renameHelpEmoji": "Use \"/\" to access emoji library and enter a number to choose an emoji\n(e.g. \"/1\" for the first emoji, max. 6)",
"nickname": "Nickname",
"errorServerDown": "Poffarbacco! C'è stato un errore nella comunicazione col server.\n\nPuoi lasciare questa finestra aperta,\nil gioco si riconnetterà automaticamente.",
"noSaves": "Non ci sono file di salvataggio registrati!",

View File

@ -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, max. 6)",
"nickname": "ニックネーム",
"errorServerDown": "おや!\nサーバーとの 接続中に 問題が 発生しました。\nゲームは 自動的に 再接続されます から\nウィンドウは 開いたままに しておいても よろしいです。",
"noSaves": "何の セーブファイルも ありません!",

View File

@ -50,7 +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)",
"renameHelpEmoji": "Use \"/\" to access emoji library and enter a number to choose an emoji\n(e.g. \"/1\" for the first emoji, max. 6)",
"nickname": "닉네임",
"errorServerDown": "서버 연결 중 문제가 발생했습니다.\n\n이 창을 종료하지 않고 두면,\n게임은 자동으로 재접속됩니다.",
"noSaves": "기기에 세이브 파일이 없습니다!",

View File

@ -50,7 +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)",
"renameHelpEmoji": "Use \"/\" to access emoji library and enter a number to choose an emoji\n(e.g. \"/1\" for the first emoji, max. 6)",
"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."
}

View File

@ -50,7 +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)",
"renameHelpEmoji": "Use \"/\" to access emoji library and enter a number to choose an emoji\n(e.g. \"/1\" for the first emoji, max. 6)",
"nickname": "昵称",
"errorServerDown": "糟糕!访问服务器时发生了错误。\n\n你可以保持页面开启\n游戏会自动重新连接。",
"noSaves": "你没有任何记录文件!",

View File

@ -47,6 +47,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, max. 6)",
"nickname": "昵稱",
"errorServerDown": "糟糕!訪問服務器時發生了錯誤。\n\n你可以保持頁面開啓\n遊戲會自動重新連接。",
"noSaves": "你沒有任何記錄檔!",

View File

@ -354,5 +354,6 @@ export default abstract class AbstractOptionSelectUiHandler extends UiHandler {
this.cursorObj.destroy();
}
this.cursorObj = null;
this.scrollCursor = 0;
}
}

View File

@ -14,42 +14,11 @@ export interface OptionSelectConfigAC extends OptionSelectConfig {
export default class AutoCompleteUiHandler extends AbstractOptionSelectUiHandler {
modalContainer: Phaser.GameObjects.Container;
inputContainer: Phaser.GameObjects.Container;
handlerKeyDown: (inputObject: InputText, evt: KeyboardEvent) => void;
revertAutoCompleteMode: () => void;
reverse?: true;
constructor(scene: BattleScene, mode: Mode = Mode.AUTO_COMPLETE) {
super(scene, mode);
this.handlerKeyDown = (inputObject, evt) => {
// Don't move inputText cursor, cursor move fast for this
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 if not press...
if (!["enter", "arrowup", "arrowdown", "shift", "control", "alt"].some((key) => (evt.code || evt.key).toLowerCase().includes(key))) {
this.revertAutoCompleteMode();
}
// Recovery focus
if (["escape"].some((key) => key === (evt.code || evt.key).toLowerCase())) {
const recoveryFocus = () => (inputObject.setFocus(), inputObject.off("blur", recoveryFocus));
inputObject.on("blur", recoveryFocus);
}
};
this.revertAutoCompleteMode = () => {
const ui = this.getUi();
if (ui.getMode() === Mode.AUTO_COMPLETE) {
ui.revertMode();
}
};
this.handlerKeyDown = this.handlerKeyDown.bind(this);
}
getWindowWidth(): integer {
@ -124,7 +93,7 @@ export default class AutoCompleteUiHandler extends AbstractOptionSelectUiHandler
// If the modal goes off screen, center it
// if ((this.optionSelectContainer.getBounds().width + this.optionSelectContainer.getBounds().x) > this.scene.game.canvas.width) {
// this.optionSelectContainer.setX(this.optionSelectContainer.getBounds().x - ((this.optionSelectContainer.getBounds().width + this.optionSelectContainer.getBounds().x) - this.scene.game.canvas.width));
// this.optionSelectContainer.setX((this.optionSelectContainer.x) - ((this.optionSelectContainer.width + this.optionSelectContainer.x) - (this.scene.game.canvas.width / 6)));
// }
}
}
@ -139,12 +108,44 @@ export default class AutoCompleteUiHandler extends AbstractOptionSelectUiHandler
return false;
}
handlerKeyDown (inputObject: InputText, evt: KeyboardEvent): void {
// Don't move inputText cursor
// TODO: cursor move fast for this
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 if not press...
if (!["enter", "arrowup", "arrowdown", "shift", "control", "alt"].some((key) => (evt.code || evt.key).toLowerCase().includes(key))) {
this.revertAutoCompleteMode();
}
// Recovery focus
if (["escape"].some((key) => key === (evt.code || evt.key).toLowerCase())) {
const recoveryFocus = () => {
inputObject.setFocus();
inputObject.off("blur", recoveryFocus);
};
inputObject.on("blur", recoveryFocus);
}
}
revertAutoCompleteMode(): void {
const ui = this.scene.ui;
if (ui.getMode() === Mode.AUTO_COMPLETE) {
ui.revertMode();
}
}
clear(): void {
super.clear();
const input = this.inputContainer.list.find((el) => el instanceof InputText);
input?.off("keydown", this.handlerKeyDown);
input?.off("blur", this.revertAutoCompleteMode);
this.modalContainer.off("pointerdown", this.revertAutoCompleteMode);
this.scrollCursor = 0;
}
}

View File

@ -91,7 +91,7 @@ export abstract class FormModalUiHandler extends ModalUiHandler {
if (this.buttonBgs.length) {
this.buttonBgs[0].off("pointerdown");
this.buttonBgs[0].on("pointerdown", () => {
if (this.submitAction) {
if (this.scene.ui.getMode() === this.mode && this.submitAction) {
this.submitAction();
}
});

View File

@ -119,7 +119,11 @@ export abstract class ModalUiHandler extends UiHandler {
for (let a = 0; a < this.buttonBgs.length; a++) {
if (a < this.buttonBgs.length) {
this.buttonBgs[a].on("pointerdown", (_) => config.buttonActions[a]());
this.buttonBgs[a].on("pointerdown", (_) => {
if (this.scene.ui.getMode() === this.mode) {
config.buttonActions[a]();
}
});
}
}

View File

@ -8,10 +8,15 @@ 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";
import AutoCompleteUiHandler, { OptionSelectConfigAC } from "./autocomplete-ui-handler";
import { OptionSelectConfigAC } from "./autocomplete-ui-handler";
import emojisAvailable from "#app/data/emoji";
import { emojiRegex } from "#app/data/emoji";
/**
* Split string with emojis, since emojis length is longer and native split doesn't work.
* @param str
* @returns string[]
*/
function textArrayWithEmojis(str: string): string[] {
const result: string[] = [];
let match;
@ -33,7 +38,10 @@ function textArrayWithEmojis(str: string): string[] {
}
export default class RenameFormUiHandler extends FormModalUiHandler {
protected autocomplete: AutoCompleteUiHandler;
constructor (scene, mode: Mode | null = Mode.RENAME_POKEMON) {
super(scene, mode);
}
getModalTitle(config?: ModalConfig): string {
return i18next.t("menu:renamePokemon");
@ -71,11 +79,11 @@ export default class RenameFormUiHandler extends FormModalUiHandler {
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, {
const helpEmojiListText = addTextObject(this.scene, 8, 4, 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;
helpEmojiListText.setWordWrapWidth(890);
const height = ((Math.min((helpEmojiListText.getWrappedText(helpEmojiListText.text)).length, 99)) * (80 + helpEmojiListText.y) * scale) + helpEmojiListText.y;
helpEmojiListBg.setSize(helpEmojiListBg.width, height);
helpEmojiListContainer.add(helpEmojiListText);
@ -96,18 +104,10 @@ export default class RenameFormUiHandler extends FormModalUiHandler {
this.inputs[0].text = args[1];
}
this.submitAction = (_) => {
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();
}
};
// emoji list config
@ -119,11 +119,11 @@ export default class RenameFormUiHandler extends FormModalUiHandler {
label: `${emoji} /${index + 1}`,
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 command = textArrayWithEmojis(input.text).filter((_, i) => i >= (textArrayWithEmojis(input.text).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 text = input.text;
const textBeforeCursor = text.substring(0, input.cursorPosition);
const textAfterCursor = text.substring(input.cursorPosition);
const exactlyCommand = textBeforeCursor.lastIndexOf(command);
if (exactlyCommand !== -1) {
@ -142,25 +142,19 @@ export default class RenameFormUiHandler extends FormModalUiHandler {
};
input.on("textchange", (inputObject:InputText, evt:InputEvent) => {
// If deleting and currently positioned at "/", display the list of emojis
if (
!evt.data &&
input.text.split("").filter((char) => emojisAvailable.some((em) => em === char)).length < maxEmojis &&
input.text.split("").some((char, i) => char === "/" && i + 1 === input.cursorPosition)
) {
ui.setOverlayMode(Mode.AUTO_COMPLETE, modalOptions);
}
const text = input.text;
const arrayText = textArrayWithEmojis(text);
// Remove disallowed emojis.
if (textArrayWithEmojis(input.text).filter((char) => {
// const isEmoji = !char.match(/[\u0000-\u00ff]/); // Emojis, special characters and kaomojis
if (arrayText.filter((char) => {
// const isEmoji = !char.match(/[\u0000-\u00ff]/); // Emojis, special characters and kaomojis, technically
const isEmoji = char.match(emojiRegex); // Only Emojis
const isAllowedEmoji = emojisAvailable.includes(char);
return isEmoji && !isAllowedEmoji;
}).length) {
const regex = emojiRegex;
let totalLength: number = 0;
const newText = input.text.replace(regex, (match) => {
const newText = text.replace(regex, (match) => {
if (emojisAvailable.includes(match)) {
return match;
}
@ -174,13 +168,16 @@ export default class RenameFormUiHandler extends FormModalUiHandler {
}
// If the number of available emojis exceeds the maximum allowed number of emojis..
//.. Delete any attempt to insert another one.
while (textArrayWithEmojis(input.text).filter((char) => emojisAvailable.includes(char)).length > maxEmojis) {
const charactersWithEmojis = textArrayWithEmojis(input.text);
const emojis = charactersWithEmojis.filter((char, i, arr) => {
const splitWithEmojis = textArrayWithEmojis(input.text);
// Retrieve only the emojis that are trying to be inserted
const emojis = splitWithEmojis.filter((char, i, arr) => {
if (emojisAvailable.includes(char)) {
// The length of the emojis is usually greater than one
// And many can also be inserted by pasting
let totalLength = 0;
for (let j = 0; j <= i; j++) {
totalLength += arr[j].length;
@ -189,9 +186,10 @@ export default class RenameFormUiHandler extends FormModalUiHandler {
}
return false;
});
const cursorPosition = input.cursorPosition;
const lastEmoji = emojis[emojis.length - 1];
const lastEmojiIndex = charactersWithEmojis.filter((char, i, arr) => {
// Retrieve only the position before the cursorInput of the last available emoji that you want to insert
const lastEmojiIndex = splitWithEmojis.filter((char, i, arr) => {
let totalLength = 0;
for (let j = 0; j <= i; j++) {
totalLength += arr[j].length;
@ -200,22 +198,23 @@ export default class RenameFormUiHandler extends FormModalUiHandler {
}).lastIndexOf(lastEmoji);
if (lastEmojiIndex !== -1) {
const textBeforeCursor = charactersWithEmojis.slice(0, lastEmojiIndex).join("");
const textAfterCursor = charactersWithEmojis.slice(lastEmojiIndex + 1).join("");
const textBeforeCursor = splitWithEmojis.slice(0, lastEmojiIndex).join("");
const textAfterCursor = splitWithEmojis.slice(lastEmojiIndex + 1).join("");
const newText = textBeforeCursor + textAfterCursor;
if (newText !== input.text) {
if (newText !== text) {
const previousCursor = input.cursorPosition;
input.setText(newText);
input.setCursorPosition(cursorPosition - lastEmoji.length);
input.setCursorPosition(previousCursor - lastEmoji.length);
}
}
}
// If the number of available emojis has been reached, do not display the list of emojis
if (evt.data && input.text.split("").filter((char) => emojisAvailable.some((em) => em === char)).length < maxEmojis) {
if (arrayText.filter((char) => emojisAvailable.some((em) => em === char)).length < maxEmojis) {
// Retrieve the exact command, as it can be either "/", or "/n"
const command = input.text.split("").filter((_, i, arr) => i >= (input.text.split("").filter((_, i) => i < input.cursorPosition).lastIndexOf("/")) && i < input.cursorPosition).join("");
const command = arrayText.filter((_, i) => i >= (arrayText.filter((_, i) => i < input.cursorPosition).lastIndexOf("/")) && i < input.cursorPosition).join("");
if (evt.data === "/") {
ui.setOverlayMode(Mode.AUTO_COMPLETE, modalOptions);

View File

@ -130,19 +130,10 @@ export default class TestDialogueUiHandler extends FormModalUiHandler {
this.inputs[0].text = args[1];
}
this.submitAction = (_) => {
if (ui.getMode() === Mode.TEST_DIALOGUE) {
this.sanitizeInputs();
const sanitizedName = btoa(unescape(encodeURIComponent(this.inputs[0].text)));
config.buttonActions[0](sanitizedName);
return true;
}
return false;
};
const originalCancel = config.buttonActions[1];
config.buttonActions[1] = ()=>{
if (ui.getMode() === Mode.TEST_DIALOGUE) {
originalCancel();
}
};
return true;
}