import type { ReactNode } from "react"; // avatarUrl liefert den Bildpfad oder das Platzhalterbild bei leerem Avatar. export function avatarUrl(path: string): string { return path ? `/${path}` : "/static/assets/no_profile_pic.jpg"; } export function formatTime(unix: number): string { return new Date(unix * 1000).toLocaleString("de-DE"); } const urlPattern = /https?:\/\/[^\s<]+/g; // linkify macht aus URLs im Text Links und aus Zeilenumbrüchen
. React // escaped den Text selbst -- anders als im alten Frontend gibt es hier kein // innerHTML und damit keinen Escaping-Schritt, der vergessen werden könnte. export function linkify(text: string): ReactNode[] { const out: ReactNode[] = []; text.split("\n").forEach((line, i) => { if (i > 0) out.push(
); let last = 0; for (const m of line.matchAll(urlPattern)) { const start = m.index; if (start > last) out.push(line.slice(last, start)); out.push( {m[0]} , ); last = start + m[0].length; } if (last < line.length) out.push(line.slice(last)); }); return out; }