Add files via upload

- Added the ability to add a scroll bar.
- Fixed a bug on rendering emotes on resub messages
- Fixed a bug on how likes would not display correctly
- Fixed inner margin between messages and events
This commit is contained in:
Rodrigo Emanuel
2025-05-21 14:49:23 -03:00
committed by GitHub
parent 12db7b715e
commit e208759fea
8 changed files with 87 additions and 30 deletions

View File

@@ -45,10 +45,11 @@
<div class="wrapper">
<div id="chat">
<div id="container">
<div class="wrapper">
<div id="chat">
</div>
</div>
</div>

View File

@@ -20,22 +20,44 @@ html {
body {
height: 100%;
overflow: hidden;
}
.wrapper {
position: absolute;
width: 100%;
#container {
height: 100%;
display: flex;
flex-direction: column;
}
.wrapper {
flex: 1;
display: flex;
flex-direction: column;
overflow: hidden;
}
#chat {
flex: 1;
display: flex;
flex-direction: column-reverse; /* conteúdo começa no fundo */
overflow-y: auto;
padding: 10px;
scrollbar-color: #555 #1e1e1e;
}
#chat {
position: absolute;
width: 100%;
bottom: 0px;
padding: 10px;
#chat.noscrollbar {
overflow-y: hidden;
}
#chat::-webkit-scrollbar { width: 8px; }
#chat::-webkit-scrollbar-track { background: #1e1e1e; }
#chat::-webkit-scrollbar-thumb { background-color: #555; border-radius: 4px; border: 2px solid #1e1e1e; }
#chat::-webkit-scrollbar-thumb:hover { background-color: #777; }
#chat .message {
color: #FFF;
font-size: 18px;
@@ -134,7 +156,7 @@ body {
display: block;
text-shadow: none;
font-size: 14px;
margin: 2px 0 -5px 0;
margin: 10px 0 -5px 0;
color: #999;
}
@@ -163,7 +185,9 @@ body {
align-items: flex-start;
}
#chat .message:not(.event) > div {
margin-top: -10px;
}
#chat .message.twitch .shared span {

View File

@@ -63,6 +63,8 @@
</label>
</div>
<div class="setting"><label>Scroll Bar<br><small>Adds a scrollbar. Perfect if you using ChatRD as a chat reader instead of an overlay.</small></label></label><label class="switch"><input type="checkbox" name="chatScrollBar"><span class="slider"></span></label></div>
<div class="setting">
<label>Background Color<br><small>Changes ChatRD's background color</small></label>
<label>

View File

