diff --git a/.resources/logo.png b/.resources/logo.png new file mode 100644 index 0000000..5a8df41 Binary files /dev/null and b/.resources/logo.png differ diff --git a/.utilities/settings-page-builder/index.html b/.utilities/settings-page-builder/index.html index 98ffbff..846a3f7 100644 --- a/.utilities/settings-page-builder/index.html +++ b/.utilities/settings-page-builder/index.html @@ -4,17 +4,26 @@ + Settings +
+
+ + +

Widget URL

- - +
+ + +
+
@@ -24,7 +33,8 @@
-

Load Settings From Widget URL

+

Load Settings

+
diff --git a/.utilities/settings-page-builder/script.js b/.utilities/settings-page-builder/script.js index 0b5cfa3..3984ea4 100644 --- a/.utilities/settings-page-builder/script.js +++ b/.utilities/settings-page-builder/script.js @@ -1,14 +1,52 @@ +// Search paramaters const queryString = window.location.search; const urlParams = new URLSearchParams(queryString); - 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', () => { + const settingsContent = document.getElementById('settings-content'); const saveButton = document.getElementById('save-settings'); fetch(settingsJson) - //fetch('../../multichat-overlay/settings/settings.json') .then(response => response.json()) .then(data => { const groupedSettings = {}; @@ -33,12 +71,15 @@ document.addEventListener('DOMContentLoaded', () => { groupedSettings[groupName].forEach(setting => { const settingItem = document.createElement('div'); settingItem.classList.add('setting-item'); + settingItem.id = `item-${setting.id}`; const labelDescriptionDiv = document.createElement('div'); - const label = document.createElement('label'); - label.textContent = setting.label; - labelDescriptionDiv.appendChild(label); + if (setting.label) { + const label = document.createElement('label'); + label.textContent = setting.label; + labelDescriptionDiv.appendChild(label); + } if (setting.description) { const description = document.createElement('p'); @@ -74,6 +115,7 @@ document.addEventListener('DOMContentLoaded', () => { // Add event listener to the switchDiv labelDiv.addEventListener('click', () => { checkBoxElement.checked = !checkBoxElement.checked; + UpdateSettingItemVisibility(); }); inputElement = labelDiv; break; @@ -106,6 +148,37 @@ document.addEventListener('DOMContentLoaded', () => { inputElement.max = setting.max; inputElement.step = setting.step; 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: inputElement = document.createElement('input'); inputElement.type = 'text'; @@ -114,30 +187,53 @@ document.addEventListener('DOMContentLoaded', () => { } inputElement.addEventListener('input', function (event) { - SendDateToParent(data); + SendDataToParent(data); }); settingItemContent.appendChild(inputElement); - settingItem.appendChild(labelDescriptionDiv); - settingItem.appendChild(settingItemContent); + if (setting.type == 'button') + { + settingItem.style.display = 'block' + settingItem.appendChild(settingItemContent); + } + else + { + settingItem.appendChild(labelDescriptionDiv); + settingItem.appendChild(settingItemContent); + } + groupDiv.appendChild(settingItem); }); 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', () => { - // SendDateToParent(data); + // SendDataToParent(data); // }); - SendDateToParent(data); + SendDataToParent(data); }) .catch(error => console.error('Error loading settings:', error)); }); // In the iframe's JavaScript: -function SendDateToParent(data) { +function SendDataToParent(data) { const settings = {}; data.settings.forEach(setting => { let inputElement = document.getElementById(setting.id); @@ -183,12 +279,6 @@ saveButton.addEventListener('click', () => { }, 3000); }); -widgetURLBox.addEventListener('click', () => { - let loadSettingsBox = document.getElementById('mommy-milkers'); - loadSettingsBox.style.visibility = 'visible'; - loadSettingsBox.style.opacity = 1; -}); - function CloseSettings() { let loadSettingsBox = document.getElementById('mommy-milkers'); loadSettingsBox.style.visibility = 'hidden'; @@ -198,12 +288,11 @@ function CloseSettings() { function LoadSettings() { let loadURLBox = document.getElementById('load-url'); const url = new URL(loadURLBox.value); - + url.searchParams.forEach((value, key) => { const inputElement = document.getElementById(key); - if (inputElement != null) - { + if (inputElement != null) { if (inputElement.type == 'checkbox') inputElement.checked = value.toLocaleLowerCase() == 'true'; else @@ -230,8 +319,15 @@ function GetWidgetURL() { } return result; + //return 'D:/Projects/GitHub Projects/nutty.gg/multistream-alerts/index.html' } 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; } \ No newline at end of file diff --git a/.utilities/settings-page-builder/style.css b/.utilities/settings-page-builder/style.css index 692dc42..6a05854 100644 --- a/.utilities/settings-page-builder/style.css +++ b/.utilities/settings-page-builder/style.css @@ -2,10 +2,12 @@ font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica, Arial, sans-serif; font-size: 16px; color: white; + --accent-color: #2196f3; } body { background-color: #181818; + margin: 0px 20px; } body::-webkit-scrollbar { @@ -63,7 +65,7 @@ body::-webkit-scrollbar-thumb:hover { .setting-group { margin-bottom: 20px; /* border: 1px solid #ddd; */ - padding: 15px; + padding-bottom: 15px; border-radius: 5px; } @@ -97,7 +99,7 @@ h2 { font-weight: 300; /* color: #666; */ opacity: 0.6; - margin-bottom: 0; + margin: 0; } a { @@ -126,6 +128,7 @@ input[type="number"] { -moz-box-sizing: border-box; box-sizing: border-box; } + #widget-url:hover { cursor: pointer; } @@ -195,11 +198,11 @@ input:focus { } input:checked+.slider { - background-color: #2196F3; + background-color: var(--accent-color); } input:focus+.slider { - box-shadow: 0 0 1px #2196F3; + box-shadow: 0 0 1px var(--accent-color); } input:checked+.slider:before { @@ -227,7 +230,7 @@ button { border-radius: 0.5em; padding: 10px 20px; width: 100%; - transition: all 0.2s ease; + transition: all 0.2s ease-in-out; } button:hover { @@ -270,5 +273,5 @@ button:hover { } #load-settings { - background-color: #2196F3; + background-color: var(--accent-color); } \ No newline at end of file diff --git a/multistream-alerts/index.html b/multistream-alerts/index.html index 3e6224c..8609f93 100644 --- a/multistream-alerts/index.html +++ b/multistream-alerts/index.html @@ -24,7 +24,7 @@
- + nutty

