email: push new-mail to /email via SSE (IMAP IDLE -> sidecar -> server -> EventSource)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-23 17:29:20 +00:00
co-authored by Claude Opus 4.8
parent 5a0b9ce70f
commit 4b08d0b99c
6 changed files with 93 additions and 4 deletions
@@ -68,6 +68,26 @@ export const EmailList = () => {
}
}, [folder, data?.total, allCount]);
// Live updates: while /email is open, listen for new-mail pushes (IMAP IDLE → SSE) and refetch.
// The EventSource closes automatically when this component unmounts (i.e. when you leave /email).
useEffect(() => {
const token = localStorage.getItem('BEARER_TOKEN');
if (!token) return;
const es = new EventSource(`/api/email/events?token=${encodeURIComponent(token)}`);
es.onmessage = (ev) => {
try {
if ((JSON.parse(ev.data) as { type?: string }).type === 'new-mail') {
queryClient.invalidateQueries({ queryKey: ['email-messages'] });
queryClient.invalidateQueries({ queryKey: ['email-messages-all-count'] });
queryClient.invalidateQueries({ queryKey: ['email-accounts'] });
}
} catch {
/* ignore non-JSON keepalives */
}
};
return () => es.close();
}, [queryClient]);
const handleFolderChange = (newFolder: string) => {
setFolder(newFolder);
setPage(1);