From 17643d54ea39dd6a10ad62ff187e741c7dbbfc04 Mon Sep 17 00:00:00 2001 From: Kyle Pope Date: Wed, 25 Feb 2026 18:23:26 +0800 Subject: [PATCH] Suppress reminder toasts while lock screen is active Swap LockProvider to outer wrapper so AlertsProvider can read isLocked. When locked, dismiss all visible reminder toasts and skip firing new ones. Toasts re-fire normally on unlock via the firedRef.clear() reset. Co-Authored-By: Claude Opus 4.6 --- frontend/src/components/layout/AppLayout.tsx | 8 ++++---- frontend/src/hooks/useAlerts.tsx | 14 ++++++++++++-- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/frontend/src/components/layout/AppLayout.tsx b/frontend/src/components/layout/AppLayout.tsx index c300cac..ddd1929 100644 --- a/frontend/src/components/layout/AppLayout.tsx +++ b/frontend/src/components/layout/AppLayout.tsx @@ -14,8 +14,8 @@ export default function AppLayout() { const [mobileOpen, setMobileOpen] = useState(false); return ( - - + +
-
-
+ + ); } diff --git a/frontend/src/hooks/useAlerts.tsx b/frontend/src/hooks/useAlerts.tsx index cd971fd..fdf5a67 100644 --- a/frontend/src/hooks/useAlerts.tsx +++ b/frontend/src/hooks/useAlerts.tsx @@ -5,6 +5,7 @@ import { toast } from 'sonner'; import { Bell, X } from 'lucide-react'; import api from '@/lib/api'; import { getRelativeTime, toLocalDatetime } from '@/lib/date-utils'; +import { useLock } from '@/hooks/useLock'; import SnoozeDropdown from '@/components/reminders/SnoozeDropdown'; import type { Reminder } from '@/types'; @@ -29,6 +30,7 @@ export function useAlerts() { export function AlertsProvider({ children }: { children: ReactNode }) { const queryClient = useQueryClient(); const location = useLocation(); + const { isLocked } = useLock(); const firedRef = useRef>(new Set()); const prevPathnameRef = useRef(location.pathname); const isDashboard = location.pathname === '/' || location.pathname === '/dashboard'; @@ -186,12 +188,20 @@ export function AlertsProvider({ children }: { children: ReactNode }) { } } - // Unified toast management — single effect handles both route changes and new alerts + // Unified toast management — single effect handles route changes, lock state, and new alerts useEffect(() => { const wasOnDashboard = prevPathnameRef.current === '/' || prevPathnameRef.current === '/dashboard'; const nowOnDashboard = isDashboard; prevPathnameRef.current = location.pathname; + // Suppress toasts while locked — dismiss any visible ones + if (isLocked) { + alerts.forEach((a) => toast.dismiss(`reminder-${a.id}`)); + toast.dismiss('reminder-summary'); + firedRef.current.clear(); + return; + } + if (nowOnDashboard) { // On dashboard — dismiss all toasts, banner takes over alerts.forEach((a) => toast.dismiss(`reminder-${a.id}`)); @@ -207,7 +217,7 @@ export function AlertsProvider({ children }: { children: ReactNode }) { // On non-dashboard page — fire toasts for any unfired alerts fireToasts(alerts); - }, [location.pathname, isDashboard, alerts]); + }, [location.pathname, isDashboard, alerts, isLocked]); return (