diff --git a/module/applications/sheets/api/application-mixin.mjs b/module/applications/sheets/api/application-mixin.mjs index 83dc1581..ab1c9ab2 100644 --- a/module/applications/sheets/api/application-mixin.mjs +++ b/module/applications/sheets/api/application-mixin.mjs @@ -121,7 +121,7 @@ export default function DHApplicationMixin(Base) { } } ], - dragDrop: [], + dragDrop: [{ dragSelector: '.inventory-item[data-type="effect"]', dropSelector: null }], tagifyConfigs: [] }; @@ -249,14 +249,37 @@ export default function DHApplicationMixin(Base) { * @param {DragEvent} event * @protected */ - _onDragStart(event) {} + async _onDragStart(event) { + const inventoryItem = event.currentTarget.closest('.inventory-item'); + if (inventoryItem) { + const { type, itemUuid } = inventoryItem.dataset; + if (type === 'effect') { + const effect = await foundry.utils.fromUuid(itemUuid); + const effectData = { + type: 'ActiveEffect', + data: { ...effect.toObject(), _id: null }, + fromInternal: this.document.uuid + }; + event.dataTransfer.setData('text/plain', JSON.stringify(effectData)); + event.dataTransfer.setDragImage(inventoryItem.querySelector('img'), 60, 0); + } + } + } /** * Handle drop event. * @param {DragEvent} event * @protected */ - _onDrop(event) {} + _onDrop(event) { + event.stopPropagation(); + const data = foundry.applications.ux.TextEditor.implementation.getDragEventData(event); + if (data.fromInternal === this.document.uuid) return; + + if (data.type === 'ActiveEffect') { + this.document.createEmbeddedDocuments('ActiveEffect', [data.data]); + } + } /* -------------------------------------------- */ /* Context Menu */ diff --git a/module/applications/sheets/api/base-actor.mjs b/module/applications/sheets/api/base-actor.mjs index 67cec44f..2535142f 100644 --- a/module/applications/sheets/api/base-actor.mjs +++ b/module/applications/sheets/api/base-actor.mjs @@ -195,6 +195,8 @@ export default class DHBaseActorSheet extends DHApplicationMixin(ActorSheetV2) { }; event.dataTransfer.setData('text/plain', JSON.stringify(attackData)); event.dataTransfer.setDragImage(attackItem.querySelector('img'), 60, 0); + } else if (this.document.type !== 'environment') { + super._onDragStart(event); } } } diff --git a/module/applications/sheets/api/base-item.mjs b/module/applications/sheets/api/base-item.mjs index a9d3237d..9d7df6ee 100644 --- a/module/applications/sheets/api/base-item.mjs +++ b/module/applications/sheets/api/base-item.mjs @@ -252,6 +252,8 @@ export default class DHBaseItemSheet extends DHApplicationMixin(ItemSheetV2) { }; event.dataTransfer.setData('text/plain', JSON.stringify(actionData)); event.dataTransfer.setDragImage(actionItem.querySelector('img'), 60, 0); + } else { + super._onDragStart(event); } } } @@ -261,6 +263,8 @@ export default class DHBaseItemSheet extends DHApplicationMixin(ItemSheetV2) { * @param {DragEvent} event - The drag event */ async _onDrop(event) { + super._onDrop(event); + const data = foundry.applications.ux.TextEditor.implementation.getDragEventData(event); if (data.fromInternal) return; diff --git a/module/applications/sheets/api/item-attachment-sheet.mjs b/module/applications/sheets/api/item-attachment-sheet.mjs index 73c39923..2898f5ac 100644 --- a/module/applications/sheets/api/item-attachment-sheet.mjs +++ b/module/applications/sheets/api/item-attachment-sheet.mjs @@ -41,7 +41,7 @@ export default function ItemAttachmentSheet(Base) { } async _onDrop(event) { - const data = TextEditor.getDragEventData(event); + const data = foundry.applications.ux.TextEditor.implementation.getDragEventData(event); const attachmentsSection = event.target.closest('.attachments-section'); if (!attachmentsSection) return super._onDrop(event); diff --git a/module/applications/sheets/items/ancestry.mjs b/module/applications/sheets/items/ancestry.mjs index c7796f9a..8c0a5620 100644 --- a/module/applications/sheets/items/ancestry.mjs +++ b/module/applications/sheets/items/ancestry.mjs @@ -27,6 +27,9 @@ export default class AncestrySheet extends DHHeritageSheet { * @param {DragEvent} event - The drag event */ async _onDrop(event) { + const data = TextEditor.getDragEventData(event); + if (data.type === 'ActiveEffect') return super._onDrop(event); + const target = event.target.closest('fieldset.drop-section'); const typeField = this.document.system[target.dataset.type === 'primary' ? 'primaryFeature' : 'secondaryFeature']; diff --git a/module/applications/sheets/items/class.mjs b/module/applications/sheets/items/class.mjs index 79a689d8..01f4249a 100644 --- a/module/applications/sheets/items/class.mjs +++ b/module/applications/sheets/items/class.mjs @@ -115,16 +115,17 @@ export default class ClassSheet extends DHBaseItemSheet { async _onDrop(event) { event.stopPropagation(); const data = TextEditor.getDragEventData(event); - const item = await fromUuid(data.uuid); + const item = data.data ?? (await fromUuid(data.uuid)); + const itemType = data.data ? data.type : item.type; const target = event.target.closest('fieldset.drop-section'); - if (item.type === 'subclass') { + if (itemType === 'subclass') { await this.document.update({ 'system.subclasses': [...this.document.system.subclasses.map(x => x.uuid), item.uuid] }); - } else if (item.type === 'feature') { + } else if (['feature', 'ActiveEffect'].includes(itemType)) { super._onDrop(event); } else if (this.document.parent?.type !== 'character') { - if (item.type === 'weapon') { + if (itemType === 'weapon') { if (target.classList.contains('primary-weapon-section')) { if (!item.system.secondary) await this.document.update({ @@ -136,21 +137,21 @@ export default class ClassSheet extends DHBaseItemSheet { 'system.characterGuide.suggestedSecondaryWeapon': item.uuid }); } - } else if (item.type === 'armor') { + } else if (itemType === 'armor') { if (target.classList.contains('armor-section')) { await this.document.update({ 'system.characterGuide.suggestedArmor': item.uuid }); } } else if (target.classList.contains('choice-a-section')) { - if (item.type === 'loot' || item.type === 'consumable') { + if (itemType === 'loot' || itemType === 'consumable') { const filteredChoiceA = this.document.system.inventory.choiceA; if (filteredChoiceA.length < 2) await this.document.update({ 'system.inventory.choiceA': [...filteredChoiceA.map(x => x.uuid), item.uuid] }); } - } else if (item.type === 'loot') { + } else if (itemType === 'loot') { if (target.classList.contains('take-section')) { const filteredTake = this.document.system.inventory.take.filter(x => x); if (filteredTake.length < 3)