@@ -200,6 +200,7 @@ function generateMockEvent() {
'twitch-chat', 'twitch-chat', 'twitch-chat', 'twitch-chat', 'twitch-chat',
'twitch-follow', 'twitch-bits', 'twitch-sub', 'twitch-resub',
'twitch-giftsub', 'twitch-giftbomb', 'twitch-raid',
'twitch-announcement', 'twitch-reward', 'twitch-gigantifyemote',

View File

@@ -15,6 +15,7 @@ const chatContainer = document.querySelector('#chat');
const chatFontSize = getURLParam("chatFontSize", 1);
const chatBackground = getURLParam("chatBackground", "#121212");
const chatBackgroundOpacity = getURLParam("chatBackgroundOpacity", 1);
const chatScrollBar = getURLParam("chatScrollBar", false);
const currentLang = lang[getURLParam("language", 'ptbr')];
const eventsMockup = getURLParam("eventsMockup", true);
@@ -34,6 +35,7 @@ const userColors = new Map();
const ignoreUserList = ignoreChatters.split(',').map(item => item.trim().toLowerCase()) || [];
chatContainer.style.zoom = chatFontSize;
if (chatScrollBar == false) { chatContainer.classList.add('noscrollbar'); }
/* ----------------------- */
/* START */
@@ -110,7 +112,7 @@ async function addMessageToChat(userID, messageID, platform, data) {
</div>
`);
chatContainer.insertAdjacentHTML('beforeend', html);
chatContainer.insertAdjacentHTML('afterbegin', html);
const messageElement = document.getElementById(messageID);
@@ -148,7 +150,7 @@ async function addEventToChat(userID, messageID, platform, data) {
</div>
`);
chatContainer.insertAdjacentHTML('beforeend', html);
chatContainer.insertAdjacentHTML('afterbegin', html);
const messageElement = document.getElementById(messageID);
@@ -178,15 +180,20 @@ const whatTimeIsIt = () => {
function removeExtraChatMessages() {
const chatMessages = chatContainer.querySelectorAll('div.message').length;
if (chatMessages >= chatThreshhold) {
for (let i = 0; i < Math.floor(chatThreshhold/2); i++) {
chatContainer.removeChild(chatContainer.firstElementChild);
const chatMessages = chatContainer.querySelectorAll('div.message');
const total = chatMessages.length;
if (total >= chatThreshhold) {
const toRemove = Math.floor(total * 0.25); // 25% do total
for (let i = 0; i < toRemove; i++) {
const last = chatContainer.lastElementChild;
if (last) chatContainer.removeChild(last);
}
}
}
// Function to format large numbers (e.g., 1000 => '1K')
function formatNumber(num) {
if (num >= 1000000) {

View File

@@ -148,7 +148,6 @@ async function tiktokLikesMessage(data) {
if (showTikTokLikes == false) return;
const {
userId: userID,
msgId: messageID,
@@ -281,4 +280,4 @@ async function tiktokUpdateStatistics(data, type) {
}
}
}

View File

@@ -263,7 +263,7 @@ async function twitchAnnouncementMessage(data) {
data.message = {
message: await getTwitchAnnouncementEmotes(data)
message: await getTwitchEmotesOnParts(data)
};
@@ -366,6 +366,7 @@ async function twitchReSubMessage(data) {
} = data;
const messageID = createRandomString(40);
const messagetext = await getTwitchEmotesOnParts(data);
const [avatar, message] = await Promise.all([
'',
@@ -373,7 +374,7 @@ async function twitchReSubMessage(data) {
months : data.cumulativeMonths,
isPrime : data.isPrime,
tier : data.subTier,
message : text
message : messagetext
})
]);
@@ -452,7 +453,11 @@ async function twitchGiftSubsMessage(data) {
const [avatar, message] = await Promise.all([
'',
currentLang.twitch.giftedbomb({ count : data.total, tier : data.sub_tier, total : data.cumulative_total })
currentLang.twitch.giftedbomb({
count : data.total,
tier : data.sub_tier,
total : data.cumulative_total
})
]);
const classes = 'sub';
@@ -542,7 +547,7 @@ async function getTwitchEmotes(data) {
}
async function getTwitchAnnouncementEmotes(data) {
/*async function getTwitchAnnouncementEmotes(data) {
const message = data.text;
const emotes = data.parts;
const words = message.split(" ");
@@ -555,8 +560,23 @@ async function getTwitchAnnouncementEmotes(data) {
});
}
return words.join(" ");
}
}*/
async function getTwitchEmotesOnParts(data) {
const parts = data?.parts;
if (!Array.isArray(parts)) {
return data.text;
}
return parts.map(part => {
if (part.type === 'text') {
return part.text;
} else if (part.type === 'emote') {
return `<img src="${part.imageUrl}" alt="${part.text}" class="emote">`;
}
}).join('');
}
async function getTwitchBadges(data) {
const badges = data.message.badges;

View File

@@ -140,12 +140,13 @@ async function youTubeSuperChatMessage(data) {
} = data;
var money = amount;
var messagewithemotes = await getYouTubeEmotes(textmessage);
const [avatar, message] = await Promise.all([
``,
currentLang.youtube.superchat({
money : money,
message : textmessage
message : messagewithemotes
})
]);
@@ -223,12 +224,14 @@ async function youTubeNewSponsorMessage(data) {
message: messagetext,
} = data;
var messagewithemotes = await getYouTubeEmotes(messagetext);
const [avatar, message] = await Promise.all([
``,
currentLang.youtube.member({
months : months,
tier : levelName,
message: messagetext
message: messagewithemotes
})
]);
@@ -357,7 +360,7 @@ async function getYouTubeEmotes(data) {
emoteMap.set(emote.code, { html: emoteElement, raw: emote.code });
}
// YouTube emotes (ex: :vortisLaugh:)
// YouTube emotes (ex: :hand-pink-waving:)
if (data.emotes) {
for (const emote of data.emotes) {
const emoteElement = `<img src="${emote.imageUrl}" class="emote" alt="${emote.name}">`;