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)); | 
