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:
@@ -45,10 +45,11 @@
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="wrapper">
|
||||
<div id="chat">
|
||||
|
||||
<div id="container">
|
||||
<div class="wrapper">
|
||||
<div id="chat">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
44
css/app.css
44
css/app.css
@@ -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 {
|
||||
|
@@ -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>
|
||||
|
@@ -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',
|
||||
|
||||
|
19
js/app.js
19
js/app.js
@@ -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) {
|
||||
|
@@ -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) {
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
@@ -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;
|
||||
|
@@ -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}">`;
|
||||
|
Reference in New Issue
Block a user