Skip to content

Instantly share code, notes, and snippets.

@Glutnix
Last active October 11, 2022 22:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Glutnix/feeede22c8f129ec26f42d5ff16d8a09 to your computer and use it in GitHub Desktop.
Save Glutnix/feeede22c8f129ec26f42d5ff16d8a09 to your computer and use it in GitHub Desktop.
MrBoost Sideways Chat + Pronouns
{
"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"
}
}
@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;
}
<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>
// 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