Skip to content

Instantly share code, notes, and snippets.

@drakantas
Last active June 18, 2024 02:34
Show Gist options
  • Save drakantas/9fafa08d9a4168d778566980373d3caa to your computer and use it in GitHub Desktop.
Save drakantas/9fafa08d9a4168d778566980373d3caa to your computer and use it in GitHub Desktop.
Streamlabs Chatbox with avatars
@import url('https://fonts.googleapis.com/css?family=Orbitron&display=swap');
* {
display;
box-sizing: border-box;
}
html, body {
height: 100%;
overflow: hidden;
}
body {
font-family: 'Orbitron', sans-serif;
font-weight: 700;
font-size: {font_size};
line-height: 1.5em;
color: {text_color}
}
.colon {
display: none;
}
#log {
position: absolute;
bottom: 0;
left: 0;
padding: 0 10px 10px;
width: 100%;
box-sizing: border-box;
}
#log > div {
display: flex;
flex-wrap: nowrap;
justify-content: flex-end;
align-items: flex-end;
text-align: right;
padding-bottom: 20px;
box-sizing: border-box;
transition: 300ms visibility ease-in-out;
-webkit-transition: 300ms visibility ease-in-out;
animation: fadeInLeft .3s ease forwards, fadeOut 0.5s ease {message_hide_delay} forwards;
-webkit-animation: fadeInLeft .3s ease forwards, fadeOut 0.5s ease {message_hide_delay} forwards;
}
#log > div:last-child {
padding-bottom: 0;
}
#log > div.deleted {
visibility: hidden;
}
#log .meta {
text-align: right;
padding-right: 10px;
box-sizing: border-box;
}
#log .message {
word-wrap: break-word;
width: 100%;
letter-spacing: 0.5px;
color: #FFFFFF;
text-shadow: 0px 0px 8px rgba(235, 84, 197, 0.9),
0px 0px 6px rgba(235, 84, 197, 0.9),
0px 0px 4px rgba(235, 84, 197, 0.9),
0px 0px 3px rgba(255, 255, 255, 0.5),
0 2px 0 rgba(0, 0, 0, 0.9);
background-color: rgba(0, 0, 0, 0.7);
padding: 15px;
border-radius: 20px 20px 20px 0px;
text-align: left;
vertical-align: middle;
}
#log .message .author {
display: flex;
flex-wrap: nowrap;
align-items: center;
text-shadow: none;
}
#log .message .author .badges {
display: flex;
}
#log .emote {
display: inline;
line-height: 1em;
padding-left: 0.25em;
padding-right: 0.25em;
box-sizing: border-box;
position: relative;
background-image: none !important;
vertical-align: bottom;
}
#log .emote > img {
width: auto;
height: 1.85em;
}
#log .pic > img {
border-radius: 50%;
}
.badge {
display: block;
height: 1em;
margin-right: 0.2em;
vertical-align: middle;
}
.name {
margin-left: 0.2em;
}
.tw-avatar{
width: 50;
}
<!-- item will be appened to this layout -->
<div id="log" class="sl__chat__layout">
</div>
<!-- chat item -->
<script type="text/template" id="chatlist_item">
<div data-from="{from}" data-id="{messageId}">
<div class="meta">
<div class="pic">
<img class="message-{from}-avatar" src="https://cdn.discordapp.com/attachments/618989681316724737/619015100770287686/default_picture.jpg" width="50" height="50" alt="">
</div>
</div>
<div class="message">
<div class="author" style="color: {color}">
<div class="badges"></div>
<div class="name">{from}</div>
</div>
{message}
</div>
</div>
</script>
document.addEventListener('onLoad', function(obj) {
// obj will be empty for chat widget
// this will fire only once when the widget loads
});
const clientId = 'rj73sxdx0hxur1u9lw34ig549ah9aw';
const endpoint = channelName => `https://api.twitch.tv/helix/users?login=${channelName}`;
const defaultAvatarUrl = 'https://cdn.discordapp.com/attachments/618989681316724737/619015100770287686/default_picture.jpg';
const cache = {};
document.addEventListener('onEventReceived', function(obj) {
if (!obj || typeof obj.detail === 'undefined' || obj.detail === null) {
return;
}
const { from: username, messageId, tags } = obj.detail;
const displayName = tags['display-name'] || null;
console.log(displayName, '<-');
if (!username) {
return;
}
if (typeof cache[username] !== 'undefined') {
const elems = displayName !== null ? document.getElementsByClassName(`message-${displayName}-avatar`) : document.getElementsByClassName('message--avatar');
for (const elem of elems) {
elem.src = cache[username];
}
return;
}
fetch(endpoint(username), {
method: 'GET',
headers: {
'Client-ID': clientId
}
}).then(r => {
if (r.status < 200 || r.status > 299) {
cache[username] = defaultAvatarUrl;
return;
}
return r.json();
}).then(({ data }) => {
const [ user ] = data;
cache[username] = user['profile_image_url'];
}).catch(() => {
cache[username] = defaultAvatarUrl;
}).finally(() => {
const elems = displayName !== null ? document.getElementsByClassName(`message-${displayName}-avatar`) : document.getElementsByClassName('message--avatar');
for (const elem of elems) {
elem.src = cache[username];
}
});
});
@11thRaggedyMan
Copy link

Streamlabs keeps saying "Invalid .JSON" and I'm just copy pasting the css code into the custom css code field in Streamlabs

@thewokgamur
Copy link

still not showing youtube avatar

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment