import { app } from "../../../scripts/app.js"; import { api } from "../../../scripts/api.js"; app.registerExtension({ name: "AudioCraft.AudioManager", async beforeRegisterNodeDef(nodeType, nodeData, app) { if (nodeData.name === "AudioManager") { const onExecuted = nodeType.prototype.onExecuted; nodeType.prototype.onExecuted = function (message) { onExecuted?.apply(this, arguments); if (!message?.text) return; const summary = message.text[0]?.content || ""; const files = message.files || []; if (this._managerWidget) { // Update existing widget content this._managerContainer.innerHTML = ""; buildContent(this._managerContainer, summary, files); const h = Math.min(60 + files.length * 22, 500); this._managerWidget.computeSize = () => [this.size[0], h]; this.setSize([this.size[0], h + 80]); } else { const container = document.createElement("div"); container.style.cssText = "padding:4px;overflow-y:auto;max-height:450px;"; buildContent(container, summary, files); this._managerContainer = container; this._managerWidget = this.addDOMWidget("audio_manager", "dom", container, { serialize: false, hideOnZoom: false, }); const h = Math.min(60 + files.length * 22, 500); this._managerWidget.computeSize = () => [this.size[0], h]; this.setSize([this.size[0], h + 80]); } app.graph.setDirtyCanvas(true); }; } }, }); function buildContent(container, summary, files) { const header = document.createElement("div"); header.textContent = summary; header.style.cssText = "font-weight:bold;margin-bottom:6px;color:#fff;font-size:12px;"; container.appendChild(header); if (files.length === 0) return; for (const f of files) { const row = document.createElement("div"); row.style.cssText = "display:flex;justify-content:space-between;padding:2px 0;font-size:11px;color:#ccc;border-bottom:1px solid #333;align-items:center;"; const name = document.createElement("span"); name.textContent = f.name; name.style.cssText = "overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1;margin-right:8px;"; const size = document.createElement("span"); size.textContent = f.size_mb + " MB"; size.style.cssText = "color:#8cf;min-width:60px;text-align:right;margin-right:8px;"; const playBtn = document.createElement("button"); playBtn.textContent = "\u25B6"; playBtn.style.cssText = "background:#444;border:none;color:#8f8;cursor:pointer;padding:1px 6px;border-radius:3px;font-size:10px;"; const audioSrc = api.apiURL( `/view?filename=${encodeURIComponent(f.name)}&subfolder=audio&type=output` ); let currentAudio = null; playBtn.onclick = () => { if (currentAudio) { currentAudio.pause(); currentAudio = null; playBtn.textContent = "\u25B6"; return; } currentAudio = new Audio(audioSrc); currentAudio.play(); playBtn.textContent = "\u25A0"; currentAudio.onended = () => { playBtn.textContent = "\u25B6"; currentAudio = null; }; }; row.appendChild(name); row.appendChild(size); row.appendChild(playBtn); container.appendChild(row); } }