- 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.
-