mirror of
https://github.com/nuttylmao/nutty.gg.git
synced 2026-09-19 04:00:59 -04:00
+31
-10
@@ -222,21 +222,42 @@ function EscapeRegExp(string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Given a string, return a random hex code. The same input always results in the same output
|
// Given a string, return a random hex code. The same input always results in the same output
|
||||||
function StringToHex(str) {
|
function RandomHex(str) {
|
||||||
// Simple hash function to convert string to a number
|
// Simple hash to convert string to a number
|
||||||
let hash = 0;
|
let hash = 0;
|
||||||
for (let i = 0; i < str.length; i++) {
|
for (let i = 0; i < str.length; i++) {
|
||||||
hash = str.charCodeAt(i) + ((hash << 5) - hash);
|
hash = str.charCodeAt(i) + ((hash << 5) - hash);
|
||||||
hash |= 0; // Convert to 32bit integer
|
hash |= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert hash to a hex color
|
// Use the hash to generate a hue (0–360)
|
||||||
let color = '#';
|
const hue = Math.abs(hash) % 360;
|
||||||
for (let i = 0; i < 3; i++) {
|
|
||||||
// Extract each byte and convert to 2-digit hex
|
// Force super saturation + readable brightness
|
||||||
const value = (hash >> (i * 8)) & 0xFF;
|
const saturation = 100; // maximum saturation
|
||||||
color += value.toString(16).padStart(2, '0');
|
const lightness = 55; // tweak 50–60 depending on your background
|
||||||
|
|
||||||
|
// Convert HSL → RGB → hex
|
||||||
|
function hslToHex(h, s, l) {
|
||||||
|
s /= 100;
|
||||||
|
l /= 100;
|
||||||
|
|
||||||
|
const k = n => (n + h / 30) % 12;
|
||||||
|
const a = s * Math.min(l, 1 - l);
|
||||||
|
const f = n =>
|
||||||
|
l - a * Math.max(-1, Math.min(k(n) - 3, Math.min(9 - k(n), 1)));
|
||||||
|
|
||||||
|
const r = Math.round(255 * f(0));
|
||||||
|
const g = Math.round(255 * f(8));
|
||||||
|
const b = Math.round(255 * f(4));
|
||||||
|
|
||||||
|
return (
|
||||||
|
"#" +
|
||||||
|
r.toString(16).padStart(2, "0") +
|
||||||
|
g.toString(16).padStart(2, "0") +
|
||||||
|
b.toString(16).padStart(2, "0")
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return color;
|
return hslToHex(hue, saturation, lightness);
|
||||||
}
|
}
|
||||||
@@ -46,6 +46,7 @@ const showTwitchFollows = GetBooleanParam("showTwitchFollows", false);
|
|||||||
const showTwitchSubs = GetBooleanParam("showTwitchSubs", true);
|
const showTwitchSubs = GetBooleanParam("showTwitchSubs", true);
|
||||||
const showTwitchChannelPointRedemptions = GetBooleanParam("showTwitchChannelPointRedemptions", true);
|
const showTwitchChannelPointRedemptions = GetBooleanParam("showTwitchChannelPointRedemptions", true);
|
||||||
const showTwitchRaids = GetBooleanParam("showTwitchRaids", true);
|
const showTwitchRaids = GetBooleanParam("showTwitchRaids", true);
|
||||||
|
const showTwitchWatchStreaks = GetBooleanParam("showTwitchWatchStreaks", true);
|
||||||
const showTwitchSharedChat = GetBooleanParam("showTwitchSharedChat", true);
|
const showTwitchSharedChat = GetBooleanParam("showTwitchSharedChat", true);
|
||||||
|
|
||||||
const kickUsername = urlParams.get("kickUsername") || "";
|
const kickUsername = urlParams.get("kickUsername") || "";
|
||||||
@@ -181,6 +182,11 @@ client.on('Twitch.Raid', (response) => {
|
|||||||
TwitchRaid(response.data);
|
TwitchRaid(response.data);
|
||||||
})
|
})
|
||||||
|
|
||||||
|
client.on('Twitch.WatchStreak', (response) => {
|
||||||
|
console.debug(response.data);
|
||||||
|
TwitchWatchStreak(response.data);
|
||||||
|
})
|
||||||
|
|
||||||
client.on('Twitch.ChatMessageDeleted', (response) => {
|
client.on('Twitch.ChatMessageDeleted', (response) => {
|
||||||
console.debug(response.data);
|
console.debug(response.data);
|
||||||
TwitchChatMessageDeleted(response.data);
|
TwitchChatMessageDeleted(response.data);
|
||||||
@@ -789,6 +795,18 @@ async function TwitchRaid(data) {
|
|||||||
ShowAlert(message, 'twitch');
|
ShowAlert(message, 'twitch');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function TwitchWatchStreak(data) {
|
||||||
|
if (!showTwitchWatchStreaks)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const displayName = data.displayName;
|
||||||
|
const watchStreak = data.watchStreak;
|
||||||
|
|
||||||
|
let message = `${displayName} is currently on a ${watchStreak} stream streak!`;
|
||||||
|
|
||||||
|
ShowAlert(message, 'twitch');
|
||||||
|
}
|
||||||
|
|
||||||
function TwitchChatMessageDeleted(data) {
|
function TwitchChatMessageDeleted(data) {
|
||||||
const messageList = document.getElementById("messageList");
|
const messageList = document.getElementById("messageList");
|
||||||
|
|
||||||
@@ -878,7 +896,7 @@ function YouTubeMessage(data) {
|
|||||||
if (showUsername) {
|
if (showUsername) {
|
||||||
usernameDiv.innerText = data.user.name;
|
usernameDiv.innerText = data.user.name;
|
||||||
if (randomYouTubeColors)
|
if (randomYouTubeColors)
|
||||||
usernameDiv.style.color = StringToHex(data.user.name);
|
usernameDiv.style.color = RandomHex(data.user.name);
|
||||||
else
|
else
|
||||||
usernameDiv.style.color = youtubeColor; // YouTube users do not have colors, so just set it to red
|
usernameDiv.style.color = youtubeColor; // YouTube users do not have colors, so just set it to red
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -175,6 +175,14 @@
|
|||||||
"defaultValue": true,
|
"defaultValue": true,
|
||||||
"group": "Which Twitch messages do you want to see?"
|
"group": "Which Twitch messages do you want to see?"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"id": "showTwitchWatchStreaks",
|
||||||
|
"label": "Watch Streaks",
|
||||||
|
"description": "",
|
||||||
|
"type": "checkbox",
|
||||||
|
"defaultValue": true,
|
||||||
|
"group": "Which Twitch messages do you want to see?"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"id": "showTwitchSharedChat",
|
"id": "showTwitchSharedChat",
|
||||||
"label": "Shared Chat Messages",
|
"label": "Shared Chat Messages",
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ const showTwitchFollows = GetBooleanParam("showTwitchFollows", false);
|
|||||||
const showTwitchSubs = GetBooleanParam("showTwitchSubs", true);
|
const showTwitchSubs = GetBooleanParam("showTwitchSubs", true);
|
||||||
const showTwitchChannelPointRedemptions = GetBooleanParam("showTwitchChannelPointRedemptions", true);
|
const showTwitchChannelPointRedemptions = GetBooleanParam("showTwitchChannelPointRedemptions", true);
|
||||||
const showTwitchRaids = GetBooleanParam("showTwitchRaids", true);
|
const showTwitchRaids = GetBooleanParam("showTwitchRaids", true);
|
||||||
|
const showTwitchWatchStreaks = GetBooleanParam("showTwitchWatchStreaks", true);
|
||||||
const showTwitchSharedChat = GetIntParam("showTwitchSharedChat", 2);
|
const showTwitchSharedChat = GetIntParam("showTwitchSharedChat", 2);
|
||||||
|
|
||||||
const kickUsername = urlParams.get("kickUsername") || "";
|
const kickUsername = urlParams.get("kickUsername") || "";
|
||||||
@@ -200,6 +201,11 @@ client.on('Twitch.Raid', (response) => {
|
|||||||
TwitchRaid(response.data);
|
TwitchRaid(response.data);
|
||||||
})
|
})
|
||||||
|
|
||||||
|
client.on('Twitch.WatchStreak', (response) => {
|
||||||
|
console.debug(response.data);
|
||||||
|
TwitchWatchStreak(response.data);
|
||||||
|
})
|
||||||
|
|
||||||
client.on('Twitch.ChatMessageDeleted', (response) => {
|
client.on('Twitch.ChatMessageDeleted', (response) => {
|
||||||
console.debug(response.data);
|
console.debug(response.data);
|
||||||
TwitchChatMessageDeleted(response.data);
|
TwitchChatMessageDeleted(response.data);
|
||||||
@@ -1160,6 +1166,67 @@ async function TwitchRaid(data) {
|
|||||||
AddMessageItem(instance, data.messageId);
|
AddMessageItem(instance, data.messageId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function TwitchWatchStreak(data) {
|
||||||
|
if (!showTwitchWatchStreaks)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Get a reference to the template
|
||||||
|
const template = document.getElementById('cardTemplate');
|
||||||
|
|
||||||
|
// Create a new instance of the template
|
||||||
|
const instance = template.content.cloneNode(true);
|
||||||
|
|
||||||
|
// Get divs
|
||||||
|
const cardDiv = instance.querySelector("#card");
|
||||||
|
const headerDiv = instance.querySelector("#header");
|
||||||
|
const avatarDiv = instance.querySelector("#avatar");
|
||||||
|
const iconDiv = instance.querySelector("#icon");
|
||||||
|
const titleDiv = instance.querySelector("#title");
|
||||||
|
const contentDiv = instance.querySelector("#content");
|
||||||
|
|
||||||
|
// Set the card background colors
|
||||||
|
cardDiv.classList.add('twitch');
|
||||||
|
|
||||||
|
if (showAvatar) {
|
||||||
|
// Render avatars
|
||||||
|
const username = data.userName;
|
||||||
|
const avatarURL = await GetAvatar(username, 'twitch');
|
||||||
|
const avatar = new Image();
|
||||||
|
avatar.src = avatarURL;
|
||||||
|
avatar.classList.add("avatar");
|
||||||
|
avatarDiv.appendChild(avatar);
|
||||||
|
}
|
||||||
|
|
||||||
|
const displayName = data.displayName;
|
||||||
|
const watchStreak = data.watchStreak;
|
||||||
|
const message = data.message;
|
||||||
|
|
||||||
|
titleDiv.innerText = `${displayName} is currently on a ${watchStreak} stream streak! `;
|
||||||
|
contentDiv.innerText = `${message}`;
|
||||||
|
|
||||||
|
// 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');
|
||||||
|
contentDiv.innerHTML = contentDiv.innerHTML.replace(regex, emoteElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
AddMessageItem(instance, data.messageId);
|
||||||
|
}
|
||||||
|
|
||||||
function TwitchChatMessageDeleted(data) {
|
function TwitchChatMessageDeleted(data) {
|
||||||
const messageList = document.getElementById("messageList");
|
const messageList = document.getElementById("messageList");
|
||||||
|
|
||||||
@@ -1265,7 +1332,7 @@ async function YouTubeMessage(data) {
|
|||||||
if (showUsername) {
|
if (showUsername) {
|
||||||
usernameDiv.innerText = data.user.name;
|
usernameDiv.innerText = data.user.name;
|
||||||
if (randomYouTubeColors)
|
if (randomYouTubeColors)
|
||||||
usernameDiv.style.color = StringToHex(data.user.name);
|
usernameDiv.style.color = RandomHex(data.user.name);
|
||||||
else
|
else
|
||||||
usernameDiv.style.color = youtubeColor; // YouTube users do not have colors, so just set it to red
|
usernameDiv.style.color = youtubeColor; // YouTube users do not have colors, so just set it to red
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -282,6 +282,14 @@
|
|||||||
"defaultValue": true,
|
"defaultValue": true,
|
||||||
"group": "Which Twitch messages do you want to see?"
|
"group": "Which Twitch messages do you want to see?"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"id": "showTwitchWatchStreaks",
|
||||||
|
"label": "Watch Streaks",
|
||||||
|
"description": "",
|
||||||
|
"type": "checkbox",
|
||||||
|
"defaultValue": true,
|
||||||
|
"group": "Which Twitch messages do you want to see?"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"id": "showTwitchSharedChat",
|
"id": "showTwitchSharedChat",
|
||||||
"label": "Shared Chat Messages",
|
"label": "Shared Chat Messages",
|
||||||
|
|||||||
@@ -67,6 +67,8 @@ const showTwitchCheers = GetBooleanParam("showTwitchCheers", true);
|
|||||||
const twitchCheerAction = urlParams.get("twitchCheerAction") || "";
|
const twitchCheerAction = urlParams.get("twitchCheerAction") || "";
|
||||||
const showTwitchRaids = GetBooleanParam("showTwitchRaids", true);
|
const showTwitchRaids = GetBooleanParam("showTwitchRaids", true);
|
||||||
const twitchRaidAction = urlParams.get("twitchRaidAction") || "";
|
const twitchRaidAction = urlParams.get("twitchRaidAction") || "";
|
||||||
|
const showTwitchWatchStreaks = GetBooleanParam("showTwitchWatchStreaks", true);
|
||||||
|
const twitchWatchStreaksAction = urlParams.get("twitchWatchStreaksAction") || "";
|
||||||
|
|
||||||
// Which Kick alerts do you want to see?
|
// Which Kick alerts do you want to see?
|
||||||
const kickUsername = urlParams.get("kickUsername") || "";
|
const kickUsername = urlParams.get("kickUsername") || "";
|
||||||
@@ -211,6 +213,11 @@ client.on('Twitch.Raid', (response) => {
|
|||||||
TwitchRaid(response.data);
|
TwitchRaid(response.data);
|
||||||
})
|
})
|
||||||
|
|
||||||
|
client.on('Twitch.WatchStreak', (response) => {
|
||||||
|
console.debug(response.data);
|
||||||
|
TwitchWatchStreak(response.data);
|
||||||
|
})
|
||||||
|
|
||||||
client.on('YouTube.SuperChat', (response) => {
|
client.on('YouTube.SuperChat', (response) => {
|
||||||
console.debug(response.data);
|
console.debug(response.data);
|
||||||
YouTubeSuperChat(response.data);
|
YouTubeSuperChat(response.data);
|
||||||
@@ -721,6 +728,30 @@ async function TwitchRaid(data) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function TwitchWatchStreak(data) {
|
||||||
|
if (!showTwitchWatchStreaks)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Render avatars
|
||||||
|
const avatarURL = await GetAvatar(data.userName, 'twitch');
|
||||||
|
|
||||||
|
// Set the text
|
||||||
|
const username = data.displayName;
|
||||||
|
const watchStreak = data.watchStreak;
|
||||||
|
|
||||||
|
UpdateAlertBox(
|
||||||
|
'twitch',
|
||||||
|
avatarURL,
|
||||||
|
`${username}`,
|
||||||
|
`is currently on a ${watchStreak} stream streak!`,
|
||||||
|
'',
|
||||||
|
username,
|
||||||
|
'',
|
||||||
|
twitchWatchStreaksAction,
|
||||||
|
data
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
function YouTubeSuperChat(data) {
|
function YouTubeSuperChat(data) {
|
||||||
if (!showYouTubeSuperChats)
|
if (!showYouTubeSuperChats)
|
||||||
return;
|
return;
|
||||||
@@ -836,7 +867,7 @@ async function StreamElementsTip(data) {
|
|||||||
|
|
||||||
UpdateAlertBox(
|
UpdateAlertBox(
|
||||||
'streamelements',
|
'streamelements',
|
||||||
''
|
'',
|
||||||
`${donater}`,
|
`${donater}`,
|
||||||
`donated ${currency}${formattedAmount}`,
|
`donated ${currency}${formattedAmount}`,
|
||||||
``,
|
``,
|
||||||
|
|||||||
@@ -312,6 +312,23 @@
|
|||||||
"showIf": "showTwitchRaids",
|
"showIf": "showTwitchRaids",
|
||||||
"group": "Which Twitch alerts do you want to see?"
|
"group": "Which Twitch alerts do you want to see?"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"id": "showTwitchWatchStreaks",
|
||||||
|
"label": "Watch Streaks",
|
||||||
|
"description": "",
|
||||||
|
"type": "checkbox",
|
||||||
|
"defaultValue": true,
|
||||||
|
"group": "Which Twitch alerts do you want to see?"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "twitchWatchStreaksAction",
|
||||||
|
"label": "",
|
||||||
|
"description": "Also run this Streamer.bot Action",
|
||||||
|
"type": "sb-actions",
|
||||||
|
"defaultValue": "",
|
||||||
|
"showIf": "showTwitchWatchStreaks",
|
||||||
|
"group": "Which Twitch alerts do you want to see?"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"id": "showYouTubeSuperChats",
|
"id": "showYouTubeSuperChats",
|
||||||
"label": "Super Chats",
|
"label": "Super Chats",
|
||||||
|
|||||||
Reference in New Issue
Block a user