feat(settings/options/language): implement language selection menu
This commit is contained in:
@@ -1,13 +1,120 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
const { locales, locale, setLocale } = useI18n();
|
||||||
|
const store = useSettingsStore();
|
||||||
|
const confirmationModal = useConfirmationModal();
|
||||||
|
const { assets } = useAssets();
|
||||||
const { onRender } = useScreen();
|
const { onRender } = useScreen();
|
||||||
|
|
||||||
|
const BUTTON_KEYS = [
|
||||||
|
"english",
|
||||||
|
"german",
|
||||||
|
"french",
|
||||||
|
"spanish",
|
||||||
|
"italian",
|
||||||
|
"japanese",
|
||||||
|
] as const;
|
||||||
|
|
||||||
|
const BUTTON_POSITIONS = [
|
||||||
|
[15, 32],
|
||||||
|
[143, 32],
|
||||||
|
[15, 80],
|
||||||
|
[143, 80],
|
||||||
|
[15, 128],
|
||||||
|
[143, 128],
|
||||||
|
] as const;
|
||||||
|
|
||||||
|
const { selected, selectorPosition } = useButtonNavigation({
|
||||||
|
buttons: {
|
||||||
|
english: [10, 27, 106, 41],
|
||||||
|
german: [138, 27, 106, 41],
|
||||||
|
french: [10, 75, 106, 41],
|
||||||
|
spanish: [138, 75, 106, 41],
|
||||||
|
italian: [10, 123, 106, 41],
|
||||||
|
japanese: [138, 123, 106, 41],
|
||||||
|
},
|
||||||
|
initialButton:
|
||||||
|
BUTTON_KEYS[locales.value.findIndex((l) => l.code === locale.value)] ??
|
||||||
|
BUTTON_KEYS[0]!,
|
||||||
|
navigation: {
|
||||||
|
english: {
|
||||||
|
right: "german",
|
||||||
|
down: "french",
|
||||||
|
},
|
||||||
|
german: {
|
||||||
|
left: "english",
|
||||||
|
down: "spanish",
|
||||||
|
},
|
||||||
|
french: {
|
||||||
|
up: "english",
|
||||||
|
right: "spanish",
|
||||||
|
down: "italian",
|
||||||
|
},
|
||||||
|
spanish: {
|
||||||
|
up: "german",
|
||||||
|
left: "french",
|
||||||
|
down: "japanese",
|
||||||
|
},
|
||||||
|
italian: {
|
||||||
|
up: "french",
|
||||||
|
right: "japanese",
|
||||||
|
},
|
||||||
|
japanese: {
|
||||||
|
up: "spanish",
|
||||||
|
left: "italian",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const handleCancel = () => {
|
||||||
|
store.closeSubMenu();
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleConfirm = () => {
|
||||||
|
const selectedLocale = locales.value[BUTTON_KEYS.indexOf(selected.value)]!;
|
||||||
|
|
||||||
|
setLocale(selectedLocale.code);
|
||||||
|
|
||||||
|
confirmationModal.open({
|
||||||
|
text: $t(
|
||||||
|
"settings.options.language.confirmation",
|
||||||
|
{},
|
||||||
|
{ locale: selectedLocale.code },
|
||||||
|
),
|
||||||
|
onClosed: () => store.closeSubMenu(),
|
||||||
|
});
|
||||||
|
// TODO: add "timeout" to confirmationModal.open
|
||||||
|
setTimeout(() => confirmationModal.close(), 2000);
|
||||||
|
};
|
||||||
|
|
||||||
onRender((ctx) => {
|
onRender((ctx) => {
|
||||||
ctx.font = "10px NDS10";
|
ctx.font = "10px NDS10";
|
||||||
ctx.fillStyle = "#000000";
|
ctx.fillStyle = "#010101";
|
||||||
ctx.fillText("Language", 10, 20);
|
|
||||||
|
for (let i = 0; i < locales.value.length; i += 1) {
|
||||||
|
const [x, y] = BUTTON_POSITIONS[i]!;
|
||||||
|
const isSelected = selected.value === BUTTON_KEYS[i];
|
||||||
|
const buttonImage = isSelected
|
||||||
|
? assets.images.settings.bottomScreen.options.languageButtonActive
|
||||||
|
: assets.images.settings.bottomScreen.options.languageButton;
|
||||||
|
|
||||||
|
buttonImage.draw(ctx, x, y, isSelected ? { colored: true } : undefined);
|
||||||
|
fillTextHCentered(ctx, locales.value[i].name, x, y + 20, 96);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
render: () => null,
|
render: () => null,
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<CommonButtons
|
||||||
|
:y-offset="0"
|
||||||
|
b-label="Cancel"
|
||||||
|
a-label="Confirm"
|
||||||
|
@activate-b="handleCancel"
|
||||||
|
@activate-a="handleConfirm"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<CommonButtonSelector :rect="selectorPosition" />
|
||||||
|
</template>
|
||||||
|
|||||||
1
i18n/locales/de.json
Normal file
1
i18n/locales/de.json
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{}
|
||||||
@@ -23,7 +23,8 @@
|
|||||||
},
|
},
|
||||||
"language": {
|
"language": {
|
||||||
"title": "Language",
|
"title": "Language",
|
||||||
"description": "Select the language to use."
|
"description": "Select the language to use.",
|
||||||
|
"confirmation": "Language set to English."
|
||||||
},
|
},
|
||||||
"gbaMode": {
|
"gbaMode": {
|
||||||
"title": "GBA Mode",
|
"title": "GBA Mode",
|
||||||
|
|||||||
1
i18n/locales/es.json
Normal file
1
i18n/locales/es.json
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{}
|
||||||
1
i18n/locales/fr.json
Normal file
1
i18n/locales/fr.json
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{}
|
||||||
1
i18n/locales/it.json
Normal file
1
i18n/locales/it.json
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{}
|
||||||
1
i18n/locales/ja.json
Normal file
1
i18n/locales/ja.json
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{}
|
||||||
@@ -20,7 +20,14 @@ export default defineNuxtConfig({
|
|||||||
},
|
},
|
||||||
i18n: {
|
i18n: {
|
||||||
strategy: "no_prefix",
|
strategy: "no_prefix",
|
||||||
locales: [{ code: "en", language: "en-US", file: "en.json" }],
|
locales: [
|
||||||
|
{ code: "en", language: "en-US", name: "English", file: "en.json" },
|
||||||
|
{ code: "de", language: "de-DE", name: "Deutsch", file: "de.json" },
|
||||||
|
{ code: "fr", language: "fr-FR", name: "Français", file: "fr.json" },
|
||||||
|
{ code: "es", language: "es-ES", name: "Español", file: "es.json" },
|
||||||
|
{ code: "it", language: "it-IT", name: "Italiano", file: "it.json" },
|
||||||
|
{ code: "ja", language: "ja-JP", name: "日本語", file: "ja.json" },
|
||||||
|
],
|
||||||
defaultLocale: "en",
|
defaultLocale: "en",
|
||||||
},
|
},
|
||||||
image: {
|
image: {
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 1.6 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 120 B |
Reference in New Issue
Block a user