Skip to content

Commit

Permalink
[foundryvtt#2930]Add Tooltip, Context Menu Toggle, and Icons
Browse files Browse the repository at this point in the history
Added context menu localization for charge and uncharge
Added fa-arrows-rotate icon for uncharged and fa-bolt icon for charged
Added i.fa-bolt less to use the color gold
Moved isOnCooldown from sheets context to item as it was used in multiple places and outside the sheet context
Added context menu toggle to inventory.js
Added toggleCharge action to inventory.js
Modified handlebars to get isOnCooldown from item instead of context.
  • Loading branch information
Hoppyhob committed May 18, 2024
1 parent 4e97bad commit 26cc237
Show file tree
Hide file tree
Showing 9 changed files with 43 additions and 13 deletions.
2 changes: 2 additions & 0 deletions lang/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,8 @@
"DND5E.ContextMenuActionEquip": "Equip",
"DND5E.ContextMenuActionUnequip": "Unequip",
"DND5E.ContextMenuActionPrepare": "Prepare",
"DND5E.ContextMenuActionExpendCharge": "Uncharge",
"DND5E.ContextMenuActionCharge": "Charge",
"DND5E.ContextMenuActionUnprepare": "Unprepare",
"DND5E.ContextMenuActionAttune": "Attune",
"DND5E.ContextMenuActionUnattune": "Unattune",
Expand Down
8 changes: 8 additions & 0 deletions less/v2/character.less
Original file line number Diff line number Diff line change
Expand Up @@ -1299,6 +1299,14 @@
.pill-lg.empty { width: 240px; }
}

/* ---------------------------------- */
/* Features */
/* ---------------------------------- */

.features .item-uses i.fa-bolt{
color: var(--dnd5e-color-gold);
}

