diff --git a/app/ui/composer/elements/status.js b/app/ui/composer/elements/status.js index 5d1bacd0..9490ee1a 100644 --- a/app/ui/composer/elements/status.js +++ b/app/ui/composer/elements/status.js @@ -135,6 +135,8 @@ function toastStack() { for (const tone of ["info", "good", "warn", "danger"]) { define("toast", tone, ({ text, action, duration = 3200 } = {}) => { + // Nothing to say: nothing shown. An empty bubble reads as a message that went missing. + if (!String(text ?? "").trim() && !(action && action.node)) return { node: null, setText() {}, destroy() {} }; const node = el("div", { cls: ["cx-toast", `cx-toast-${tone}`], attrs: { role: tone === "danger" ? "alert" : "status" }, children: [ el("span", { cls: "cx-toast-text", text }), diff --git a/app/ui/composer/tests/overlays.test.js b/app/ui/composer/tests/overlays.test.js index 8e3c0df4..e69eb0a9 100644 --- a/app/ui/composer/tests/overlays.test.js +++ b/app/ui/composer/tests/overlays.test.js @@ -646,3 +646,10 @@ test("closing a window while a field in it is focused still commits what was typ win.close(); assert.equal(got, "portraits"); }); + +test("a toast with no words is not shown at all", () => { + const before = document.querySelectorAll(".cx-toast").length; + for (const text of [null, undefined, "", " "]) composer.toast.warn({ text }).destroy(); + composer.toast.warn({ text: null }); + assert.equal(document.querySelectorAll(".cx-toast").length, before); +}); diff --git a/app/ui/features/generate/index.js b/app/ui/features/generate/index.js index 052c7f2f..f845a320 100644 --- a/app/ui/features/generate/index.js +++ b/app/ui/features/generate/index.js @@ -21,9 +21,9 @@ export default { setup({ host, app }) { const p = app.project, g = app.generate; let said = false; - const tell = (text) => { said = true; c.toast.warn({ text }); }; + const tell = (text) => { if (!text) return; said = true; c.toast.warn({ text }); }; // no words, no toast: an empty one read as a message gone missing let current = 0; // the scene being queued: a refusal said meanwhile names it - g.on("say", (t) => tell(current ? `Scene ${current}: ${t}` : t)); g.on("warn", tell); + g.on("say", (t) => tell(t && (current ? `Scene ${current}: ${t}` : t))); g.on("warn", tell); g.on("hold", () => { held = true; draw(); }); g.on("release", () => { held = false; draw(); }); // while the page asks ComfyUI whether a run is already going // the pipeline check's refusals: said where the person is looking let busy = false, stopped = false, held = false;