From 64c043feb56b789d20a3854882271adf04421822 Mon Sep 17 00:00:00 2001 From: Mow910 Date: Fri, 6 Mar 2026 23:59:04 +0100 Subject: [PATCH] =?UTF-8?q?Ajout=20de=20fonctionnalit=C3=A9s=20de=20mentio?= =?UTF-8?q?n=20dans=20la=20shoutbox=20pour=20les=20mod=C3=A9rateurs=20Twit?= =?UTF-8?q?ch.=20Impl=C3=A9mentation=20de=20la=20gestion=20des=20mentions?= =?UTF-8?q?=20d'utilisateurs=20avec=20un=20syst=C3=A8me=20de=20mise=20en?= =?UTF-8?q?=20surbrillance=20pour=20les=20messages=20contenant=20des=20men?= =?UTF-8?q?tions.=20Mise=20=C3=A0=20jour=20de=20l'interface=20utilisateur?= =?UTF-8?q?=20pour=20permettre=20aux=20mod=C3=A9rateurs=20de=20mentionner?= =?UTF-8?q?=20facilement=20d'autres=20utilisateurs=20et=20d'am=C3=A9liorer?= =?UTF-8?q?=20l'interaction=20dans=20la=20shoutbox.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- webapp/templates/shoutbox-popout.html | 29 +++++++++++++++++++--- webapp/templates/twitch-moderation.html | 33 +++++++++++++++++++++---- 2 files changed, 54 insertions(+), 8 deletions(-) diff --git a/webapp/templates/shoutbox-popout.html b/webapp/templates/shoutbox-popout.html index 17d2922..9ec0952 100644 --- a/webapp/templates/shoutbox-popout.html +++ b/webapp/templates/shoutbox-popout.html @@ -85,6 +85,8 @@ function userColor(name) { return colorMap[name]; } +var currentUser = '{{ current_user.username }}'; + function esc(t) { var d = document.createElement('div'); d.textContent = t; return d.innerHTML; } function fmtTime(iso) { @@ -92,6 +94,22 @@ function fmtTime(iso) { return d.getHours().toString().padStart(2,'0') + ':' + d.getMinutes().toString().padStart(2,'0'); } +function mentionUser(username) { + var input = document.getElementById('shoutboxInput'); + var val = input.value; + var mention = '@' + username + ' '; + if (val && !val.endsWith(' ')) mention = ' ' + mention; + input.value = val + mention; + input.focus(); +} + +function renderText(text) { + var escaped = esc(text); + var mentioned = currentUser && text.toLowerCase().indexOf('@' + currentUser.toLowerCase()) >= 0; + escaped = escaped.replace(/@(\w+)/g, '@$1'); + return { html: escaped, mentioned: mentioned }; +} + function addItem(item) { if (knownIds.has(item.id)) return; knownIds.add(item.id); @@ -100,12 +118,16 @@ function addItem(item) { if (ph) ph.remove(); var line = document.createElement('div'); - line.className = 'py-0.5 leading-relaxed'; + line.className = 'py-0.5 leading-relaxed rounded px-1'; var time = '[' + fmtTime(item.created_at) + '] '; if (item.type === 'message') { var c = userColor(item.author); - line.innerHTML = time + '<' + esc(item.author) + '> ' + esc(item.text) + ''; + var rendered = renderText(item.text); + line.innerHTML = time + '<' + esc(item.author) + '> ' + rendered.html + ''; + if (rendered.mentioned) { + line.className += ' bg-red-900/40 font-bold'; + } } else { var au = (item.action || '').toUpperCase(); var sc = 'text-red-400'; @@ -135,7 +157,8 @@ function updateOnline(users) { list.innerHTML = ''; users.forEach(function(u) { var el = document.createElement('div'); - el.className = 'flex items-center gap-1.5 text-xs text-gray-300'; + el.className = 'flex items-center gap-1.5 text-xs text-gray-300 cursor-pointer hover:text-white'; + el.onclick = function() { mentionUser(u); }; el.innerHTML = '' + esc(u); list.appendChild(el); }); diff --git a/webapp/templates/twitch-moderation.html b/webapp/templates/twitch-moderation.html index 0644b9b..24ec397 100644 --- a/webapp/templates/twitch-moderation.html +++ b/webapp/templates/twitch-moderation.html @@ -979,6 +979,7 @@ document.addEventListener('keydown', function(e) { // ============================= // Shoutbox modérateurs (IRC) // ============================= +var shoutboxCurrentUser = '{{ current_user.username }}'; var shoutboxKnownIds = new Set(); var shoutboxLastTimestamp = ''; var shoutboxAutoScroll = true; @@ -1025,6 +1026,23 @@ function shoutboxTime(isoStr) { return d.getHours().toString().padStart(2, '0') + ':' + d.getMinutes().toString().padStart(2, '0'); } +function shoutboxMention(username) { + var input = document.getElementById('shoutboxInput'); + var val = input.value; + var mention = '@' + username + ' '; + if (val && !val.endsWith(' ')) mention = ' ' + mention; + input.value = val + mention; + input.focus(); +} + +function shoutboxRenderText(text) { + var escaped = escapeHtml(text); + var isMentioned = shoutboxCurrentUser && text.toLowerCase().indexOf('@' + shoutboxCurrentUser.toLowerCase()) >= 0; + escaped = escaped.replace(/@(\w+)/g, '@$1'); + if (isMentioned) return { html: escaped, mentioned: true }; + return { html: escaped, mentioned: false }; +} + function addShoutboxItem(item) { if (shoutboxKnownIds.has(item.id)) return; shoutboxKnownIds.add(item.id); @@ -1034,15 +1052,19 @@ function addShoutboxItem(item) { if (ph) ph.remove(); var line = document.createElement('div'); - line.className = 'py-0.5 leading-relaxed'; + line.className = 'py-0.5 leading-relaxed rounded px-1'; var time = '[' + shoutboxTime(item.created_at) + '] '; if (item.type === 'message') { var color = shoutboxColor(item.author); + var rendered = shoutboxRenderText(item.text); line.innerHTML = time + - '<' + escapeHtml(item.author) + '> ' + - '' + escapeHtml(item.text) + ''; + '<' + escapeHtml(item.author) + '> ' + + '' + rendered.html + ''; + if (rendered.mentioned) { + line.className += ' bg-red-900/40 font-bold'; + } } else { var actionUpper = (item.action || '').toUpperCase(); var sanctionColor = 'text-red-400'; @@ -1052,7 +1074,7 @@ function addShoutboxItem(item) { var text = '*** ' + actionUpper; if (item.moderator) text += ' par ' + item.moderator; - if (item.target) text += ' → ' + item.target; + if (item.target) text += ' \u2192 ' + item.target; if (item.details && item.details !== '-') text += ' (' + item.details + ')'; text += ' ***'; @@ -1077,7 +1099,8 @@ function updateOnlineList(users) { list.innerHTML = ''; users.forEach(function(u) { var el = document.createElement('div'); - el.className = 'flex items-center gap-1.5 text-xs text-gray-300'; + el.className = 'flex items-center gap-1.5 text-xs text-gray-300 cursor-pointer hover:text-white'; + el.onclick = function() { shoutboxMention(u); }; el.innerHTML = '' + escapeHtml(u); list.appendChild(el); });