diff --git a/frontend/src/components/BrowserTabsPanel.tsx b/frontend/src/components/BrowserTabsPanel.tsx index 3520087..ea4c7b3 100644 --- a/frontend/src/components/BrowserTabsPanel.tsx +++ b/frontend/src/components/BrowserTabsPanel.tsx @@ -185,10 +185,6 @@ export default function BrowserTabsPanel({ active, disabled, busy, onList, onOpe -

- Die Tabs gehören zum Firefox auf dem Rechner der SwyxTray-App. Ohne verbundenes Plugin - beantwortet die App die drei Kommandos nach etwa fünf Sekunden mit einem Fehler. -

{hint &&

{hint}

} {outcome &&

{outcome}

} diff --git a/frontend/src/components/ContactsPanel.tsx b/frontend/src/components/ContactsPanel.tsx index 3234b61..ac44fe0 100644 --- a/frontend/src/components/ContactsPanel.tsx +++ b/frontend/src/components/ContactsPanel.tsx @@ -1,13 +1,11 @@ import { useCallback, useEffect, useRef, useState } from 'react' import { describeContact, type Contact } from '../swyx/protocol' -import type { Directory, DirectoryProgress, SweepOptions } from '../swyx/directory' import { fetchAddresses } from '../addresses' -import LoadingDialog from './LoadingDialog' interface Props { /** Panel ist sichtbar – erst dann wird abgefragt. */ active: boolean - /** Keine Verbindung zur SwyxTray-App – Anrufen und Telefonbuch-Abgleich entfallen. */ + /** Keine Verbindung zur SwyxTray-App – Anrufen entfällt. */ disabled: boolean /** * Adress-Cache, den die App unaufgefordert schickt. Er wird hier nicht @@ -15,7 +13,6 @@ interface Props { * hat ihn gerade hineingeschrieben. */ cache: Contact[] | null - onLoad: (options: SweepOptions) => Promise onDial: (number: string) => void } @@ -36,30 +33,22 @@ const SEARCH_DEBOUNCE_MS = 300 * Abfrageergebnis; der Bereich funktioniert damit auch ohne Verbindung zur * SwyxTray-App. * - * Das Telefonbuch der App fließt auf zwei Wegen in die Ablage: - * - * 1. Der **Cache-Push** beim Verbinden (Protokoll 8) – die Startseite meldet - * ihn ans Backend; das Panel fragt die Ablage danach neu ab. - * 2. „Neu laden" bei bestehender Verbindung: erst das Telefonbuch der App - * holen (Cache oder rund 110 Einzelabfragen), das Backend legt es ab, - * dann die Ablage abfragen. + * Das Telefonbuch der App fließt über den **Cache-Push** beim Verbinden + * (Protokoll 8) in die Ablage – die Startseite meldet ihn ans Backend; das + * Panel fragt die Ablage danach neu ab. */ -export default function ContactsPanel({ active, disabled, cache, onLoad, onDial }: Props) { +export default function ContactsPanel({ active, disabled, cache, onDial }: Props) { // Das jeweils letzte Abfrageergebnis – kein Bestand, nur die Anzeige. const [results, setResults] = useState(null) const [loadError, setLoadError] = useState(null) - // Warnung aus dem letzten Telefonbuch-Abgleich: dort fehlen evtl. Einträge. - const [incomplete, setIncomplete] = useState(false) - const [progress, setProgress] = useState(null) // Bewusst nicht gemerkt: Nach einem Neustart beginnt die Suche leer. const [filter, setFilter] = useState('') - const abortRef = useRef(null) // Zählt die Abfragen: Eine überholte darf das Ergebnis einer neueren nicht // mehr überschreiben – Antworten kommen nicht zwingend in Reihenfolge. const queryIdRef = useRef(0) // Der aktuelle Suchbegriff für Abfragen außerhalb des Eingabe-Effekts - // (Cache-Push, „Neu laden") – ohne den Effekt neu anzustoßen. + // (Cache-Push) – ohne den Effekt neu anzustoßen. const filterRef = useRef(filter) filterRef.current = filter @@ -89,42 +78,6 @@ export default function ContactsPanel({ active, disabled, cache, onLoad, onDial // eslint-disable-next-line react-hooks/exhaustive-deps }, [active, filter, search]) - /** - * „Neu laden": Bei bestehender Verbindung zuerst das Telefonbuch der App - * holen – das Backend schreibt es dabei in die Ablage –, danach in jedem - * Fall die Ablage frisch abfragen. - */ - const reload = useCallback(async () => { - abortRef.current?.abort() - const controller = new AbortController() - abortRef.current = controller - - try { - if (!disabled) { - setProgress({ done: 0, total: 0, found: 0 }) - const result = await onLoad({ - signal: controller.signal, - onProgress: (next) => { - if (abortRef.current === controller) setProgress(next) - }, - }) - if (abortRef.current !== controller) return - // null heißt: Fehler – der steht bereits in der Fehleranzeige der Seite. - setIncomplete(result !== null && !result.complete) - // Das Backend schreibt nebenbei; kurz warten, damit die Abfrage den - // frischen Stand schon sieht. - await new Promise((resolve) => setTimeout(resolve, ARCHIVE_WRITE_DELAY_MS)) - if (abortRef.current !== controller) return - } - await search() - } finally { - if (abortRef.current === controller) { - abortRef.current = null - setProgress(null) - } - } - }, [disabled, onLoad, search]) - // Telefonbuch-Push der App: Die Startseite hat ihn ans Backend gemeldet; // nach einer kurzen Schreibfrist die Ablage neu abfragen. useEffect(() => { @@ -133,25 +86,9 @@ export default function ContactsPanel({ active, disabled, cache, onLoad, onDial return () => clearTimeout(timer) }, [cache, search]) - // Ein laufender Telefonbuch-Abgleich soll nicht weiterfragen, wenn die - // Seite verschwindet. - useEffect(() => () => abortRef.current?.abort(), []) - - const loading = progress !== null - return ( <> -
-

Adressdaten

- -
+

Adressdaten

{/* Die `.row` ist nicht bloß Zierde: `.field` wächst (`flex: 1 1 260px`) und würde als direktes Kind der Karte – einer Spalte – in die *Höhe* @@ -180,22 +117,15 @@ export default function ContactsPanel({ active, disabled, cache, onLoad, onDial <>

{filter.trim() ? `${results.length} Treffer` : `${results.length} Einträge`} - {' · direkt aus der Adress-Ablage des Backends'}

- {incomplete && ( -

- Der letzte Telefonbuch-Abgleich war unvollständig; es können Einträge fehlen. - „Neu laden" versucht es erneut. -

- )} - {results.length === 0 ? ( -

- {filter.trim() - ? `Kein Eintrag zu „${filter.trim()}".` - : 'Die Ablage ist noch leer – sie füllt sich über die Webhooks und über das Telefonbuch der SwyxTray-App.'} -

+ !filter.trim() && ( +

+ Die Ablage ist noch leer – sie füllt sich über die Webhooks und über das + Telefonbuch der SwyxTray-App. +

+ ) ) : (
    {results.map((contact, index) => ( @@ -212,12 +142,13 @@ export default function ContactsPanel({ active, disabled, cache, onLoad, onDial )} {contact.number && {contact.number}} - {contact.number && ( + {/* Ohne Verbindung zur Tray-App gibt es nichts zu wählen – + der Knopf erscheint dann gar nicht erst. */} + {contact.number && !disabled && ( @@ -228,24 +159,6 @@ export default function ContactsPanel({ active, disabled, cache, onLoad, onDial )} )} - -

    - Jede Suche fragt die Adress-Ablage des Backends (MongoDB) direkt ab – die per Webhook - gemeldeten Kunden und Kuriere sowie das Telefonbuch des Swyx-Clients; im Browser wird - kein Bestand vorgehalten. Das Telefonbuch fließt bei bestehender Verbindung zur - SwyxTray-App in die Ablage ein – beim Verbinden von selbst, bei „Neu laden" auf - Anforderung. -

    - - {loading && ( - 0 ? `${progress.found} Einträge bisher` : undefined} - onCancel={() => abortRef.current?.abort()} - /> - )} ) } diff --git a/frontend/src/pages/HomePage.tsx b/frontend/src/pages/HomePage.tsx index 2417e14..b5f5d4d 100644 --- a/frontend/src/pages/HomePage.tsx +++ b/frontend/src/pages/HomePage.tsx @@ -38,7 +38,6 @@ export default function HomePage() { const [url, setUrl] = useState(DEFAULT_WS_URL) const [configNote, setConfigNote] = useState(null) const [tab, setTab] = useState('calls') - const [draft, setDraft] = useState('') const tray = useSwyxTray() const { status, error, log, history, calls, ringingCall, busy, tray: appState } = tray @@ -119,11 +118,6 @@ export default function HomePage() { tray.disconnect() } - function handleSendRaw(event: FormEvent) { - event.preventDefault() - const message = draft.trim() - if (message && tray.sendRaw(message)) setDraft('') - } return (
    @@ -193,9 +187,6 @@ export default function HomePage() { active={tab === 'contacts'} disabled={!isConnected} cache={tray.addressCache} - // Unverpackt weitergereicht: der Rückruf ist stabil, damit das - // Panel nicht bei jedem Rendern neu lädt. - onLoad={tray.loadDirectory} onDial={(number) => void tray.dial(number)} /> {error &&

    {error}

    } @@ -279,26 +270,8 @@ export default function HomePage() {

    Diagnose

    -
    - +
    -
    - +