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:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user