import type { CallEvent } from './swyx/protocol' /** Ein gespeicherter eingehender Anruf aus GET /api/calls. */ export interface StoredCall { id: string receivedAt: string line: number | null peer: string | null peerNumber: string | null peerName: string | null } export async function fetchIncomingCalls(signal?: AbortSignal): Promise { const response = await fetch('/api/calls', { signal, cache: 'no-store' }) if (!response.ok) { throw new Error(`Anrufhistorie nicht abrufbar (HTTP ${response.status}).`) } return (await response.json()) as StoredCall[] } /** Ältere Snapshots enthalten die Rufnummer teilweise nur in der Anzeigeform. */ export function callerNumber(call: StoredCall): string | null { const number = call.peerNumber?.trim() if (number) return number const peer = call.peer?.trim() ?? '' const candidate = peer.match(/\(([^()]+)\)$/)?.[1] ?? peer return /^[+\d][\d\s()/.-]*$/.test(candidate) ? candidate : null } export function matchesCall(call: StoredCall, query: string): boolean { const wanted = query.trim().toLocaleLowerCase('de') if (!wanted) return true const text = [callerNumber(call), call.peerName, call.peer].filter(Boolean).join(' ') if (text.toLocaleLowerCase('de').includes(wanted)) return true // Rufnummern auch ohne die Leerzeichen/Klammern ihrer Anzeigeform finden. const digits = wanted.replace(/\D/g, '') return /^[+\d\s()/.-]+$/.test(wanted) && digits.length > 0 && (callerNumber(call)?.replace(/\D/g, '').includes(digits) ?? false) } /** * Meldet Anruf-Ereignisse an das Backend, das sie in der MongoDB ablegt. * * Die Ereignisse entstehen nur hier im Browser (aus dem Vergleich zweier * SwyxTray-Snapshots); das Backend sieht die WebSocket-Verbindung nicht. * Fire-and-forget: Ist das Backend nicht erreichbar, läuft die Anzeige * unverändert weiter – die Speicherung ist Beiwerk, nicht Voraussetzung. */ export function reportCallEvents(events: CallEvent[]): void { if (events.length === 0) return void fetch('/api/calls', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(events), // Auch beim Schließen des Tabs noch absetzen, z. B. das "ended" beim Auflegen. keepalive: true, }).catch((e: unknown) => { console.warn('Anrufdaten nicht an das Backend gemeldet:', e) }) }