From 6edfe700204a626d97c62ae2b1c3d0faca49933c Mon Sep 17 00:00:00 2001 From: Lotus CI Date: Wed, 23 Sep 2026 21:31:29 -0400 Subject: [PATCH] feat(desktop): mirror a pending update into the tray (cinny-desktop #6) While an update is available the web client asks the native side to show "Restart to update (vX)" in the tray menu and an "update ready" tooltip; it's cleared once a check reports we're current, and kept while installing or after a failed attempt. Clicking the tray item runs the same install flow as the toast, so progress and failures show in-app. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01PPmy3tPq869XDW4njjVaKA --- src/app/pages/client/ClientNonUIFeatures.tsx | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/app/pages/client/ClientNonUIFeatures.tsx b/src/app/pages/client/ClientNonUIFeatures.tsx index 261cc00b4..1bb404c37 100644 --- a/src/app/pages/client/ClientNonUIFeatures.tsx +++ b/src/app/pages/client/ClientNonUIFeatures.tsx @@ -68,7 +68,7 @@ import { useReminders } from '../../hooks/useReminders'; import { getRoomRetentionMs, isExpired } from '../../utils/retention'; import { useTauriUpdateProgress, useTauriUpdater } from '../../hooks/useTauriUpdater'; import { isNetworkUpdateError } from '../../utils/updateErrors'; -import { invokeTauri, isTauri as isTauriApp } from '../../hooks/useTauri'; +import { invokeTauri, isTauri as isTauriApp, useTauriEvent } from '../../hooks/useTauri'; import { TauriDesktopFeatures } from '../../components/TauriDesktopFeatures'; import { KeyboardShortcutsDialog, useKeyboardShortcutsTrigger } from '../../features/shortcuts'; import { useRoomsListener } from '../../hooks/useRoomsListener'; @@ -965,6 +965,24 @@ function TauriUpdateFeature() { }); }, [status, setToast, installFromToast]); + // [cinny-desktop #6] Mirror a pending update into the tray ("Restart to + // update" + tooltip) so a dismissed toast isn't the only reminder. Kept while + // installing or after a failed attempt (the update is still pending); cleared + // once a check says we're current. + useEffect(() => { + if (!isTauri) return; + if (status.state === 'available') { + invokeTauri('set_tray_update_ready', { version: status.version }); + } else if (status.state === 'up-to-date') { + invokeTauri('set_tray_update_ready', { version: null }); + } + }, [isTauri, status]); + + useTauriEvent('lotus-tray-install-update', () => { + if (firedRef.current) dismissToast(`tauri-update-${firedRef.current}`); + installFromToast(); + }); + return null; }