diff --git a/package-lock.json b/package-lock.json index b21f00438f0..b93e2b2c6a3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,6 +10,7 @@ "dependencies": { "@material/material-color-utilities": "^0.2.7", "crypto-js": "^4.2.0", + "i18next": "^23.11.1", "json-stable-stringify": "^1.1.0", "phaser": "^3.70.0", "phaser3-rex-plugins": "^1.1.84" @@ -2750,9 +2751,9 @@ } }, "node_modules/i18next": { - "version": "22.5.1", - "resolved": "https://registry.npmjs.org/i18next/-/i18next-22.5.1.tgz", - "integrity": "sha512-8TGPgM3pAD+VRsMtUMNknRz3kzqwp/gPALrWMsDnmC1mKqJwpWyooQRLMcbTwq8z8YwSmuj+ZYvc+xCuEpkssA==", + "version": "23.11.1", + "resolved": "https://registry.npmjs.org/i18next/-/i18next-23.11.1.tgz", + "integrity": "sha512-mXw4A24BiPZKRsbb9ewgSvjYd6fxFCNwJyfK6nYfSTIAX2GkCWcb598m3DFkDZmqADatvuASrKo6qwORz3VwTQ==", "funding": [ { "type": "individual", @@ -2768,7 +2769,7 @@ } ], "dependencies": { - "@babel/runtime": "^7.20.6" + "@babel/runtime": "^7.23.2" } }, "node_modules/i18next-http-backend": { @@ -3819,6 +3820,28 @@ "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz", "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==" }, + "node_modules/phaser3-rex-plugins/node_modules/i18next": { + "version": "22.5.1", + "resolved": "https://registry.npmjs.org/i18next/-/i18next-22.5.1.tgz", + "integrity": "sha512-8TGPgM3pAD+VRsMtUMNknRz3kzqwp/gPALrWMsDnmC1mKqJwpWyooQRLMcbTwq8z8YwSmuj+ZYvc+xCuEpkssA==", + "funding": [ + { + "type": "individual", + "url": "https://locize.com" + }, + { + "type": "individual", + "url": "https://locize.com/i18next.html" + }, + { + "type": "individual", + "url": "https://www.i18next.com/how-to/faq#i18next-is-awesome.-how-can-i-support-the-project" + } + ], + "dependencies": { + "@babel/runtime": "^7.20.6" + } + }, "node_modules/phaser3spectorjs": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/phaser3spectorjs/-/phaser3spectorjs-0.0.8.tgz", diff --git a/package.json b/package.json index 9065bc17a55..fd189fd4d89 100644 --- a/package.json +++ b/package.json @@ -30,6 +30,7 @@ "dependencies": { "@material/material-color-utilities": "^0.2.7", "crypto-js": "^4.2.0", + "i18next": "^23.11.1", "json-stable-stringify": "^1.1.0", "phaser": "^3.70.0", "phaser3-rex-plugins": "^1.1.84" diff --git a/src/locales/en/menu.ts b/src/locales/en/menu.ts new file mode 100644 index 00000000000..1525f2f9068 --- /dev/null +++ b/src/locales/en/menu.ts @@ -0,0 +1,8 @@ +export const menu = { + "cancel": "Cancel", + "continue": "Continue", + "newGame": "New Game", + "loadGame": "Load Game", + "dailyRun": "Daily Run (Beta)", + "selectGameMode": "Select a game mode." +} as const; \ No newline at end of file diff --git a/src/phases.ts b/src/phases.ts index 480c6c9a3f9..eb30c04d216 100644 --- a/src/phases.ts +++ b/src/phases.ts @@ -57,6 +57,7 @@ import { SaveSlotUiMode } from "./ui/save-slot-select-ui-handler"; import { fetchDailyRunSeed, getDailyRunStarters } from "./data/daily-run"; import { GameModes, gameModes } from "./game-mode"; import { getPokemonSpecies, speciesStarters } from "./data/pokemon-species"; +import { default as i18next, menuNS }from './plugins/i18n'; export class LoginPhase extends Phase { private showText: boolean; @@ -173,12 +174,12 @@ export class TitlePhase extends Phase { const options: OptionSelectItem[] = []; if (loggedInUser.lastSessionSlot > -1) { options.push({ - label: 'Continue', + label: i18next.t('continue', {ns: menuNS}), handler: () => this.loadSaveSlot(this.lastSessionData ? -1 : loggedInUser.lastSessionSlot) }); } options.push({ - label: 'New Game', + label: i18next.t('menu:newGame'), handler: () => { const setModeAndEnd = (gameMode: GameModes) => { this.gameMode = gameMode; @@ -204,14 +205,14 @@ export class TitlePhase extends Phase { }); } options.push({ - label: 'Cancel', + label: i18next.t('menu:cancel'), handler: () => { this.scene.clearPhaseQueue(); this.scene.pushPhase(new TitlePhase(this.scene)); super.end(); } }); - this.scene.ui.showText('Select a game mode.', null, () => this.scene.ui.setOverlayMode(Mode.OPTION_SELECT, { options: options })); + this.scene.ui.showText(i18next.t("menu:selectGameMode"), null, () => this.scene.ui.setOverlayMode(Mode.OPTION_SELECT, { options: options })); } else { this.gameMode = GameModes.CLASSIC; this.scene.ui.setMode(Mode.MESSAGE); @@ -221,7 +222,7 @@ export class TitlePhase extends Phase { } }, { - label: 'Load Game', + label: i18next.t('menu:loadGame'), handler: () => this.scene.ui.setOverlayMode(Mode.SAVE_SLOT, SaveSlotUiMode.LOAD, (slotId: integer) => { if (slotId === -1) @@ -231,7 +232,7 @@ export class TitlePhase extends Phase { ) }, { - label: 'Daily Run (Beta)', + label: i18next.t('menu:dailyRun'), handler: () => this.initDailyRun(), keepOpen: true }); diff --git a/src/plugins/i18n.ts b/src/plugins/i18n.ts new file mode 100644 index 00000000000..3d2f6da45d3 --- /dev/null +++ b/src/plugins/i18n.ts @@ -0,0 +1,17 @@ +import i18next from 'i18next'; +import { menu as enMenu } from '../locales/en/menu'; + +export const menuNS = 'menu'; + +i18next.init({ + lng: 'en', // Default language + fallbackLng: 'en', // Fallback language + debug: true, // Enable debug mode (optional) + resources: { + en: { + menu: enMenu, + }, + }, +}); + +export default i18next; \ No newline at end of file