diff --git a/module.json b/module.json
index ed3df3e..6eefe42 100644
--- a/module.json
+++ b/module.json
@@ -2,10 +2,10 @@
"id": "duality-roller",
"title": "Daggerheart Duality Dice Roller",
"description": "Adds a button next to the chat dice/controls that triggers the /dr command for the Foundryborne Daggerheart system.",
- "version": "1.1.6",
+ "version": "1.2.0",
"compatibility": {
"minimum": "13",
- "verified": "13"
+ "verified": "14"
},
"authors": [
{
@@ -22,5 +22,5 @@
"languages": [],
"url": "https://git.geeks.gay/cosmo/DualityDiceRoller",
"manifest": "https://git.geeks.gay/cosmo/DualityDiceRoller/raw/branch/main/module.json",
- "download": "https://git.geeks.gay/cosmo/DualityDiceRoller/releases/download/1.1.6/DualityDiceRoller.zip"
+ "download": "https://git.geeks.gay/cosmo/DualityDiceRoller/releases/download/1.2.0/DualityDiceRoller.zip"
}
\ No newline at end of file
diff --git a/scripts/dr-button.js b/scripts/dr-button.js
index 099b14a..dd6b9b1 100644
--- a/scripts/dr-button.js
+++ b/scripts/dr-button.js
@@ -8,46 +8,89 @@ Hooks.once("init", () => {
});
// Sidebar chat
-Hooks.on("renderChatLog", (_app, _html) => addDRButton());
+Hooks.on("renderChatLog", (app, html) => addDRButton(html));
// Mini/Popout chat
-Hooks.on("renderChatPopout", (_app, _html) => addDRButton());
+Hooks.on("renderChatPopout", (app, html) => addDRButton(html));
-function addDRButton() {
+/**
+ * Adds the DR button to the chat controls
+ * @param {HTMLElement|jQuery} html - The application HTML
+ */
+function addDRButton(html) {
+ if (!html) return;
try {
- // Find all roll-privacy divs and append one button per container, avoiding duplicates
- const rollPrivacyDivs = document.querySelectorAll("#roll-privacy");
- rollPrivacyDivs.forEach(div => {
- // If this container already has our button, skip adding another
- if (div.querySelector(".dr-quick-button-container")) return;
+ // Handle both jQuery (legacy) and HTMLElement (v14/AppV2)
+ const root = html instanceof HTMLElement ? html : html[0];
+ if (!root) return;
- const container = document.createElement("div");
- container.className = "dr-quick-button-container";
+ console.debug("DR Quick Button | addDRButton called. Root element:", root.tagName, root.className, root.getAttribute("data-application-part"));
- // Build button
- const btn = document.createElement("button");
- btn.type = "button";
- btn.className = "ui-control icon fas-solid dr-quick-button";
- btn.title = "Duality Dice Roll";
- btn.setAttribute("aria-label", "Duality Dice Roll");
+ // Common selectors for chat controls/roll privacy across versions
+ const targetSelectors = [
+ "#message-modes", // Foundry v14+ (Split button container)
+ "#chat-controls", // Generic chat controls
+ "#roll-privacy", // Legacy ID
+ ".roll-privacy", // Legacy class
+ ".roll-type-select", // System specific
+ ".chat-controls" // Generic fallback
+ ];
- // Inline SVG (or use icon.src = "modules/dr-quick-button/icons/dr.svg"; if external)
- btn.innerHTML = `
`;
- btn.addEventListener("click", async () => {
- await runDRCommand();
+ let found = false;
+ for (const selector of targetSelectors) {
+ // Find targets within the root, or check if the root itself is the target
+ let targets = Array.from(root.querySelectorAll(selector));
+ if (root.matches && root.matches(selector)) targets.push(root);
+
+ // Fallback: If not found in the provided root part, search the whole document
+ // (In v14, the hook might pass only one part of the ApplicationV2)
+ if (targets.length === 0) {
+ const globalTargets = document.querySelectorAll(selector);
+ // Only consider global targets that are actually visible/relevant
+ targets = Array.from(globalTargets).filter(t => root.contains(t) || t.closest(".window-app") === root.closest(".window-app") || t.closest("#sidebar") === root.closest("#sidebar"));
+ }
+
+ if (targets.length === 0) continue;
+
+ targets.forEach(div => {
+ // Avoid duplicates
+ if (div.querySelector(".dr-quick-button-container")) return;
+
+ console.log(`DR Quick Button | Adding button to target: ${selector}`);
+
+ const container = document.createElement("div");
+ container.className = "dr-quick-button-container";
+
+ const btn = document.createElement("button");
+ btn.type = "button";
+ btn.className = "ui-control icon fa-solid dr-quick-button";
+ btn.title = "Duality Dice Roll";
+ btn.setAttribute("aria-label", "Duality Dice Roll");
+
+ // Use the Daggerheart system icon
+ btn.innerHTML = `
`;
+ btn.addEventListener("click", async (event) => {
+ event.preventDefault();
+ await runDRCommand();
+ });
+
+ container.appendChild(btn);
+ div.appendChild(container);
+ found = true;
});
- container.appendChild(btn);
- div.appendChild(container);
- });
+ if (found) break;
+ }
+
+ if (!found) {
+ console.debug("DR Quick Button | No suitable target found in root or related containers.");
+ }
} catch (err) {
console.error("DR Quick Button | addDRButton error:", err);
}
}
-
-
/** Run `/dr` as if typed into chat */
async function runDRCommand() {
try {