Last active
October 11, 2022 22:49
-
-
Save Glutnix/feeede22c8f129ec26f42d5ff16d8a09 to your computer and use it in GitHub Desktop.
MrBoost Sideways Chat + Pronouns
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"testMessage": { | |
"type": "button", | |
"label": "Test message", | |
"value": "Test message", | |
"group": "Test" | |
}, | |
"noname": { | |
"type": "dropdown", | |
"label": "Show nickname every msg?", | |
"value": "Yes", | |
"options": { | |
"show": "No", | |
"hide": "Yes" | |
} | |
}, | |
"messagesLimit": { | |
"type": "number", | |
"label": "Messages limit", | |
"value": 6 | |
}, | |
"hideAfter": { | |
"type": "number", | |
"label": "Hide after seconds (999 to disable)", | |
"value": 999 | |
}, | |
"animationOut": { | |
"type": "dropdown", | |
"label": "Animation Out:", | |
"value": "none", | |
"options": { | |
"none": "None", | |
"bounceOut": "bounceOut", | |
"bounceOutDown": "bounceOutDown", | |
"bounceOutLeft": "bounceOutLeft", | |
"bounceOutRight": "bounceOutRight", | |
"bounceOutUp": "bounceOutUp", | |
"fadeOut": "fadeOut", | |
"fadeOutDown": "fadeOutDown", | |
"fadeOutDownBig": "fadeOutDownBig", | |
"fadeOutLeft": "fadeOutLeft", | |
"fadeOutLeftBig": "fadeOutLeftBig", | |
"fadeOutRight": "fadeOutRight", | |
"fadeOutRightBig": "fadeOutRightBig", | |
"fadeOutUp": "fadeOutUp", | |
"fadeOutUpBig": "fadeOutUpBig", | |
"flipOutX": "flipOutX", | |
"flipOutY": "flipOutY", | |
"lightSpeedOut": "lightSpeedOut", | |
"rotateOut": "rotateOut", | |
"rotateOutDownLeft": "rotateOutDownLeft", | |
"rotateOutDownRight": "rotateOutDownRight", | |
"rotateOutUpLeft": "rotateOutUpLeft", | |
"rotateOutUpRight": "rotateOutUpRight", | |
"slideOutUp": "slideOutUp", | |
"slideOutDown": "slideOutDown", | |
"slideOutLeft": "slideOutLeft", | |
"slideOutRight": "slideOutRight", | |
"zoomOut": "zoomOut", | |
"zoomOutDown": "zoomOutDown", | |
"zoomOutLeft": "zoomOutLeft", | |
"zoomOutRight": "zoomOutRight", | |
"zoomOutUp": "zoomOutUp", | |
"rollOut": "rollOut" | |
} | |
}, | |
"customFont": { | |
"type": "dropdown", | |
"label": "Use NUTTY'S font?", | |
"value": "Yes", | |
"options": { | |
"Uni Sans Heavy CAPS": "Yes", | |
"{fontName}": "No" | |
} | |
}, | |
"fontName": { | |
"label": "Font Family", | |
"type": "googleFont", | |
"value": "Roboto Condensed" | |
}, | |
"fontSize": { | |
"type": "number", | |
"label": "Font size", | |
"value": 24 | |
}, | |
"fontWeight": { | |
"label": "Font Weight", | |
"type": "dropdown", | |
"value": "400", | |
"options": { | |
"100": "Thin (100)", | |
"300": "Light (300)", | |
"400": "Regular (400)", | |
"500": "Medium (500)", | |
"700": "Bold (700)", | |
"900": "Black (900)" | |
} | |
}, | |
"fontColor": { | |
"type": "colorpicker", | |
"label": "Font Color", | |
"value": "rgba(255,255,255,1)" | |
}, | |
"textShadow": { | |
"type": "text", | |
"label": "Text shadow", | |
"value": "rgb(0, 0, 0) 1px 1px 1px" | |
}, | |
"bgColor": { | |
"label": "Background Color", | |
"type": "colorpicker", | |
"value": "rgb(0, 0, 0)" | |
}, | |
"nickColor": { | |
"type": "dropdown", | |
"label": "Nickname color:", | |
"value": "user", | |
"options": { | |
"user": "as on twitch", | |
"messagecolor": "same as message text", | |
"custom": "specified below" | |
} | |
}, | |
"customNickColor": { | |
"type": "colorpicker", | |
"label": "Custom nickname color:", | |
"value": "rgba(0,255,0,1)" | |
}, | |
"showPronouns": { | |
"type": "dropdown", | |
"label": "Use pronouns.alejo.io?", | |
"value": "Yes", | |
"options": { | |
"show": "Show Pronouns", | |
"hide": "Disable Pronouns" | |
} | |
}, | |
"hideCommands": { | |
"label": "Hide lines starting with ! (!command)", | |
"type": "dropdown", | |
"value": "yes", | |
"options": { | |
"yes": "Yes", | |
"no": "No" | |
} | |
}, | |
"ignoredUsers": { | |
"label": "Ignored users (comma separated)", | |
"type": "text", | |
"value": "StreamElements,OtherBot" | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@import url('https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.5.2/animate.min.css'); | |
@import url('https://fonts.googleapis.com/css?family={{fontName}}:100,300,400,500,700,900'); | |
@font-face { | |
font-family: 'Uni Sans Heavy CAPS'; | |
src: url('https://cdn.jsdelivr.net/gh/mrboost/fonts/uni-sans.heavy-caps-webfont.woff') format('woff') | |
} | |
* { | |
font-family: '{{customFont}}'; | |
color: {{fontColor}}; | |
font-weight: {{fontWeight}}; | |
text-shadow: {{textShadow}}; | |
} | |
:root { | |
--bgColor: {bgColor}; | |
} | |
.main-container{ | |
position: absolute; | |
bottom: 0; | |
right: 0; | |
width: 9999px; | |
height: calc({fontSize}px + 0px); | |
white-space: nowrap; | |
overflow: hidden; | |
padding-bottom: 15px; | |
padding-right: 8px; | |
background: var(--bgColor); | |
} | |
.message-row{ | |
display: inline-block; | |
bottom: 0; | |
right: 0; | |
float: right; | |
padding: 4px 4px; | |
} | |
.badge{ | |
display: inline-block; | |
margin-right: 0em; | |
position: relative; | |
height: 1em; | |
vertical-align: middle; | |
top: -1px; | |
} | |
.user-box{ | |
display:inline; | |
font-size:{{fontSize}}px; | |
} | |
.hidden-box { | |
position: absolute; | |
widget: 0px; | |
opacity: 0; | |
} | |
.user-box > span{ | |
font-size:{{fontSize}}px; | |
} | |
.user-message{ | |
display:inline; | |
font-size:{{fontSize}}px; | |
word-wrap: break-word; | |
} | |
.emote { | |
display: inline-block; | |
margin-right: 0.1em; | |
position: relative; | |
height: 1.1em; | |
vertical-align: middle; | |
top: 0em; | |
} | |
.emote img { | |
display: inline-block; | |
position: relative; | |
height: 1.3em; | |
opacity: 0; | |
} | |
.action{ | |
font-style: italic; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script src="//cdnjs.cloudflare.com/ajax/libs/blueimp-md5/2.12.0/js/md5.min.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.5.0/gsap.min.js" crossorigin="anonymous"></script> | |
<div class="main-container"></div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Sideways Chat by MrBoost | |
// pronouns.alejo.io support added by JuniperSkunktaur | |
let totalMessages = 0, messagesLimit = 0, noname = "show", nickColor = "user", removeSelector, addition, customNickColor, channelName, | |
provider; | |
let pronounsList; | |
let showPronouns; | |
let animationIn = 'bounceIn'; | |
let animationOut = 'bounceOut'; | |
let hideAfter = 60; | |
let hideCommands = "no"; | |
let ignoredUsers = []; | |
let previousSender = ''; | |
window.addEventListener('onEventReceived', async function (obj) | |
{ | |
if (obj.detail.event.listener === 'widget-button') { | |
if (obj.detail.event.field === 'testMessage') { | |
let emulated = new CustomEvent("onEventReceived", { | |
detail: { | |
listener: "message", event: { | |
service: "twitch", | |
data: { | |
time: Date.now(), | |
tags: { | |
"badge-info": "", | |
badges: "moderator/1,partner/1", | |
color: "#5B99FF", | |
"display-name": "StreamElements", | |
emotes: "25:46-50", | |
flags: "", | |
id: "43285909-412c-4eee-b80d-89f72ba53142", | |
mod: "1", | |
"room-id": "85827806", | |
subscriber: "0", | |
"tmi-sent-ts": "1579444549265", | |
turbo: "0", | |
"user-id": "100135110", | |
"user-type": "mod" | |
}, | |
nick: channelName, | |
userId: "100135110", | |
displayName: channelName, | |
displayColor: "#5B99FF", | |
badges: [{ | |
type: "moderator", | |
version: "1", | |
url: "https://static-cdn.jtvnw.net/badges/v1/3267646d-33f0-4b17-b3df-f923a41db1d0/3", | |
description: "Moderator" | |
}, { | |
type: "partner", | |
version: "1", | |
url: "https://static-cdn.jtvnw.net/badges/v1/d12a2e27-16f6-41d0-ab77-b780518f00a3/3", | |
description: "Verified" | |
}], | |
channel: channelName, | |
text: "Howdy! My name is MrBoost and I am here to serve Kappa", | |
isAction: !1, | |
emotes: [{ | |
type: "twitch", | |
name: "Kappa", | |
id: "25", | |
gif: !1, | |
urls: { | |
1: "https://static-cdn.jtvnw.net/emoticons/v1/25/1.0", | |
2: "https://static-cdn.jtvnw.net/emoticons/v1/25/1.0", | |
4: "https://static-cdn.jtvnw.net/emoticons/v1/25/3.0" | |
}, | |
start: 46, | |
end: 50 | |
}], | |
msgId: "43285909-412c-4eee-b80d-89f72ba53142" | |
}, | |
renderedText: 'Howdy! My name is Bill and I am here to serve <img src="https://static-cdn.jtvnw.net/emoticons/v1/25/1.0" srcset="https://static-cdn.jtvnw.net/emoticons/v1/25/1.0 1x, https://static-cdn.jtvnw.net/emoticons/v1/25/1.0 2x, https://static-cdn.jtvnw.net/emoticons/v1/25/3.0 4x" title="Kappa" class="emote">' | |
} | |
} | |
}); | |
window.dispatchEvent(emulated); | |
} | |
return; | |
} | |
if (obj.detail.listener === "delete-message") { | |
const msgId = obj.detail.event.msgId; | |
$(`.message-row[data-msgid=${msgId}]`).remove(); | |
return; | |
} else if (obj.detail.listener === "delete-messages") { | |
const sender = obj.detail.event.userId; | |
$(`.message-row[data-sender=${sender}]`).remove(); | |
return; | |
} | |
if (obj.detail.listener !== "message") return; | |
let data = obj.detail.event.data; | |
if (data.text.startsWith("!") && hideCommands === "yes") return; | |
if (ignoredUsers.indexOf(data.nick) !== -1) return; | |
let message = attachEmotes(data); | |
let badges = "", badge; | |
if (provider === 'mixer') { | |
data.badges.push({ url: data.avatar }); | |
} | |
for (let i = 0; i < data.badges.length; i++) { | |
badge = data.badges[i]; | |
badges += `<img alt="" src="${badge.url}" class="badge"> `; | |
} | |
let nickname = data.displayName; | |
let userPronouns = ""; | |
if (showPronouns && provider === 'twitch') { | |
const pronouns = await getPronouns(nickname); | |
if (pronouns){ | |
userPronouns = ` (${pronouns})`; | |
} | |
} | |
let username = data.displayName + userPronouns + ":"; | |
if (nickColor === "user") { | |
const color = data.displayColor !== "" ? data.displayColor : "#" + (md5(nickname).substr(26)); | |
username = `<span style="color:${color}">${username}</span>`; | |
} | |
if (nickColor === "custom") { | |
const color = customNickColor; | |
username = `<span style="color:${color}">${username}</span>`; | |
} | |
addMessage(nickname, username, badges, message, data.isAction, data.userId, data.msgId); | |
}); | |
window.addEventListener('onWidgetLoad', function (obj) | |
{ | |
const fieldData = obj.detail.fieldData; | |
animationIn = fieldData.animationIn; | |
animationOut = fieldData.animationOut; | |
hideAfter = fieldData.hideAfter; | |
messagesLimit = fieldData.messagesLimit; | |
nickColor = fieldData.nickColor; | |
customNickColor = fieldData.customNickColor; | |
showPronouns = fieldData.showPronouns; | |
hideCommands = fieldData.hideCommands; | |
channelName = obj.detail.channel.username; | |
animate = fieldData.messageAlign; | |
noname = fieldData.noname; | |
fetch('https://api.streamelements.com/kappa/v2/channels/' + obj.detail.channel.id + '/') | |
.then(response => response.json()) | |
.then((profile) => | |
{ | |
provider = profile.provider; | |
}); | |
if (showPronouns === "show") { | |
fetch('https://pronouns.alejo.io/api/pronouns') | |
.then(response => response.json()) | |
.then(pronounArray => | |
{ | |
pronounsList = pronounArray.reduce( | |
(obj, item) => Object.assign(obj, { [item.name]: item.display }), {}); | |
console.log(pronounsList); | |
}); | |
} | |
ignoredUsers = fieldData.ignoredUsers.toLowerCase().replace(" ", "").split(","); | |
}); | |
function attachEmotes(message) | |
{ | |
let text = html_encode(message.text); | |
let data = message.emotes; | |
return text | |
.replace( | |
/([^\s]*)/gi, | |
function (m, key) | |
{ | |
let result = data.filter(emote => | |
{ | |
return emote.name === key | |
}); | |
if (typeof result[0] !== "undefined") { | |
let url = result[0]['urls'][1]; | |
return `<img alt="" src="${url}" class="emote"/>`; | |
} else return key; | |
} | |
); | |
} | |
function html_encode(e) | |
{ | |
return e.replace(/[<>"^]/g, function (e) | |
{ | |
return "&#" + e.charCodeAt(0) + ";"; | |
}); | |
} | |
function addMessage(nickname, username, badges, message, isAction, uid, msgId) | |
{ | |
if (noname === "show") { | |
if (previousSender !== username) { | |
previousSender = username; | |
} | |
else { | |
username = ''; | |
badges = ''; | |
} | |
} | |
totalMessages += 1; | |
let actionClass = ""; | |
if (isAction) { | |
actionClass = "action"; | |
} | |
const element = $.parseHTML(` | |
<div data-sender="${uid}" data-msgid="${msgId}" class="message-row animated" id="msg-${totalMessages}"> | |
<div class="user-box ${actionClass}">${badges}${username}</div> | |
<div class="user-message ${actionClass}">${message}</div> | |
</div>`); | |
if (hideAfter !== 999 && noname == "hide") { | |
$('.main-container').prepend(element); | |
gsap.fromTo(`#msg-${totalMessages}`, 0.5, { right: "-50px", width: 0 }, { width: "auto" }); | |
$('.main-container .message-row').prepend(element).delay(hideAfter * 1000).queue(function () | |
{ | |
$(this).removeClass(animationIn).addClass(animationOut).delay(1000).queue(function () | |
{ | |
$(this).remove() | |
}).dequeue(); | |
}); | |
} else { | |
$('.main-container').prepend(element); | |
gsap.fromTo(`#msg-${totalMessages}`, 0.5, { right: "-50px", width: 0 }, { width: "auto" }); | |
} | |
if (totalMessages > messagesLimit) { | |
removeRow(totalMessages - messagesLimit); | |
} | |
} | |
function removeRow() | |
{ | |
if (!$(removeSelector).length) { | |
return; | |
} | |
if (animationOut !== "none" || !$(removeSelector).hasClass(animationOut)) { | |
if (hideAfter !== 999) { | |
$(removeSelector).dequeue(); | |
} else { | |
$(removeSelector).addClass(animationOut).delay(1000).queue(function () | |
{ | |
$(this).remove().dequeue() | |
}); | |
} | |
return; | |
} | |
} | |
async function getPronouns(nickname) | |
{ | |
const userResponse = await (await fetch(`https://pronouns.alejo.io/api/users/${nickname}`)).json(); | |
console.log(userResponse); | |
if (userResponse.length === 0) return ""; | |
const userPronouns = pronounsList[userResponse[0].pronoun_id]; | |
console.log(nickname, userPronouns); | |
return userPronouns; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment