diff --git a/src/app/features/toast/LotusToastContainer.tsx b/src/app/features/toast/LotusToastContainer.tsx index c97a2568c..58e3efb4c 100644 --- a/src/app/features/toast/LotusToastContainer.tsx +++ b/src/app/features/toast/LotusToastContainer.tsx @@ -32,13 +32,14 @@ function ToastCard({ toast }: ToastCardProps) { const timerRef = useRef | null>(null); useEffect(() => { + if (toast.sticky) return; timerRef.current = setTimeout(() => { dismiss(toast.id); }, 4000); return () => { if (timerRef.current !== null) clearTimeout(timerRef.current); }; - }, [dismiss, toast.id]); + }, [dismiss, toast.id, toast.sticky]); const handleCardClick = () => { if (toast.onClick) { @@ -58,12 +59,14 @@ function ToastCard({ toast }: ToastCardProps) { const cardStyle: CSSProperties = { position: 'relative', background: 'var(--lt-bg-card)', - border: '1px solid var(--lt-border-color)', + border: toast.sticky + ? '1px solid var(--lt-accent-cyan-border)' + : '1px solid var(--lt-border-color)', borderRadius: '12px', padding: '12px 14px', minWidth: '280px', maxWidth: '340px', - boxShadow: 'var(--lt-box-glow-orange)', + boxShadow: toast.sticky ? 'var(--lt-box-glow-cyan)' : 'var(--lt-box-glow-orange)', cursor: 'pointer', animation: 'lotusToastIn 0.2s ease-out both', userSelect: 'none', @@ -100,7 +103,7 @@ function ToastCard({ toast }: ToastCardProps) { }; const nameStyle: CSSProperties = { - color: 'var(--lt-accent-orange)', + color: toast.sticky ? 'var(--lt-accent-cyan)' : 'var(--lt-accent-orange)', fontWeight: 600, fontSize: '0.85rem', overflow: 'hidden', @@ -127,8 +130,9 @@ function ToastCard({ toast }: ToastCardProps) { fontSize: '0.82rem', margin: '4px 0 2px', overflow: 'hidden', - textOverflow: 'ellipsis', - whiteSpace: 'nowrap', + ...(toast.sticky + ? { whiteSpace: 'normal', lineHeight: 1.4 } + : { textOverflow: 'ellipsis', whiteSpace: 'nowrap' }), }; const roomNameStyle: CSSProperties = { diff --git a/src/app/pages/client/ClientNonUIFeatures.tsx b/src/app/pages/client/ClientNonUIFeatures.tsx index 6d2d425c3..bd9d6840d 100644 --- a/src/app/pages/client/ClientNonUIFeatures.tsx +++ b/src/app/pages/client/ClientNonUIFeatures.tsx @@ -459,11 +459,12 @@ function TauriUpdateFeature() { firedRef.current = status.version; setToast({ id: `tauri-update-${status.version}`, - displayName: 'Update Available', - body: `Lotus Chat ${status.version} is ready to install.`, + displayName: '⬆ Update Available', + body: `Lotus Chat ${status.version} is ready. Click to install and restart.`, roomName: 'System', roomId: '', onClick: install, + sticky: true, }); }, [status, setToast, install]); diff --git a/src/app/state/toast.ts b/src/app/state/toast.ts index 61b084d5a..c13e7c40b 100644 --- a/src/app/state/toast.ts +++ b/src/app/state/toast.ts @@ -9,6 +9,7 @@ export type ToastNotif = { roomId: string; hashPath?: string; // overrides window.location.hash navigation when set onClick?: () => void; // custom click handler; skips hash navigation when set + sticky?: boolean; // when true, does not auto-dismiss — use for action toasts that require a click }; const baseAtom = atom([]);