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 = `DR`; - 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 = `DR`; + 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 {