Skip to content

Commit

Permalink
[#893] Remove manual sorting from summoning profiles
Browse files Browse the repository at this point in the history
  • Loading branch information
arbron committed Feb 29, 2024
1 parent a78f797 commit 0180b13
Show file tree
Hide file tree
Showing 4 changed files with 6 additions and 73 deletions.
13 changes: 0 additions & 13 deletions less/v1/items.less
Original file line number Diff line number Diff line change
Expand Up @@ -480,24 +480,11 @@
border-radius: 4px;
box-shadow: 0 0 4px var(--dnd5e-shadow-45);

&:has(.drag-bar) { padding-inline-end: 18px; }

.details {
gap: 4px;
input { height: unset; }
input::placeholder { opacity: .5; }
}
.drag-bar {
position: absolute;
display: flex;
align-items: center;
justify-content: center;
inset-block: 0;
inset-inline-end: 0;
inline-size: 16px;
cursor: grab;
color: var(--dnd5e-color-faint);
}
[data-action="delete-profile"] {
--size: 26px;
flex: 0 0 var(--size);
Expand Down
60 changes: 4 additions & 56 deletions module/applications/item/summoning-config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export default class SummoningConfig extends DocumentSheet {
static get defaultOptions() {
return foundry.utils.mergeObject(super.defaultOptions, {
classes: ["dnd5e", "summoning-config"],
dragDrop: [{ dragSelector: ".drag-bar", dropSelector: "form" }],
dragDrop: [{ dropSelector: "form" }],
template: "systems/dnd5e/templates/apps/summoning-config.hbs",
width: 500,
height: "auto",
Expand Down Expand Up @@ -48,7 +48,9 @@ export default class SummoningConfig extends DocumentSheet {
const profile = { id: p._id, ...p };
if ( p.uuid ) profile.document = fromUuidSync(p.uuid);
return profile;
}).sort((lhs, rhs) => lhs.sort - rhs.sort);
}).sort((lhs, rhs) =>
(lhs.name || lhs.document?.name || "").localeCompare(rhs.name || rhs.document?.name || "", game.i18n.lang)
);
context.summons = this.document.system.summons;
return context;
}
Expand Down Expand Up @@ -76,13 +78,11 @@ export default class SummoningConfig extends DocumentSheet {
_getSubmitData(...args) {
const data = foundry.utils.expandObject(super._getSubmitData(...args));
data.profiles = Object.values(data.profiles ?? {});
const highestSort = this.profiles.reduce((sort, i) => i.sort > sort ? i.sort : sort, 0);

switch ( data.action ) {
case "add-profile":
data.profiles.push({
_id: foundry.utils.randomID(),
sort: highestSort + CONST.SORT_INTEGER_DENSITY,
...(data.addDetails ?? {})
});
break;
Expand Down Expand Up @@ -112,27 +112,11 @@ export default class SummoningConfig extends DocumentSheet {

/* -------------------------------------------- */

/** @inheritDoc */
_onDragStart(event) {
const entry = event.target.closest("[data-profile-id]");
if ( !entry ) return;
event.dataTransfer.setData("text/plain", JSON.stringify({
type: "summoning-profile", item: this.document.uuid, profileId: entry.dataset.profileId
}));
const box = entry.getBoundingClientRect();
event.dataTransfer.setDragImage(entry, box.width - 6, box.height / 2);
}

/* -------------------------------------------- */

/** @inheritDoc */
async _onDrop(event) {
// Try to extract the data
const data = TextEditor.getDragEventData(event);

// Handle re-ordering of list
if ( data.item === this.document.uuid ) return this._onSortEntry(event, data);

// Handle dropping linked items
if ( data?.type !== "Actor" ) return;
const actor = await Actor.implementation.fromDropData(data);
Expand All @@ -147,40 +131,4 @@ export default class SummoningConfig extends DocumentSheet {
// Otherwise create a new profile
else this.submit({ updateData: { action: "add-profile", addDetails: { uuid: actor.uuid } } });
}

/* -------------------------------------------- */

/**
* Sort a profile on drop.
* @param {DragEvent} event Triggering drop event.
* @param {object} data Drag event data.
*/
_onSortEntry(event, data) {
const dropArea = event.target.closest("[data-profile-id]");
const dragProfile = this.profiles.find(p => p._id === data?.profileId);
const dropProfile = this.profiles.find(p => p._id === dropArea?.dataset.profileId);

// Do nothing if dropped on itself
if ( dragProfile === dropProfile ) return;

const siblings = this.profiles.filter(e => e !== dragProfile).sort((lhs, rhs) => lhs.sort - rhs.sort);
let sortBefore;
let target = dropProfile;

// If dropped outside any profile, sort to top or bottom of list
if ( !target ) {
const box = this.form.getBoundingClientRect();
sortBefore = (event.clientY - box.y) < (box.height * .25);
target = sortBefore ? siblings[0] : siblings[siblings.length - 1];
}

if ( !target ) return;

const sortUpdates = SortingHelpers.performIntegerSort(dragProfile, { target, siblings, sortBefore });
const updateData = sortUpdates.reduce((obj, { target, update }) => {
obj[`profiles.${target._id}.sort`] = update.sort;
return obj;
}, {});
this.submit({ updateData });
}
}
4 changes: 2 additions & 2 deletions module/data/item/templates/action.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@ const {
* Information for a single summoned creature.
*
* @typedef {object} SummonsProfile
* @property {string} _id Unique ID for this profile.
* @property {number} count Number of creatures to summon.
* @property {string} label Display name for this profile if it differs from actor's name.
* @property {string} name Display name for this profile if it differs from actor's name.
* @property {string} uuid UUID of the actor to summon.
*/

Expand Down Expand Up @@ -84,7 +85,6 @@ export default class ActionTemplate extends ItemDataModel {
_id: new DocumentIdField({initial: () => foundry.utils.randomID()}),
count: new NumberField({integer: true, min: 1}),
name: new StringField(),
sort: new IntegerSortField(),
uuid: new StringField()
}))
})
Expand Down
2 changes: 0 additions & 2 deletions templates/apps/summoning-config.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,7 @@
<i class="fa-solid fa-trash fa-fw" inert></i>
</button>
</div>
<div class="drag-bar"><i class="fa-solid fa-grip-lines-vertical" inert></i></div>
<input type="hidden" name="profiles.{{ id }}._id" value="{{ id }}">
<input type="hidden" name="profiles.{{ id }}.sort" value="{{ sort }}" data-dtype="Number">
<input type="hidden" name="profiles.{{ id }}.uuid" value="{{ uuid }}">
</li>
{{else}}
Expand Down

0 comments on commit 0180b13

Please sign in to comment.