From 0fb10b7ae2dd44e57435ece71d6547fffbde8d83 Mon Sep 17 00:00:00 2001 From: Oliver Date: Wed, 29 Apr 2026 19:51:56 -0600 Subject: [PATCH 01/23] Prevent early returning in the taf.getRollData hook --- module/documents/Actor.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/module/documents/Actor.mjs b/module/documents/Actor.mjs index 7a0f47c..e99108e 100644 --- a/module/documents/Actor.mjs +++ b/module/documents/Actor.mjs @@ -71,7 +71,7 @@ export class TAFActor extends Actor { ...this.system.attr, }; - Hooks.call(`taf.getRollData`, data, this); + Hooks.callAll(`taf.getRollData`, data, this); return data; }; From c090daa2aaf3c11b9e393125ba2e4883223a9860 Mon Sep 17 00:00:00 2001 From: Oliver Date: Wed, 29 Apr 2026 19:53:39 -0600 Subject: [PATCH 02/23] Improve the chat message handling to make it so that the flavour can be properly updated if you include @active roll data --- module/data/Item/attribute.mjs | 25 +++++++++++++++++++++---- module/data/Item/generic.mjs | 23 ++++++++++++++++++++--- 2 files changed, 41 insertions(+), 7 deletions(-) diff --git a/module/data/Item/attribute.mjs b/module/data/Item/attribute.mjs index 0059667..25eee87 100644 --- a/module/data/Item/attribute.mjs +++ b/module/data/Item/attribute.mjs @@ -136,11 +136,28 @@ export class AttributeItemData extends foundry.abstract.TypeDataModel { // Provide the chat-specific context when required if (macro.type === `chat`) { + const extraContext = { + name: this.parent.name, + min: this.min, + value: this.value, + max: this.max, + }; + Hooks.once(`taf.getRollData`, (data) => { - data.active = { - min: this.min, - value: this.value, - max: this.max, + data.active = extraContext; + }); + + // Apply any roll data additions to the message flavour as well + // since that doesn't get formatted by the ChatLog + Hooks.once(`preCreateChatMessage`, (message) => { + if (message.flavor.includes(`@active`)) { + const flavor = message.flavor.replaceAll( + /@active\.(\w+)/g, + (fullMatch, key) => { + return extraContext[key] || fullMatch; + }, + ); + message.updateSource({ flavor, }); }; }); }; diff --git a/module/data/Item/generic.mjs b/module/data/Item/generic.mjs index a8f8490..33b6477 100644 --- a/module/data/Item/generic.mjs +++ b/module/data/Item/generic.mjs @@ -59,10 +59,27 @@ export class GenericItemData extends foundry.abstract.TypeDataModel { // Provide the chat-specific context when required if (macro.type === `chat`) { + const extraContext = { + name: this.parent.name, + quantity: this.quantity, + equipped: this.equipped ? 1 : 0, + }; + Hooks.once(`taf.getRollData`, (data) => { - data.active = { - quantity: this.quantity, - equipped: this.equipped ? 1 : 0, + data.active = extraContext; + }); + + // Apply any roll data additions to the message flavour as well + // since that doesn't get formatted by the ChatLog + Hooks.once(`preCreateChatMessage`, (message) => { + if (message.flavor.includes(`@active`)) { + const flavor = message.flavor.replaceAll( + /@active\.(\w+)/g, + (fullMatch, key) => { + return extraContext[key] || fullMatch; + }, + ); + message.updateSource({ flavor, }); }; }); }; From a30d68a3277e886ca887deda7fe1016f4d188b7b Mon Sep 17 00:00:00 2001 From: Oliver Date: Wed, 29 Apr 2026 21:38:07 -0600 Subject: [PATCH 03/23] Lint and fix undefined reference error --- module/data/Item/attribute.mjs | 2 +- module/data/Item/generic.mjs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/module/data/Item/attribute.mjs b/module/data/Item/attribute.mjs index d982c04..6c83a9d 100644 --- a/module/data/Item/attribute.mjs +++ b/module/data/Item/attribute.mjs @@ -157,7 +157,7 @@ export class AttributeItemData extends foundry.abstract.TypeDataModel { return extraContext[key] || fullMatch; }, ); - message.updateSource({ flavor, }); + message.updateSource({ flavor }); }; }); }; diff --git a/module/data/Item/generic.mjs b/module/data/Item/generic.mjs index 33b6477..6552f19 100644 --- a/module/data/Item/generic.mjs +++ b/module/data/Item/generic.mjs @@ -79,12 +79,12 @@ export class GenericItemData extends foundry.abstract.TypeDataModel { return extraContext[key] || fullMatch; }, ); - message.updateSource({ flavor, }); + message.updateSource({ flavor }); }; }); }; - await macro?.execute({ item }); + await macro?.execute({ item: this.parent }); }; // #endregion Methods }; From 6723e0d25f86fbde8f892ab1daa09c45b6ad4584 Mon Sep 17 00:00:00 2001 From: Oliver Date: Wed, 29 Apr 2026 22:12:18 -0600 Subject: [PATCH 04/23] Add a different default image for attribute items so they stand out a bit more in the item tab --- module/documents/Item.mjs | 8 ++++++++ module/hooks/init.mjs | 4 +++- 2 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 module/documents/Item.mjs diff --git a/module/documents/Item.mjs b/module/documents/Item.mjs new file mode 100644 index 0000000..1a5a42f --- /dev/null +++ b/module/documents/Item.mjs @@ -0,0 +1,8 @@ +export class TAFItem extends foundry.documents.Item { + static getDefaultArtwork(itemData) { + switch (itemData.type) { + case `attribute`: return { img: `icons/svg/jump.svg` }; + }; + return super.getDefaultArtwork(itemData); + }; +}; diff --git a/module/hooks/init.mjs b/module/hooks/init.mjs index 54190fc..de838f7 100644 --- a/module/hooks/init.mjs +++ b/module/hooks/init.mjs @@ -13,6 +13,7 @@ import { PlayerData } from "../data/Actor/player.mjs"; // Documents import { TAFActor } from "../documents/Actor.mjs"; import { TAFCombatant } from "../documents/Combatant.mjs"; +import { TAFItem } from "../documents/Item.mjs"; import { TAFTokenDocument } from "../documents/Token.mjs"; // Settings @@ -29,9 +30,10 @@ Hooks.on(`init`, () => { Logger.debug(`Initializing`); // #region Documents - CONFIG.Token.documentClass = TAFTokenDocument; CONFIG.Actor.documentClass = TAFActor; CONFIG.Combatant.documentClass = TAFCombatant; + CONFIG.Item.documentClass = TAFItem; + CONFIG.Token.documentClass = TAFTokenDocument; // #endregion Documents // #region Data Models From 749d442bd8e222ba0e91f588acfb95eede3934c5 Mon Sep 17 00:00:00 2001 From: Oliver Date: Fri, 1 May 2026 15:26:57 -0600 Subject: [PATCH 05/23] Update the QueryStatus app theme (closes #61) --- styles/Apps/QueryStatus.css | 39 ++++++++++++++++++++++++++++++++++++- styles/elements/div.css | 1 - styles/themes/dark.css | 23 +++++++++++++++++----- 3 files changed, 56 insertions(+), 7 deletions(-) diff --git a/styles/Apps/QueryStatus.css b/styles/Apps/QueryStatus.css index 4f45ff4..0cd64e3 100644 --- a/styles/Apps/QueryStatus.css +++ b/styles/Apps/QueryStatus.css @@ -1,4 +1,9 @@ .taf.QueryStatus { + > .window-content { + color: var(--query-status-colour); + background: var(--query-status-background); + } + .user-list { display: flex; flex-direction: column; @@ -11,7 +16,8 @@ display: flex; flex-direction: column; margin: 0; - border: 1px solid rebeccapurple; + color: var(--query-status-user-colour); + background: var(--query-status-user-background); border-radius: 4px; padding: 4px 8px; @@ -22,6 +28,19 @@ /* Same height as the icons used for loading/disconnected */ height: 35px; } + + button { + color: var(--query-status-user-button-colour); + background: var(--query-status-user-button-background); + + &:hover { + background: var(--query-status-user-button-hover-background); + } + + &:focus-visible { + border-color: var(--query-status-user-button-focus); + } + } } } @@ -29,5 +48,23 @@ display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; + + button { + color: var(--query-status-control-colour); + background: var(--query-status-control-background); + + &:hover { + background: var(--query-status-control-hover-background); + } + + &:focus-visible { + border-color: var(--query-status-control-focus); + } + } + } + + button { + border: 2px solid transparent; + outline: none; } } diff --git a/styles/elements/div.css b/styles/elements/div.css index b3d1566..6e77ca1 100644 --- a/styles/elements/div.css +++ b/styles/elements/div.css @@ -3,7 +3,6 @@ display: inline flex; color: var(--chip-colour); background: var(--chip-background); - border: 1px solid var(--chip-border-colour); border-radius: 4px; .key { diff --git a/styles/themes/dark.css b/styles/themes/dark.css index 97cf099..7f58e62 100644 --- a/styles/themes/dark.css +++ b/styles/themes/dark.css @@ -81,10 +81,23 @@ --attribute-sheet-toggle-slider-enabled-colour: var(--item-sheet-toggle-slider-enabled-colour); --attribute-sheet-toggle-slider-disabled-colour: var(--item-sheet-toggle-slider-disabled-colour); + /* Query Status App Variables */ + --query-status-colour: var(--steel-100); + --query-status-background: var(--steel-800); + --query-status-user-colour: var(--steel-100); + --query-status-user-background: var(--steel-700); + --query-status-user-button-colour: var(--steel-100); + --query-status-user-button-background: var(--steel-600); + --query-status-user-button-focus: var(--zinc-100); + --query-status-user-button-hover-background: var(--steel-650); + --query-status-control-colour: var(--steel-100); + --query-status-control-background: var(--steel-600); + --query-status-control-focus: var(--zinc-100); + --query-status-control-hover-background: var(--steel-650); + /* Chip Variables */ - --chip-colour: #fff7ed; - --chip-background: #2b3642; - --chip-value-colour: #fff7ed; - --chip-value-background: #10161d; - --chip-border-colour: var(--chip-value-background); + --chip-colour: var(--steel-100); + --chip-background: var(--steel-600); + --chip-value-colour: var(--steel-100); + --chip-value-background: var(--steel-500); } From 5b59956016ec5ec8f24a0d32d747117e1fd8b075 Mon Sep 17 00:00:00 2001 From: Oliver Date: Sat, 2 May 2026 18:35:59 -0600 Subject: [PATCH 06/23] Implement the light mode using Forgejo's colour pallete (closes #51) --- styles/elements/prose-mirror.css | 10 +-- styles/themes/dark.css | 5 ++ styles/themes/light.css | 110 ++++++++++++++++++++++++++++--- 3 files changed, 111 insertions(+), 14 deletions(-) diff --git a/styles/elements/prose-mirror.css b/styles/elements/prose-mirror.css index 6f257f0..138fb7a 100644 --- a/styles/elements/prose-mirror.css +++ b/styles/elements/prose-mirror.css @@ -1,7 +1,7 @@ .taf > .window-content prose-mirror { color: var(--prosemirror-colour); - --table-row-color-odd: var(--steel-550); - --table-row-color-even: var(--steel-600); + --table-row-color-odd: var(--prosemirror-table-row-color-odd); + --table-row-color-even: var(--prosemirror-table-row-color-even); background: var(--prosemirror-background); gap: 0; @@ -44,12 +44,12 @@ pre:has(> code), code:not(pre > code) { padding: 4px 6px; - background: var(--steel-700); - color: var(--steel-200); + background: var(--prosemirror-code-background); + color: var(--prosemirror-code-colour); } blockquote { color: inherit; - border-left: 2px solid var(--steel-200); + border-left: 2px solid var(--prosemirror-blockquote-border); } } diff --git a/styles/themes/dark.css b/styles/themes/dark.css index 7f58e62..5fa22c7 100644 --- a/styles/themes/dark.css +++ b/styles/themes/dark.css @@ -7,6 +7,11 @@ --prosemirror-menu-colour: var(--steel-100); --prosemirror-menu-background: var(--steel-750); --prosemirror-divider-colour: var(--steel-250); + --prosemirror-table-row-color-odd: var(--steel-550); + --prosemirror-table-row-color-even: var(--steel-600); + --prosemirror-code-colour: var(--steel-200); + --prosemirror-code-background: var(--steel-700); + --prosemirror-blockquote-border: var(--steel-200); --spinner-outer-colour: white; --spinner-inner-colour: #FF3D00; diff --git a/styles/themes/light.css b/styles/themes/light.css index dd45d6b..ef66d4e 100644 --- a/styles/themes/light.css +++ b/styles/themes/light.css @@ -1,16 +1,108 @@ .theme-light { - --prosemirror-background: white; + /* Prose Mirror Elements */ + --prosemirror-colour: var(--zinc-700); + --prosemirror-background: var(--zinc-300); + --prosemirror-toggle-background: var(--zinc-350); + --prosemirror-toggle-hover-background: var(--zinc-400); + --prosemirror-menu-colour: var(--zinc-700); + --prosemirror-menu-background: var(--zinc-350); + --prosemirror-divider-colour: var(--zinc-600); + --prosemirror-table-row-color-odd: var(--zinc-350); + --prosemirror-table-row-color-even: var(--zinc-400); + --prosemirror-code-colour: var(--zinc-800); + --prosemirror-code-background: var(--zinc-400); + --prosemirror-blockquote-border: var(--zinc-500); - --spinner-outer-colour: black; + --spinner-outer-colour: var(--steel-600); --spinner-inner-colour: #FF3D00; - --tab-button-active: rebeccapurple; - --tab-button-hover-bg: var(--color-light-3); + --toggle-background-colour: var(--zinc-350); + --toggle-slider-unchecked-colour: red; + --toggle-slider-checked-colour: green; + + --tab-nav-divider-colour: var(--zinc-300); + --tab-button-colour: var(--zinc-550); + --tab-button-focus-colour: var(--zinc-750); + --tab-button-hover-colour: var(--zinc-800); + --tab-button-active-colour: var(--zinc-900); + + /* Actor Sheet Variables */ + --actor-sheet-colour: var(--zinc-800); + --actor-sheet-background: var(--zinc-200); + --actor-sheet-divider-colour: var(--zinc-300); + --actor-sheet-header-colour: var(--zinc-800); + --actor-sheet-header-background:var(--zinc-100); + --actor-sheet-header-input-colour: var(--zinc-800); + --actor-sheet-header-input-background: var(--zinc-250); + + --inventory-summary-colour: var(--zinc-600); + --inventory-summary-background: var(--zinc-100); + --inventory-input-colour: var(--zinc-700); + --inventory-input-background: var(--zinc-250); + --inventory-input-disabled-colour: var(--zinc-500); + + --embedded-list-header-colour: var(--inventory-summary-colour); + --embedded-list-header-background: var(--inventory-summary-background); + --embedded-list-header-input-colour: var(--inventory-input-colour); + --embedded-list-header-input-background: var(--inventory-input-background); + + --attribute-colour: var(--zinc-700); + --attribute-background: var(--zinc-300); + --attribute-input-colour: var(--zinc-700); + --attribute-input-background: var(--zinc-350); + --attribute-input-focus-colour: var(--zinc-700); + --attribute-button-active-background: var(--zinc-400); + --attribute-disabled-input-colour: var(--zinc-500); + + --item-card-colour: var(--zinc-800); + --item-card-background: var(--zinc-300); + --item-card-header-colour: var(--zinc-800); + --item-card-header-background: var(--zinc-300); + --item-card-header-input-colour: var(--zinc-700); + --item-card-header-input-background: var(--zinc-350); + --item-card-header-input-focus-colour: var(--zinc-700); + --item-card-header-disabled-input-colour: var(--zinc-700); + + /* Item Sheet Variables */ + --item-sheet-colour: var(--zinc-800); + --item-sheet-background: var(--zinc-200); + --item-sheet-divider-colour: var(--zinc-300); + --item-sheet-input-colour: var(--zinc-800); + --item-sheet-input-background: var(--zinc-300); + --item-sheet-toggle-slider-enabled-colour: green; + --item-sheet-toggle-slider-disabled-colour: red; + --item-sheet-description-menu-colour: var(--zinc-800); + --item-sheet-description-menu-background: var(--zinc-350); + --item-sheet-description-content-background: var(--zinc-300); + + /* Attribute Sheet Variables */ + --attribute-sheet-colour: var(--item-sheet-colour); + --attribute-sheet-background: var(--item-sheet-background); + --attribute-sheet-divider-colour: var(--item-sheet-divider); + --attribute-sheet-hint-colour: var(--zinc-550); + --attribute-sheet-input-colour: var(--item-sheet-input-colour); + --attribute-sheet-input-background: var(--item-sheet-input-background); + --attribute-sheet-disabled-input-colour: var(--zinc-550); + --attribute-sheet-toggle-slider-enabled-colour: var(--item-sheet-toggle-slider-enabled-colour); + --attribute-sheet-toggle-slider-disabled-colour: var(--item-sheet-toggle-slider-disabled-colour); + + /* Query Status App Variables */ + --query-status-colour: var(--zinc-800); + --query-status-background: var(--zinc-200); + --query-status-user-colour: var(--zinc-800); + --query-status-user-background: var(--zinc-300); + --query-status-user-button-colour: var(--steel-700); + --query-status-user-button-background: var(--zinc-350); + --query-status-user-button-focus: var(--steel-700); + --query-status-user-button-hover-background: var(--zinc-400); + --query-status-control-colour: var(--steel-700); + --query-status-control-background: var(--zinc-350); + --query-status-control-focus: var(--steel-700); + --query-status-control-hover-background: var(--zinc-400); /* Chip Variables */ - --chip-colour: #18181b; - --chip-background: #fafafa; - --chip-value-colour: #18181b; - --chip-value-background: #d4d4d8aa; - --chip-border-colour: var(--chip-value-background); + --chip-colour: ; + --chip-background: ; + --chip-value-colour: ; + --chip-value-background: ; } From 74d881c3df40dd5f425b9b429d83558ef8e8a9f5 Mon Sep 17 00:00:00 2001 From: Oliver Date: Sat, 2 May 2026 18:56:23 -0600 Subject: [PATCH 07/23] Fix a bug where the actor context was not being correctly called unless the user had an actor assigned to them --- module/data/Item/attribute.mjs | 9 ++++++++- module/data/Item/generic.mjs | 7 +++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/module/data/Item/attribute.mjs b/module/data/Item/attribute.mjs index 6c83a9d..1bb65c1 100644 --- a/module/data/Item/attribute.mjs +++ b/module/data/Item/attribute.mjs @@ -162,7 +162,14 @@ export class AttributeItemData extends foundry.abstract.TypeDataModel { }); }; - await macro?.execute({ item: this.parent }); + // Get the speaker so that Foundry has the correct context to be able to call + // the Actor's getData method, letting us augment the context dynamically for + // the @active roll context + const speaker = foundry.documents.ChatMessage.implementation.getSpeaker({ + actor: this.parent.parent + }); + + await macro?.execute({ item: this.parent, speaker }); }; // #endregion Methods }; diff --git a/module/data/Item/generic.mjs b/module/data/Item/generic.mjs index 6552f19..5c0b8db 100644 --- a/module/data/Item/generic.mjs +++ b/module/data/Item/generic.mjs @@ -84,6 +84,13 @@ export class GenericItemData extends foundry.abstract.TypeDataModel { }); }; + // Get the speaker so that Foundry has the correct context to be able to call + // the Actor's getData method, letting us augment the context dynamically for + // the @active roll context + const speaker = foundry.documents.ChatMessage.implementation.getSpeaker({ + actor: this.parent.parent + }); + await macro?.execute({ item: this.parent }); }; // #endregion Methods From c6d3c094b88a8ca2a6d47ba58ec72b4ccd67d425 Mon Sep 17 00:00:00 2001 From: Oliver Date: Sat, 2 May 2026 19:23:20 -0600 Subject: [PATCH 08/23] Add an extra paragraph to the Macro deletion dialog in order to tell people how many items use that macro (closes #81) --- langs/en-ca.json | 1 + module/documents/Macro.mjs | 39 ++++++++++++++++++++++++++++++++++++++ module/hooks/init.mjs | 2 ++ 3 files changed, 42 insertions(+) create mode 100644 module/documents/Macro.mjs diff --git a/langs/en-ca.json b/langs/en-ca.json index bf97c0c..daef559 100644 --- a/langs/en-ca.json +++ b/langs/en-ca.json @@ -64,6 +64,7 @@ "edit": "Edit", "resizable": "Resizable", "not-resizable": "Not Resizable", + "macro-is-in-use": "The Macro is used by {count} items/attributes in the world or Actors, the items will lose their ability to use the macro.", "item": { "weight": "Weight", "quantity": "Quantity", diff --git a/module/documents/Macro.mjs b/module/documents/Macro.mjs new file mode 100644 index 0000000..53d4ced --- /dev/null +++ b/module/documents/Macro.mjs @@ -0,0 +1,39 @@ +export class TAFMacro extends foundry.documents.Macro { + async deleteDialog(options, operation) { + const itemsUsingMacro = new Set(); + + // Check Items on Actors + game.actors.forEach(actor => { + actor.items.forEach(item => { + console.log(item.uuid, `owned by`, actor.uuid); + if (item.system.trigger === this.uuid) { + itemsUsingMacro.add(item.uuid); + }; + }); + }); + + // Check World Items + game.items.forEach(item => { + if (item.system.trigger === this.uuid) { + itemsUsingMacro.add(item.uuid); + }; + }); + + // Modify the dialog arguments + const type = _loc(this.constructor.metadata.label); + const question = _loc(`COMMON.AreYouSure`); + const warning = _loc(`SIDEBAR.DeleteWarning`, { type }); + let content = `

${question} ${warning}

`; + + if (itemsUsingMacro.size) { + const extraInfo = _loc( + `taf.misc.macro-is-in-use`, + { count: itemsUsingMacro.size }, + ); + content += `

${extraInfo}

`; + }; + + options.content = content; + return super.deleteDialog(options, operation); + }; +}; diff --git a/module/hooks/init.mjs b/module/hooks/init.mjs index de838f7..e898f46 100644 --- a/module/hooks/init.mjs +++ b/module/hooks/init.mjs @@ -14,6 +14,7 @@ import { PlayerData } from "../data/Actor/player.mjs"; import { TAFActor } from "../documents/Actor.mjs"; import { TAFCombatant } from "../documents/Combatant.mjs"; import { TAFItem } from "../documents/Item.mjs"; +import { TAFMacro } from "../documents/Macro.mjs"; import { TAFTokenDocument } from "../documents/Token.mjs"; // Settings @@ -33,6 +34,7 @@ Hooks.on(`init`, () => { CONFIG.Actor.documentClass = TAFActor; CONFIG.Combatant.documentClass = TAFCombatant; CONFIG.Item.documentClass = TAFItem; + CONFIG.Macro.documentClass = TAFMacro; CONFIG.Token.documentClass = TAFTokenDocument; // #endregion Documents From 77413687e9d6d6c564acdd2bf10c69cb9a522cf1 Mon Sep 17 00:00:00 2001 From: Oliver Date: Sat, 2 May 2026 19:28:03 -0600 Subject: [PATCH 09/23] Make the generic Item subtype actually provide the speaker data to the macro --- module/data/Item/attribute.mjs | 2 +- module/data/Item/generic.mjs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/module/data/Item/attribute.mjs b/module/data/Item/attribute.mjs index 1bb65c1..aaa92dc 100644 --- a/module/data/Item/attribute.mjs +++ b/module/data/Item/attribute.mjs @@ -166,7 +166,7 @@ export class AttributeItemData extends foundry.abstract.TypeDataModel { // the Actor's getData method, letting us augment the context dynamically for // the @active roll context const speaker = foundry.documents.ChatMessage.implementation.getSpeaker({ - actor: this.parent.parent + actor: this.parent.parent, }); await macro?.execute({ item: this.parent, speaker }); diff --git a/module/data/Item/generic.mjs b/module/data/Item/generic.mjs index 5c0b8db..9af745a 100644 --- a/module/data/Item/generic.mjs +++ b/module/data/Item/generic.mjs @@ -88,10 +88,10 @@ export class GenericItemData extends foundry.abstract.TypeDataModel { // the Actor's getData method, letting us augment the context dynamically for // the @active roll context const speaker = foundry.documents.ChatMessage.implementation.getSpeaker({ - actor: this.parent.parent + actor: this.parent.parent, }); - await macro?.execute({ item: this.parent }); + await macro?.execute({ item: this.parent, speaker }); }; // #endregion Methods }; From a55748d6fc768a761a9abe33c989a7a10b39ca4d Mon Sep 17 00:00:00 2001 From: Oliver Date: Sat, 2 May 2026 19:28:13 -0600 Subject: [PATCH 10/23] Remove log that slipped through the cracks --- module/documents/Macro.mjs | 1 - 1 file changed, 1 deletion(-) diff --git a/module/documents/Macro.mjs b/module/documents/Macro.mjs index 53d4ced..3cc3aeb 100644 --- a/module/documents/Macro.mjs +++ b/module/documents/Macro.mjs @@ -5,7 +5,6 @@ export class TAFMacro extends foundry.documents.Macro { // Check Items on Actors game.actors.forEach(actor => { actor.items.forEach(item => { - console.log(item.uuid, `owned by`, actor.uuid); if (item.system.trigger === this.uuid) { itemsUsingMacro.add(item.uuid); }; From a9567c200ac419a998e375f3407e7919c1e3ffee Mon Sep 17 00:00:00 2001 From: Oliver Date: Sat, 2 May 2026 20:27:15 -0600 Subject: [PATCH 11/23] Add the macro trigger into the Items tab, and localize the trigger button for attributes (closes #85) --- langs/en-ca.json | 2 ++ module/apps/PlayerSheet.mjs | 1 + styles/Apps/PlayerSheet.css | 17 +++++++++++++---- .../PlayerSheet/tabs/attributes/attribute.hbs | 2 +- templates/PlayerSheet/tabs/items/item.hbs | 8 ++++++++ 5 files changed, 25 insertions(+), 5 deletions(-) diff --git a/langs/en-ca.json b/langs/en-ca.json index daef559..ce47b7a 100644 --- a/langs/en-ca.json +++ b/langs/en-ca.json @@ -65,6 +65,8 @@ "resizable": "Resizable", "not-resizable": "Not Resizable", "macro-is-in-use": "The Macro is used by {count} items/attributes in the world or Actors, the items will lose their ability to use the macro.", + "roll": "Roll", + "use": "Use", "item": { "weight": "Weight", "quantity": "Quantity", diff --git a/module/apps/PlayerSheet.mjs b/module/apps/PlayerSheet.mjs index 7ed89fe..1565f92 100644 --- a/module/apps/PlayerSheet.mjs +++ b/module/apps/PlayerSheet.mjs @@ -382,6 +382,7 @@ export class PlayerSheet extends weight: config.weightFormatter(item.system.quantifiedWeight), isExpanded: this.#expandedItems.has(item.uuid), canExpand: item.system.description.length > 0, + trigger: item.system.trigger, }; ctx.description = ``; diff --git a/styles/Apps/PlayerSheet.css b/styles/Apps/PlayerSheet.css index 3442d76..e450389 100644 --- a/styles/Apps/PlayerSheet.css +++ b/styles/Apps/PlayerSheet.css @@ -135,8 +135,8 @@ margin-bottom: 0; .summary { - display: grid; - grid-template-columns: min-content auto 1fr 50px auto; + display: flex; + flex-direction: row; align-items: center; gap: 8px; background: var(--item-card-header-background); @@ -154,6 +154,7 @@ display: flex; flex-direction: column; gap: 4px; + flex-grow: 1; } .name { @@ -164,10 +165,15 @@ opacity: 90%; } + input { + width: 50px; + } + input, button { background: var(--item-card-header-input-background); color: var(--item-card-header-input-colour); text-align: center; + height: 32px; &:disabled { color: var(--item-card-header-disabled-input-colour); @@ -175,14 +181,17 @@ } } - .expand-button { + button { border: none; - aspect-ratio: 1; &:focus-visible { filter: brightness(150%); outline: none; } + } + + .expand-button { + aspect-ratio: 1; &[data-expanded="true"] { rotate: 180deg; diff --git a/templates/PlayerSheet/tabs/attributes/attribute.hbs b/templates/PlayerSheet/tabs/attributes/attribute.hbs index ac84637..f2123ca 100644 --- a/templates/PlayerSheet/tabs/attributes/attribute.hbs +++ b/templates/PlayerSheet/tabs/attributes/attribute.hbs @@ -10,7 +10,7 @@ type="button" data-action="executeTrigger" > - Roll + {{ localize "taf.misc.roll" }} {{/if}} {{ name }} {{ weight }} + {{#if trigger}} + + {{/if}} Date: Sat, 2 May 2026 20:51:05 -0600 Subject: [PATCH 12/23] Add way to set default attributes now that we no longer have the AttributeManager (closes #83) --- langs/en-ca.json | 1 + module/apps/PlayerSheet.mjs | 18 ++++++++++++++++++ module/documents/Actor.mjs | 26 ++++++++++++++++++++++++++ 3 files changed, 45 insertions(+) diff --git a/langs/en-ca.json b/langs/en-ca.json index ce47b7a..149bb72 100644 --- a/langs/en-ca.json +++ b/langs/en-ca.json @@ -91,6 +91,7 @@ "invalid-input-type": "Invalid input type provided: {type}" }, "PlayerSheet": { + "save-attributes-as-defaults": "Save Attributes as Defaults", "create-item": "Create Embedded Item", "current-value": "Current value", "max-value": "Maximum value", diff --git a/module/apps/PlayerSheet.mjs b/module/apps/PlayerSheet.mjs index 1565f92..74830d6 100644 --- a/module/apps/PlayerSheet.mjs +++ b/module/apps/PlayerSheet.mjs @@ -4,6 +4,7 @@ import { config } from "../config.mjs"; import { Logger } from "../utils/Logger.mjs"; import { TAFDocumentSheetConfig } from "./TAFDocumentSheetConfig.mjs"; import { TAFDocumentSheetMixin } from "./mixins/TAFDocumentSheetMixin.mjs"; +import { TAFActor } from "../documents/Actor.mjs"; const { HandlebarsApplicationMixin } = foundry.applications.api; const { ActorSheetV2 } = foundry.applications.sheets; @@ -38,6 +39,7 @@ export class PlayerSheet extends configureSheet: this.#configureSheet, toggleExpand: this.#toggleExpand, executeTrigger: this.#executeTrigger, + saveDefaultAttrs: this.#saveDefaultAttrs, }, }; @@ -193,6 +195,12 @@ export class PlayerSheet extends const controls = super._getHeaderControls(); controls.push( + { + icon: `fa-solid fa-globe`, + label: `taf.Apps.PlayerSheet.save-attributes-as-defaults`, + action: `saveDefaultAttrs`, + visible: () => game.user.isGM, + }, { icon: `fa-solid fa-suitcase`, label: `taf.Apps.PlayerSheet.create-item`, @@ -475,5 +483,15 @@ export class PlayerSheet extends const item = await fromUuid(itemUuid); await item?.system.execute?.(); }; + + /** + * Saves the Actor's current attribute items into the world setting for newly + * created Actors to have the same attribute list. + * + * @this {PlayerSheet} + */ + static async #saveDefaultAttrs() { + TAFActor.setDefaultAttributes(this.actor); + }; // #endregion Actions }; diff --git a/module/documents/Actor.mjs b/module/documents/Actor.mjs index e99108e..1bfa0ea 100644 --- a/module/documents/Actor.mjs +++ b/module/documents/Actor.mjs @@ -155,4 +155,30 @@ export class TAFActor extends Actor { }; }; // #endregion Data Migration + + // #region Static API + /** + * Sets the default attributes that are created when a new Actor is created, + * this uses all of the existing values that are a part of the items, it does + * not prompt for default values. + */ + static async setDefaultAttributes(actor) { + if (!game.user.isGM) { return }; + const minifiedData = []; + + const attrs = actor.itemTypes.attribute ?? []; + for (const attr of attrs) { + const raw = attr.toObject(); + minifiedData.push({ + img: raw.img, // doesn't really matter but ¯\_(ツ)_/¯ + name: raw.name, + type: raw.type, + system: raw.system, + }); + }; + + game.settings.set(__ID__, `actorDefaultAttributes`, minifiedData); + ui.notifications.success(_loc(`taf.notifs.success.saved-default-attributes`)); + }; + // #endregion Static API }; From 9527cd972efd7f4dda4fdc0dcf5985c5b4cc8de2 Mon Sep 17 00:00:00 2001 From: Oliver Date: Sun, 3 May 2026 00:09:24 -0600 Subject: [PATCH 13/23] Tweak comment in data model --- module/data/Actor/player.mjs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/module/data/Actor/player.mjs b/module/data/Actor/player.mjs index 81a197e..58b35b8 100644 --- a/module/data/Actor/player.mjs +++ b/module/data/Actor/player.mjs @@ -1,7 +1,7 @@ import { __ID__ } from "../../consts.mjs"; export class PlayerData extends foundry.abstract.TypeDataModel { - // #region Schema + // MARK: Schema static defineSchema() { const fields = foundry.data.fields; return { @@ -18,7 +18,6 @@ export class PlayerData extends foundry.abstract.TypeDataModel { attr: new fields.ObjectField({ persisted: false, initial: {} }), }; }; - // #endregion Schema // #region Lifecycle /** From 786cb7f5ecd7a88a009f16d10ecd11b235b087a5 Mon Sep 17 00:00:00 2001 From: Oliver Date: Sun, 3 May 2026 15:45:52 -0600 Subject: [PATCH 14/23] Remove unused CDN URL environment variable --- .forgejo/workflows/draft-release.yaml | 1 - 1 file changed, 1 deletion(-) diff --git a/.forgejo/workflows/draft-release.yaml b/.forgejo/workflows/draft-release.yaml index cd816e7..b48374c 100644 --- a/.forgejo/workflows/draft-release.yaml +++ b/.forgejo/workflows/draft-release.yaml @@ -43,7 +43,6 @@ jobs: run: node scripts/src/createForgejoRelease.mjs env: TAG: "v${{steps.version.outputs.version}}" - CDN_URL: "${{vars.CDN_URL}}" wiki-release-artifact: name: "Add Wiki to Release" From a34525f05e7f5028d83802f53f2f870bb213b6cb Mon Sep 17 00:00:00 2001 From: Oliver Date: Tue, 5 May 2026 17:56:20 -0600 Subject: [PATCH 15/23] Remove useless command from the wiki portion of my action --- .forgejo/workflows/draft-release.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.forgejo/workflows/draft-release.yaml b/.forgejo/workflows/draft-release.yaml index b48374c..fcec406 100644 --- a/.forgejo/workflows/draft-release.yaml +++ b/.forgejo/workflows/draft-release.yaml @@ -64,7 +64,7 @@ jobs: token: ${{forgejo.token}} - name: "Install dependencies" - run: "pwd; npm i" + run: "npm i" - name: "Remove development folders" run: "rm -rf .git .vscode" From dddad7f55d4421e342c5b0cf53c56cd5d3531c18 Mon Sep 17 00:00:00 2001 From: Oliver Date: Wed, 6 May 2026 16:10:34 -0600 Subject: [PATCH 16/23] Fix actor creation throwing an error (closes #89) --- module/documents/Actor.mjs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/module/documents/Actor.mjs b/module/documents/Actor.mjs index 1bfa0ea..0c464b5 100644 --- a/module/documents/Actor.mjs +++ b/module/documents/Actor.mjs @@ -130,8 +130,11 @@ export class TAFActor extends Actor { * This checks and performs all data migrations that the system requires, some * of these are one-time only migrations, others of them will happen every time * an Actor is updated. + * + * The defaulting of options is provided to ensure that the migration doesn't + * cause errors in Foundry v13 */ - static migrateData(data, options) { + static migrateData(data, options = {}) { this.#migrateToAttributeItems(data, options); return super.migrateData(data, options); }; From 288f3a54b52c852b993791e5cfc2e705730f1912 Mon Sep 17 00:00:00 2001 From: Oliver Date: Wed, 6 May 2026 16:11:02 -0600 Subject: [PATCH 17/23] Update system version in the manifest --- system.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system.json b/system.json index a301e22..8e186b1 100644 --- a/system.json +++ b/system.json @@ -2,7 +2,7 @@ "id": "taf", "title": "Text-Based Actors", "description": "An intentionally minimalist system that enables you to play rules-light games without getting in your way!", - "version": "3.0.0", + "version": "3.0.1", "download": "", "manifest": "", "url": "https://git.varify.ca/Foundry/taf", From 9177b7cc2de6974884e66e517e791ce8051954b3 Mon Sep 17 00:00:00 2001 From: Oliver Date: Wed, 6 May 2026 16:18:23 -0600 Subject: [PATCH 18/23] Remove the web-only files from the wiki archive --- .forgejo/workflows/draft-release.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.forgejo/workflows/draft-release.yaml b/.forgejo/workflows/draft-release.yaml index fcec406..2984948 100644 --- a/.forgejo/workflows/draft-release.yaml +++ b/.forgejo/workflows/draft-release.yaml @@ -66,8 +66,8 @@ jobs: - name: "Install dependencies" run: "npm i" - - name: "Remove development folders" - run: "rm -rf .git .vscode" + - name: "Remove development/web folders" + run: "rm -rf .git .vscode _*" working-directory: "wiki" - name: "Compress wiki folder" From b36fe27182562c2f4fb69b2dbf1cd15b8bfebc68 Mon Sep 17 00:00:00 2001 From: Oliver Date: Thu, 7 May 2026 18:05:00 -0600 Subject: [PATCH 19/23] Fix the issue with ContextMenus being completely non-functional in v13 (closes #91) --- module/apps/PlayerSheet.mjs | 10 +++++----- module/apps/utils.mjs | 19 +++++++++++++++++++ 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/module/apps/PlayerSheet.mjs b/module/apps/PlayerSheet.mjs index 74830d6..7002a72 100644 --- a/module/apps/PlayerSheet.mjs +++ b/module/apps/PlayerSheet.mjs @@ -1,5 +1,5 @@ import { __ID__, filePath } from "../consts.mjs"; -import { deleteItemFromElement, editItemFromElement } from "./utils.mjs"; +import { createContextMenuOption, deleteItemFromElement, editItemFromElement } from "./utils.mjs"; import { config } from "../config.mjs"; import { Logger } from "../utils/Logger.mjs"; import { TAFDocumentSheetConfig } from "./TAFDocumentSheetConfig.mjs"; @@ -226,7 +226,7 @@ export class PlayerSheet extends this.element, `[data-item-uuid]`, [ - { + createContextMenuOption({ label: _loc(`taf.misc.edit`), condition: (el) => { const itemUuid = el.dataset.itemUuid; @@ -234,8 +234,8 @@ export class PlayerSheet extends return this.isEditable && itemExists; }, onClick: editItemFromElement, - }, - { + }), + createContextMenuOption({ label: _loc(`taf.misc.delete`), condition: (el) => { const itemUuid = el.dataset.itemUuid; @@ -243,7 +243,7 @@ export class PlayerSheet extends return this.isEditable && itemExists; }, onClick: deleteItemFromElement, - }, + }), ], { jQuery: false, fixed: true }, ); diff --git a/module/apps/utils.mjs b/module/apps/utils.mjs index de8edcc..e6e492a 100644 --- a/module/apps/utils.mjs +++ b/module/apps/utils.mjs @@ -3,6 +3,25 @@ This file contains utility methods used by Applications in order to be DRYer */ +/** + * A helper function that takes a v14-compatible ContextMenuEntry option + * and adjusts it for v13 if required + * + * @param {ContextMenuEntry} option The v14+ compatible menu entry option + * @returns {ContextMenuEntry} The v14+ or option.onClick(null, target), + }; + }; + + return option; +}; + /** * @param {Event} _event The click event * @param {HTMLElement} target The element to operate on From 500eabc755b7938a14ec63be87eae113e423fa95 Mon Sep 17 00:00:00 2001 From: Oliver Date: Sun, 10 May 2026 14:56:28 -0600 Subject: [PATCH 20/23] Fix the deprecation warning in v14 & hide the context menu options in v13 correctly --- module/apps/PlayerSheet.mjs | 4 ++-- module/apps/utils.mjs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/module/apps/PlayerSheet.mjs b/module/apps/PlayerSheet.mjs index 7002a72..46c3225 100644 --- a/module/apps/PlayerSheet.mjs +++ b/module/apps/PlayerSheet.mjs @@ -228,7 +228,7 @@ export class PlayerSheet extends [ createContextMenuOption({ label: _loc(`taf.misc.edit`), - condition: (el) => { + visible: (el) => { const itemUuid = el.dataset.itemUuid; const itemExists = itemUuid != null && itemUuid !== ``; return this.isEditable && itemExists; @@ -237,7 +237,7 @@ export class PlayerSheet extends }), createContextMenuOption({ label: _loc(`taf.misc.delete`), - condition: (el) => { + visible: (el) => { const itemUuid = el.dataset.itemUuid; const itemExists = itemUuid != null && itemUuid !== ``; return this.isEditable && itemExists; diff --git a/module/apps/utils.mjs b/module/apps/utils.mjs index e6e492a..b883ddf 100644 --- a/module/apps/utils.mjs +++ b/module/apps/utils.mjs @@ -14,7 +14,7 @@ export function createContextMenuOption(option) { if (game.release.generation < 14) { return { name: option.label, - visible: option.condition, + condition: option.visible, callback: (target) => option.onClick(null, target), }; }; From 849da4bb5403594f550138d0bf15ab950396cdd6 Mon Sep 17 00:00:00 2001 From: Oliver Date: Sun, 10 May 2026 15:07:04 -0600 Subject: [PATCH 21/23] Add dev-only hook to remove the core software update notification because it annoys me --- dev/dev.mjs | 1 + dev/hooks/renderSettings.mjs | 5 +++++ system.json | 3 ++- 3 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 dev/dev.mjs create mode 100644 dev/hooks/renderSettings.mjs diff --git a/dev/dev.mjs b/dev/dev.mjs new file mode 100644 index 0000000..186743f --- /dev/null +++ b/dev/dev.mjs @@ -0,0 +1 @@ +import "./hooks/renderSettings.mjs"; diff --git a/dev/hooks/renderSettings.mjs b/dev/hooks/renderSettings.mjs new file mode 100644 index 0000000..ad11762 --- /dev/null +++ b/dev/hooks/renderSettings.mjs @@ -0,0 +1,5 @@ +Hooks.on(`renderSettings`, (app, html, ctx, options) => { + /** @type {HTMLElement|undefined} */ + const coreUpdateTooltip = html.querySelector(`.build .value a`); + coreUpdateTooltip?.remove(); +}); diff --git a/system.json b/system.json index 8e186b1..754695b 100644 --- a/system.json +++ b/system.json @@ -15,7 +15,8 @@ { "name": "Oliver" } ], "esmodules": [ - "module/main.mjs" + "module/main.mjs", + "dev/dev.mjs" ], "styles": [ { From 8cadd8318b8d657cb292334f2bd4fd41925c5e35 Mon Sep 17 00:00:00 2001 From: Oliver Date: Sun, 10 May 2026 23:45:00 -0600 Subject: [PATCH 22/23] Add some TAF-specific links into the settings sidebar --- langs/en-ca.json | 5 ++ module/apps/PlayerSheet.mjs | 2 +- .../TAFDocumentSheetConfig.mjs | 6 +-- module/apps/overrides/TAFSettingsSidebar.mjs | 30 ++++++++++++ module/hooks/init.mjs | 5 ++ styles/Apps/TAFSettingsSidebar.css | 29 +++++++++++ styles/main.css | 1 + templates/settings-sidebar-addition.hbs | 48 +++++++++++++++++++ 8 files changed, 122 insertions(+), 4 deletions(-) rename module/apps/{ => overrides}/TAFDocumentSheetConfig.mjs (96%) create mode 100644 module/apps/overrides/TAFSettingsSidebar.mjs create mode 100644 styles/Apps/TAFSettingsSidebar.css create mode 100644 templates/settings-sidebar-addition.hbs diff --git a/langs/en-ca.json b/langs/en-ca.json index 149bb72..43dcbb0 100644 --- a/langs/en-ca.json +++ b/langs/en-ca.json @@ -67,6 +67,11 @@ "macro-is-in-use": "The Macro is used by {count} items/attributes in the world or Actors, the items will lose their ability to use the macro.", "roll": "Roll", "use": "Use", + "version": "Version {version}", + "whats-new": "What's New", + "releases": "Releases", + "wiki": "Wiki", + "issues": "Issues", "item": { "weight": "Weight", "quantity": "Quantity", diff --git a/module/apps/PlayerSheet.mjs b/module/apps/PlayerSheet.mjs index 46c3225..5dfab59 100644 --- a/module/apps/PlayerSheet.mjs +++ b/module/apps/PlayerSheet.mjs @@ -2,7 +2,7 @@ import { __ID__, filePath } from "../consts.mjs"; import { createContextMenuOption, deleteItemFromElement, editItemFromElement } from "./utils.mjs"; import { config } from "../config.mjs"; import { Logger } from "../utils/Logger.mjs"; -import { TAFDocumentSheetConfig } from "./TAFDocumentSheetConfig.mjs"; +import { TAFDocumentSheetConfig } from "./overrides/TAFDocumentSheetConfig.mjs"; import { TAFDocumentSheetMixin } from "./mixins/TAFDocumentSheetMixin.mjs"; import { TAFActor } from "../documents/Actor.mjs"; diff --git a/module/apps/TAFDocumentSheetConfig.mjs b/module/apps/overrides/TAFDocumentSheetConfig.mjs similarity index 96% rename from module/apps/TAFDocumentSheetConfig.mjs rename to module/apps/overrides/TAFDocumentSheetConfig.mjs index c35b8f6..f31f585 100644 --- a/module/apps/TAFDocumentSheetConfig.mjs +++ b/module/apps/overrides/TAFDocumentSheetConfig.mjs @@ -1,6 +1,6 @@ -import { __ID__, filePath } from "../consts.mjs"; -import { getDefaultSizing } from "../utils/getSizing.mjs"; -import { localizer } from "../utils/localizer.mjs"; +import { __ID__, filePath } from "../../consts.mjs"; +import { getDefaultSizing } from "../../utils/getSizing.mjs"; +import { localizer } from "../../utils/localizer.mjs"; const { diffObject, expandObject, flattenObject } = foundry.utils; const { DocumentSheetConfig } = foundry.applications.apps; diff --git a/module/apps/overrides/TAFSettingsSidebar.mjs b/module/apps/overrides/TAFSettingsSidebar.mjs new file mode 100644 index 0000000..b33bbb8 --- /dev/null +++ b/module/apps/overrides/TAFSettingsSidebar.mjs @@ -0,0 +1,30 @@ +import { filePath } from "../../consts.mjs"; + +const { renderTemplate } = foundry.applications.handlebars; +const { Settings } = foundry.applications.sidebar.tabs; + +export class TAFSettingsSidebar extends Settings { + // #region Lifecycle + async _onRender() { + // remove the row from the HTML + const systemRow = this.element.querySelector(`.info .system`); + systemRow?.remove(); + + // add the more customized system info into the sidebar + const systemBlock = this.element.querySelector(`section.system`); + if (!systemBlock) { + const htmlString = await renderTemplate( + filePath(`templates/settings-sidebar-addition.hbs`), + { system: game.system, }, + ); + + const temp = document.createElement(`div`); + temp.innerHTML = htmlString; + const rendered = temp.firstChild; + + const info = this.element.querySelector(`section.info`); + info.insertAdjacentElement(`afterend`, rendered); + }; + }; + // #endregion Lifecycle +}; diff --git a/module/hooks/init.mjs b/module/hooks/init.mjs index e898f46..b06467e 100644 --- a/module/hooks/init.mjs +++ b/module/hooks/init.mjs @@ -26,6 +26,7 @@ import helpers from "../handlebarsHelpers/_index.mjs"; import { Logger } from "../utils/Logger.mjs"; import { registerCustomComponents } from "../apps/elements/_index.mjs"; import { registerSockets } from "../sockets/_index.mjs"; +import { TAFSettingsSidebar } from "../apps/overrides/TAFSettingsSidebar.mjs"; Hooks.on(`init`, () => { Logger.debug(`Initializing`); @@ -44,6 +45,10 @@ Hooks.on(`init`, () => { CONFIG.Item.dataModels.attribute = AttributeItemData; // #endregion Data Models + // #region App Overrides + CONFIG.ui.settings = TAFSettingsSidebar; + // #endregion App Overrides + // #region Sheets foundry.documents.collections.Actors.registerSheet( __ID__, diff --git a/styles/Apps/TAFSettingsSidebar.css b/styles/Apps/TAFSettingsSidebar.css new file mode 100644 index 0000000..010d6b4 --- /dev/null +++ b/styles/Apps/TAFSettingsSidebar.css @@ -0,0 +1,29 @@ +#settings > .system { + .version-info { + display: flex; + justify-content: center; + align-items: center; + flex-direction: row; + gap: 8px; + + .whats-new { + font-size: smaller; + } + } + + .links { + display: flex; + justify-content: center; + align-items: center; + flex-direction: row; + flex-wrap: wrap; + gap: 8px; + list-style-type: none; + padding: 0; + margin: 0; + + li { + margin: 0; + } + } +} diff --git a/styles/main.css b/styles/main.css index 627b546..682b25d 100644 --- a/styles/main.css +++ b/styles/main.css @@ -31,3 +31,4 @@ @import url("./Apps/PlayerSheet.css") layer(apps); @import url("./Apps/QueryStatus.css") layer(apps); @import url("./Apps/TAFDocumentSheetConfig.css") layer(apps); +@import url("./Apps/TAFSettingsSidebar.css") layer(apps); diff --git a/templates/settings-sidebar-addition.hbs b/templates/settings-sidebar-addition.hbs new file mode 100644 index 0000000..71fed2b --- /dev/null +++ b/templates/settings-sidebar-addition.hbs @@ -0,0 +1,48 @@ +
+

+ {{ system.title }} +

+
+ + {{localize "taf.misc.version" version=system.version}} + + + {{localize "taf.misc.whats-new"}} + +
+ +
From 211b9b313524b1cd7f5aced31c8db342b8bcadfb Mon Sep 17 00:00:00 2001 From: Oliver Date: Sun, 10 May 2026 23:46:31 -0600 Subject: [PATCH 23/23] Update version to 3.0.2 in the manifest --- system.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/system.json b/system.json index 754695b..22a301f 100644 --- a/system.json +++ b/system.json @@ -2,7 +2,7 @@ "id": "taf", "title": "Text-Based Actors", "description": "An intentionally minimalist system that enables you to play rules-light games without getting in your way!", - "version": "3.0.1", + "version": "3.0.2", "download": "", "manifest": "", "url": "https://git.varify.ca/Foundry/taf", @@ -55,6 +55,7 @@ }, "socket": true, "flags": { + "forgejo_api": "https://git.varify.ca/api/v1", "hotReload": { "extensions": ["css", "hbs", "json", "js", "mjs", "svg"], "paths": ["templates", "langs", "styles", "module", "assets"]