From 71b40b1189e721b5a795d4942b9dd93397b0a1f7 Mon Sep 17 00:00:00 2001 From: Carlos Fernandez Date: Tue, 16 Dec 2025 01:57:26 -0500 Subject: [PATCH] Support drag dropping currencies to actor sheets --- module/applications/dialogs/_module.mjs | 1 - module/applications/dialogs/itemTransfer.mjs | 70 ---------------- module/applications/sheets/api/base-actor.mjs | 79 +++++++++++++++++-- styles/less/dialog/item-transfer/sheet.less | 43 ++++++---- templates/dialogs/item-transfer.hbs | 23 ++++-- .../sheets/actors/character/inventory.hbs | 6 +- templates/sheets/actors/party/inventory.hbs | 6 +- 7 files changed, 122 insertions(+), 106 deletions(-) delete mode 100644 module/applications/dialogs/itemTransfer.mjs diff --git a/module/applications/dialogs/_module.mjs b/module/applications/dialogs/_module.mjs index 92038c41..43faa68a 100644 --- a/module/applications/dialogs/_module.mjs +++ b/module/applications/dialogs/_module.mjs @@ -6,7 +6,6 @@ export { default as DamageReductionDialog } from './damageReductionDialog.mjs'; export { default as DeathMove } from './deathMove.mjs'; export { default as Downtime } from './downtime.mjs'; export { default as ImageSelectDialog } from './imageSelectDialog.mjs'; -export { default as ItemTransferDialog } from './itemTransfer.mjs'; export { default as MulticlassChoiceDialog } from './multiclassChoiceDialog.mjs'; export { default as OwnershipSelection } from './ownershipSelection.mjs'; export { default as RerollDamageDialog } from './rerollDamageDialog.mjs'; diff --git a/module/applications/dialogs/itemTransfer.mjs b/module/applications/dialogs/itemTransfer.mjs deleted file mode 100644 index aba43d27..00000000 --- a/module/applications/dialogs/itemTransfer.mjs +++ /dev/null @@ -1,70 +0,0 @@ -const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api; - -export default class ItemTransferDialog extends HandlebarsApplicationMixin(ApplicationV2) { - constructor(item) { - super({}); - - this.item = item; - this.quantity = item.system.quantity; - } - - get title() { - return this.item.name; - } - - static DEFAULT_OPTIONS = { - tag: 'form', - classes: ['daggerheart', 'dh-style', 'dialog', 'item-transfer'], - position: { width: 300, height: 'auto' }, - window: { icon: 'fa-solid fa-hand-holding-hand' }, - actions: { - finish: ItemTransferDialog.#finish - }, - form: { handler: this.updateData, submitOnChange: true, closeOnSubmit: false } - }; - - static PARTS = { - main: { template: 'systems/daggerheart/templates/dialogs/item-transfer.hbs' } - }; - - _attachPartListeners(partId, htmlElement, options) { - super._attachPartListeners(partId, htmlElement, options); - - htmlElement.querySelector('.number-display').addEventListener('change', event => { - this.quantity = isNaN(event.target.value) ? this.quantity : Number(event.target.value); - this.render(); - }); - } - - async _prepareContext(_options) { - const context = await super._prepareContext(_options); - context.item = this.item; - context.quantity = this.quantity; - - return context; - } - - static async updateData(_event, _element, formData) { - const { quantity } = foundry.utils.expandObject(formData.object); - this.quantity = quantity; - this.render(); - } - - static async #finish() { - this.close({ submitted: true }); - } - - close(options = {}) { - if (!options.submitted) this.quantity = null; - - super.close(); - } - - static async configure(item) { - return new Promise(resolve => { - const app = new this(item); - app.addEventListener('close', () => resolve(app.quantity), { once: true }); - app.render({ force: true }); - }); - } -} diff --git a/module/applications/sheets/api/base-actor.mjs b/module/applications/sheets/api/base-actor.mjs index adb0d39a..f0ebe250 100644 --- a/module/applications/sheets/api/base-actor.mjs +++ b/module/applications/sheets/api/base-actor.mjs @@ -34,7 +34,10 @@ export default class DHBaseActorSheet extends DHApplicationMixin(ActorSheetV2) { } } ], - dragDrop: [{ dragSelector: '.inventory-item[data-type="attack"]', dropSelector: null }] + dragDrop: [ + { dragSelector: '.inventory-item[data-type="attack"]', dropSelector: null }, + { dragSelector: ".currency[data-currency] .drag-handle", dropSelector: null } + ] }; /* -------------------------------------------- */ @@ -254,14 +257,67 @@ export default class DHBaseActorSheet extends DHApplicationMixin(ActorSheetV2) { /* Application Drag/Drop */ /* -------------------------------------------- */ + async #determineTransferQuantity({ originActor, item, currency }) { + originActor ??= item?.actor; + const max = item?.system.quantity ?? originActor.system.gold[currency] ?? null; + if (!max || max === 0) return null; + if (max === 1) return max; + + const homebrewKey = CONFIG.DH.SETTINGS.gameSettings.Homebrew; + const currencySetting = game.settings.get(CONFIG.DH.id, homebrewKey).currency?.[currency] ?? null; + const name = item?.name ?? currencySetting?.label; + + return foundry.applications.api.DialogV2.input({ + classes: ['daggerheart', 'dh-style', "item-transfer"], + content: await foundry.applications.handlebars.renderTemplate( + "systems/daggerheart/templates/dialogs/item-transfer.hbs", + { + originActor: originActor, + targetActor: this.document, + itemImage: item?.img, + currencyIcon: currencySetting?.icon, + max, + } + ), + window: { + title: name, + icon: 'fa-solid fa-hand-holding-hand' + }, + position: { + width: 400, + }, + ok: { + label: game.i18n.localize("DAGGERHEART.APPLICATIONS.ItemTransfer.transfer"), + callback: (_, button) => button.form.elements.quantity.value || null, + } + }); + } + + async _onDrop(event) { + event.stopPropagation(); + const data = foundry.applications.ux.TextEditor.implementation.getDragEventData(event); + if (data.type === 'Currency' && ['character', 'party'].includes(this.document.type)) { + const originActor = await foundry.utils.fromUuid(data.originActor); + if (!originActor || originActor.uuid === this.document.uuid) return; + const currency = data.currency; + const quantity = await this.#determineTransferQuantity({ originActor, currency }); + if (quantity) { + originActor.update({ [`system.gold.${currency}`]: Math.max(0, originActor.system.gold[currency] - quantity) }); + this.document.update({ [`system.gold.${currency}`]: this.document.system.gold[currency] + quantity }); + } + return; + } + + return super._onDrop(event); + } + async _onDropItem(event, item) { const data = foundry.applications.ux.TextEditor.implementation.getDragEventData(event); - const physicalActorTypes = ['character', 'party']; const originActor = item.actor; if ( item.actor?.uuid === this.document.uuid || !originActor || - !physicalActorTypes.includes(this.document.type) + !['character', 'party'].includes(this.document.type) ) { return super._onDropItem(event, item); } @@ -270,10 +326,7 @@ export default class DHBaseActorSheet extends DHApplicationMixin(ActorSheetV2) { if (item.system.metadata.isInventoryItem) { if (item.system.metadata.isQuantifiable) { const actorItem = originActor.items.get(data.originId); - const quantityTransfered = - actorItem.system.quantity === 1 - ? 1 - : await game.system.api.applications.dialogs.ItemTransferDialog.configure(item); + const quantityTransfered = await this.#determineTransferQuantity({ item }); if (quantityTransfered) { if (quantityTransfered === actorItem.system.quantity) { @@ -314,6 +367,16 @@ export default class DHBaseActorSheet extends DHApplicationMixin(ActorSheetV2) { * @param {DragEvent} event - The drag event */ async _onDragStart(event) { + // Handle drag/dropping currencies + const currencyEl = event.currentTarget.closest(".currency[data-currency]"); + if (currencyEl) { + const currency = currencyEl.dataset.currency; + const data = { type: 'Currency', currency, originActor: this.document.uuid }; + event.dataTransfer.setData('text/plain', JSON.stringify(data)); + return; + } + + // Handle drag/dropping attacks const attackItem = event.currentTarget.closest('.inventory-item[data-type="attack"]'); if (attackItem) { const attackData = { @@ -340,4 +403,4 @@ export default class DHBaseActorSheet extends DHApplicationMixin(ActorSheetV2) { super._onDragStart(event); } -} +} \ No newline at end of file diff --git a/styles/less/dialog/item-transfer/sheet.less b/styles/less/dialog/item-transfer/sheet.less index dd55fdb2..c95ffc03 100644 --- a/styles/less/dialog/item-transfer/sheet.less +++ b/styles/less/dialog/item-transfer/sheet.less @@ -1,20 +1,35 @@ .daggerheart.dh-style.dialog.item-transfer { - .item-transfer-container { - display: grid; - grid-template-columns: 1fr 42px; - gap: 4px; + .summary { + display: flex; + align-items: center; + justify-content: center; + gap: 2rem; + + .actor-img { + border-radius: 50%; + width: 72px; + height: 72px; + object-fit: cover; + object-position: top center; + } - .number-display { - text-align: center; + .granted-item { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + font-size: var(--font-size-32); + + img { + width: 32px; + height: 32px; + object-fit: contain; + border-radius: 3px; + } } } - - .item-sheet-footer { - padding-top: 8px; - display: flex; - - button { - flex: 1; - } + label { + flex: 0; + margin-right: 0.5rem; } } diff --git a/templates/dialogs/item-transfer.hbs b/templates/dialogs/item-transfer.hbs index 2b9fa19c..c657a180 100644 --- a/templates/dialogs/item-transfer.hbs +++ b/templates/dialogs/item-transfer.hbs @@ -1,9 +1,18 @@ -
-
- - +
+ +
+ {{#if itemImage}} + + {{else}} + + {{/if}} + +
+ +
+
+ +
+
-
- -
\ No newline at end of file diff --git a/templates/sheets/actors/character/inventory.hbs b/templates/sheets/actors/character/inventory.hbs index f9dee872..a05fed35 100644 --- a/templates/sheets/actors/character/inventory.hbs +++ b/templates/sheets/actors/character/inventory.hbs @@ -14,10 +14,10 @@ {{#if this.inventory.hasCurrency}}
- {{#each this.inventory.currencies as | currency |}} + {{#each this.inventory.currencies as |currency key|}} {{#if currency.enabled}} -
- +
+ {{localize currency.label}} diff --git a/templates/sheets/actors/party/inventory.hbs b/templates/sheets/actors/party/inventory.hbs index 09f3ba62..92371b8d 100644 --- a/templates/sheets/actors/party/inventory.hbs +++ b/templates/sheets/actors/party/inventory.hbs @@ -17,10 +17,10 @@ {{#if inventory.hasCurrency}}
- {{#each this.inventory.currencies as | currency |}} + {{#each this.inventory.currencies as |currency key|}} {{#if currency.enabled}} -
- +
+ {{localize currency.label}}