diff options
author | Daniel Weipert <code@drogueronin.de> | 2023-08-24 14:42:12 +0200 |
---|---|---|
committer | Daniel Weipert <code@drogueronin.de> | 2023-08-24 14:42:12 +0200 |
commit | bde5dc98ad96546b59e91f5a6e552bf80cbf48e4 (patch) | |
tree | 37196f5b5065c61ac038ae43d6f2392e29e39371 /resources | |
parent | 7b1c251fcb085dc37de439ea1137373f1905d82e (diff) |
translations and error handling
Diffstat (limited to 'resources')
-rw-r--r-- | resources/js/classes/Area.js | 6 | ||||
-rw-r--r-- | resources/js/db.js | 1 | ||||
-rw-r--r-- | resources/js/game.js | 8 | ||||
-rw-r--r-- | resources/js/helpers.js | 36 | ||||
-rw-r--r-- | resources/js/main.js | 6 | ||||
-rw-r--r-- | resources/js/memory.js | 1 | ||||
-rw-r--r-- | resources/js/ui.js | 81 |
7 files changed, 102 insertions, 37 deletions
diff --git a/resources/js/classes/Area.js b/resources/js/classes/Area.js index e8d7acc..f518f22 100644 --- a/resources/js/classes/Area.js +++ b/resources/js/classes/Area.js @@ -12,7 +12,11 @@ class Area { async initialize () {} get name () { - return DB.areas[this.slug].name; + return translate(this.alternateSlug) || slugToName(this.slug); + } + + get alternateSlug () { + return DB.areas[this.slug]['modules/tuxemon.slug']; } get encounters () { diff --git a/resources/js/db.js b/resources/js/db.js index f5cff6c..a04d32e 100644 --- a/resources/js/db.js +++ b/resources/js/db.js @@ -87,6 +87,7 @@ async function initializeDB () { } await fetchTranslation(Memory.state.Settings.language); + applyTranslation(); DB.currencies = await fetch('/db/_generated/currencies.json').then((response) => response.json()); } diff --git a/resources/js/game.js b/resources/js/game.js index 663e6b0..0ba5a8d 100644 --- a/resources/js/game.js +++ b/resources/js/game.js @@ -954,7 +954,7 @@ const Game = { }; // Game click bindings -UI.elements.nextTrainer.addEventListener('click', Game.encounterTrainer); -UI.elements.battleOpponent.addEventListener('click', Game.battleClick); -UI.elements.techniques.addEventListener('click', Game.techniqueClick); -UI.elements.menuCatch.addEventListener('click', Game.catchMonster); +UI.elements.nextTrainer.addEventListener('click', UI.createEventListener(Game.encounterTrainer)); +UI.elements.battleOpponent.addEventListener('click', UI.createEventListener(Game.battleClick)); +UI.elements.techniques.addEventListener('click', UI.createEventListener(Game.techniqueClick)); +UI.elements.menuCatch.addEventListener('click', UI.createEventListener(Game.catchMonster)); diff --git a/resources/js/helpers.js b/resources/js/helpers.js index adf0bb7..58e2113 100644 --- a/resources/js/helpers.js +++ b/resources/js/helpers.js @@ -59,9 +59,41 @@ function randomString () { /** * @param {string} msgid + * + * @returns {string} */ -function translate (msgid) { - return DB.translations[Memory.state.Settings.language][msgid]; +function translate (msgid, showTranslationMissing = false) { + let translation = DB.translations[Memory.state.Settings.language][msgid]; + + if (!translation && showTranslationMissing) { + translation = (translate('translation_missing') || 'translation_missing') + `: ${msgid}`; + } + + return translation; +} + +function applyTranslation () { + document.querySelectorAll('body, template').forEach((element) => { + let parentNode = element; + if (element.content) { + parentNode = element.content; + } + + parentNode.querySelectorAll('[data-i18n-msgid]').forEach((node) => { + node.innerHTML = translate(node.dataset.i18nMsgid, true); + }); + + parentNode.querySelectorAll('[data-i18n-properties]').forEach((node) => { + const properties = node.dataset.i18nProperties.split(',') + const msgids = node.dataset.i18nPropertyMsgids.split(',') + for (const idx in properties) { + const property = properties[idx]; + const msgid = msgids[idx]; + + node.setAttribute(property, translate(msgid, true)) + } + }); + }); } /** diff --git a/resources/js/main.js b/resources/js/main.js index 6ea94e2..aa86423 100644 --- a/resources/js/main.js +++ b/resources/js/main.js @@ -1,4 +1,4 @@ -(async function () { +UI.createEventListener(async function () { await initializeDB(); // Start Game @@ -7,7 +7,7 @@ const monsterSelection = UI.openStarterMonsterSelection( await Promise.all(possibleStarterMonsters.map(async (monsterSlug) => await fetchMonster(monsterSlug))) ); - monsterSelection.addEventListener('starter:monster:selected', async (event) => { + monsterSelection.addEventListener('starter:monster:selected', UI.createEventListener(async (event) => { if (!confirm(`Select ${event.detail.monster.name}?`)) { return; } @@ -35,5 +35,5 @@ UI.drawActiveTechniques(); event.detail.popup.remove(); - }); + })); })(); diff --git a/resources/js/memory.js b/resources/js/memory.js index 40be4df..6023e49 100644 --- a/resources/js/memory.js +++ b/resources/js/memory.js @@ -173,6 +173,7 @@ const Memory = { Memory.state.Settings.language = loadedState.Settings.language; await fetchTranslation(Memory.state.Settings.language); + applyTranslation(); Memory.state.Settings.currency = loadedState.Settings.currency; Memory.state.Settings.logMaxLength = loadedState.Settings.logMaxLength; diff --git a/resources/js/ui.js b/resources/js/ui.js index 6f38867..77b5b54 100644 --- a/resources/js/ui.js +++ b/resources/js/ui.js @@ -725,7 +725,7 @@ const UI = { template.querySelector('[data-template-slot="heal"]').addEventListener('click', () => { const applicableMonsters = Memory.state.player.monsters.filter((monster) => monster.hp < monster.stats.hp || monster.statusEffect); if (applicableMonsters.length === 0) { - alert('No applicable monsters.'); + alert(translate('ui:no_applicable_monsters', true)); return; } @@ -1004,7 +1004,8 @@ const UI = { const connection = currentArea.connections[connectionSlug]; const connectionNode = UI.createTemplate(Template.areaSelectionItem); - connectionNode.querySelector('[data-template-slot="text"]').textContent = connection.name; + connectionNode.querySelector('[data-template-slot="text"]').textContent = + translate(connection['modules/tuxemon.slug']) || slugToName(connection['modules/tuxemon.slug']); let canGo = true; for (const condition of connection.conditions) { @@ -1090,27 +1091,27 @@ const UI = { const tabs = { heal: { - heading: 'Heal', + heading: translate('ui:inventory:tab:heal'), items: [], }, stats: { - heading: 'Stats', + heading: translate('ui:inventory:tab:stats'), items: [], }, balls: { - heading: 'Balls', + heading: translate('ui:inventory:tab:balls'), items: [], }, techniques: { - heading: 'Techniques', + heading: translate('ui:inventory:tab:techniques'), items: [], }, other: { - heading: 'Other', + heading: translate('ui:inventory:tab:other'), items: [], }, keyItems: { - heading: 'Key Items', + heading: translate('ui:inventory:tab:key_items'), items: [], }, }; @@ -1180,13 +1181,13 @@ const UI = { const popup = UI.createPopup(); const journal = UI.createTemplate(Template.menuJournal); - journal.querySelector('[data-template-slot="save"]').addEventListener('click', () => { + journal.querySelector('[data-template-slot="save"]').addEventListener('click', UI.createEventListener(() => { UI.openSaveDialog(); - }); + })); - journal.querySelector('[data-template-slot="load"]').addEventListener('click', () => { + journal.querySelector('[data-template-slot="load"]').addEventListener('click', UI.createEventListener(() => { UI.openLoadDialog(); - }); + })); popup.querySelector('.popup').appendChild(journal); UI.drawPopup(popup); @@ -1237,9 +1238,9 @@ const UI = { Memory.state.Settings.language = selected.value; await fetchTranslation(Memory.state.Settings.language); - UI.drawOpponentMonster(); - UI.drawActiveMonster(); - UI.drawActiveTechniques(); + applyTranslation(); + + UI.drawArea(); }); @@ -1572,7 +1573,7 @@ const UI = { template.classList.add('inventory__monster-selection'); if (template.children.length === 0) { - alert('No applicable monsters.'); + alert(translate('ui:no_applicable_monsters', true)); return; } @@ -1608,14 +1609,14 @@ const UI = { const saveData = Memory.save(); dialog.querySelector('[data-template-slot="saveData"]').value = saveData; - dialog.querySelector('[data-template-slot="saveClipboard"]').addEventListener('click', async () => { + dialog.querySelector('[data-template-slot="saveClipboard"]').addEventListener('click', UI.createEventListenr(async () => { if (navigator.clipboard) { await navigator.clipboard.writeText(saveData); alert('Saved to clipboard!'); } else { alert('ERROR: Browser can\'t copy to clipboard! You have to do it manually.'); } - }); + })); popup.querySelector('.popup').appendChild(dialog); UI.drawPopup(popup); @@ -1625,24 +1626,50 @@ const UI = { const popup = UI.createPopup(); const dialog = UI.createTemplate(Template.dialogLoad); - dialog.querySelector('[data-template-slot="load"]').addEventListener('click', () => { + dialog.querySelector('[data-template-slot="load"]').addEventListener('click', UI.createEventListener(() => { Memory.load( dialog.querySelector('[data-template-slot="saveData"]').value.trim() ); document.querySelectorAll('.popup__overlay').forEach((element) => element.remove()) - }); + })); popup.querySelector('.popup').appendChild(dialog); UI.drawPopup(popup); }, + + + // Error + + /** + * @param {Function} listener + * + * @returns {Function} + */ + createEventListener (listener) { + return (event) => { + try { + listener(event); + } catch (exception) { + console.log(exception); + UI.showErrorMessage(exception); + } + }; + }, + + /** + * @param {string} message + */ + showErrorMessage (message) { + alert(message); + }, }; // UI element click bindings -UI.elements.showMap.addEventListener('click', UI.openMap); -UI.elements.changeArea.addEventListener('click', UI.openAreaSelection); -UI.elements.menuParty.addEventListener('click', UI.openPartyMenu); -UI.elements.menuInventory.addEventListener('click', UI.openInventoryMenu); -UI.elements.menuLog.addEventListener('click', UI.toggleLog); -UI.elements.menuJournal.addEventListener('click', UI.openJournalMenu); -UI.elements.menuSettings.addEventListener('click', UI.openSettingsMenu); +UI.elements.showMap.addEventListener('click', UI.createEventListener(UI.openMap)); +UI.elements.changeArea.addEventListener('click', UI.createEventListener(UI.createEventListener(UI.openAreaSelection))); +UI.elements.menuParty.addEventListener('click', UI.createEventListener(UI.openPartyMenu)); +UI.elements.menuInventory.addEventListener('click', UI.createEventListener(UI.openInventoryMenu)); +UI.elements.menuLog.addEventListener('click', UI.createEventListener(UI.toggleLog)); +UI.elements.menuJournal.addEventListener('click', UI.createEventListener(UI.openJournalMenu)); +UI.elements.menuSettings.addEventListener('click', UI.createEventListener(UI.openSettingsMenu)); |