New "Connection Status" popup

This commit is contained in:
nutty
2026-10-20 10:40:46 +11:00
parent 58495dcc7e
commit 773de858ac
17 changed files with 203 additions and 213 deletions
+68
View File
@@ -0,0 +1,68 @@
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap');
.connection-status {
position: fixed;
top: 50%;
left: 50%;
z-index: 99999;
font-family: 'Inter', sans-serif;
font-size: 30px;
font-weight: 700;
font-style: italic;
text-align: center;
color: white;
padding: 16px 28px;
border-radius: 10px;
background: #D12025;
/* Centering and entrance animation */
opacity: 0;
visibility: hidden;
transform: translate(-50%, calc(-50% + 10px));
transition:
opacity 200ms ease,
transform 200ms ease,
visibility 200ms ease;
pointer-events: none;
white-space: nowrap;
}
.connection-status.is-visible {
opacity: 1;
visibility: visible;
transform: translate(-50%, -50%);
}
/* Optional dark translucent backdrop */
.connection-status-backdrop {
position: fixed;
inset: 0;
z-index: 99998;
background: rgba(0, 0, 0, 0.45);
opacity: 0;
visibility: hidden;
transition:
opacity 200ms ease,
visibility 200ms ease;
pointer-events: none;
}
.connection-status-backdrop.is-visible {
opacity: 1;
visibility: visible;
}
.connection-status--streamerbot {
background: linear-gradient(
135deg,
#a257ed 0%,
#a257ed 20%,
#0b72ff 100%
);
}
+76
View File
@@ -0,0 +1,76 @@
class ConnectionStatus {
constructor({
target = document.body,
name = "Service",
disconnectedMessage,
className = "",
showDelay = 0,
} = {}) {
this.name = name;
this.showDelay = showDelay;
this.wasConnected = false;
this.disconnectTimer = null;
// Generate a CSS class from the service name.
const serviceClass = {
"Streamer.bot": "connection-status--streamerbot",
}[name] || "";
this.element = document.createElement("div");
this.element.className = [
"connection-status",
serviceClass,
className
].filter(Boolean).join(" ");
this.element.setAttribute("role", "status");
this.element.setAttribute("aria-live", "polite");
this.element.hidden = true;
this.disconnectedMessage =
disconnectedMessage ?? `${name} disconnected`;
target.appendChild(this.element);
}
setConnected(connected) {
clearTimeout(this.disconnectTimer);
this.disconnectTimer = null;
if (connected) {
this.wasConnected = true;
this.hide();
return;
}
this.disconnectTimer = setTimeout(() => {
this.show(this.disconnectedMessage);
}, this.showDelay);
}
show(message) {
this.element.textContent = message;
this.element.hidden = false;
this.element.classList.remove("is-visible");
void this.element.offsetHeight;
this.element.classList.add("is-visible");
}
hide() {
this.element.classList.remove("is-visible");
setTimeout(() => {
if (!this.element.classList.contains("is-visible")) {
this.element.hidden = true;
}
}, 220);
}
destroy() {
clearTimeout(this.disconnectTimer);
this.element.remove();
}
}