Chat-Overlay: echte Twitch-Abzeichen statt farbiger Punkte

Der Hub loest die Abzeichen aus dem IRC-Tag ueber Helix (global und
Kanal) zu Bildern auf und schickt sie mit jeder Chatzeile mit.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
ZeasyAlexandClaude Opus 5.5 committed 2026-10-27 16:12:37 +01:00
1 parent 884e4517d8
commit 67ca472317
13 files changed
+171 -19

No files matched your search

+1 -1
View File
@@ -10,7 +10,7 @@ function nachricht(over: Partial<ChatEvent> = {}): ChatEvent {
return {
kind: 'chat', id: 'm1', userId: 'u1', login: 'kevin', name: 'Kevin',
text: 'moin', color: null, emotes: [], gifs: [], first: false, mod: false,
sub: false, broadcaster: false, bits: 0,
sub: false, broadcaster: false, badges: [], bits: 0,
...over,
};
}
+2
View File
@@ -29,6 +29,8 @@ export type ChatEvent = {
mod: boolean;
sub: boolean;
broadcaster: boolean;
/** Abzeichen als fertige Bilder, aufgeloest im Hub (#twitch/badges.ts). */
badges: Array<{ url: string; title: string }>;
bits: number;
};
+18 -2
View File
@@ -96,6 +96,23 @@ export const TEST_KNOEPFE: TestKnopf[] = [
{ art: 'live-aus', label: 'Stand zurücksetzen', gruppe: 'Stand' },
];
// Twitchs globale Abzeichen. Die Adressen sind fest, so zeigt die Vorfuehrung
// echte Bilder, ohne Helix fragen zu muessen.
const ABZEICHEN = 'https://static-cdn.jtvnw.net/badges/v1/';
const MOD = { url: `${ABZEICHEN}3267646d-33f0-4b17-b3df-f923a41db1d0/2`, title: 'Moderator' };
const VIP = { url: `${ABZEICHEN}b817aba4-fad8-49e2-b88a-7cc744dfa6ec/2`, title: 'VIP' };
const ABO = { url: `${ABZEICHEN}5d9f2208-5dd8-11e7-8513-2ff4adfae661/2`, title: 'Subscriber' };
function zufallsAbzeichen(): Pick<ChatEvent, 'mod' | 'sub' | 'badges'> {
const mod = Math.random() < 0.15;
const vip = !mod && Math.random() < 0.1;
const sub = Math.random() < 0.3;
return {
mod, sub,
badges: [...(mod ? [MOD] : []), ...(vip ? [VIP] : []), ...(sub ? [ABO] : [])],
};
}
function chat(over: Partial<ChatEvent> = {}): ChatEvent {
const name = zufall(NAMEN);
return {
@@ -109,8 +126,7 @@ function chat(over: Partial<ChatEvent> = {}): ChatEvent {
emotes: [],
gifs: [],
first: false,
mod: Math.random() < 0.15,
sub: Math.random() < 0.3,
...zufallsAbzeichen(),
broadcaster: false,
bits: 0,
...over,