diff --git a/multistream-alerts/script.js b/multistream-alerts/script.js index 8d1dcbb..ff3fb7a 100644 --- a/multistream-alerts/script.js +++ b/multistream-alerts/script.js @@ -28,48 +28,103 @@ let alertQueue = []; // 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 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 fontSize = GetIntParam("fontSize", 30); +const useCustomBackground = GetBooleanParam("useCustomBackground", true); +const background = urlParams.get("background") || ""; +const opacity = GetIntParam("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); +// General +const hideAfter = GetIntParam("hideAfter", 8); +const showAnimation = urlParams.get("showAnimation") || ""; +const hideAnimation = urlParams.get("hideAnimation") || ""; +const alignment = urlParams.get("alignment") || ""; +const showMesesages = GetBooleanParam("showMesesages", true); -const showTwitchMessages = GetBooleanParam("showTwitchMessages", true); -const showTwitchAnnouncements = GetBooleanParam("showTwitchAnnouncements", true); +// Which Twitch alerts do you want to see? +const showTwitchFollows = GetBooleanParam("showTwitchFollows", false); +const twitchFollowAction = urlParams.get("twitchFollowAction") || ""; const showTwitchSubs = GetBooleanParam("showTwitchSubs", true); +const twitchSubAction = urlParams.get("twitchSubAction") || ""; 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 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 youtubeSuperChatAction = urlParams.get("youtubeSuperChatAction") || ""; const showYouTubeSuperStickers = GetBooleanParam("showYouTubeSuperStickers", true); +const youtubeSuperStickerAction = urlParams.get("youtubeSuperStickerAction") || ""; const showYouTubeMemberships = GetBooleanParam("showYouTubeMemberships", true); +const youtubeMembershipAction = urlParams.get("youtubeMembershipAction") || ""; -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); +// Which donation alerts do you want to see? +const showStreamlabsDonations = GetBooleanParam("showStreamlabsDonations", false); +const streamlabsDonationAction = urlParams.get("streamlabsDonationAction") || ""; +const showStreamElementsTips = GetBooleanParam("showStreamElementsTips", false); +const streamelementsTipAction = urlParams.get("streamelementsTipAction") || ""; +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); - -const furryMode = GetBooleanParam("furryMode", false); +// Set avatar visibility +if (!showAvatar) + avatarElement.style.display = 'none'; // Set fonts for the widget document.body.style.fontFamily = font; @@ -124,7 +179,7 @@ const client = new StreamerbotClient({ client.on('Twitch.Cheer', (response) => { console.debug(response.data); - TwitchChatMessage(response.data); + TwitchCheer(response.data); }) client.on('Twitch.Sub', (response) => { @@ -248,6 +303,59 @@ client.on('Fourthwall.GiftDrawEnded', (response) => { // 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 = ``; + 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 = ``; + const bitsElements = `${bits}` + 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) { if (!showTwitchSubs) return; @@ -380,7 +488,7 @@ async function TwitchRaid(data) { // Set the text const username = data.from_broadcaster_user_login; const viewers = data.viewers; - + UpdateAlertBox( 'twitch', avatarURL, @@ -388,7 +496,9 @@ async function TwitchRaid(data) { `is raiding with a party of ${viewers}`, '', username, - '' + '', + twitchFollowAction, + data ); } @@ -1142,12 +1252,12 @@ function GetWinnersList(gifts) { // 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 // If any alerts are requested while the animation is playing, it should be added to the alert queue if (widgetLocked) { 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); return; } @@ -1173,8 +1283,16 @@ function UpdateAlertBox(platform, avatarURL, headerText, descriptionText, attrib messageLabel.innerHTML = message != null ? `${message}` : ''; theContentThatShowsLastInsteadOfFirst.style.opacity = 0; - alertBox.style.height = theContentThatShowsFirstInsteadOfSecond.offsetHeight + 40 + "px"; - alertBox.style.animation = 'slideInFromTop 0.5s ease-out forwards'; + theContentThatShowsFirstInsteadOfSecond.style.display = 'flex'; + 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) // (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 setTimeout(() => { alertBox.style.transition = 'all 0.5s ease-in-out'; - alertBox.style.height = theContentThatShowsLastInsteadOfFirst.offsetHeight + 40 + "px"; 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; - + setTimeout(() => { - alertBox.style.animation = 'slideBackUp 0.5s ease-out forwards'; + alertBox.style.animation = 'slideOffRight 0.5s ease-out forwards'; setTimeout(() => { - alertBox.style.transition = ''; + alertBox.style.maxHeight = '0px'; theContentThatShowsFirstInsteadOfSecond.style.opacity = 1; theContentThatShowsLastInsteadOfFirst.style.opacity = 0; - alertBox.style.height = '0px'; + theContentThatShowsFirstInsteadOfSecond.style.position = 'relative'; + theContentThatShowsLastInsteadOfFirst.style.display = 'none'; widgetLocked = false; if (alertQueue.length > 0) { console.debug("Pulling next alert from the queue"); 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); - }, 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` + //`` + ); } diff --git a/multistream-alerts/settings/index.html b/multistream-alerts/settings/index.html index 7ddcb25..aebc55b 100644 --- a/multistream-alerts/settings/index.html +++ b/multistream-alerts/settings/index.html @@ -1,5 +1,4 @@ - @@ -50,15 +49,10 @@ - -
-
- - - +
- \ No newline at end of file + \ No newline at end of file diff --git a/multistream-alerts/settings/script.js b/multistream-alerts/settings/script.js index 45fcbf9..c62f79e 100644 --- a/multistream-alerts/settings/script.js +++ b/multistream-alerts/settings/script.js @@ -1,5 +1,6 @@ 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=../../multistream-alerts/settings/settings.json` console.log(settingsContainer.src); function reloadWidget(data) { @@ -26,4 +27,10 @@ function getParentUrl() { } return parentUrl; +} + +function callFunction(functionName) { + console.debug(`Calling ${functionName}`); + let widget = document.getElementById("widget"); + widget.contentWindow[functionName](); } \ No newline at end of file diff --git a/multistream-alerts/settings/settings.json b/multistream-alerts/settings/settings.json index 36599eb..030dd8e 100644 --- a/multistream-alerts/settings/settings.json +++ b/multistream-alerts/settings/settings.json @@ -1,5 +1,13 @@ { "settings": [ + { + "id": "testWidgetButton", + "label": "Send Test Alert", + "description": "", + "type": "button", + "callFunction": "testWidget", + "group": "Test Alerts" + }, { "id": "showAvatar", "label": "Show Avatar", @@ -56,7 +64,7 @@ { "id": "hideAfter", "label": "Hide After", - "description": "Alerts will show for X seconds", + "description": "Alerts will hide for X seconds", "type": "number", "min": 1, "max": 120, @@ -151,18 +159,19 @@ }, { "id": "showTwitchFollows", - "label": "New Follows", + "label": "New Followers", "description": "", "type": "checkbox", - "defaultValue": true, + "defaultValue": false, "group": "Which Twitch alerts do you want to see?" }, { - "id": "showTwitchCheers", - "label": "Cheers", - "description": "", - "type": "checkbox", - "defaultValue": true, + "id": "twitchFollowAction", + "label": "", + "description": "Also run this Streamer.bot Action", + "type": "sb-actions", + "defaultValue": "", + "hideIf": "showTwitchFollows", "group": "Which Twitch alerts do you want to see?" }, { @@ -173,6 +182,15 @@ "defaultValue": true, "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", "label": "Channel Point Redemptions", @@ -181,6 +199,32 @@ "defaultValue": true, "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", "label": "Raids", @@ -189,6 +233,15 @@ "defaultValue": true, "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", "label": "Super Chats", @@ -197,6 +250,15 @@ "defaultValue": true, "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", "label": "Super Stickers", @@ -205,6 +267,15 @@ "defaultValue": true, "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", "label": "Memberships", @@ -213,12 +284,30 @@ "defaultValue": true, "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", "label": "Streamlabs Tips", "description": "Click to connect", "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?" }, { @@ -226,7 +315,16 @@ "label": "StreamElements Tips", "description": "Click to connect", "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?" }, { @@ -234,7 +332,16 @@ "label": "Patreon Memberships", "description": "Click to connect", "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?" }, { @@ -242,7 +349,16 @@ "label": "Ko-fi Donations", "description": "Click to connect", "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?" }, { @@ -250,7 +366,16 @@ "label": "TipeeeStream Donations", "description": "Click to connect", "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?" }, { @@ -258,7 +383,16 @@ "label": "Fourthwall Alerts", "description": "Click to connect", "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?" } ] diff --git a/multistream-alerts/style.css b/multistream-alerts/style.css index 0a31fed..59bc810 100644 --- a/multistream-alerts/style.css +++ b/multistream-alerts/style.css @@ -1,9 +1,9 @@ * { margin: 0; padding: 0; - --margin: 20px; - /* --border-radius: 20px; */ - font-size: 30px; + --margin: 0.5em; + --border-radius: 1em; + /* font-size: 30px; */ /* --line-spacing: 1.7em; */ } @@ -37,12 +37,14 @@ html { } #mainContainer { - display: block; position: absolute; width: 100%; height: 100%; padding: calc(2 * var(--margin)); box-sizing: border-box; + display: flex; + flex-direction: column; + justify-content: flex-end; } #alertBox { @@ -53,10 +55,10 @@ html { overflow: hidden; box-sizing: border-box; /* text-align: center; */ - position: relative; + /* position: relative; */ /* transition: all 1s ease-in-out; */ - min-height: 0px; - height: 0px; + /* min-height: 0px; + max-height: 0px; */ } /* #alertBox::before { @@ -79,21 +81,25 @@ html { display: flex; align-items: center; z-index: 1; - position: absolute; - left: var(--margin); - top: var(--margin); + /* position: absolute; */ + /* left: var(--margin); + top: var(--margin); */ transition: inherit; + padding: var(--margin); + display: none; } #theContentThatShowsLastInsteadOfFirst { - position: absolute; - display: block; + /* position: absolute; */ + display: inline-block; align-items: center; z-index: 0; - position: absolute; - left: var(--margin); - top: var(--margin); + /* position: absolute; */ + /* left: var(--margin); + top: var(--margin); */ + padding: var(--margin); transition: inherit; + display: none; } #avatar { @@ -146,6 +152,19 @@ html { 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 { width: calc(100% - 2 * var(--margin)); z-index: 0; @@ -167,7 +186,7 @@ html { } } -@keyframes slideBackUp { +@keyframes slideOffUp { 0% { transform: translateY(0); opacity: 1; @@ -191,7 +210,7 @@ html { } } -@keyframes slideBackDown { +@keyframes slideOffDown { 0% { transform: translateY(0); opacity: 1; @@ -215,7 +234,7 @@ html { } } -@keyframes slideBackLeft { +@keyframes slideOffLeft { 0% { transform: translateX(0); opacity: 1; @@ -239,7 +258,7 @@ html { } } -@keyframes slideBackRight { +@keyframes slideOffRight { 0% { transform: translateX(0); opacity: 1;