From 4b5444c2eeb2a548f529f6dab8fba6d2fc09f302 Mon Sep 17 00:00:00 2001 From: Rodrigo Emanuel Date: Sat, 17 May 2025 16:20:56 -0300 Subject: [PATCH] Add files via upload - Added newer events in new languages - Added a Background Color Picker - Added a Background Color Opacity Slider --- css/app.css | 4 +-- css/settings.css | 11 ++++++-- index.html | 17 +++++++++++- js/app.js | 17 ++++++++++++ js/lang/en.js | 2 +- js/lang/es.js | 63 +++++++++++++++++++++++++++++++++++++++++++++ js/lang/ptbr.js | 63 +++++++++++++++++++++++++++++++++++++++++++++ js/settings.js | 19 ++++++++++++++ js/twitch/module.js | 3 +++ 9 files changed, 192 insertions(+), 7 deletions(-) diff --git a/css/app.css b/css/app.css index a59ca14..aef478a 100644 --- a/css/app.css +++ b/css/app.css @@ -20,8 +20,6 @@ html { body { - background-color: #121212; - background-size: cover; overflow: hidden; } @@ -529,4 +527,4 @@ body { width: 18px; filter: drop-shadow(2px 2px 2px rgba(0,0,0,0.5)); } -} +} \ No newline at end of file diff --git a/css/settings.css b/css/settings.css index 89c82a6..8556a84 100644 --- a/css/settings.css +++ b/css/settings.css @@ -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; @@ -523,4 +530,4 @@ footer .nav-bar a.active svg { #memberemotesbstatus.offline i { color: #ff0000; text-shadow: 0 0 5px #ff0000; -} +} \ No newline at end of file diff --git a/index.html b/index.html index 9c787cf..1c77766 100644 --- a/index.html +++ b/index.html @@ -59,7 +59,22 @@ + + +
+ + +
+ +
+ +
diff --git a/js/app.js b/js/app.js index 5d86868..65ed598 100644 --- a/js/app.js +++ b/js/app.js @@ -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'); } @@ -349,4 +353,17 @@ async function cleanStringOfHTMLButEmotes(string) { 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})`; } \ No newline at end of file diff --git a/js/lang/en.js b/js/lang/en.js index a953491..458781e 100644 --- a/js/lang/en.js +++ b/js/lang/en.js @@ -107,7 +107,7 @@ const en = { kofi : { donation : ({ money, message }) => ` donated 馃獧 ${money}${message ? '
'+message : ''}`, sub : ({ money, tier, message }) => ` subscribed (${money}) ${tier ? '(Tier '+tier+')' : ''}${message ? '
'+message : ''}`, - resub : ({ money, tier, message }) => ` subscribed ${money} ${tier ? '(Tier '+tier+')' : ''}${message ? '
'+message : ''}`, + resub : ({ money, tier, message }) => ` resubscribed ${money} ${tier ? '(Tier '+tier+')' : ''}${message ? '
'+message : ''}`, order : ({ money, items }) => ` ordered ${items} ${items == 1 ? 'item' : 'items'} (${money == 0 ? 'Free' : money})`, }, diff --git a/js/lang/es.js b/js/lang/es.js index 5809c9a..6776096 100644 --- a/js/lang/es.js +++ b/js/lang/es.js @@ -87,4 +87,67 @@ const es = { raid : ({ viewers }) => ` hizo una raid al canal con ${viewers} espectadores` }, + + patreon: { + membership: ({ money }) => ` apoy贸 con una membres铆a ($${money})` + + }, + + tipeeestream : { + tip : ({ money, message }) => ` don贸 馃獧 ${money}${message ? '
'+message : ''}`, + }, + + kofi : { + donation : ({ money, message }) => ` don贸 馃獧 ${money}${message ? '
'+message : ''}`, + sub : ({ money, tier, message }) => ` se suscribi贸 (${money}) ${tier ? '(Tier '+tier+')' : ''}${message ? '
'+message : ''}`, + resub : ({ money, tier, message }) => ` renov贸 la suscripci贸n ${money} ${tier ? '(Tier '+tier+')' : ''}${message ? '
'+message : ''}`, + order : ({ money, items }) => ` compr贸 ${items} ${items == 1 ? 'art铆culo' : 'art铆culos'} (${money == 0 ? 'Gratis' : money})`, + }, + + fourthwall : { + someone : () => `Algu茅m`, + + donation : ({ money, message }) => ` don贸 馃獧 ${money}${message ? '
'+message : ''}`, + sub : ({ money }) => ` se suscribi贸 (${money})`, + + order : ({ + money, + firstItem, + items, + message, + image, + + }) => ` + ${image ? '
': ''} + compr贸 ${firstItem} ${items > 1 ? 'y '+(items - 1)+' '+((items - 1) == 1 ? 'art铆culo' : 'art铆culos')+'' : ''} + (${money == 0 ? 'Gratis' : money}) + ${message.trim() ? '
'+message : ''} + ${image ? '': ''} + `, + + gift : ({ + money, + firstItem, + items, + message, + image, + + }) => ` + ${image ? '
': ''} + regal贸 ${items}x ${firstItem} + (${money == 0 ? 'Gratis' : money}) + ${message.trim() ? '
'+message : ''} + ${image ? '': ''} + `, + + + + drawstart : ({ gift, command, time }) => ` + 隆Sorteo iniciado! +
Escribe ${command} para tener la oportunidad de ganar ${gift}. 隆Tienes ${time} segundos!`, + + drawend : ({ winners }) => ` + 馃帀 隆Sorteo finalizado! +
Felicitaciones ${winners}`, + }, } diff --git a/js/lang/ptbr.js b/js/lang/ptbr.js index 1aaa06d..d59357b 100644 --- a/js/lang/ptbr.js +++ b/js/lang/ptbr.js @@ -94,4 +94,67 @@ const ptbr = { raid : ({ viewers }) => ` raidou o canal com ${viewers} pessoas` }, + + patreon: { + membership: ({ money }) => ` apoiou com uma assinatura ($${money})` + + }, + + tipeeestream : { + tip : ({ money, message }) => ` doou 馃獧 ${money}${message ? '
'+message : ''}`, + }, + + kofi : { + donation : ({ money, message }) => ` doou 馃獧 ${money}${message ? '
'+message : ''}`, + sub : ({ money, tier, message }) => ` se inscreveu (${money}) ${tier ? '(Tier '+tier+')' : ''}${message ? '
'+message : ''}`, + resub : ({ money, tier, message }) => ` se reninscreveu ${money} ${tier ? '(Tier '+tier+')' : ''}${message ? '
'+message : ''}`, + order : ({ money, items }) => ` comprou ${items} ${items == 1 ? 'item' : 'itens'} (${money == 0 ? 'Gr谩tis' : money})`, + }, + + fourthwall : { + someone : () => `Algu茅m`, + + donation : ({ money, message }) => ` doou 馃獧 ${money}${message ? '
'+message : ''}`, + sub : ({ money }) => ` se inscreveu (${money})`, + + order : ({ + money, + firstItem, + items, + message, + image, + + }) => ` + ${image ? '
': ''} + comprou ${firstItem} ${items > 1 ? 'e '+(items - 1)+' '+((items - 1) == 1 ? 'item' : 'items')+'' : ''} + (${money == 0 ? 'Gr谩tis' : money}) + ${message.trim() ? '
'+message : ''} + ${image ? '': ''} + `, + + gift : ({ + money, + firstItem, + items, + message, + image, + + }) => ` + ${image ? '
': ''} + presenteou ${items}x ${firstItem} + (${money == 0 ? 'Gr谩tis' : money}) + ${message.trim() ? '
'+message : ''} + ${image ? '': ''} + `, + + + + drawstart : ({ gift, command, time }) => ` + Sorteio iniciado! +
Digite ${command} para concorrer a ${gift}. Voc锚 tem ${time} segundos!`, + + drawend : ({ winners }) => ` + 馃帀 Sorteio Encerrado! +
Parab茅ns ${winners}`, + }, } \ No newline at end of file diff --git a/js/settings.js b/js/settings.js index 8f3b061..8798bb3 100644 --- a/js/settings.js +++ b/js/settings.js @@ -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); }); diff --git a/js/twitch/module.js b/js/twitch/module.js index 4bcaa91..21a946f 100644 --- a/js/twitch/module.js +++ b/js/twitch/module.js @@ -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; }