Files
fvtt-yggdrasill/modules/applications/sheets/base-item-sheet.mjs

179 lines
5.1 KiB
JavaScript

const { HandlebarsApplicationMixin } = foundry.applications.api
export default class YggdrasillItemSheet extends HandlebarsApplicationMixin(foundry.applications.sheets.ItemSheetV2) {
constructor(options = {}) {
super(options)
this.#dragDrop = this.#createDragDropHandlers()
}
#dragDrop
/** @override */
static DEFAULT_OPTIONS = {
classes: ["fvtt-yggdrasill", "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: YggdrasillItemSheet.#onEditImage,
postItem: YggdrasillItemSheet.#onPostItem,
},
}
/**
* Tab groups state
* @type {object}
*/
tabGroups = { primary: "description" }
/** @override */
async _prepareContext() {
// Import config
const YGGDRASILL_CONFIG = game.system.yggdrasill?.config || game.system.config || {};
// Create options for niveau 0-5
const optionsNiveaux4 = {};
for (let i = 0; i <= 5; i++) {
optionsNiveaux4[`${i}`] = `${i}`;
}
// Create options for base (0-20)
const optionsBase = {};
for (let i = 0; i <= 20; i++) {
optionsBase[`${i}`] = `${i}`;
}
const context = {
fields: this.document.schema.fields,
systemFields: this.document.system.schema.fields,
item: this.document,
system: this.document.system,
data: this.document.system,
source: this.document.toObject(),
enrichedDescription: await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.description || "", { async: true }),
enrichedEffet: await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.effet || "", { async: true }),
isEditMode: true,
isEditable: this.isEditable,
editable: this.isEditable,
isGM: game.user.isGM,
config: YGGDRASILL_CONFIG,
optionsBase: optionsBase,
optionsNiveaux4: optionsNiveaux4,
}
return context
}
/** @override */
_onRender(context, options) {
super._onRender(context, options)
// 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
const body = this.element.querySelector('section.sheet-body')
if (body) {
body.querySelectorAll('[data-tab]').forEach(content => {
const tab = content.dataset.tab
content.style.display = tab === activeTab ? 'block' : 'none'
})
}
}
}
/**
* Creates drag-and-drop handlers for this application
* @returns {DragDrop[]} An array of DragDrop handlers
* @private
*/
#createDragDropHandlers() {
return []
}
/**
* Handle changing a Document's image
* @this {YggdrasillItemSheet}
* @param {PointerEvent} event - The triggering event
* @param {HTMLElement} target - The button element
*/
static async #onEditImage(event, target) {
const attr = target.dataset.edit || "img"
const current = foundry.utils.getProperty(this.document, attr)
const fp = new FilePicker({
current,
type: "image",
callback: (path) => {
this.document.update({ [attr]: path })
},
})
return fp.browse()
}
/**
* Handle posting item to chat
* @this {YggdrasillItemSheet}
* @param {PointerEvent} event - The triggering event
* @param {HTMLElement} target - The button element
*/
static async #onPostItem(event, target) {
const item = this.document
const chatData = {
user: game.user.id,
speaker: ChatMessage.getSpeaker(),
content: await foundry.applications.handlebars.renderTemplate("systems/fvtt-yggdrasill/templates/chat-item-card.hbs", {
item: item,
system: item.system,
description: await TextEditor.enrichHTML(item.system.description || "", { async: true })
})
}
ChatMessage.create(chatData)
}
/**
* Handle beginning of a drag operation
* @param {DragEvent} event - The originating drag event
* @protected
*/
_onDragStart(event) {
const dragData = this.document.toDragData()
event.dataTransfer.setData("text/plain", JSON.stringify(dragData))
}
/**
* Handle a drop event
* @param {DragEvent} event - The originating drop event
* @protected
*/
async _onDrop(event) {
// Items generally don't handle drops, but method exists for extensibility
return false
}
}