Fix unread badge refresh and reply thread UI

This commit is contained in:
cyph3rasi
2026-03-08 00:31:21 -08:00
parent 98359886df
commit a8f104ee14
4 changed files with 46 additions and 24 deletions
+5 -1
View File
@@ -126,12 +126,16 @@ export default function ChatPage() {
const markAsRead = async (conversationId: string) => {
try {
await fetch('/api/swarm/chat/messages', {
const res = await fetch('/api/swarm/chat/messages', {
method: 'PATCH',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ conversationId })
});
if (!res.ok) {
return;
}
setConversations(prev => prev.map(c => c.id === conversationId ? { ...c, unreadCount: 0 } : c));
window.dispatchEvent(new Event('synapsis:chat-updated'));
} catch { }
};
+1
View File
@@ -69,6 +69,7 @@ export default function NotificationsPage() {
throw new Error('Failed to mark notifications as read');
}
setNotifications(prev => prev.map(n => ({ ...n, readAt: new Date().toISOString() })));
window.dispatchEvent(new Event('synapsis:notifications-updated'));
} catch (err) {
console.error('Failed to mark notifications as read:', err);
}
-1
View File
@@ -473,7 +473,6 @@ export function PostCard({ post, onLike, onRepost, onComment, onDelete, onHide,
showThread={false}
isThreadParent={true}
/>
<div className="thread-line" />
</div>
)}
<article className={`post ${isDetail ? 'detail' : ''}`}>
+40 -22
View File
@@ -1,6 +1,6 @@
'use client';
import { useState, useEffect } from 'react';
import { useState, useEffect, useCallback } from 'react';
import Link from 'next/link';
import Image from 'next/image';
import { usePathname, useRouter } from 'next/navigation';
@@ -31,43 +31,61 @@ export function Sidebar() {
});
}, []);
const fetchUnreadNotifications = useCallback(() => {
fetch('/api/notifications?unread=true&limit=50')
.then(res => res.json())
.then(data => {
setUnreadCount(data.notifications?.length || 0);
})
.catch(() => { });
}, []);
const fetchUnreadChats = useCallback(() => {
fetch('/api/chat/unread')
.then(res => res.json())
.then(data => {
setUnreadChatCount(data.unreadCount || 0);
})
.catch(() => { });
}, []);
// Fetch unread notification count
useEffect(() => {
if (!user) return;
const fetchUnread = () => {
fetch('/api/notifications?unread=true&limit=50')
.then(res => res.json())
.then(data => {
setUnreadCount(data.notifications?.length || 0);
})
.catch(() => { });
fetchUnreadNotifications();
const handleUnreadRefresh = () => {
fetchUnreadNotifications();
};
fetchUnread();
window.addEventListener('synapsis:notifications-updated', handleUnreadRefresh);
// Poll every 30 seconds
const interval = setInterval(fetchUnread, 30000);
return () => clearInterval(interval);
}, [user]);
const interval = setInterval(fetchUnreadNotifications, 30000);
return () => {
clearInterval(interval);
window.removeEventListener('synapsis:notifications-updated', handleUnreadRefresh);
};
}, [user, fetchUnreadNotifications]);
// Fetch unread chat count
useEffect(() => {
if (!user) return;
const fetchUnreadChats = () => {
fetch('/api/chat/unread')
.then(res => res.json())
.then(data => {
setUnreadChatCount(data.unreadCount || 0);
})
.catch(() => { });
fetchUnreadChats();
const handleUnreadRefresh = () => {
fetchUnreadChats();
};
fetchUnreadChats();
window.addEventListener('synapsis:chat-updated', handleUnreadRefresh);
// Poll every 10 seconds
const interval = setInterval(fetchUnreadChats, 10000);
return () => clearInterval(interval);
}, [user]);
return () => {
clearInterval(interval);
window.removeEventListener('synapsis:chat-updated', handleUnreadRefresh);
};
}, [user, fetchUnreadChats]);
// Home is exact match
const isHome = pathname === '/';