From d3e65b98ca932aef1e05e33d74eaf62be520cdd4 Mon Sep 17 00:00:00 2001 From: Daniel Weipert Date: Fri, 18 Aug 2023 16:07:39 +0200 Subject: inventory and items --- resources/js/ui.js | 148 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 144 insertions(+), 4 deletions(-) (limited to 'resources/js/ui.js') diff --git a/resources/js/ui.js b/resources/js/ui.js index 3739ce6..455e785 100644 --- a/resources/js/ui.js +++ b/resources/js/ui.js @@ -1,6 +1,11 @@ const Template = { popup: document.querySelector('#tpl___popup'), + tabs: document.querySelector('#tpl___tabs'), + tabHeading: document.querySelector('#tpl___tabs__tab-heading'), + tabPanels: document.querySelector('#tpl___tabs__panels'), + tabPanel: document.querySelector('#tpl___tabs__tab-panel'), + battleMonster: document.querySelector('#tpl___battle__monster'), battleHpBar: document.querySelector('#tpl___battle__hp-bar'), battleExpBar: document.querySelector('#tpl___battle__exp-bar'), @@ -17,6 +22,9 @@ const Template = { movesetList: document.querySelector('#tpl___moveset__list'), movesetItem: document.querySelector('#tpl___moveset__item'), + inventory: document.querySelector('#tpl___inventory'), + inventoryItem: document.querySelector('#tpl___inventory__item'), + menuJournal: document.querySelector('#tpl___menu__journal'), dialogSave: document.querySelector('#tpl___dialog__save'), dialogLoad: document.querySelector('#tpl___dialog__load'), @@ -49,7 +57,22 @@ const UI = { const templateBase = document.createElement('div'); templateBase.innerHTML = template.innerHTML.trim(); - return templateBase.firstChild; + const templateNode = templateBase.firstChild; + + /** + * @param {HTMLElement} targetElement + */ + templateNode.appendTo = function (targetElement) { + if (templateNode.dataset.templateType && templateNode.dataset.templateType === 'multiple') { + for (const child of [...this.children]) { + targetElement.appendChild(child); + } + } else { + targetElement.appendChild(this); + } + }; + + return templateNode; }, /** @@ -68,6 +91,56 @@ const UI = { return popup; }, + /** + * @typedef {Object} Tab + * @property {HTMLElement} heading + * @property {HTMLElement} content + * @inner + * + * @param {Tab[]} tabs + * + * @returns {HTMLElement} + */ + createTabs (tabs) { + const wrap = UI.createTemplate(Template.tabs); + const panelsNode = UI.createTemplate(Template.tabPanels); + + wrap.style.gridTemplateColumns = '1fr '.repeat(tabs.length); + + const name = randomString(); + + for (const idx in tabs) { + const tab = tabs[idx]; + const tabHeading = UI.createTemplate(Template.tabHeading); + const tabPanel = UI.createTemplate(Template.tabPanel); + + const inputId = `${name}_${idx}`; + const panelId = randomString(); + + const tabHeadingInput = tabHeading.querySelector('[data-template-slot="input"]'); + tabHeadingInput.name = name; + tabHeadingInput.id = inputId; + tabHeadingInput.setAttribute('aria-controls', panelId); + if (idx == 0) { + tabHeadingInput.checked = true; + } + + const tabHeadingLabel = tabHeading.querySelector('[data-template-slot="label"]'); + tabHeadingLabel.setAttribute('for', inputId); + tabHeadingLabel.appendChild(tab.heading); + + tabPanel.id = panelId; + tabPanel.appendChild(tab.content); + + tabHeading.appendTo(wrap); + panelsNode.appendChild(tabPanel); + } + + wrap.appendChild(panelsNode); + + return wrap; + }, + /** * @param {HTMLElement} slotNode * @param {HTMLElement} replacingNode @@ -527,15 +600,82 @@ const UI = { UI.drawPopup(popup); }, - openInventoryMenu () { // TODO + openInventoryMenu () { const popup = UI.createPopup(); + const inventory = UI.createTemplate(Template.inventory); + + const tabs = { + heal: { + heading: 'Heal', + items: [], + }, + stats: { + heading: 'Stats', + items: [], + }, + balls: { + heading: 'Balls', + items: [], + }, + techniques: { + heading: 'Techniques', + items: [], + }, + other: { + heading: 'Other', + items: [], + }, + keyItems: { + heading: 'Key Items', + items: [], + }, + }; - const inventory = document.createElement('div'); - inventory.id = 'inventory'; for (const item of state.inventory) { + const inventoryItemNode = UI.createTemplate(Template.inventoryItem); + + inventoryItemNode.querySelector('[data-template-slot="sprite"]').src = `/modules/tuxemon/mods/tuxemon/${item.sprite}`; + inventoryItemNode.querySelector('[data-template-slot="name"]').textContent = item.name; + inventoryItemNode.querySelector('[data-template-slot="quantity"]').textContent = item.quantity; + + if (['potion', 'revive'].includes(item.category)) { + tabs['heal'].items.push(inventoryItemNode); + } + else if (['stats'].includes(item.category)) { + tabs['stats'].items.push(inventoryItemNode); + } + else if (['capture'].includes(item.category)) { + tabs['balls'].items.push(inventoryItemNode); + } + else if (['technique'].includes(item.category)) { + tabs['techniques'].items.push(inventoryItemNode); + } + else if (['KeyItem'].includes(item.type)) { + tabs['keyItems'].items.push(inventoryItemNode); + } + else { + tabs['other'].items.push(inventoryItemNode); + } } + const tabsNode = UI.createTabs(Object.values(tabs).map((tab) => { + const content = document.createElement('div'); + for (const item of tab.items) { + content.appendChild(item); + } + + return { + heading: document.createTextNode(tab.heading), + content: content, + }; + })); + + tabsNode.style.gridTemplateColumns = '1fr 1fr 1fr'; + inventory.appendChild(tabsNode); + popup.querySelector('.popup').appendChild(inventory); + popup.classList.add('inventory__popup'); + UI.drawPopup(popup); }, -- cgit v1.2.3