Add files via upload

- Added newer events in new languages
- Added a Background Color Picker
- Added a Background Color Opacity Slider
This commit is contained in:
Rodrigo Emanuel
2025-05-17 16:20:56 -03:00
committed by GitHub
parent 3f2ddde6ee
commit 4b5444c2ee
9 changed files with 192 additions and 7 deletions

View File

@@ -20,8 +20,6 @@ html {
body {
background-color: #121212;
background-size: cover;
overflow: hidden;
}

View File

@@ -272,6 +272,13 @@ a { color: #ffcc00; }
transition: .4s;
}
.tab-content .setting input[type=color] {
background: #111;
padding: 0 2px;
}
.tab-content .setting input[type=checkbox]:checked + .slider {
background-color: #03c4de;
}
@@ -321,7 +328,7 @@ a { color: #ffcc00; }
#font-value {
.slider-value {
display: inline-block;
font-style: normal;
font-size: 14px;

View File

@@ -59,7 +59,22 @@
<label>Chat Font Size<br><small>Changes ChatRD's font size</small></label>
<label>
<input type="range" id="font-slider" name="chatFontSize" min="0.1" max="2" step="0.1" value="1">
<br><em id="font-value">100%</em>
<br><em id="font-value" class="slider-value">100%</em>
</label>
</div>
<div class="setting">
<label>Background Color<br><small>Changes ChatRD's background color</small></label>
<label>
<input type="color" name="chatBackground" value="#121212">
</label>
</div>
<div class="setting slider">
<label><i class="fa-solid fa-arrow-turn-up"></i> Background Opacity<br><small>Changes ChatRD's background color opacity</small></label>
<label>
<input type="range" id="bg-opacity-slider" name="chatBackgroundOpacity" min="0.0" max="1" step="0.1" value="1">
<br><em id="bg-opacity-value" class="slider-value">1</em>
</label>
</div>

View File

@@ -13,6 +13,8 @@ const chatThreshhold = 50;
const chatContainer = document.querySelector('#chat');
const chatFontSize = getURLParam("chatFontSize", 1);
const chatBackground = getURLParam("chatBackground", "#121212");
const chatBackgroundOpacity = getURLParam("chatBackgroundOpacity", 1);
const currentLang = lang[getURLParam("language", 'ptbr')];
const eventsMockup = getURLParam("eventsMockup", true);
@@ -37,6 +39,8 @@ chatContainer.style.zoom = chatFontSize;
/* START */
/* ----------------------- */
document.body.style.backgroundColor = hexToRGBA(chatBackground,chatBackgroundOpacity);
if (showPlatformStatistics == false) { document.querySelector('#statistics').style.display = 'none'; }
if (chatHorizontal == true) { chatContainer.classList.add('horizontal'); }
@@ -350,3 +354,16 @@ function stripStringFromHtml(html) {
let doc = new DOMParser().parseFromString(html, 'text/html');
return doc.body.textContent || "";
}
function hexToRGBA(hexadecimal,opacity) {
const hex = hexadecimal;
const alpha = parseFloat(opacity);
// Converter hex para RGB
const r = parseInt(hex.substr(1, 2), 16);
const g = parseInt(hex.substr(3, 2), 16);
const b = parseInt(hex.substr(5, 2), 16);
return `rgba(${r}, ${g}, ${b}, ${alpha})`;
}

View File

@@ -107,7 +107,7 @@ const en = {
kofi : {
donation : ({ money, message }) => ` donated 🪙 <strong>${money}</strong>${message ? '<br>'+message : ''}`,
sub : ({ money, tier, message }) => ` subscribed <strong>(${money}) ${tier ? '(Tier '+tier+')' : ''}</strong>${message ? '<br>'+message : ''}`,
resub : ({ money, tier, message }) => ` subscribed <strong>${money} ${tier ? '(Tier '+tier+')' : ''}</strong>${message ? '<br>'+message : ''}`,
resub : ({ money, tier, message }) => ` resubscribed <strong>${money} ${tier ? '(Tier '+tier+')' : ''}</strong>${message ? '<br>'+message : ''}`,
order : ({ money, items }) => ` ordered <strong>${items} ${items == 1 ? 'item' : 'items'} (${money == 0 ? 'Free' : money})`,
},

View File

@@ -87,4 +87,67 @@ const es = {
raid : ({ viewers }) => ` hizo una raid al canal con <i class="fa-solid fa-users"></i> <strong>${viewers} espectadores</strong>`
},
patreon: {
membership: ({ money }) => ` apoyó con una membresía ($${money})`
},
tipeeestream : {
tip : ({ money, message }) => ` donó 🪙 <strong>${money}</strong>${message ? '<br>'+message : ''}`,
},
kofi : {
donation : ({ money, message }) => ` donó 🪙 <strong>${money}</strong>${message ? '<br>'+message : ''}`,
sub : ({ money, tier, message }) => ` se suscribió <strong>(${money}) ${tier ? '(Tier '+tier+')' : ''}</strong>${message ? '<br>'+message : ''}`,
resub : ({ money, tier, message }) => ` renovó la suscripción <strong>${money} ${tier ? '(Tier '+tier+')' : ''}</strong>${message ? '<br>'+message : ''}`,
order : ({ money, items }) => ` compró <strong>${items} ${items == 1 ? 'artículo' : 'artículos'} (${money == 0 ? 'Gratis' : money})`,
},
fourthwall : {
someone : () => `Alguém`,
donation : ({ money, message }) => ` donó 🪙 <strong>${money}</strong>${message ? '<br>'+message : ''}`,
sub : ({ money }) => ` se suscribió <strong>(${money})</strong>`,
order : ({
money,
firstItem,
items,
message,
image,
}) => `
${image ? '<br>': ''}
compró <strong>${firstItem}</strong> ${items > 1 ? 'y <strong>'+(items - 1)+' '+((items - 1) == 1 ? 'artículo' : 'artículos')+'</strong>' : ''}
(${money == 0 ? 'Gratis' : money})
${message.trim() ? '<br>'+message : ''}
${image ? '</span></span><span class="image"><img src="'+image+'"></span>': ''}
`,
gift : ({
money,
firstItem,
items,
message,
image,
}) => `
${image ? '<br>': ''}
regaló <strong>${items}x ${firstItem}</strong>
(${money == 0 ? 'Gratis' : money})
${message.trim() ? '<br>'+message : ''}
${image ? '</span></span><span class="image"><img src="'+image+'"></span>': ''}
`,
drawstart : ({ gift, command, time }) => `
<strong><i class="fa-solid fa-gift"></i> ¡Sorteo iniciado!</strong>
<br>Escribe <strong>${command}</strong> para tener la oportunidad de ganar <strong>${gift}</strong>. ¡Tienes <strong>${time} segundos</strong>!`,
drawend : ({ winners }) => `
<strong>🎉 ¡Sorteo finalizado!</strong>
<br>Felicitaciones <strong>${winners}</strong>`,
},
}

View File

@@ -94,4 +94,67 @@ const ptbr = {
raid : ({ viewers }) => ` raidou o canal com <i class="fa-solid fa-users"></i> <strong>${viewers} pessoas</strong>`
},
patreon: {
membership: ({ money }) => ` apoiou com uma assinatura ($${money})`
},
tipeeestream : {
tip : ({ money, message }) => ` doou 🪙 <strong>${money}</strong>${message ? '<br>'+message : ''}`,
},
kofi : {
donation : ({ money, message }) => ` doou 🪙 <strong>${money}</strong>${message ? '<br>'+message : ''}`,
sub : ({ money, tier, message }) => ` se inscreveu <strong>(${money}) ${tier ? '(Tier '+tier+')' : ''}</strong>${message ? '<br>'+message : ''}`,
resub : ({ money, tier, message }) => ` se reninscreveu <strong>${money} ${tier ? '(Tier '+tier+')' : ''}</strong>${message ? '<br>'+message : ''}`,
order : ({ money, items }) => ` comprou <strong>${items} ${items == 1 ? 'item' : 'itens'} (${money == 0 ? 'Grátis' : money})`,
},
fourthwall : {
someone : () => `Alguém`,
donation : ({ money, message }) => ` doou 🪙 <strong>${money}</strong>${message ? '<br>'+message : ''}`,
sub : ({ money }) => ` se inscreveu <strong>(${money})</strong>`,
order : ({
money,
firstItem,
items,
message,
image,
}) => `
${image ? '<br>': ''}
comprou <strong>${firstItem}</strong> ${items > 1 ? 'e <strong>'+(items - 1)+' '+((items - 1) == 1 ? 'item' : 'items')+'</strong>' : ''}
(${money == 0 ? 'Grátis' : money})
${message.trim() ? '<br>'+message : ''}
${image ? '</span></span><span class="image"><img src="'+image+'"></span>': ''}
`,
gift : ({
money,
firstItem,
items,
message,
image,
}) => `
${image ? '<br>': ''}
presenteou <strong>${items}x ${firstItem}</strong>
(${money == 0 ? 'Grátis' : money})
${message.trim() ? '<br>'+message : ''}
${image ? '</span></span><span class="image"><img src="'+image+'"></span>': ''}
`,
drawstart : ({ gift, command, time }) => `
<strong><i class="fa-solid fa-gift"></i> Sorteio iniciado!</strong>
<br>Digite <strong>${command}</strong> para concorrer a <strong>${gift}</strong>. Você tem <strong>${time} segundos!</strong>`,
drawend : ({ winners }) => `
<strong>🎉 Sorteio Encerrado!</strong>
<br>Parabéns <strong>${winners}</strong>`,
},
}

View File

@@ -5,6 +5,7 @@ async function saveSettingsToLocalStorage() {
const checkboxes = document.querySelectorAll("input[type=checkbox]:not(.avoid)");
const textfields = document.querySelectorAll("input[type=text]:not(.avoid)");
const numberfields = document.querySelectorAll("input[type=number]:not(.avoid)");
const colorfields = document.querySelectorAll("input[type=color]:not(.avoid)");
const selects = document.querySelectorAll("select:not(.avoid)");
const hiddenField = document.querySelector("textarea[name=youTubeCustomEmotes]:not(.avoid)");
@@ -25,6 +26,9 @@ async function saveSettingsToLocalStorage() {
numberfields.forEach((numberfield) => {
settings[numberfield.name] = numberfield.value;
});
colorfields.forEach((colorfield) => {
settings[colorfield.name] = colorfield.value;
});
selects.forEach((select) => {
settings[select.name] = select.value;
});
@@ -109,6 +113,7 @@ async function pushChangeEvents() {
const checkboxes = document.querySelectorAll("input[type=checkbox]:not(.avoid)");
const textfields = document.querySelectorAll("input[type=text]:not(.avoid)");
const numberfields = document.querySelectorAll("input[type=number]:not(.avoid)");
const colorfields = document.querySelectorAll("input[type=color]:not(.avoid)");
const selects = document.querySelectorAll("select:not(.avoid)");
const ranges = document.querySelectorAll("input[type=range]:not(.avoid)");
@@ -131,6 +136,12 @@ async function pushChangeEvents() {
saveSettingsToLocalStorage();
});
});
colorfields.forEach((colorfield) => {
colorfield.addEventListener('change', () => {
generateUrl();
saveSettingsToLocalStorage();
});
});
selects.forEach((select) => {
select.addEventListener('change', () => {
generateUrl();
@@ -154,6 +165,10 @@ async function pushChangeEvents() {
document.querySelector('#font-slider').addEventListener('input', function () {
document.querySelector('#font-value').textContent = Math.floor(this.value * 100) + '%';
});
document.querySelector('#bg-opacity-slider').addEventListener('input', function () {
document.querySelector('#bg-opacity-value').textContent = this.value;
});
}
@@ -166,6 +181,7 @@ async function generateUrl() {
const checkboxes = document.querySelectorAll("input[type=checkbox]:not(.avoid)");
const textfields = document.querySelectorAll("input[type=text]:not(.avoid)");
const numberfields = document.querySelectorAll("input[type=number]:not(.avoid)");
const colorfields = document.querySelectorAll("input[type=color]:not(.avoid)");
const selects = document.querySelectorAll("select:not(.avoid)");
const ranges = document.querySelectorAll("input[type=range]:not(.avoid)");
@@ -181,6 +197,9 @@ async function generateUrl() {
checkboxes.forEach((checkbox) => {
params.set(checkbox.name, checkbox.checked);
});
colorfields.forEach((colorfield) => {
params.set(colorfield.name, colorfield.value);
});
textfields.forEach((textfield) => {
params.set(textfield.name, textfield.value);
});

View File

@@ -578,6 +578,9 @@ async function getTwitchAvatar(user) {
console.debug(`Twitch avatar not found for ${user}! Getting it from DECAPI!`);
var decapi = await fetch('https://decapi.me/twitch/avatar/' + user);
var newavatar = await decapi.text()
if (!newavatar) { newavatar = 'https://static-cdn.jtvnw.net/user-default-pictures-uv/cdd517fe-def4-11e9-948e-784f43822e80-profile_image-300x300.png'; }
avatars.set(user, newavatar);
return newavatar;
}