/* ---------------------------------- */
/* Spells */
/* ---------------------------------- */
Expand Down
5 changes: 2 additions & 3 deletions module/applications/actor/character-sheet.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export default class ActorSheet5eCharacter extends ActorSheet5e {

// Partition items by category
let {items, spells, feats, races, backgrounds, classes, subclasses} = context.items.reduce((obj, item) => {
const {quantity, uses, recharge} = item.system;
const {quantity, uses} = item.system;

// Item details
const ctx = context.itemContext[item.id] ??= {};
Expand All @@ -86,8 +86,7 @@ export default class ActorSheet5eCharacter extends ActorSheet5e {

// Item usage
ctx.hasUses = item.hasLimitedUses;
ctx.isOnCooldown = recharge && !!recharge.value && (recharge.charged === false);
ctx.isDepleted = ctx.isOnCooldown && ctx.hasUses && (uses.value > 0);
ctx.isDepleted = item.isOnCooldown && ctx.hasUses && (uses.value > 0);
ctx.hasTarget = item.hasAreaTarget || item.hasIndividualTarget;

// Unidentified items
Expand Down
3 changes: 1 addition & 2 deletions module/applications/actor/npc-sheet.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,11 @@ export default class ActorSheet5eNPC extends ActorSheet5e {
// Start by classifying items into groups for rendering
const maxLevelDelta = CONFIG.DND5E.maxLevel - (this.actor.system.details.level ?? 0);
let [spells, other] = context.items.reduce((arr, item) => {
const {quantity, uses, recharge, target} = item.system;
const {quantity, uses, target} = item.system;
const ctx = context.itemContext[item.id] ??= {};
ctx.isStack = Number.isNumeric(quantity) && (quantity !== 1);
ctx.isExpanded = this._expanded.has(item.id);
ctx.hasUses = uses && (uses.max > 0);
ctx.isOnCooldown = recharge && !!recharge.value && (recharge.charged === false);
ctx.isDepleted = item.isOnCooldown && (uses.per && (uses.value > 0));
ctx.hasTarget = !!target && !(["none", ""].includes(target.type));
ctx.canToggle = false;
Expand Down
3 changes: 1 addition & 2 deletions module/applications/actor/vehicle-sheet.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -162,12 +162,11 @@ export default class ActorSheet5eVehicle extends ActorSheet5e {
};

context.items.forEach(item => {
const {uses, recharge} = item.system;
const {uses} = item.system;
const ctx = context.itemContext[item.id] ??= {};
ctx.canToggle = false;
ctx.isExpanded = this._expanded.has(item.id);
ctx.hasUses = uses && (uses.max > 0);
ctx.isOnCooldown = recharge && !!recharge.value && (recharge.charged === false);
ctx.isDepleted = item.isOnCooldown && (uses.per && (uses.value > 0));
});

Expand Down
11 changes: 11 additions & 0 deletions module/applications/components/inventory.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,15 @@ export default class InventoryElement extends HTMLElement {
group: "state"
});

// Toggle Charged State
if ( item.isOnCooldown || item.system.recharge.value ) options.push({
name: item.system.recharge?.charged ? "DND5E.ContextMenuActionExpendCharge" : "DND5E.ContextMenuActionCharge",
icon: "<i class='fa-solid fa-bolt'></i>",
condition: () => item.isOwner,
callback: li => this._onAction(li[0], "toggleCharge"),
group: "state"
});

// Toggle Prepared State
else if ( ("preparation" in item.system) && (item.system.preparation?.mode === "prepared") ) options.push({
name: item.system?.preparation?.prepared ? "DND5E.ContextMenuActionUnprepare" : "DND5E.ContextMenuActionPrepare",
Expand Down Expand Up @@ -386,6 +395,8 @@ export default class InventoryElement extends HTMLElement {
return item.update({"system.preparation.prepared": !item.system.preparation?.prepared});
case "recharge":
return item.rollRecharge();
case "toggleCharge":
return item.update({"system.recharge.charged": !item.system.recharge?.charged});
case "unfavorite":
return this.actor.system.removeFavorite(item.getRelativeUUID(this.actor));
case "use":
Expand Down
12 changes: 12 additions & 0 deletions module/documents/item.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,18 @@ export default class Item5e extends SystemDocumentMixin(Item) {

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

/**
* Is the item on recharge cooldown?
* @type {boolean}
* @see {@link ActionTemplate#isOnCooldown}
*/
get isOnCooldown() {
const chg = this.system.recharge;
return (chg && !!chg.value && (chg.charged === false)) ?? false;
}

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

/**
* Does this item require concentration?
* @type {boolean}
Expand Down
2 changes: 1 addition & 1 deletion templates/actors/parts/actor-features.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@

{{#if section.hasActions}}
<div class="item-detail item-uses">
{{#if ctx.isOnCooldown}}
{{#if item.isOnCooldown}}
<a class="item-action" data-action="recharge">{{item.labels.recharge}}</a>
{{else if item.system.recharge.value}}
{{localize "DND5E.Charged"}}
Expand Down
10 changes: 5 additions & 5 deletions templates/actors/tabs/character-features.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -124,12 +124,12 @@
</div>

{{!-- Item Uses --}}
{{#if ctx.isOnCooldown}}
<div class="item-detail item-uses">
<a class="item-action" data-action="recharge">{{item.labels.recharge}}</a>
{{#if item.isOnCooldown}}
<div class="item-detail item-uses" data-tooltip-direction="LEFT" data-tooltip="{{item.labels.recharge}}" aria-label="{{item.labels.recharge}}" >
<a class="item-action" data-action="recharge"><i class="fa-solid fa-arrows-rotate"></i></a>
{{else if item.system.recharge.value}}
<div class="item-detail item-uses">
{{localize "DND5E.Charged"}}
<div class="item-detail item-uses" data-tooltip-direction="LEFT" data-tooltip="{{item.labels.recharge}}" aria-label="{{item.labels.recharge}}" >
<i class="fa-solid fa-bolt"></i>
{{else if ctx.hasUses}}
<div class="item-detail item-uses">
<input type="text" value="{{ item.system.uses.value }}" placeholder="0" data-dtype="Number"
Expand Down

0 comments on commit 26cc237

Please sign in to comment.