diff --git a/.common/utils/connection-status.css b/.common/utils/connection-status.css new file mode 100644 index 0000000..b61bb89 --- /dev/null +++ b/.common/utils/connection-status.css @@ -0,0 +1,70 @@ +@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: 0.25em 1em; + border-radius: 10px; + background: #D12025; + + box-shadow: 5px 5px 10px rgba(0, 0, 0, 0.5); + + /* 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: 0.9; + 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% + ); +} \ No newline at end of file diff --git a/.common/utils/connection-status.js b/.common/utils/connection-status.js new file mode 100644 index 0000000..f5bcae3 --- /dev/null +++ b/.common/utils/connection-status.js @@ -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(); + } +} diff --git a/horizontal-chat/index.html b/horizontal-chat/index.html index ccf2530..779bf35 100644 --- a/horizontal-chat/index.html +++ b/horizontal-chat/index.html @@ -8,7 +8,6 @@ -
Connecting...
@@ -39,4 +38,6 @@ + + \ No newline at end of file diff --git a/horizontal-chat/script.js b/horizontal-chat/script.js index ed558fc..80eab63 100644 --- a/horizontal-chat/script.js +++ b/horizontal-chat/script.js @@ -125,6 +125,14 @@ document.documentElement.style.setProperty('--animation-speed', `${animationSpee // STREAMER.BOT CLIENT // ///////////////////////// +const connectionStatus = new ConnectionStatus({ + name: "Streamer.bot", + showDelay: 1000, + disconnectedMessage: "Connecting to Streamer.bot..." +}); + +connectionStatus.setConnected(false); + const client = new StreamerbotClient({ host: sbServerAddress, port: sbServerPort, @@ -132,13 +140,13 @@ const client = new StreamerbotClient({ onConnect: (data) => { console.log(`Streamer.bot successfully connected to ${sbServerAddress}:${sbServerPort}`) console.debug(data); - SetConnectionStatus(true); + connectionStatus.setConnected(true); KickConnect(); }, onDisconnect: () => { console.error(`Streamer.bot disconnected from ${sbServerAddress}:${sbServerPort}`) - SetConnectionStatus(false); + connectionStatus.setConnected(false); } }); @@ -1848,30 +1856,4 @@ function GetWinnersList(gifts) { const secondLastWinner = winners.pop(); return `${winners.join(", ")}, ${secondLastWinner} and ${lastWinner}`; } -} - - - -/////////////////////////////////// -// STREAMER.BOT WEBSOCKET STATUS // -/////////////////////////////////// - -// This function sets the visibility of the Streamer.bot status label on the overlay -function SetConnectionStatus(connected) { - let statusContainer = document.getElementById("statusContainer"); - if (connected) { - statusContainer.style.background = "#2FB774"; - statusContainer.innerText = "Connected!"; - statusContainer.style.opacity = 1; - setTimeout(() => { - statusContainer.style.transition = "all 2s ease"; - statusContainer.style.opacity = 0; - }, 10); - } - else { - statusContainer.style.background = "#D12025"; - statusContainer.innerText = "Connecting..."; - statusContainer.style.transition = ""; - statusContainer.style.opacity = 1; - } } \ No newline at end of file diff --git a/horizontal-chat/style.css b/horizontal-chat/style.css index 50553da..b879505 100644 --- a/horizontal-chat/style.css +++ b/horizontal-chat/style.css @@ -21,20 +21,6 @@ html { overflow-wrap: break-word; } -#statusContainer { - font-weight: 500; - font-size: 30px; - text-align: center; - background-color: #D12025; - color: white; - padding: 10px; - border-radius: 10px; - position: absolute; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); -} - #mainContainer { position: absolute; height: calc(100% - 2 * var(--margin)); diff --git a/multichat-overlay/index.html b/multichat-overlay/index.html index a5134d4..03f6542 100644 --- a/multichat-overlay/index.html +++ b/multichat-overlay/index.html @@ -9,7 +9,6 @@ -
@@ -106,4 +105,6 @@ + + \ No newline at end of file diff --git a/multichat-overlay/script.js b/multichat-overlay/script.js index e3f50a2..9f94784 100644 --- a/multichat-overlay/script.js +++ b/multichat-overlay/script.js @@ -145,6 +145,14 @@ document.documentElement.style.setProperty('--animation-speed', `${animationSpee // STREAMER.BOT CLIENT // ///////////////////////// +const connectionStatus = new ConnectionStatus({ + name: "Streamer.bot", + showDelay: 1000, + disconnectedMessage: "Connecting to Streamer.bot..." +}); + +connectionStatus.setConnected(false); + const client = new StreamerbotClient({ host: sbServerAddress, port: sbServerPort, @@ -153,13 +161,13 @@ const client = new StreamerbotClient({ onConnect: (data) => { console.log(`Streamer.bot successfully connected to ${sbServerAddress}:${sbServerPort}`) console.debug(data); - SetConnectionStatus(true); + connectionStatus.setConnected(true); KickConnect(); }, onDisconnect: () => { console.error(`Streamer.bot disconnected from ${sbServerAddress}:${sbServerPort}`) - SetConnectionStatus(false); + connectionStatus.setConnected(false); } }); @@ -3383,32 +3391,6 @@ function GetWinnersList(gifts) { } } - - -/////////////////////////////////// -// STREAMER.BOT WEBSOCKET STATUS // -/////////////////////////////////// - -// This function sets the visibility of the Streamer.bot status label on the overlay -function SetConnectionStatus(connected) { - let statusContainer = document.getElementById("statusContainer"); - if (connected) { - statusContainer.style.background = "#2FB774"; - statusContainer.innerText = "Connected!"; - statusContainer.style.opacity = 1; - setTimeout(() => { - statusContainer.style.transition = "all 2s ease"; - statusContainer.style.opacity = 0; - }, 10); - } - else { - statusContainer.style.background = "#D12025"; - statusContainer.innerText = "Connecting..."; - statusContainer.style.transition = ""; - statusContainer.style.opacity = 1; - } -} - async function GetYouTubeVideoData(videoId) { const url = `https://www.youtube.com/oembed?url=https://www.youtube.com/watch?v=${videoId}&format=json`; diff --git a/multichat-overlay/style.css b/multichat-overlay/style.css index 1e013c7..271b252 100644 --- a/multichat-overlay/style.css +++ b/multichat-overlay/style.css @@ -21,20 +21,6 @@ html { overflow-wrap: break-word; } -#statusContainer { - font-weight: 500; - font-size: 30px; - text-align: center; - background-color: #D12025; - color: white; - padding: 10px; - border-radius: 10px; - position: absolute; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); -} - #mainContainer { position: absolute; height: calc(100% - 2 * var(--margin)); diff --git a/multistream-alerts/index.html b/multistream-alerts/index.html index 6d1abb4..6d0688e 100644 --- a/multistream-alerts/index.html +++ b/multistream-alerts/index.html @@ -8,7 +8,6 @@ -
Connecting...
@@ -45,4 +44,6 @@ + + \ No newline at end of file diff --git a/multistream-alerts/script.js b/multistream-alerts/script.js index 6d3afe7..7b1c8b5 100644 --- a/multistream-alerts/script.js +++ b/multistream-alerts/script.js @@ -173,6 +173,14 @@ switch (alignment) // STREAMER.BOT CLIENT // ///////////////////////// +const connectionStatus = new ConnectionStatus({ + name: "Streamer.bot", + showDelay: 1000, + disconnectedMessage: "Connecting to Streamer.bot..." +}); + +connectionStatus.setConnected(false); + const client = new StreamerbotClient({ host: sbServerAddress, port: sbServerPort, @@ -180,13 +188,13 @@ const client = new StreamerbotClient({ onConnect: (data) => { console.log(`Streamer.bot successfully connected to ${sbServerAddress}:${sbServerPort}`) console.debug(data); - SetConnectionStatus(true); + connectionStatus.setConnected(true); KickConnect(); }, onDisconnect: () => { console.error(`Streamer.bot disconnected from ${sbServerAddress}:${sbServerPort}`) - SetConnectionStatus(false); + connectionStatus.setConnected(false); } }); @@ -1813,29 +1821,4 @@ async function testWidget() `O-oooooooooo AAAAE-A-A-I-A-U- JO-oooooooooooo AAE-O-A-A-U-U-A- E-eee-ee-eee AAAAE-A-E-I-E-A-JO-ooo-oo-oo-oo EEEEO-A-AAA-AAAA` //`` ); -} - - -/////////////////////////////////// -// STREAMER.BOT WEBSOCKET STATUS // -/////////////////////////////////// - -// This function sets the visibility of the Streamer.bot status label on the overlay -function SetConnectionStatus(connected) { - let statusContainer = document.getElementById("statusContainer"); - if (connected) { - statusContainer.style.background = "#2FB774"; - statusContainer.innerText = "Connected!"; - statusContainer.style.opacity = 1; - setTimeout(() => { - statusContainer.style.transition = "all 2s ease"; - statusContainer.style.opacity = 0; - }, 10); - } - else { - statusContainer.style.background = "#D12025"; - statusContainer.innerText = "Connecting..."; - statusContainer.style.transition = ""; - statusContainer.style.opacity = 1; - } } \ No newline at end of file diff --git a/multistream-alerts/style.css b/multistream-alerts/style.css index 58a1cd1..c310dc8 100644 --- a/multistream-alerts/style.css +++ b/multistream-alerts/style.css @@ -22,20 +22,6 @@ html { overflow-wrap: break-word; } -#statusContainer { - font-weight: 500; - font-size: 30px; - text-align: center; - background-color: #D12025; - color: white; - padding: 10px; - border-radius: 10px; - position: absolute; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); -} - #mainContainer { position: absolute; width: 100%; diff --git a/now-playing/themes/color-palette/script.js b/now-playing/themes/color-palette/script.js index bb194e4..b0a0a2d 100644 --- a/now-playing/themes/color-palette/script.js +++ b/now-playing/themes/color-palette/script.js @@ -91,6 +91,8 @@ async function ChangeTrack(mediaProps, accentColorPalette) { boxes[role].style.color = colorValue; labels[role].style.opacity = ''; }); + + SetVisibility(true); // Show the overlay for a few seconds if autoHide is enabled }, 250); } diff --git a/obs-info-hud/index.html b/obs-info-hud/index.html index afcb382..f33560c 100644 --- a/obs-info-hud/index.html +++ b/obs-info-hud/index.html @@ -8,7 +8,6 @@ -
Connecting...
@@ -77,4 +76,6 @@ + + \ No newline at end of file diff --git a/obs-info-hud/script.js b/obs-info-hud/script.js index 0e95aa5..0773a32 100644 --- a/obs-info-hud/script.js +++ b/obs-info-hud/script.js @@ -25,6 +25,13 @@ let previousOutputTimecode = 0; let previousOutputBytes = 0; let activeFps; +const connectionStatus = new ConnectionStatus({ + showDelay: 1000, + disconnectedMessage: "Connecting to Streamer.bot..." +}); + +connectionStatus.setConnected(false); + function connectws() { if ("WebSocket" in window) { @@ -32,7 +39,7 @@ function connectws() { // Reconnect ws.onclose = function () { - SetConnectionStatus(false); + connectionStatus.setConnected(false); setTimeout(connectws, 5000); }; @@ -67,7 +74,7 @@ function connectws() { break; case 2: // Identify OpCode console.log("Connected to OBS!"); - SetConnectionStatus(true); + connectionStatus.setConnected(true); break; case 5: // Event OpCode switch (data.d.eventType) { @@ -379,26 +386,6 @@ function hexToBase64(hexstring) { // WEBSOCKET STATUS // ////////////////////// -// This function sets the visibility of the Streamer.bot status label on the overlay -function SetConnectionStatus(connected) { - let statusContainer = document.getElementById("statusContainer"); - - if (connected) { - statusContainer.style.background = "#2FB774"; - statusContainer.innerText = "Connected!"; - mainContainer.style.visibility = `visible`; - var tl = new TimelineMax(); - tl - .to(statusContainer, 2, { opacity: 0, ease: Linear.easeNone }); - } - else { - statusContainer.style.background = "#D12025"; - statusContainer.innerText = "Connecting..."; - statusContainer.style.opacity = 1; - mainContainer.style.visibility = `hidden`; - } -} - connectws(); setInterval(GetStreamStatus, 1000); diff --git a/obs-info-hud/style.css b/obs-info-hud/style.css index 2effbd0..2a1f8d5 100644 --- a/obs-info-hud/style.css +++ b/obs-info-hud/style.css @@ -6,24 +6,6 @@ body { background-size: cover; } -#statusContainer { - font-family: 'Metropolis'; - font-style: italic; - font-weight: bold; - font-size: 30px; - width: 400px; - max-width: fit-content; - text-align: center; - background-color: #D12025; - color: white; - padding: 10px; - border-radius: 10px; - position: absolute; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); -} - #top, #bottom, #left, diff --git a/twitch-ad-countdown-timer/index.html b/twitch-ad-countdown-timer/index.html index 71d8c37..fc5f623 100644 --- a/twitch-ad-countdown-timer/index.html +++ b/twitch-ad-countdown-timer/index.html @@ -9,7 +9,6 @@ -
Connecting...
@@ -26,4 +25,6 @@ + + \ No newline at end of file diff --git a/twitch-ad-countdown-timer/script.js b/twitch-ad-countdown-timer/script.js index bae7b05..b4c7ef8 100644 --- a/twitch-ad-countdown-timer/script.js +++ b/twitch-ad-countdown-timer/script.js @@ -113,6 +113,14 @@ switch (timerPosition) { // STREAMER.BOT CLIENT // ///////////////////////// +const connectionStatus = new ConnectionStatus({ + name: "Streamer.bot", + showDelay: 1000, + disconnectedMessage: "Connecting to Streamer.bot..." +}); + +connectionStatus.setConnected(false); + const client = new StreamerbotClient({ host: sbServerAddress, port: sbServerPort, @@ -120,12 +128,12 @@ const client = new StreamerbotClient({ onConnect: (data) => { console.log(`Streamer.bot successfully connected to ${sbServerAddress}:${sbServerPort}`) console.debug(data); - SetConnectionStatus(true); + connectionStatus.setConnected(true); }, onDisconnect: () => { console.error(`Streamer.bot disconnected from ${sbServerAddress}:${sbServerPort}`) - SetConnectionStatus(false); + connectionStatus.setConnected(false); } }); @@ -355,31 +363,4 @@ function testAd() { function testUpcomingAdWarning() { UpcomingAdWarning(warningSeconds); -} - - - - -/////////////////////////////////// -// STREAMER.BOT WEBSOCKET STATUS // -/////////////////////////////////// - -// This function sets the visibility of the Streamer.bot status label on the overlay -function SetConnectionStatus(connected) { - let statusContainer = document.getElementById("statusContainer"); - if (connected) { - statusContainer.style.background = "#2FB774"; - statusContainer.innerText = "Connected!"; - statusContainer.style.opacity = 1; - setTimeout(() => { - statusContainer.style.transition = "all 2s ease"; - statusContainer.style.opacity = 0; - }, 10); - } - else { - statusContainer.style.background = "#D12025"; - statusContainer.innerText = "Connecting..."; - statusContainer.style.transition = ""; - statusContainer.style.opacity = 1; - } } \ No newline at end of file diff --git a/twitch-ad-countdown-timer/style.css b/twitch-ad-countdown-timer/style.css index 6033fd4..411ce46 100644 --- a/twitch-ad-countdown-timer/style.css +++ b/twitch-ad-countdown-timer/style.css @@ -14,20 +14,6 @@ html { overflow-wrap: break-word; */ } -#statusContainer { - font-weight: 500; - font-size: 30px; - text-align: center; - background-color: #D12025; - color: white; - padding: 10px; - border-radius: 10px; - position: absolute; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); -} - #timer-bar { width: 0px; height: 0px;