From 339a1d70f9471bc931dbd2015c22f7a5dbe1776c Mon Sep 17 00:00:00 2001 From: enricobuehler Date: Wed, 12 Aug 2026 22:05:16 +0200 Subject: [PATCH] fix(decky): stop toasting on every launch and every failed panel refresh MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Field complaint: the plugin toasts too much. Inventory of all 14 toast sites says almost all are rare, explicit-tap feedback (pairing, update buttons, recovery actions) — but two were routine-volume offenders: * startStream toasted "Starting stream — " on EVERY successful launch, i.e. the overwhelming majority of all toasts the plugin ever shows. It repeats the button the user just pressed, and lands ON TOP of the starting stream after the QAM closes. Gone; launch FAILURES still toast (the QAM may already be closed, so inline state would go unseen). * useHosts.refresh() toasted "Couldn't list hosts" from its catch — and the panel remounts (and refreshes) on every QAM open, so a broken backend nagged on each open. It's now a third inline `problem` row ("Couldn't scan for hosts"), sitting next to the Refresh button that retries it, like the client-unavailable/client-outdated states already did. The update-flow, pairing, trust and recovery toasts stay: each is a rare, single, information-carrying response to an explicit tap (or, for the request-access hint, the only warning that the connect is about to park). Verified: tsc --noEmit and the rollup bundle pass. --- clients/decky/src/hooks.ts | 16 ++++++++++++---- clients/decky/src/index.tsx | 8 ++++++-- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/clients/decky/src/hooks.ts b/clients/decky/src/hooks.ts index 7c7c4c7d..3f52076f 100644 --- a/clients/decky/src/hooks.ts +++ b/clients/decky/src/hooks.ts @@ -215,9 +215,10 @@ export function useHosts() { const [views, setViews] = useState([]); const [scanning, setScanning] = useState(false); // Why the list is empty, when it is empty for a reason other than an empty LAN. Rendering - // either of these as "No hosts yet" would blame the user's network for the plugin's problem: + // any of these as "No hosts yet" would blame the user's network for the plugin's problem: // "client-outdated" — the installed client predates `punktfunk discover` // "client-unavailable" — there is no client installed at all + // "list-failed" — the refresh itself blew up (backend down, call threw) const [problem, setProblem] = useState(null); const refresh = useCallback(async () => { @@ -236,7 +237,11 @@ export function useHosts() { ); setViews(mergeHosts(s.hosts ?? [], d.hosts ?? [])); } catch (e) { - toaster.toast({ title: "Punktfunk", body: `Couldn't list hosts: ${e}` }); + // Inline, not a toast: the panel remounts (and refreshes) on every QAM open, so while + // the backend is unhappy a toast here nagged on each open. The panel row also sits next + // to the Refresh button that retries it, which is where the eyes already are. + console.warn("punktfunk: host list refresh failed", e); + setProblem("list-failed"); } finally { setScanning(false); } @@ -454,9 +459,12 @@ export async function startStream( ): Promise { try { await launchStream(v.ref, opts); + // No success toast: the user just pressed the button that names this host/card, the QAM + // closes, and Steam's own launch UI takes over — a toast here fired on EVERY launch and + // then sat on top of the starting stream. Failure still toasts (the QAM may already be + // closed, so inline error state would go unseen). Navigation.CloseSideMenus(); - toaster.toast({ title: "Punktfunk", body: `Starting ${label ?? "stream"} — ${v.name}` }); } catch (e) { - toaster.toast({ title: "Punktfunk", body: `Launch failed: ${e}` }); + toaster.toast({ title: "Punktfunk", body: `Launch failed${label ? ` (${label})` : ""}: ${e}` }); } } diff --git a/clients/decky/src/index.tsx b/clients/decky/src/index.tsx index 7df68bd3..3b334eaf 100644 --- a/clients/decky/src/index.tsx +++ b/clients/decky/src/index.tsx @@ -230,12 +230,16 @@ const QamPanel: FC = () => { label={ problem === "client-unavailable" ? "Punktfunk isn’t installed" - : "Update the Punktfunk client" + : problem === "list-failed" + ? "Couldn’t scan for hosts" + : "Update the Punktfunk client" } description={ problem === "client-unavailable" ? "This panel launches the Punktfunk app, which isn’t on this Deck yet. Install it in Desktop Mode." - : "This client is too old to find hosts on your network. Saved hosts still work." + : problem === "list-failed" + ? "Something went wrong while scanning — Refresh tries again." + : "This client is too old to find hosts on your network. Saved hosts still work." } />