// Textbausteine fuer die Go-Live-Ankuendigung. // // Warum mehrere: eine Ankuendigung, die jeden Donnerstag Wort fuer Wort // dieselbe ist, wird nach drei Wochen nicht mehr gelesen. Das ist kein // Algorithmus-Aberglaube, sondern gilt genauso fuer Menschen, die die // Nachricht in der Seitenleiste ueberfliegen. // // Die Auswahl ist nicht zufaellig, sondern haengt an der Stream-ID: derselbe // Stream bekommt bei einem Wiederholungsversuch denselben Text, und Tests // bekommen ein vorhersagbares Ergebnis. Zwei aufeinanderfolgende Streams // bekommen verschiedene IDs und damit fast immer verschiedene Texte. /** Die Zeile ueber dem Embed. Hier steht der Ping, also faellt sie ins Auge. */ export const OPENERS = [ 'Abdu ist live.', 'Der Stream läuft.', 'Es geht los.', 'Abdu ist da.', 'Ab jetzt live.', ]; /** Die Zeile im Embed. Darf laenger sein, wird ruhiger gelesen. */ export const INVITATIONS = [ 'Schau vorbei.', 'Komm rein, es ist noch Platz.', 'Jetzt einschalten.', 'Der Chat ist offen.', 'Bis gleich im Chat.', ]; /** * Kleiner, stabiler Hash. Kein crypto: er muss nur gleichmaessig streuen und * ueber Neustarts hinweg dasselbe Ergebnis liefern. */ export function pick(list: readonly T[], seed: string): T { if (list.length === 0) throw new Error('Keine Textbausteine hinterlegt.'); let h = 2166136261; for (let i = 0; i < seed.length; i++) { h ^= seed.charCodeAt(i); h = Math.imul(h, 16777619); } return list[Math.abs(h) % list.length]!; } /** * Platzhalter ersetzen. Unbekannte Platzhalter bleiben stehen - so sieht man * im Ergebnis, dass einer falsch geschrieben ist, statt eine Luecke zu * bekommen, die nach Absicht aussieht. */ export function fill(template: string, values: Record): string { return template.replace(/\{\{(\w+)\}\}/g, (all, key: string) => key in values ? values[key]! : all); }