miyuchiq chat gen 1
This commit is contained in:
14
StreamLabsChats/miyuchiq/generation 1/index.html
Normal file
14
StreamLabsChats/miyuchiq/generation 1/index.html
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<div id="chatbox" class="sl__chat__layout">
|
||||||
|
<a class="font-1">1</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script type="text/template" id="chatlist_item">
|
||||||
|
<message id="{messageId}">
|
||||||
|
<top>
|
||||||
|
<author>{from}</author>
|
||||||
|
</top>
|
||||||
|
<bottom>
|
||||||
|
<content>{message}</content>
|
||||||
|
</bottom>
|
||||||
|
</message>
|
||||||
|
</script>
|
||||||
535
StreamLabsChats/miyuchiq/generation 1/script.js
Normal file
535
StreamLabsChats/miyuchiq/generation 1/script.js
Normal file
@ -0,0 +1,535 @@
|
|||||||
|
let $chatBox = $(".sl__chat__layout");
|
||||||
|
|
||||||
|
let usersPfp = {};
|
||||||
|
let parity = true;
|
||||||
|
|
||||||
|
let emoteSetId;
|
||||||
|
let websocketEmotesConnected = false;
|
||||||
|
let globalEmotes = [];
|
||||||
|
let channelEmotes = [];
|
||||||
|
let subMysteries = [];
|
||||||
|
|
||||||
|
let messageProcessingList = [
|
||||||
|
detachMessage,
|
||||||
|
loadGlobalEmotes,
|
||||||
|
loadChannelEmotes,
|
||||||
|
processTags,
|
||||||
|
getProfilePicture,
|
||||||
|
cleanText,
|
||||||
|
userPings,
|
||||||
|
upscaleBadges,
|
||||||
|
upscaleEmotes,
|
||||||
|
process7TVEmotes,
|
||||||
|
fixEmotesPadding,
|
||||||
|
largeEmotes,
|
||||||
|
parityParse,
|
||||||
|
preloadImages,
|
||||||
|
animate,
|
||||||
|
];
|
||||||
|
|
||||||
|
$(document).on("onEventReceived", function (event) {
|
||||||
|
let details = event.detail;
|
||||||
|
let command = details.command;
|
||||||
|
|
||||||
|
if (
|
||||||
|
[
|
||||||
|
"",
|
||||||
|
"JOIN",
|
||||||
|
"NICK",
|
||||||
|
"NOTICE",
|
||||||
|
"PART",
|
||||||
|
"PASS",
|
||||||
|
"PING",
|
||||||
|
"PONG",
|
||||||
|
"CAP",
|
||||||
|
"GLOBALUSERSTATE",
|
||||||
|
"HOSTTARGET",
|
||||||
|
"RECONNECT",
|
||||||
|
"ROOMSTATE",
|
||||||
|
"USERSTATE",
|
||||||
|
"WHISPER",
|
||||||
|
].includes(command)
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (command) {
|
||||||
|
case "PRIVMSG":
|
||||||
|
commandPRIVMSG(details);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "USERNOTICE":
|
||||||
|
commandUSERNOTICE(details);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "CLEARCHAT":
|
||||||
|
commandClearCHAT(details);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "CLEARMSG":
|
||||||
|
commandClearMSG(details);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
console.log(`Event ${command} not handled.`, details);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
async function nextFunction(
|
||||||
|
$messageElement,
|
||||||
|
$parentElement,
|
||||||
|
details,
|
||||||
|
functions
|
||||||
|
) {
|
||||||
|
if (functions[0] != undefined)
|
||||||
|
await functions[0](
|
||||||
|
$messageElement,
|
||||||
|
$parentElement,
|
||||||
|
details,
|
||||||
|
functions.slice(1)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function commandPRIVMSG(details) {
|
||||||
|
let $messageElement = $(`#${details.messageId}`);
|
||||||
|
let $parentElement = $messageElement.parent() || $chatBox;
|
||||||
|
|
||||||
|
if (details.body == '!event' && details.tags['user-id'] == details.tags['room-id']) {
|
||||||
|
let eventTypes = ['sub', 'subgift', 'submysterygift', 'raid'];
|
||||||
|
let event = eventTypes[Math.floor(Math.random()*eventTypes.length)];
|
||||||
|
details.tags['msg-id'] = event;
|
||||||
|
return commandUSERNOTICE(details);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$messageElement.length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await nextFunction(
|
||||||
|
$messageElement,
|
||||||
|
$parentElement,
|
||||||
|
details,
|
||||||
|
messageProcessingList
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function commandUSERNOTICE(details) {
|
||||||
|
let $eventElement = $('#chatlist_event')
|
||||||
|
let eventType = details.tags['msg-id']
|
||||||
|
let author = details.tags['display-name']
|
||||||
|
let tier;
|
||||||
|
let content;
|
||||||
|
let desc;
|
||||||
|
let type;
|
||||||
|
|
||||||
|
let displayName = details.tags['display-name']
|
||||||
|
let recipient = details.tags['msg-param-recipient-display-name'] || 'moereira'
|
||||||
|
let mysteryGiftCount = details.tags['msg-param-mass-gift-count'] || 100
|
||||||
|
let viewerCount = details.tags['msg-param-viewerCount'] || 100
|
||||||
|
let subPlan = details.tags['msg-param-sub-plan'] || 1000
|
||||||
|
|
||||||
|
switch (subPlan) {
|
||||||
|
case 1000:
|
||||||
|
tier = '1';
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2000:
|
||||||
|
tier = '2';
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3000:
|
||||||
|
tier = '3';
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!$eventElement.length) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (eventType) {
|
||||||
|
case 'sub':
|
||||||
|
case 'resub':
|
||||||
|
case 'standardpayforward':
|
||||||
|
case 'communitypayforward':
|
||||||
|
case 'giftpaidupgrade':
|
||||||
|
case 'primepaidupgrade':
|
||||||
|
content = 'subscribed'
|
||||||
|
type = 'sub';
|
||||||
|
desc = `with tier ${tier}`
|
||||||
|
break;
|
||||||
|
case 'subgift':
|
||||||
|
case 'anonsubgift':
|
||||||
|
if (subMysteries.includes(details.tags['msg-param-origin-id'])) return
|
||||||
|
content = `Has gifted a sub to`;
|
||||||
|
desc = recipient;
|
||||||
|
type = 'gift';
|
||||||
|
break;
|
||||||
|
case 'submysterygift':
|
||||||
|
if (subMysteries.includes(details.tags['msg-param-origin-id'])) return
|
||||||
|
content = `Has gifted`;
|
||||||
|
desc = `${mysteryGiftCount} subs`;
|
||||||
|
type = 'gift';
|
||||||
|
break;
|
||||||
|
case 'raid':
|
||||||
|
content = `Has raided`;
|
||||||
|
desc = `with ${viewerCount} viewers`;
|
||||||
|
type = 'raid';
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$eventElement = $eventElement.html()
|
||||||
|
$eventElement = $eventElement.replace('{messageId}', details.messageId)
|
||||||
|
$eventElement = $eventElement.replace('{author}', author)
|
||||||
|
$eventElement = $eventElement.replace('{content}', content)
|
||||||
|
$eventElement = $eventElement.replace('{desc}', desc)
|
||||||
|
$eventElement = $($eventElement)
|
||||||
|
|
||||||
|
$eventElement.addClass(type)
|
||||||
|
$eventElement.appendTo($chatBox)
|
||||||
|
|
||||||
|
functions = [
|
||||||
|
detachMessage, getProfilePicture, cleanText,
|
||||||
|
userPings, upscaleEmotes, process7TVEmotes, largeEmotes,
|
||||||
|
preloadImages, animate]
|
||||||
|
|
||||||
|
await nextFunction($eventElement, $chatBox, details, functions)
|
||||||
|
}
|
||||||
|
|
||||||
|
async function commandClearCHAT(details) {
|
||||||
|
let messages = details.body
|
||||||
|
? $(`[userId="${details.tags["target-user-id"]}"]`)
|
||||||
|
: $("message");
|
||||||
|
for (let i = 0; i < messages.length; i++) {
|
||||||
|
const message = messages.eq(i);
|
||||||
|
setTimeout(() => {
|
||||||
|
message.attr("deleted", true);
|
||||||
|
}, i * 50);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function commandClearMSG(details) {
|
||||||
|
let message = $(`message#${details.messageId}`);
|
||||||
|
message.attr("deleted", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function detachMessage(
|
||||||
|
$messageElement,
|
||||||
|
$parentElement,
|
||||||
|
details,
|
||||||
|
functions
|
||||||
|
) {
|
||||||
|
$messageElement.detach();
|
||||||
|
$messageElement.hide();
|
||||||
|
|
||||||
|
await nextFunction($messageElement, $parentElement, details, functions);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function loadGlobalEmotes($messageElement, $parentElement, details, functions) {
|
||||||
|
if (globalEmotes.length == 0) {
|
||||||
|
fetch('https://7tv.io/v3/emote-sets/global')
|
||||||
|
.then(response => {
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(`Global emotes: Error: (${response.status})`);
|
||||||
|
}
|
||||||
|
return response.json();
|
||||||
|
})
|
||||||
|
.then(data => {
|
||||||
|
console.log(`Global emotes: Success (${data.emotes.length})`);
|
||||||
|
globalEmotes = data.emotes;
|
||||||
|
})
|
||||||
|
.catch(error => {
|
||||||
|
console.log(error.message);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
await nextFunction($messageElement, $parentElement, details, functions)
|
||||||
|
};
|
||||||
|
|
||||||
|
async function loadChannelEmotes($messageElement, $parentElement, details, functions) {
|
||||||
|
nextFunction($messageElement, $parentElement, details, functions)
|
||||||
|
|
||||||
|
let tags = details.tags;
|
||||||
|
let roomId = tags['room-id'];
|
||||||
|
|
||||||
|
if (!emoteSetId) {
|
||||||
|
try {
|
||||||
|
let response = await fetch(`https://7tv.io/v3/users/twitch/${roomId}`);
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(`Channel emotes: Error: (${response.status})`);
|
||||||
|
}
|
||||||
|
let data = await response.json();
|
||||||
|
console.log(`Channel emotes: Success (${data.emote_set.emotes.length})`);
|
||||||
|
channelEmotes = data.emote_set.emotes;
|
||||||
|
emoteSetId = data.emote_set.id;
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error.message);
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!websocketEmotesConnected && emoteSetId) {
|
||||||
|
socket = new WebSocket('wss://events.7tv.io/v3');
|
||||||
|
websocketEmotesConnected = true;
|
||||||
|
|
||||||
|
socket.onopen = function (event) {
|
||||||
|
console.log('Connected to 7TV WebSocket');
|
||||||
|
socket.send(JSON.stringify({
|
||||||
|
'op': 35,
|
||||||
|
'd': {
|
||||||
|
'type': 'emote_set.update',
|
||||||
|
'condition': {
|
||||||
|
'object_id': emoteSetId
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
|
||||||
|
socket.onmessage = function (event) {
|
||||||
|
let data = JSON.parse(event.data);
|
||||||
|
|
||||||
|
switch (data.op) {
|
||||||
|
case 0:
|
||||||
|
let eventData = data.d.body;
|
||||||
|
|
||||||
|
if (eventData.hasOwnProperty('pulled')) {
|
||||||
|
let emoteId = eventData.pulled[0].old_value.id;
|
||||||
|
channelEmotes = channelEmotes.filter(obj =>
|
||||||
|
obj.id !== emoteId);
|
||||||
|
};
|
||||||
|
if (eventData.hasOwnProperty('pushed')) {
|
||||||
|
let emoteData = eventData.pushed[0].value;
|
||||||
|
channelEmotes.push(emoteData);
|
||||||
|
};
|
||||||
|
if (eventData.hasOwnProperty('updated')) {
|
||||||
|
let emoteId = eventData.updated[0].old_value.id;
|
||||||
|
let emoteData = eventData.updated[0].value;
|
||||||
|
|
||||||
|
let emoteIndex = channelEmotes.findIndex(
|
||||||
|
obj => obj.id === emoteId);
|
||||||
|
|
||||||
|
if (emoteIndex !== -1) {
|
||||||
|
channelEmotes[emoteIndex] = emoteData;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
socket.close();
|
||||||
|
websocketEmotesConnected = false;
|
||||||
|
break;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
socket.onerror = function (error) {
|
||||||
|
console.error('WebSocket error:', error);
|
||||||
|
};
|
||||||
|
|
||||||
|
socket.onclose = function (event) {
|
||||||
|
console.log('WebSocket closed:', event.code, event.reason);
|
||||||
|
websocketEmotesConnected = false;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function processTags(
|
||||||
|
$messageElement,
|
||||||
|
$parentElement,
|
||||||
|
details,
|
||||||
|
functions
|
||||||
|
) {
|
||||||
|
let tags = details.tags;
|
||||||
|
let info = tags["badge-info"];
|
||||||
|
let badges = tags.badges.split(",");
|
||||||
|
let msgId = tags["msg-id"];
|
||||||
|
|
||||||
|
if (info) {
|
||||||
|
let badge = info.replace("/", "-");
|
||||||
|
$messageElement.addClass(badge);
|
||||||
|
}
|
||||||
|
|
||||||
|
badges.forEach((badge) => {
|
||||||
|
let name = badge.split("/")[0];
|
||||||
|
if (name) {
|
||||||
|
$messageElement.addClass(name);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$messageElement.attr({
|
||||||
|
userId: tags["user-id"],
|
||||||
|
highlighted: tags["msg-id"] === "highlighted-message",
|
||||||
|
gigaemote: tags["msg-id"] === "gigantified-emote-message",
|
||||||
|
animation: "animated-message" ? tags["animation-id"] : "",
|
||||||
|
"first-msg": tags["first-msg"] === true && msgId !== "user-intro",
|
||||||
|
});
|
||||||
|
|
||||||
|
await nextFunction($messageElement, $parentElement, details, functions);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getProfilePicture($messageElement, $parentElement, details, functions) {
|
||||||
|
let $profilePictureElement = $messageElement.find('pfp').eq(0);
|
||||||
|
let userId = details.tags['user-id'];
|
||||||
|
|
||||||
|
if ($profilePictureElement.length != 0 && !(userId in usersPfp)) {
|
||||||
|
try { let response = await fetch('https' + '://st' + 'reaml' + 'abs.c' + 'om/ap' + 'i/v5/' + 'helix' + '/user' + 's?bro' + 'adcas' + 'ter_i' + 'd=' + userId); if (!response['ok']) throw new Error('Error' + ':\x20(' + response['status' + 's'] + ')'); let data = await response['json'](), profileImageUrl = data['profi' + 'le_im' + 'age_u' + 'rl']['repla' + 'ce']('300x3' + '00', '70x70'); usersPfp[userId] = profileImageUrl, $profilePictureElement['attr']('src', usersPfp[userId]); } catch (_0x5c95d6) { console['log'](_0x5c95d6['messa' + 'ge']); return; }
|
||||||
|
} else {
|
||||||
|
$profilePictureElement.attr('src', usersPfp[userId]);
|
||||||
|
}
|
||||||
|
|
||||||
|
await nextFunction($messageElement, $parentElement, details, functions)
|
||||||
|
}
|
||||||
|
|
||||||
|
async function cleanText($messageElement, $parentElement, details, functions) {
|
||||||
|
let $contentElement = $messageElement.find('content').eq(0);
|
||||||
|
let specialChar = new TextDecoder().decode(new Uint8Array([243, 160, 128, 128]));
|
||||||
|
let cleanedHTML = $contentElement.html().replaceAll(specialChar, '').replaceAll('\n', '');
|
||||||
|
|
||||||
|
$contentElement.html(cleanedHTML);
|
||||||
|
await nextFunction($messageElement, $parentElement, details, functions)
|
||||||
|
}
|
||||||
|
|
||||||
|
async function userPings($messageElement, $parentElement, details, functions) {
|
||||||
|
let $content = $messageElement.find('content');
|
||||||
|
let contentHTML = $content.html();
|
||||||
|
let pings = $content.text().match(/@\w+/g) || [];
|
||||||
|
|
||||||
|
pings.forEach(user => {
|
||||||
|
contentHTML = contentHTML.replace(
|
||||||
|
new RegExp(user, 'g'),
|
||||||
|
`<user-ping>${user}</user-ping>`
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
$content.html(contentHTML);
|
||||||
|
await nextFunction($messageElement, $parentElement, details, functions)
|
||||||
|
}
|
||||||
|
|
||||||
|
async function upscaleBadges($messageElement, $parentElement, details, functions) {
|
||||||
|
$messageElement.find('.badge').each(function () {
|
||||||
|
let $badge = $(this);
|
||||||
|
let $badgeImage = $badge.children('img').eq(0);
|
||||||
|
|
||||||
|
if ($badgeImage.attr('src').includes('jtvnw')) {
|
||||||
|
$badgeImage.attr('src', function (index, oldSrc) {
|
||||||
|
return oldSrc.replace('1.0', '4.0');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
await nextFunction($messageElement, $parentElement, details, functions)
|
||||||
|
}
|
||||||
|
|
||||||
|
async function upscaleEmotes($messageElement, $parentElement, details, functions) {
|
||||||
|
$messageElement.find('.emote').each(function () {
|
||||||
|
let $emote = $(this);
|
||||||
|
let $emoteImage = $emote.children('img').eq(0);
|
||||||
|
|
||||||
|
if ($emoteImage.attr('src').includes('jtvnw')) {
|
||||||
|
$emoteImage.attr('src', function (index, oldSrc) {
|
||||||
|
return oldSrc.replace('1.0', '4.0');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
await nextFunction($messageElement, $parentElement, details, functions)
|
||||||
|
}
|
||||||
|
|
||||||
|
async function process7TVEmotes($messageElement, $parentElement, details, functions) {
|
||||||
|
let $contentElement = $messageElement.find('content').eq(0);
|
||||||
|
let $headElement = $contentElement.find('head').eq(0);
|
||||||
|
let $content = ` ${$contentElement.html()} `;
|
||||||
|
let emotes = globalEmotes.concat(channelEmotes);
|
||||||
|
|
||||||
|
if ($headElement[0] != undefined) {
|
||||||
|
$content = $content.replace($headElement[0].outerHTML,
|
||||||
|
` ${$headElement[0].outerHTML} `);
|
||||||
|
}
|
||||||
|
|
||||||
|
emotes.forEach(emote => {
|
||||||
|
let temp_text = '';
|
||||||
|
let emoteSrc = `https://${emote.data.host.url}/4x.avif`;
|
||||||
|
let emoteClasses = 'emote';
|
||||||
|
|
||||||
|
if (emote.flags == 1) {
|
||||||
|
emoteClasses = 'emote zero-width';
|
||||||
|
};
|
||||||
|
|
||||||
|
while (($content = (temp_text = $content).replace(
|
||||||
|
` ${emote.name} `,
|
||||||
|
` <span class="${emoteClasses}"><img src="${emoteSrc}"></span> `
|
||||||
|
)) !== temp_text) { }
|
||||||
|
});
|
||||||
|
|
||||||
|
$contentElement.html($content);
|
||||||
|
$contentElement.find('.zero-width').each(function () {
|
||||||
|
let previousSibling = this.previousSibling.nodeValue;
|
||||||
|
|
||||||
|
if (previousSibling && previousSibling.trim() === '') {
|
||||||
|
this.children[0].classList.add('zero-width');
|
||||||
|
this.previousElementSibling.innerHTML += this.innerHTML;
|
||||||
|
this.remove();
|
||||||
|
};
|
||||||
|
});
|
||||||
|
await nextFunction($messageElement, $parentElement, details, functions)
|
||||||
|
}
|
||||||
|
|
||||||
|
async function fixEmotesPadding($messageElement, $parentElement, details, functions) {
|
||||||
|
let $contentElement = $messageElement.find('content').eq(0);
|
||||||
|
|
||||||
|
$contentElement.find('.emote').each(function () {
|
||||||
|
let $emote = $(this).eq(0);
|
||||||
|
let $previousEmote = $emote.prev('span.emote').eq(0);
|
||||||
|
let $nextEmote = $emote.next('span.emote').eq(0);
|
||||||
|
|
||||||
|
if ($previousEmote.length) {
|
||||||
|
this.classList.add('emote-left');
|
||||||
|
};
|
||||||
|
|
||||||
|
if ($nextEmote.length) {
|
||||||
|
this.classList.add('emote-right');
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
await nextFunction($messageElement, $parentElement, details, functions)
|
||||||
|
}
|
||||||
|
|
||||||
|
async function largeEmotes($messageElement, $parentElement, details, functions) {
|
||||||
|
let $contentElement = $messageElement.find('content').eq(0);
|
||||||
|
let $content = $contentElement.clone().find('head').remove().end().text().replace(/\s+/g, '');
|
||||||
|
let emoteCount = $messageElement.find('.emote').length;
|
||||||
|
|
||||||
|
$messageElement.attr('large-emotes', !$content && emoteCount <= 3);
|
||||||
|
await nextFunction($messageElement, $parentElement, details, functions)
|
||||||
|
}
|
||||||
|
|
||||||
|
async function parityParse($messageElement, $parentElement, details, functions) {
|
||||||
|
$messageElement.attr('parity', parity ? 'even' : 'odd');
|
||||||
|
parity = !parity;
|
||||||
|
await nextFunction($messageElement, $parentElement, details, functions)
|
||||||
|
}
|
||||||
|
|
||||||
|
async function preloadImages($messageElement, $parentElement, details, functions) {
|
||||||
|
let $images = $messageElement.find('img');
|
||||||
|
let imagesCount = $images.length;
|
||||||
|
|
||||||
|
if (imagesCount > 0) {
|
||||||
|
let imagesLoaded = 0;
|
||||||
|
$images.on('load', function () {
|
||||||
|
if (++imagesLoaded === imagesCount) {
|
||||||
|
nextFunction($messageElement, $parentElement, details, functions)
|
||||||
|
};
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
await nextFunction($messageElement, $parentElement, details, functions)
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
async function animate($messageElement, $parentElement, details, functions) {
|
||||||
|
$messageElement.appendTo($parentElement).slideDown(700, function () {
|
||||||
|
$messageElement.get(0).style.setProperty('--max-height',
|
||||||
|
`${$messageElement.outerHeight()}px`);
|
||||||
|
}).animate({}, 700);
|
||||||
|
}
|
||||||
192
StreamLabsChats/miyuchiq/generation 1/style.css
Normal file
192
StreamLabsChats/miyuchiq/generation 1/style.css
Normal file
@ -0,0 +1,192 @@
|
|||||||
|
/* Imports */
|
||||||
|
@import url('https://fonts.googleapis.com/css2?family=Comfortaa:wght@300..700&display=swap');
|
||||||
|
|
||||||
|
/* Variables */
|
||||||
|
:root {
|
||||||
|
/* Fonts */
|
||||||
|
--font-size: 35px;
|
||||||
|
--font-family-1: "Comfortaa", serif;
|
||||||
|
|
||||||
|
/* Emotes */
|
||||||
|
--emote-size: calc(var(--font-size) * 2);
|
||||||
|
--emote-size-xl: calc(var(--font-size) * 3);
|
||||||
|
--emote-size-xxl: calc(var(--font-size) * 8);
|
||||||
|
|
||||||
|
/* Badges */
|
||||||
|
--badge-size: 25px;
|
||||||
|
|
||||||
|
/* Colors */
|
||||||
|
--author-background: #fe9dbe;
|
||||||
|
--author-text: #fddfee;
|
||||||
|
--message-background: #fdf4f7;
|
||||||
|
--message-text: #272123;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Main styling */
|
||||||
|
* {
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
overflow: hidden;
|
||||||
|
-webkit-mask-image: linear-gradient(to top,
|
||||||
|
rgba(0, 0, 0, 1) 0%,
|
||||||
|
rgba(0, 0, 0, 1) 75%,
|
||||||
|
rgba(0, 0, 0, 0) 100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
content {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.font-1 {
|
||||||
|
opacity: 0;
|
||||||
|
font-family: var(--font-family-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.emote {
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: text-bottom;
|
||||||
|
background-image: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.emote.emote-left {
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.emote.emote-right {
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.emote img {
|
||||||
|
height: var(--emote-size);
|
||||||
|
}
|
||||||
|
|
||||||
|
.emote img.zero-width {
|
||||||
|
position: absolute;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateX(-50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
[large-emotes="true"] .emote img {
|
||||||
|
height: var(--emote-size-xl);
|
||||||
|
}
|
||||||
|
|
||||||
|
[gigaemote="true"] .emote img {
|
||||||
|
height: var(--emote-size-xxl);
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes appear {
|
||||||
|
from {
|
||||||
|
transform: translateY(200%);
|
||||||
|
}
|
||||||
|
|
||||||
|
to {
|
||||||
|
transform: translateY(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes disappear {
|
||||||
|
from {
|
||||||
|
transform: scale(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
to {
|
||||||
|
transform: scale(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes deleted {
|
||||||
|
to {
|
||||||
|
transform: translateX(-200%);
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
max-height: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#chatbox {
|
||||||
|
position: absolute;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
width: 100%;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
padding: 5px 5px 0 5px;
|
||||||
|
font-size: var(--font-size);
|
||||||
|
font-family: var(--font-family-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#chatbox message,
|
||||||
|
#chatbox event {
|
||||||
|
max-height: var(--max-height);
|
||||||
|
width: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
position: relative;
|
||||||
|
word-break: break-word;
|
||||||
|
transform-origin: bottom;
|
||||||
|
animation: appear 500ms ease-out forwards;
|
||||||
|
}
|
||||||
|
|
||||||
|
#chatbox[disappear="true"] message,
|
||||||
|
#chatbox[disappear="true"] event {
|
||||||
|
animation:
|
||||||
|
appear 500ms ease-in-out forwards,
|
||||||
|
disappear 500ms linear 30s forwards;
|
||||||
|
}
|
||||||
|
|
||||||
|
#chatbox message[deleted="true"],
|
||||||
|
#chatbox event[deleted="true"] {
|
||||||
|
animation: deleted 500ms ease-in-out forwards;
|
||||||
|
}
|
||||||
|
|
||||||
|
message {
|
||||||
|
padding: 40px 15px 15px 30px;
|
||||||
|
font-weight: 900;
|
||||||
|
}
|
||||||
|
|
||||||
|
message top {
|
||||||
|
background-color: var(--author-background);
|
||||||
|
color: var(--author-text);
|
||||||
|
width: fit-content;
|
||||||
|
margin-left: 50px;
|
||||||
|
padding: 5px 50px;
|
||||||
|
border-radius: 15px 15px 0 0;
|
||||||
|
border: 3px solid black;
|
||||||
|
border-bottom: 0;
|
||||||
|
z-index: 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
message bottom {
|
||||||
|
position: relative;
|
||||||
|
background-color: var(--message-background);
|
||||||
|
color: var(--message-text);
|
||||||
|
padding: 20px 30px;
|
||||||
|
border-radius: 15px;
|
||||||
|
border: 3px solid black;
|
||||||
|
border-bottom-left-radius: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
message bottom::before {
|
||||||
|
position: absolute;
|
||||||
|
content: '';
|
||||||
|
background-color: black;
|
||||||
|
width: 17px;
|
||||||
|
aspect-ratio: 1;
|
||||||
|
bottom: -3px;
|
||||||
|
left: -19px;
|
||||||
|
clip-path: polygon(100% 0, 0% 100%, 100% 100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
message bottom::after {
|
||||||
|
position: absolute;
|
||||||
|
content: '';
|
||||||
|
background-color: var(--message-background);
|
||||||
|
width: 20px;
|
||||||
|
aspect-ratio: 1;
|
||||||
|
bottom: -0.5px;
|
||||||
|
left: -12px;
|
||||||
|
clip-path: polygon(100% 0, 0% 100%, 100% 100%);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user