A queued alert
If two follows arrive at once and you draw them directly, the second wipes the first before it can be read.
Widget.queue lines them up: each alert shows when the previous one ends.
{ "events": ["Twitch.Follow", "Kick.Follow", "Twitch.Sub"], "strings": { "es": { "follow": "¡Gracias por el follow, {name}!", "sub": "¡{name} se ha suscrito!" }, "en": { "follow": "Thanks for the follow, {name}!", "sub": "{name} just subscribed!" } }, "menu": { "sections": [] }}<div id="banner"></div>html,body { margin: 0; background: transparent;}
#banner { position: absolute; left: 50%; top: 40px; transform: translateX(-50%); padding: 16px 32px; font: 700 36px system-ui, sans-serif; color: #ffffff; background: #6d28d9; opacity: 0; transition: opacity 0.3s;}
#banner.visible { opacity: 1;}const banner = document.querySelector("#banner");
function thank(key) { return ({ user }) => { Widget.queue.push(() => { Widget.dom.text(banner, Widget.t(key, { name: user })); banner.classList.add("visible"); return () => banner.classList.remove("visible"); }, { duration: 6 }); };}
Widget.on("Twitch.Follow", thank("follow"));Widget.on("Kick.Follow", thank("follow"));Widget.on("Twitch.Sub", thank("sub"));How it works
Section titled “How it works”- The function you pass to
pushdraws the alert. What it returns (here, a function that removes thevisibleclass) runs when its duration ends: that is where you clean up everything you put on screen. duration: 6is how many seconds it stays visible. Without it,queue.durationSecondsfrom the manifest applies (5 by default).- The viewer’s name goes through
Widget.tandWidget.dom.text, so it is never interpreted as HTML.
Variations
Section titled “Variations”- Let a sub go ahead of the follows:
{ duration: 6, priority: 1 }. With priority, the task runs before those with less. - Fold many follows into one:
{ group: "follow" }. When the alert starts, the pending ones of the group are folded into it, and the task receives how many infolded, so you can write “and 4 more”. - Respect the cut: if the task waits for something, check
signal.abortedafter every wait before drawing:Widget.queue.clear()aborts the running task.