Lots of stuff, can't remember lol

This commit is contained in:
nuttylmao
2025-04-18 22:13:18 +10:00
parent ddc3dd10e7
commit 75658f89d3
10 changed files with 519 additions and 116 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 198 KiB

+13 -3
View File
@@ -4,17 +4,26 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="icon" href="../../.resources/logo.png" type="image/png">
<title>Settings</title> <title>Settings</title>
<link rel="stylesheet" href="style.css"> <link rel="stylesheet" href="style.css">
<script type="text/javascript" src="https://unpkg.com/@streamerbot/client/dist/streamerbot-client.js"></script>
</head> </head>
<body> <body>
<div id="pinned-header"> <div id="pinned-header">
<div style="display: flex; align-items: center; padding-bottom: 20px;">
<img src="../../.resources/logo.png" style="height: 40px;"/>
<button style="display: flex; width: auto; margin-left: auto; background: var(--accent-color);" onclick="OpenMembershipPage()">Check out my premium widgets</button>
</div>
<h2>Widget URL</h2> <h2>Widget URL</h2>
<input id="widget-url" type="text" readonly> <input id="widget-url" type="text" readonly>
<button id="save-settings">Click to copy URL</button> <div style="display: flex; gap: 10px;">
<button onclick="OpenMembershipPage()">💎 Member Exclusive Widgets</button> <button id="save-settings">Click to copy URL</button>
<button onclick="OpenLoadSettingsPopup()">Load Settings</button>
</div>
<!-- <button onclick="OpenMembershipPage()">💎 Member Exclusive Widgets</button> -->
</div> </div>
<div id="settings-container"> <div id="settings-container">
@@ -24,7 +33,8 @@
<div id="mommy-milkers"> <div id="mommy-milkers">
<div id="load-settings-container"> <div id="load-settings-container">
<h2>Load Settings From Widget URL</h2> <h2>Load Settings</h2>
<label style="font-size: 0.8em;">Paste in your existing widget URL</label>
<input id="load-url" type="text"> <input id="load-url" type="text">
<div style="display: flex;"> <div style="display: flex;">
<button id="cancel-settings" onclick="CloseSettings()">Cancel</button> <button id="cancel-settings" onclick="CloseSettings()">Cancel</button>
+117 -21
View File
@@ -1,14 +1,52 @@
// Search paramaters
const queryString = window.location.search; const queryString = window.location.search;
const urlParams = new URLSearchParams(queryString); const urlParams = new URLSearchParams(queryString);
const settingsJson = urlParams.get("settingsJson") || ""; const settingsJson = urlParams.get("settingsJson") || "";
// Connect to Streamer.bot and get list of actions
const sbServerAddress = '127.0.0.1';
const sbServerPort = '8080';
const client = new StreamerbotClient({
host: sbServerAddress,
port: sbServerPort,
onConnect: (data) => {
console.log(`Streamer.bot successfully connected to ${sbServerAddress}:${sbServerPort}`)
console.debug(data);
// Get list of actions
GetSBActions();
},
onDisconnect: () => {
console.error(`Streamer.bot disconnected from ${sbServerAddress}:${sbServerPort}`)
}
});
async function GetSBActions() {
const response = await client.getActions();
console.debug(response);
const datalistElement = document.createElement('datalist');
datalistElement.id = 'streamer-bot-actions';
for (const action of response.actions)
{
const option = document.createElement('option');
option.value = action.name;
datalistElement.appendChild(option);
}
document.body.appendChild(datalistElement);
}
document.addEventListener('DOMContentLoaded', () => { document.addEventListener('DOMContentLoaded', () => {
const settingsContent = document.getElementById('settings-content'); const settingsContent = document.getElementById('settings-content');
const saveButton = document.getElementById('save-settings'); const saveButton = document.getElementById('save-settings');
fetch(settingsJson) fetch(settingsJson)
//fetch('../../multichat-overlay/settings/settings.json')
.then(response => response.json()) .then(response => response.json())
.then(data => { .then(data => {
const groupedSettings = {}; const groupedSettings = {};
@@ -33,12 +71,15 @@ document.addEventListener('DOMContentLoaded', () => {
groupedSettings[groupName].forEach(setting => { groupedSettings[groupName].forEach(setting => {
const settingItem = document.createElement('div'); const settingItem = document.createElement('div');
settingItem.classList.add('setting-item'); settingItem.classList.add('setting-item');
settingItem.id = `item-${setting.id}`;
const labelDescriptionDiv = document.createElement('div'); const labelDescriptionDiv = document.createElement('div');
const label = document.createElement('label'); if (setting.label) {
label.textContent = setting.label; const label = document.createElement('label');
labelDescriptionDiv.appendChild(label); label.textContent = setting.label;
labelDescriptionDiv.appendChild(label);
}
if (setting.description) { if (setting.description) {
const description = document.createElement('p'); const description = document.createElement('p');
@@ -74,6 +115,7 @@ document.addEventListener('DOMContentLoaded', () => {
// Add event listener to the switchDiv // Add event listener to the switchDiv
labelDiv.addEventListener('click', () => { labelDiv.addEventListener('click', () => {
checkBoxElement.checked = !checkBoxElement.checked; checkBoxElement.checked = !checkBoxElement.checked;
UpdateSettingItemVisibility();
}); });
inputElement = labelDiv; inputElement = labelDiv;
break; break;
@@ -106,6 +148,37 @@ document.addEventListener('DOMContentLoaded', () => {
inputElement.max = setting.max; inputElement.max = setting.max;
inputElement.step = setting.step; inputElement.step = setting.step;
break; break;
case 'sb-actions':
inputElement = document.createElement('input');
inputElement.type = 'text';
inputElement.placeholder = 'Type to search...';
inputElement.id = setting.id; //Added setting ID
inputElement.value = setting.defaultValue;
inputElement.setAttribute('list', 'streamer-bot-actions');
inputElement.autocomplete = 'off';
break;
case 'button':
inputElement = document.createElement('button');
inputElement.id = setting.id; //Added setting ID
inputElement.textContent = setting.label;
inputElement.addEventListener('click', () => {
window.parent.callFunction(setting.callFunction);
const defaultBackgroundColor = "#2e2e2e";
const defaultTextColor = "white";
inputElement.style.transitionDuration = '0s'
inputElement.style.backgroundColor = "#2196f3"
inputElement.style.color = "#ffffff";
setTimeout(() => {
inputElement.style.transitionDuration = '0.2s'
inputElement.style.backgroundColor = defaultBackgroundColor;
inputElement.style.color = defaultTextColor;
}, 100);
});
break;
default: default:
inputElement = document.createElement('input'); inputElement = document.createElement('input');
inputElement.type = 'text'; inputElement.type = 'text';
@@ -114,30 +187,53 @@ document.addEventListener('DOMContentLoaded', () => {
} }
inputElement.addEventListener('input', function (event) { inputElement.addEventListener('input', function (event) {
SendDateToParent(data); SendDataToParent(data);
}); });
settingItemContent.appendChild(inputElement); settingItemContent.appendChild(inputElement);
settingItem.appendChild(labelDescriptionDiv); if (setting.type == 'button')
settingItem.appendChild(settingItemContent); {
settingItem.style.display = 'block'
settingItem.appendChild(settingItemContent);
}
else
{
settingItem.appendChild(labelDescriptionDiv);
settingItem.appendChild(settingItemContent);
}
groupDiv.appendChild(settingItem); groupDiv.appendChild(settingItem);
}); });
settingsContent.appendChild(groupDiv); settingsContent.appendChild(groupDiv);
} }
function UpdateSettingItemVisibility() {
data.settings.forEach(setting => {
if (setting.hideIf)
{
if (!document.getElementById(setting.hideIf).checked)
document.getElementById(`item-${setting.id}`).style.display = 'none'
else
document.getElementById(`item-${setting.id}`).style.display = 'flex'
}
});
}
UpdateSettingItemVisibility();
// saveButton.addEventListener('click', () => { // saveButton.addEventListener('click', () => {
// SendDateToParent(data); // SendDataToParent(data);
// }); // });
SendDateToParent(data); SendDataToParent(data);
}) })
.catch(error => console.error('Error loading settings:', error)); .catch(error => console.error('Error loading settings:', error));
}); });
// In the iframe's JavaScript: // In the iframe's JavaScript:
function SendDateToParent(data) { function SendDataToParent(data) {
const settings = {}; const settings = {};
data.settings.forEach(setting => { data.settings.forEach(setting => {
let inputElement = document.getElementById(setting.id); let inputElement = document.getElementById(setting.id);
@@ -183,12 +279,6 @@ saveButton.addEventListener('click', () => {
}, 3000); }, 3000);
}); });
widgetURLBox.addEventListener('click', () => {
let loadSettingsBox = document.getElementById('mommy-milkers');
loadSettingsBox.style.visibility = 'visible';
loadSettingsBox.style.opacity = 1;
});
function CloseSettings() { function CloseSettings() {
let loadSettingsBox = document.getElementById('mommy-milkers'); let loadSettingsBox = document.getElementById('mommy-milkers');
loadSettingsBox.style.visibility = 'hidden'; loadSettingsBox.style.visibility = 'hidden';
@@ -198,12 +288,11 @@ function CloseSettings() {
function LoadSettings() { function LoadSettings() {
let loadURLBox = document.getElementById('load-url'); let loadURLBox = document.getElementById('load-url');
const url = new URL(loadURLBox.value); const url = new URL(loadURLBox.value);
url.searchParams.forEach((value, key) => { url.searchParams.forEach((value, key) => {
const inputElement = document.getElementById(key); const inputElement = document.getElementById(key);
if (inputElement != null) if (inputElement != null) {
{
if (inputElement.type == 'checkbox') if (inputElement.type == 'checkbox')
inputElement.checked = value.toLocaleLowerCase() == 'true'; inputElement.checked = value.toLocaleLowerCase() == 'true';
else else
@@ -230,8 +319,15 @@ function GetWidgetURL() {
} }
return result; return result;
//return 'D:/Projects/GitHub Projects/nutty.gg/multistream-alerts/index.html'
} }
function OpenMembershipPage() { function OpenMembershipPage() {
window.open("https://nutty.gg/supporters/sign_in", '_blank').focus(); window.open("https://nutty.gg/supporters/sign_in", '_blank').focus();
}
function OpenLoadSettingsPopup() {
let loadSettingsBox = document.getElementById('mommy-milkers');
loadSettingsBox.style.visibility = 'visible';
loadSettingsBox.style.opacity = 1;
} }
+9 -6
View File
@@ -2,10 +2,12 @@
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica, Arial, sans-serif; font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica, Arial, sans-serif;
font-size: 16px; font-size: 16px;
color: white; color: white;
--accent-color: #2196f3;
} }
body { body {
background-color: #181818; background-color: #181818;
margin: 0px 20px;
} }
body::-webkit-scrollbar { body::-webkit-scrollbar {
@@ -63,7 +65,7 @@ body::-webkit-scrollbar-thumb:hover {
.setting-group { .setting-group {
margin-bottom: 20px; margin-bottom: 20px;
/* border: 1px solid #ddd; */ /* border: 1px solid #ddd; */
padding: 15px; padding-bottom: 15px;
border-radius: 5px; border-radius: 5px;
} }
@@ -97,7 +99,7 @@ h2 {
font-weight: 300; font-weight: 300;
/* color: #666; */ /* color: #666; */
opacity: 0.6; opacity: 0.6;
margin-bottom: 0; margin: 0;
} }
a { a {
@@ -126,6 +128,7 @@ input[type="number"] {
-moz-box-sizing: border-box; -moz-box-sizing: border-box;
box-sizing: border-box; box-sizing: border-box;
} }
#widget-url:hover { #widget-url:hover {
cursor: pointer; cursor: pointer;
} }
@@ -195,11 +198,11 @@ input:focus {
} }
input:checked+.slider { input:checked+.slider {
background-color: #2196F3; background-color: var(--accent-color);
} }
input:focus+.slider { input:focus+.slider {
box-shadow: 0 0 1px #2196F3; box-shadow: 0 0 1px var(--accent-color);
} }
input:checked+.slider:before { input:checked+.slider:before {
@@ -227,7 +230,7 @@ button {
border-radius: 0.5em; border-radius: 0.5em;
padding: 10px 20px; padding: 10px 20px;
width: 100%; width: 100%;
transition: all 0.2s ease; transition: all 0.2s ease-in-out;
} }
button:hover { button:hover {
@@ -270,5 +273,5 @@ button:hover {
} }
#load-settings { #load-settings {
background-color: #2196F3; background-color: var(--accent-color);
} }
+1 -1
View File
@@ -24,7 +24,7 @@
<div id="theContentThatShowsLastInsteadOfFirst"> <div id="theContentThatShowsLastInsteadOfFirst">
<div style="display: inline-flex; align-items: center;"> <div style="display: inline-flex; align-items: center;">
<img id="avatarButItsSmallerThanTheOneFromBeforeForPrettinessPurposes" src="https://static-cdn.jtvnw.net/jtv_user_pictures/272e643e-4d43-415f-9ee1-18916e825411-profile_image-300x300.png" class="square"> <img id="avatarButItsSmallerThanTheOneFromBeforeForPrettinessPurposes" src="https://static-cdn.jtvnw.net/jtv_user_pictures/272e643e-4d43-415f-9ee1-18916e825411-profile_image-300x300.png" class="square">
<span id="usernameTheSecond"></span> <span id="usernameTheSecond">nutty</span>
</div> </div>
<br> <br>
<span id="message"> <span id="message">
+184 -44
View File
@@ -28,48 +28,103 @@ let alertQueue = [];
// OPTIONS // // OPTIONS //
///////////// /////////////
const showPlatform = GetBooleanParam("showPlatform", true); // const showPlatform = GetBooleanParam("showPlatform", true);
// const showAvatar = GetBooleanParam("showAvatar", true);
// const showTimestamps = GetBooleanParam("showTimestamps", true);
// const showBadges = GetBooleanParam("showBadges", true);
// const showPronouns = GetBooleanParam("showPronouns", true);
// const showUsername = GetBooleanParam("showUsername", true);
// const showMessage = GetBooleanParam("showMessage", true);
// const font = urlParams.get("font") || "";
// const fontSize = urlParams.get("fontSize") || "30";
// const lineSpacing = urlParams.get("lineSpacing") || "1.7";
// const background = urlParams.get("background") || "#000000";
// const opacity = urlParams.get("opacity") || "0.85";
// const hideAfter = GetIntParam("hideAfter", 0);
// const excludeCommands = GetBooleanParam("excludeCommands", true);
// const ignoreChatters = urlParams.get("ignoreChatters") || "";
// const scrollDirection = GetIntParam("scrollDirection", 1);
// const inlineChat = GetBooleanParam("inlineChat", false);
// const imageEmbedPermissionLevel = GetIntParam("imageEmbedPermissionLevel", 20);
// const showTwitchMessages = GetBooleanParam("showTwitchMessages", true);
// const showTwitchAnnouncements = GetBooleanParam("showTwitchAnnouncements", true);
// const showTwitchSubs = GetBooleanParam("showTwitchSubs", true);
// const showTwitchChannelPointRedemptions = GetBooleanParam("showTwitchChannelPointRedemptions", true);
// const showTwitchRaids = GetBooleanParam("showTwitchRaids", true);
// const showTwitchSharedChat = GetIntParam("showTwitchSharedChat", 2);
// const twitchFollowTrigger = urlParams.get("twitchFollowTrigger") || "";
// const showYouTubeMessages = GetBooleanParam("showYouTubeMessages", true);
// const showYouTubeSuperChats = GetBooleanParam("showYouTubeSuperChats", true);
// const showYouTubeSuperStickers = GetBooleanParam("showYouTubeSuperStickers", true);
// const showYouTubeMemberships = GetBooleanParam("showYouTubeMemberships", true);
// const showStreamlabsDonations = GetBooleanParam("showStreamlabsDonations", true)
// const showStreamElementsTips = GetBooleanParam("showStreamElementsTips", true);
// const showPatreonMemberships = GetBooleanParam("showPatreonMemberships", true);
// const showKofiDonations = GetBooleanParam("showKofiDonations", true);
// const showTipeeeStreamDonations = GetBooleanParam("showTipeeeStreamDonations", true);
// const showFourthwallAlerts = GetBooleanParam("showFourthwallAlerts", true);
// const animationSpeed = GetIntParam("animationSpeed", 8000);
// const furryMode = GetBooleanParam("furryMode", false);
// Appearance
const showAvatar = GetBooleanParam("showAvatar", true); const showAvatar = GetBooleanParam("showAvatar", true);
const showTimestamps = GetBooleanParam("showTimestamps", true);
const showBadges = GetBooleanParam("showBadges", true);
const showPronouns = GetBooleanParam("showPronouns", true);
const showUsername = GetBooleanParam("showUsername", true);
const showMessage = GetBooleanParam("showMessage", true);
const font = urlParams.get("font") || ""; const font = urlParams.get("font") || "";
const fontSize = urlParams.get("fontSize") || "30"; const fontSize = GetIntParam("fontSize", 30);
const lineSpacing = urlParams.get("lineSpacing") || "1.7"; const useCustomBackground = GetBooleanParam("useCustomBackground", true);
const background = urlParams.get("background") || "#000000"; const background = urlParams.get("background") || "";
const opacity = urlParams.get("opacity") || "0.85"; const opacity = GetIntParam("opacity", 0.85);
const hideAfter = GetIntParam("hideAfter", 0); // General
const excludeCommands = GetBooleanParam("excludeCommands", true); const hideAfter = GetIntParam("hideAfter", 8);
const ignoreChatters = urlParams.get("ignoreChatters") || ""; const showAnimation = urlParams.get("showAnimation") || "";
const scrollDirection = GetIntParam("scrollDirection", 1); const hideAnimation = urlParams.get("hideAnimation") || "";
const inlineChat = GetBooleanParam("inlineChat", false); const alignment = urlParams.get("alignment") || "";
const imageEmbedPermissionLevel = GetIntParam("imageEmbedPermissionLevel", 20); const showMesesages = GetBooleanParam("showMesesages", true);
const showTwitchMessages = GetBooleanParam("showTwitchMessages", true); // Which Twitch alerts do you want to see?
const showTwitchAnnouncements = GetBooleanParam("showTwitchAnnouncements", true); const showTwitchFollows = GetBooleanParam("showTwitchFollows", false);
const twitchFollowAction = urlParams.get("twitchFollowAction") || "";
const showTwitchSubs = GetBooleanParam("showTwitchSubs", true); const showTwitchSubs = GetBooleanParam("showTwitchSubs", true);
const twitchSubAction = urlParams.get("twitchSubAction") || "";
const showTwitchChannelPointRedemptions = GetBooleanParam("showTwitchChannelPointRedemptions", true); const showTwitchChannelPointRedemptions = GetBooleanParam("showTwitchChannelPointRedemptions", true);
const twitchChannelPointRedemptionAction = urlParams.get("twitchChannelPointRedemptionAction") || "";
const showTwitchCheers = GetBooleanParam("showTwitchCheers", true);
const twitchCheerAction = urlParams.get("twitchCheerAction") || "";
const showTwitchRaids = GetBooleanParam("showTwitchRaids", true); const showTwitchRaids = GetBooleanParam("showTwitchRaids", true);
const showTwitchSharedChat = GetIntParam("showTwitchSharedChat", 2); const twitchRaidAction = urlParams.get("twitchRaidAction") || "";
const showYouTubeMessages = GetBooleanParam("showYouTubeMessages", true); // Which YouTube alerts do you want to see?
const showYouTubeSuperChats = GetBooleanParam("showYouTubeSuperChats", true); const showYouTubeSuperChats = GetBooleanParam("showYouTubeSuperChats", true);
const youtubeSuperChatAction = urlParams.get("youtubeSuperChatAction") || "";
const showYouTubeSuperStickers = GetBooleanParam("showYouTubeSuperStickers", true); const showYouTubeSuperStickers = GetBooleanParam("showYouTubeSuperStickers", true);
const youtubeSuperStickerAction = urlParams.get("youtubeSuperStickerAction") || "";
const showYouTubeMemberships = GetBooleanParam("showYouTubeMemberships", true); const showYouTubeMemberships = GetBooleanParam("showYouTubeMemberships", true);
const youtubeMembershipAction = urlParams.get("youtubeMembershipAction") || "";
const showStreamlabsDonations = GetBooleanParam("showStreamlabsDonations", true) // Which donation alerts do you want to see?
const showStreamElementsTips = GetBooleanParam("showStreamElementsTips", true); const showStreamlabsDonations = GetBooleanParam("showStreamlabsDonations", false);
const showPatreonMemberships = GetBooleanParam("showPatreonMemberships", true); const streamlabsDonationAction = urlParams.get("streamlabsDonationAction") || "";
const showKofiDonations = GetBooleanParam("showKofiDonations", true); const showStreamElementsTips = GetBooleanParam("showStreamElementsTips", false);
const showTipeeeStreamDonations = GetBooleanParam("showTipeeeStreamDonations", true); const streamelementsTipAction = urlParams.get("streamelementsTipAction") || "";
const showFourthwallAlerts = GetBooleanParam("showFourthwallAlerts", true); const showPatreonMemberships = GetBooleanParam("showPatreonMemberships", false);
const patreonMembershipActions = urlParams.get("patreonMembershipActions") || "";
const showKofiDonations = GetBooleanParam("showKofiDonations", false);
const kofiDonationAction = urlParams.get("kofiDonationAction") || "";
const showTipeeeStreamDonations = GetBooleanParam("showTipeeeStreamDonations", false);
const tipeeestreamDonationAction = urlParams.get("tipeeestreamDonationAction") || "";
const showFourthwallAlerts = GetBooleanParam("showFourthwallAlerts", false);
const fourthwallAlertAction = urlParams.get("fourthwallAlertAction") || "";
const animationSpeed = GetIntParam("animationSpeed", 8000); // Set avatar visibility
if (!showAvatar)
const furryMode = GetBooleanParam("furryMode", false); avatarElement.style.display = 'none';
// Set fonts for the widget // Set fonts for the widget
document.body.style.fontFamily = font; document.body.style.fontFamily = font;
@@ -124,7 +179,7 @@ const client = new StreamerbotClient({
client.on('Twitch.Cheer', (response) => { client.on('Twitch.Cheer', (response) => {
console.debug(response.data); console.debug(response.data);
TwitchChatMessage(response.data); TwitchCheer(response.data);
}) })
client.on('Twitch.Sub', (response) => { client.on('Twitch.Sub', (response) => {
@@ -248,6 +303,59 @@ client.on('Fourthwall.GiftDrawEnded', (response) => {
// MULTICHAT OVERLAY // // MULTICHAT OVERLAY //
/////////////////////// ///////////////////////
async function TwitchCheer(data) {
if (!showTwitchSubs)
return;
// Set the text
const username = data.message.displayName;
const bits = data.bits;
let message = data.message.message;
// Render avatars
const avatarURL = await GetAvatar(username);
// Render emotes
for (i in data.emotes) {
const emoteElement = `<img src="${data.emotes[i].imageUrl}" class="emote"/>`;
const emoteName = EscapeRegExp(data.emotes[i].name);
let regexPattern = emoteName;
// Check if the emote name consists only of word characters (alphanumeric and underscore)
if (/^\w+$/.test(emoteName)) {
regexPattern = `\\b${emoteName}\\b`;
}
else {
// For non-word emotes, ensure they are surrounded by non-word characters or boundaries
regexPattern = `(?:^|[^\\w])${emoteName}(?:$|[^\\w])`;
}
const regex = new RegExp(regexPattern, 'g');
message = message.replace(regex, emoteElement);
}
// Render cheermotes
for (i in data.cheerEmotes) {
const bits = data.cheerEmotes[i].bits;
const imageUrl = data.cheerEmotes[i].imageUrl;
const name = data.cheerEmotes[i].name;
const cheerEmoteElement = `<img src="${imageUrl}" class="emote"/>`;
const bitsElements = `<span class="bits">${bits}</span>`
message = message.replace(new RegExp(`\\b${name}${bits}\\b`, 'i'), cheerEmoteElement + bitsElements);
}
UpdateAlertBox(
'twitch',
avatarURL,
`${username}`,
`cheered ${bits} bits`,
'',
username,
message
);
}
async function TwitchSub(data) { async function TwitchSub(data) {
if (!showTwitchSubs) if (!showTwitchSubs)
return; return;
@@ -380,7 +488,7 @@ async function TwitchRaid(data) {
// Set the text // Set the text
const username = data.from_broadcaster_user_login; const username = data.from_broadcaster_user_login;
const viewers = data.viewers; const viewers = data.viewers;
UpdateAlertBox( UpdateAlertBox(
'twitch', 'twitch',
avatarURL, avatarURL,
@@ -388,7 +496,9 @@ async function TwitchRaid(data) {
`is raiding with a party of ${viewers}`, `is raiding with a party of ${viewers}`,
'', '',
username, username,
'' '',
twitchFollowAction,
data
); );
} }
@@ -1142,12 +1252,12 @@ function GetWinnersList(gifts) {
// return furryWords.join(''); // return furryWords.join('');
// } // }
function UpdateAlertBox(platform, avatarURL, headerText, descriptionText, attributeText, username, message) { async function UpdateAlertBox(platform, avatarURL, headerText, descriptionText, attributeText, username, message, sbAction, sbData) {
// Check if the widget is in the middle of an animation // Check if the widget is in the middle of an animation
// If any alerts are requested while the animation is playing, it should be added to the alert queue // If any alerts are requested while the animation is playing, it should be added to the alert queue
if (widgetLocked) { if (widgetLocked) {
console.debug("Animation is progress, added alert to queue"); console.debug("Animation is progress, added alert to queue");
let data = { platform: platform, avatarURL: avatarURL, headerText: headerText, descriptionText: descriptionText, attributeText: attributeText, message: message }; let data = { platform: platform, avatarURL: avatarURL, headerText: headerText, descriptionText: descriptionText, attributeText: attributeText, username: username, message: message, sbAction: sbAction, sbData: sbData};
alertQueue.push(data); alertQueue.push(data);
return; return;
} }
@@ -1173,8 +1283,16 @@ function UpdateAlertBox(platform, avatarURL, headerText, descriptionText, attrib
messageLabel.innerHTML = message != null ? `${message}` : ''; messageLabel.innerHTML = message != null ? `${message}` : '';
theContentThatShowsLastInsteadOfFirst.style.opacity = 0; theContentThatShowsLastInsteadOfFirst.style.opacity = 0;
alertBox.style.height = theContentThatShowsFirstInsteadOfSecond.offsetHeight + 40 + "px"; theContentThatShowsFirstInsteadOfSecond.style.display = 'flex';
alertBox.style.animation = 'slideInFromTop 0.5s ease-out forwards'; alertBox.style.maxHeight = theContentThatShowsFirstInsteadOfSecond.offsetHeight + "px";
alertBox.style.minHeight = theContentThatShowsFirstInsteadOfSecond.offsetHeight + "px";
alertBox.style.animation = 'slideInFromRight 0.5s ease-out forwards';
// Run the Streamer.bot action if there is one
if (sbAction) {
console.debug('Running Streamer.bot action: ' + sbAction);
await client.doAction({name: sbAction}, sbData);
}
// (1) Set timeout (5 seconds) // (1) Set timeout (5 seconds)
// (2) Set the message label // (2) Set the message label
@@ -1183,29 +1301,51 @@ function UpdateAlertBox(platform, avatarURL, headerText, descriptionText, attrib
// (a) Add in the CSS animation when this is working // (a) Add in the CSS animation when this is working
setTimeout(() => { setTimeout(() => {
alertBox.style.transition = 'all 0.5s ease-in-out'; alertBox.style.transition = 'all 0.5s ease-in-out';
alertBox.style.height = theContentThatShowsLastInsteadOfFirst.offsetHeight + 40 + "px";
theContentThatShowsFirstInsteadOfSecond.style.opacity = 0; theContentThatShowsFirstInsteadOfSecond.style.opacity = 0;
theContentThatShowsFirstInsteadOfSecond.style.position = 'absolute';
theContentThatShowsLastInsteadOfFirst.style.display = 'inline-block';
alertBox.style.maxHeight = theContentThatShowsLastInsteadOfFirst.offsetHeight + "px";
alertBox.style.minHeight = 'none';
theContentThatShowsLastInsteadOfFirst.style.opacity = 1; theContentThatShowsLastInsteadOfFirst.style.opacity = 1;
setTimeout(() => { setTimeout(() => {
alertBox.style.animation = 'slideBackUp 0.5s ease-out forwards'; alertBox.style.animation = 'slideOffRight 0.5s ease-out forwards';
setTimeout(() => { setTimeout(() => {
alertBox.style.transition = ''; alertBox.style.maxHeight = '0px';
theContentThatShowsFirstInsteadOfSecond.style.opacity = 1; theContentThatShowsFirstInsteadOfSecond.style.opacity = 1;
theContentThatShowsLastInsteadOfFirst.style.opacity = 0; theContentThatShowsLastInsteadOfFirst.style.opacity = 0;
alertBox.style.height = '0px'; theContentThatShowsFirstInsteadOfSecond.style.position = 'relative';
theContentThatShowsLastInsteadOfFirst.style.display = 'none';
widgetLocked = false; widgetLocked = false;
if (alertQueue.length > 0) { if (alertQueue.length > 0) {
console.debug("Pulling next alert from the queue"); console.debug("Pulling next alert from the queue");
let data = alertQueue.shift(); let data = alertQueue.shift();
UpdateAlertBox(data.platform, data.avatarURL, data.headerText, data.descriptionText, data.attributeText, data.message) UpdateAlertBox(data.platform, data.avatarURL, data.headerText, data.descriptionText, data.attributeText, data.username, data.message, data.sbAction, data.sbData);
} }
}, 1000); }, 1000);
}, messageLabel.innerText.trim() != '' ? animationSpeed : 0); }, message ? hideAfter * 1000 : 0);
}, hideAfter * 1000);
}, animationSpeed); }
////////////////////
// TEST FUNCTIONS //
////////////////////
async function testWidget()
{
UpdateAlertBox(
'twitch',
await GetAvatar('nutty'),
`nutty`,
`subscribed with Tier 3`,
'',
`nutty`,
`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`
//``
);
} }
+2 -8
View File
@@ -1,5 +1,4 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
@@ -50,15 +49,10 @@
</head> </head>
<body> <body>
<iframe id="settings-container"></iframe> <iframe id="settings-container"></iframe>
<div id="widget-container"> <div id="widget-container">
<iframe id="widget"></iframe> <iframe id="widget"></iframe>
</div> </div>
<script src="script.js"></script>
</body> </body>
</html> <script src="./script.js"></script>
+7
View File
@@ -1,5 +1,6 @@
let settingsContainer = document.getElementById('settings-container'); let settingsContainer = document.getElementById('settings-container');
settingsContainer.src = `../../.utilities/settings-page-builder?settingsJson=${window.location.href}/settings.json` settingsContainer.src = `../../.utilities/settings-page-builder?settingsJson=${window.location.href}/settings.json`
//settingsContainer.src = `../../.utilities/settings-page-builder?settingsJson=../../multistream-alerts/settings/settings.json`
console.log(settingsContainer.src); console.log(settingsContainer.src);
function reloadWidget(data) { function reloadWidget(data) {
@@ -26,4 +27,10 @@ function getParentUrl() {
} }
return parentUrl; return parentUrl;
}
function callFunction(functionName) {
console.debug(`Calling ${functionName}`);
let widget = document.getElementById("widget");
widget.contentWindow[functionName]();
} }
+148 -14
View File
@@ -1,5 +1,13 @@
{ {
"settings": [ "settings": [
{
"id": "testWidgetButton",
"label": "Send Test Alert",
"description": "",
"type": "button",
"callFunction": "testWidget",
"group": "Test Alerts"
},
{ {
"id": "showAvatar", "id": "showAvatar",
"label": "Show Avatar", "label": "Show Avatar",
@@ -56,7 +64,7 @@
{ {
"id": "hideAfter", "id": "hideAfter",
"label": "Hide After", "label": "Hide After",
"description": "Alerts will show for X seconds", "description": "Alerts will hide for X seconds",
"type": "number", "type": "number",
"min": 1, "min": 1,
"max": 120, "max": 120,
@@ -151,18 +159,19 @@
}, },
{ {
"id": "showTwitchFollows", "id": "showTwitchFollows",
"label": "New Follows", "label": "New Followers",
"description": "", "description": "",
"type": "checkbox", "type": "checkbox",
"defaultValue": true, "defaultValue": false,
"group": "Which Twitch alerts do you want to see?" "group": "Which Twitch alerts do you want to see?"
}, },
{ {
"id": "showTwitchCheers", "id": "twitchFollowAction",
"label": "Cheers", "label": "",
"description": "", "description": "Also run this Streamer.bot Action",
"type": "checkbox", "type": "sb-actions",
"defaultValue": true, "defaultValue": "",
"hideIf": "showTwitchFollows",
"group": "Which Twitch alerts do you want to see?" "group": "Which Twitch alerts do you want to see?"
}, },
{ {
@@ -173,6 +182,15 @@
"defaultValue": true, "defaultValue": true,
"group": "Which Twitch alerts do you want to see?" "group": "Which Twitch alerts do you want to see?"
}, },
{
"id": "twitchSubAction",
"label": "",
"description": "Also run this Streamer.bot Action",
"type": "sb-actions",
"defaultValue": "",
"hideIf": "showTwitchSubs",
"group": "Which Twitch alerts do you want to see?"
},
{ {
"id": "showTwitchChannelPointRedemptions", "id": "showTwitchChannelPointRedemptions",
"label": "Channel Point Redemptions", "label": "Channel Point Redemptions",
@@ -181,6 +199,32 @@
"defaultValue": true, "defaultValue": true,
"group": "Which Twitch alerts do you want to see?" "group": "Which Twitch alerts do you want to see?"
}, },
{
"id": "twitchChannelPointRedemptionAction",
"label": "",
"description": "Also run this Streamer.bot Action",
"type": "sb-actions",
"defaultValue": "",
"hideIf": "showTwitchChannelPointRedemptions",
"group": "Which Twitch alerts do you want to see?"
},
{
"id": "showTwitchCheers",
"label": "Cheers",
"description": "",
"type": "checkbox",
"defaultValue": true,
"group": "Which Twitch alerts do you want to see?"
},
{
"id": "twitchCheerAction",
"label": "",
"description": "Also run Streamer.bot Action",
"type": "sb-actions",
"defaultValue": "",
"hideIf": "showTwitchCheers",
"group": "Which Twitch alerts do you want to see?"
},
{ {
"id": "showTwitchRaids", "id": "showTwitchRaids",
"label": "Raids", "label": "Raids",
@@ -189,6 +233,15 @@
"defaultValue": true, "defaultValue": true,
"group": "Which Twitch alerts do you want to see?" "group": "Which Twitch alerts do you want to see?"
}, },
{
"id": "twitchRaidAction",
"label": "",
"description": "Also run this Streamer.bot Action",
"type": "sb-actions",
"defaultValue": "",
"hideIf": "showTwitchRaids",
"group": "Which Twitch alerts do you want to see?"
},
{ {
"id": "showYouTubeSuperChats", "id": "showYouTubeSuperChats",
"label": "Super Chats", "label": "Super Chats",
@@ -197,6 +250,15 @@
"defaultValue": true, "defaultValue": true,
"group": "Which YouTube alerts do you want to see?" "group": "Which YouTube alerts do you want to see?"
}, },
{
"id": "youtubeSuperChatAction",
"label": "",
"description": "Also run this Streamer.bot Action",
"type": "sb-actions",
"defaultValue": "",
"hideIf": "showYouTubeSuperChats",
"group": "Which YouTube alerts do you want to see?"
},
{ {
"id": "showYouTubeSuperStickers", "id": "showYouTubeSuperStickers",
"label": "Super Stickers", "label": "Super Stickers",
@@ -205,6 +267,15 @@
"defaultValue": true, "defaultValue": true,
"group": "Which YouTube alerts do you want to see?" "group": "Which YouTube alerts do you want to see?"
}, },
{
"id": "youtubeSuperStickerAction",
"label": "",
"description": "Also run this Streamer.bot Action",
"type": "sb-actions",
"defaultValue": "",
"hideIf": "showYouTubeSuperStickers",
"group": "Which YouTube alerts do you want to see?"
},
{ {
"id": "showYouTubeMemberships", "id": "showYouTubeMemberships",
"label": "Memberships", "label": "Memberships",
@@ -213,12 +284,30 @@
"defaultValue": true, "defaultValue": true,
"group": "Which YouTube alerts do you want to see?" "group": "Which YouTube alerts do you want to see?"
}, },
{
"id": "youtubeMembershipAction",
"label": "",
"description": "Also run this Streamer.bot Action",
"type": "sb-actions",
"defaultValue": "",
"hideIf": "showYouTubeMemberships",
"group": "Which YouTube alerts do you want to see?"
},
{ {
"id": "showStreamlabsDonations", "id": "showStreamlabsDonations",
"label": "Streamlabs Tips", "label": "Streamlabs Tips",
"description": "<a href=\"https://docs.streamer.bot/guide/integrations/streamlabs\" target=\"_blank\">Click to connect</a>", "description": "<a href=\"https://docs.streamer.bot/guide/integrations/streamlabs\" target=\"_blank\">Click to connect</a>",
"type": "checkbox", "type": "checkbox",
"defaultValue": true, "defaultValue": false,
"group": "Which donation alerts do you want to see?"
},
{
"id": "streamlabsDonationAction",
"label": "",
"description": "Also run this Streamer.bot Action",
"type": "sb-actions",
"defaultValue": "",
"hideIf": "showStreamlabsDonations",
"group": "Which donation alerts do you want to see?" "group": "Which donation alerts do you want to see?"
}, },
{ {
@@ -226,7 +315,16 @@
"label": "StreamElements Tips", "label": "StreamElements Tips",
"description": "<a href=\"https://docs.streamer.bot/guide/integrations/streamelements\" target=\"_blank\">Click to connect</a>", "description": "<a href=\"https://docs.streamer.bot/guide/integrations/streamelements\" target=\"_blank\">Click to connect</a>",
"type": "checkbox", "type": "checkbox",
"defaultValue": true, "defaultValue": false,
"group": "Which donation alerts do you want to see?"
},
{
"id": "streamelementsTipAction",
"label": "",
"description": "Also run this Streamer.bot Action",
"type": "sb-actions",
"defaultValue": "",
"hideIf": "showStreamElementsTips",
"group": "Which donation alerts do you want to see?" "group": "Which donation alerts do you want to see?"
}, },
{ {
@@ -234,7 +332,16 @@
"label": "Patreon Memberships", "label": "Patreon Memberships",
"description": "<a href=\"https://docs.streamer.bot/guide/integrations/patreon\" target=\"_blank\">Click to connect</a>", "description": "<a href=\"https://docs.streamer.bot/guide/integrations/patreon\" target=\"_blank\">Click to connect</a>",
"type": "checkbox", "type": "checkbox",
"defaultValue": true, "defaultValue": false,
"group": "Which donation alerts do you want to see?"
},
{
"id": "patreonMembershipActions",
"label": "",
"description": "Also run this Streamer.bot Action",
"type": "sb-actions",
"defaultValue": "",
"hideIf": "showPatreonMemberships",
"group": "Which donation alerts do you want to see?" "group": "Which donation alerts do you want to see?"
}, },
{ {
@@ -242,7 +349,16 @@
"label": "Ko-fi Donations", "label": "Ko-fi Donations",
"description": "<a href=\"https://docs.streamer.bot/guide/integrations/ko-fi\" target=\"_blank\">Click to connect</a>", "description": "<a href=\"https://docs.streamer.bot/guide/integrations/ko-fi\" target=\"_blank\">Click to connect</a>",
"type": "checkbox", "type": "checkbox",
"defaultValue": true, "defaultValue": false,
"group": "Which donation alerts do you want to see?"
},
{
"id": "kofiDonationAction",
"label": "",
"description": "Also run this Streamer.bot Action",
"type": "sb-actions",
"defaultValue": "",
"hideIf": "showKofiDonations",
"group": "Which donation alerts do you want to see?" "group": "Which donation alerts do you want to see?"
}, },
{ {
@@ -250,7 +366,16 @@
"label": "TipeeeStream Donations", "label": "TipeeeStream Donations",
"description": "<a href=\"https://docs.streamer.bot/guide/integrations/tipeee-stream\" target=\"_blank\">Click to connect</a>", "description": "<a href=\"https://docs.streamer.bot/guide/integrations/tipeee-stream\" target=\"_blank\">Click to connect</a>",
"type": "checkbox", "type": "checkbox",
"defaultValue": true, "defaultValue": false,
"group": "Which donation alerts do you want to see?"
},
{
"id": "tipeeestreamDonationAction",
"label": "",
"description": "Also run this Streamer.bot Action",
"type": "sb-actions",
"defaultValue": "",
"hideIf": "showTipeeeStreamDonations",
"group": "Which donation alerts do you want to see?" "group": "Which donation alerts do you want to see?"
}, },
{ {
@@ -258,7 +383,16 @@
"label": "Fourthwall Alerts", "label": "Fourthwall Alerts",
"description": "<a href=\"https://docs.streamer.bot/guide/integrations/fourthwall\" target=\"_blank\">Click to connect</a>", "description": "<a href=\"https://docs.streamer.bot/guide/integrations/fourthwall\" target=\"_blank\">Click to connect</a>",
"type": "checkbox", "type": "checkbox",
"defaultValue": true, "defaultValue": false,
"group": "Which donation alerts do you want to see?"
},
{
"id": "fourthwallAlertAction",
"label": "",
"description": "Also run this Streamer.bot Action",
"type": "sb-actions",
"defaultValue": "",
"hideIf": "showFourthwallAlerts",
"group": "Which donation alerts do you want to see?" "group": "Which donation alerts do you want to see?"
} }
] ]
+38 -19
View File
@@ -1,9 +1,9 @@
* { * {
margin: 0; margin: 0;
padding: 0; padding: 0;
--margin: 20px; --margin: 0.5em;
/* --border-radius: 20px; */ --border-radius: 1em;
font-size: 30px; /* font-size: 30px; */
/* --line-spacing: 1.7em; */ /* --line-spacing: 1.7em; */
} }
@@ -37,12 +37,14 @@ html {
} }
#mainContainer { #mainContainer {
display: block;
position: absolute; position: absolute;
width: 100%; width: 100%;
height: 100%; height: 100%;
padding: calc(2 * var(--margin)); padding: calc(2 * var(--margin));
box-sizing: border-box; box-sizing: border-box;
display: flex;
flex-direction: column;
justify-content: flex-end;
} }
#alertBox { #alertBox {
@@ -53,10 +55,10 @@ html {
overflow: hidden; overflow: hidden;
box-sizing: border-box; box-sizing: border-box;
/* text-align: center; */ /* text-align: center; */
position: relative; /* position: relative; */
/* transition: all 1s ease-in-out; */ /* transition: all 1s ease-in-out; */
min-height: 0px; /* min-height: 0px;
height: 0px; max-height: 0px; */
} }
/* #alertBox::before { /* #alertBox::before {
@@ -79,21 +81,25 @@ html {
display: flex; display: flex;
align-items: center; align-items: center;
z-index: 1; z-index: 1;
position: absolute; /* position: absolute; */
left: var(--margin); /* left: var(--margin);
top: var(--margin); top: var(--margin); */
transition: inherit; transition: inherit;
padding: var(--margin);
display: none;
} }
#theContentThatShowsLastInsteadOfFirst { #theContentThatShowsLastInsteadOfFirst {
position: absolute; /* position: absolute; */
display: block; display: inline-block;
align-items: center; align-items: center;
z-index: 0; z-index: 0;
position: absolute; /* position: absolute; */
left: var(--margin); /* left: var(--margin);
top: var(--margin); top: var(--margin); */
padding: var(--margin);
transition: inherit; transition: inherit;
display: none;
} }
#avatar { #avatar {
@@ -146,6 +152,19 @@ html {
border-radius: 0.5em; border-radius: 0.5em;
} }
.emote {
height: 1.5em;
margin: 1px;
transform: translate(0px, 0.4em);
}
.bits {
background: #adadad46;
border-radius: calc(var(--border-radius) / 2);
font-size: 0.7em;
padding: 5px 10px;
}
#message { #message {
width: calc(100% - 2 * var(--margin)); width: calc(100% - 2 * var(--margin));
z-index: 0; z-index: 0;
@@ -167,7 +186,7 @@ html {
} }
} }
@keyframes slideBackUp { @keyframes slideOffUp {
0% { 0% {
transform: translateY(0); transform: translateY(0);
opacity: 1; opacity: 1;
@@ -191,7 +210,7 @@ html {
} }
} }
@keyframes slideBackDown { @keyframes slideOffDown {
0% { 0% {
transform: translateY(0); transform: translateY(0);
opacity: 1; opacity: 1;
@@ -215,7 +234,7 @@ html {
} }
} }
@keyframes slideBackLeft { @keyframes slideOffLeft {
0% { 0% {
transform: translateX(0); transform: translateX(0);
opacity: 1; opacity: 1;
@@ -239,7 +258,7 @@ html {
} }
} }
@keyframes slideBackRight { @keyframes slideOffRight {
0% { 0% {
transform: translateX(0); transform: translateX(0);
opacity: 1; opacity: 1;