Make dashboard event toasts persistent
This commit is contained in:
1 parent
4798385d8b
commit
c75e71f26e
4 files changed
+91
-14
No files matched your search
@@ -168,6 +168,34 @@ export function notificationForEvent(event: DashboardEvent): NotificationDraft |
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Toasts interrupt the operator, so reserve them for inbound activity and
|
||||
* states that need attention. Routine lifecycle and successful sync events
|
||||
* remain available in the notification centre without producing a pop-up.
|
||||
*/
|
||||
export function shouldToastForEvent(event: DashboardEvent): boolean {
|
||||
switch (event.type) {
|
||||
case 'reply.received':
|
||||
case 'media.received':
|
||||
case 'message.failed':
|
||||
case 'sync.failed':
|
||||
return true;
|
||||
case 'bot.status.changed':
|
||||
return event.payload.status === 'stopped';
|
||||
case 'rate-limit.changed':
|
||||
return event.payload.limited;
|
||||
case 'reddit.session.changed':
|
||||
return ['expired', 'logged-out', 'error'].includes(event.payload.status);
|
||||
case 'message.sent':
|
||||
case 'conversation.updated':
|
||||
case 'sync.started':
|
||||
case 'sync.progress':
|
||||
case 'sync.completed':
|
||||
case 'log.created':
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function loadNotifications(): NotificationItem[] {
|
||||
const storage = notificationStorage();
|
||||
if (!storage) return [];
|
||||
@@ -221,20 +249,13 @@ export function NotificationProvider({ children, realtime: realtimeOverride }: N
|
||||
setNotifications((current) => current.some((entry) => entry.id === item.id)
|
||||
? current
|
||||
: [item, ...current].slice(0, MAX_NOTIFICATIONS));
|
||||
setToasts((current) => current.some((entry) => entry.id === item.id)
|
||||
? current
|
||||
: [...current, item].slice(-3));
|
||||
if (shouldToastForEvent(event)) {
|
||||
setToasts((current) => current.some((entry) => entry.id === item.id)
|
||||
? current
|
||||
: [...current, item]);
|
||||
}
|
||||
}), [realtime]);
|
||||
|
||||
useEffect(() => {
|
||||
if (toasts.length === 0) return undefined;
|
||||
const timers = toasts.map((toast) => globalThis.setTimeout(
|
||||
() => dismissToast(toast.id),
|
||||
toast.tone === 'error' ? 8_000 : 5_000,
|
||||
));
|
||||
return () => timers.forEach((timer) => globalThis.clearTimeout(timer));
|
||||
}, [dismissToast, toasts]);
|
||||
|
||||
useEffect(() => {
|
||||
function closeOnEscape(event: KeyboardEvent): void {
|
||||
if (event.key === 'Escape') setOpen(false);
|
||||
|
||||
Reference in new issue
Block a user