const { HandlebarsApplicationMixin } = foundry.applications.api export default class WastelandItemSheet extends HandlebarsApplicationMixin(foundry.applications.sheets.ItemSheetV2) { constructor(options = {}) { super(options) this.#dragDrop = this.#createDragDropHandlers() } #dragDrop /** @override */ static DEFAULT_OPTIONS = { classes: ["fvtt-wasteland", "item"], position: { width: 620, height: 600, }, form: { submitOnChange: true, }, window: { resizable: true, }, tabs: [ { navSelector: 'nav[data-group="primary"]', contentSelector: "section.sheet-body", initial: "description", }, ], dragDrop: [{ dragSelector: "[data-drag]", dropSelector: null }], actions: { editImage: WastelandItemSheet.#onEditImage, postItem: WastelandItemSheet.#onPostItem, }, } /** * Tab groups state * @type {object} */ tabGroups = { primary: "description" } /** @override */ async _prepareContext() { const context = { fields: this.document.schema.fields, systemFields: this.document.system.schema.fields, item: this.document, system: this.document.system, source: this.document.toObject(), enrichedDescription: await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.description, { async: true }), isEditMode: true, isEditable: this.isEditable, isGM: game.user.isGM, config: game.system.wasteland.config, } return context } /** @override */ _onRender(context, options) { super._onRender(context, options) this.#dragDrop.forEach((d) => d.bind(this.element)) // Activate tab navigation manually const nav = this.element.querySelector('nav.tabs[data-group]') if (nav) { const group = nav.dataset.group // Activate the current tab const activeTab = this.tabGroups[group] || "description" nav.querySelectorAll('[data-tab]').forEach(link => { const tab = link.dataset.tab link.classList.toggle('active', tab === activeTab) link.addEventListener('click', (event) => { event.preventDefault() this.tabGroups[group] = tab this.render() }) }) // Show/hide tab content this.element.querySelectorAll('[data-group="' + group + '"][data-tab]').forEach(content => { content.classList.toggle('active', content.dataset.tab === activeTab) }) } } // #region Drag-and-Drop Workflow /** * Create drag-and-drop workflow handlers for this Application */ #createDragDropHandlers() { return [] } // #region Actions /** * Handle editing the item image * @param {Event} event - The triggering event */ static async #onEditImage(event) { event.preventDefault() const filePicker = new FilePicker({ type: "image", current: this.document.img, callback: (path) => { this.document.update({ img: path }) }, }) filePicker.browse() } /** * Handle posting the item to chat * @param {Event} event - The triggering event */ static async #onPostItem(event) { event.preventDefault() // Prepare chat data const chatData = { name: this.document.name, img: this.document.img, type: this.document.type, system: this.document.system, } // Add actor reference if item is owned if (this.document.actor) { chatData.actor = { id: this.document.actor.id } } // Don't post any image for the item if the default image is used if (chatData.img && chatData.img.includes("/blank.png")) { chatData.img = null } // JSON object for easy creation chatData.jsondata = JSON.stringify({ compendium: "postedItem", payload: chatData, }) // Render the chat card template const html = await foundry.applications.handlebars.renderTemplate('systems/fvtt-wasteland/templates/post-item.hbs', chatData) // Create the chat message const chatOptions = { user: game.user.id, content: html, speaker: ChatMessage.getSpeaker({ actor: this.document.actor }) } ChatMessage.create(chatOptions) } }