@@ -44,10 +44,12 @@ const NotificationContext = createContext<{
4444 notifications : UnifiedNotification [ ] ;
4545 refreshNotifications : ( ) => Promise < void > ;
4646 dismissNotification : ( id : string | number ) => Promise < void > ;
47+ chatUnreadCount : number ;
4748} > ( {
4849 notifications : [ ] ,
4950 refreshNotifications : async ( ) => { } ,
5051 dismissNotification : async ( ) => { } ,
52+ chatUnreadCount : 0 ,
5153} ) ;
5254
5355export function useNotifications ( ) {
@@ -65,6 +67,8 @@ export default function NotificationHandler({
6567 const [ client , setClient ] = useState < Ably . Realtime | null > ( null ) ;
6668 const [ notifications , setNotifications ] = useState < UnifiedNotification [ ] > ( [ ] ) ;
6769
70+ const [ chatUnreadCount , setChatUnreadCount ] = useState ( 0 ) ;
71+
6872 // Ensure that mirroring doesn't overwrite sessionStorage before loading
6973 const isHydrated = useRef ( false ) ;
7074
@@ -112,7 +116,8 @@ export default function NotificationHandler({
112116
113117 const dismissNotification = useCallback (
114118 async ( id : string | number ) => {
115- if ( Number ( id ) > 0 ) {
119+ const notification = notifications . find ( ( n ) => n . id === id ) ;
120+ if ( ! notification ?. isChat && Number ( id ) > 0 ) {
116121 try {
117122 await apiClient . delete ( `/api/notifications/${ id } ` ) ;
118123 } catch ( error ) {
@@ -121,7 +126,7 @@ export default function NotificationHandler({
121126 }
122127 setNotifications ( ( prev ) => prev . filter ( ( n ) => n . id !== id ) ) ;
123128 } ,
124- [ apiClient ]
129+ [ apiClient , notifications ]
125130 ) ;
126131
127132 useEffect ( ( ) => {
@@ -235,6 +240,26 @@ export default function NotificationHandler({
235240 ) ;
236241 let didInterrupt = false ;
237242
243+ const refreshChatUnreadCount = async ( ) => {
244+ try {
245+ const channels = await streamClient . queryChannels (
246+ {
247+ type : "ticket" ,
248+ members : { $in : [ user . streamUserId ! ] } ,
249+ } ,
250+ { } ,
251+ { limit : 30 }
252+ ) ;
253+ const total = channels . reduce (
254+ ( sum , ch ) => sum + ( ch . state . unreadCount ?? 0 ) ,
255+ 0
256+ ) ;
257+ setChatUnreadCount ( total ) ;
258+ } catch ( error ) {
259+ console . error ( "Failed to query chat unread count:" , error ) ;
260+ }
261+ } ;
262+
238263 const handleTicketMessage = ( event : Event ) => {
239264 if ( event . channel_type !== "ticket" ) {
240265 return ;
@@ -276,6 +301,8 @@ export default function NotificationHandler({
276301 ...prev ,
277302 ] ) ;
278303
304+ setChatUnreadCount ( ( prev ) => prev + 1 ) ;
305+
279306 toast . custom (
280307 ( t : Toast ) => (
281308 < NotificationCard
@@ -292,6 +319,11 @@ export default function NotificationHandler({
292319 ) ;
293320 } ;
294321
322+ const handleMarkRead = ( event : Event ) => {
323+ if ( event . channel_type !== "ticket" ) return ;
324+ refreshChatUnreadCount ( ) ;
325+ } ;
326+
295327 streamClient
296328 . connectUser (
297329 {
@@ -300,10 +332,11 @@ export default function NotificationHandler({
300332 } ,
301333 user . streamUserToken
302334 )
303- . then ( ( ) => {
304- if ( ! didInterrupt ) {
305- streamClient . on ( "notification.message_new" , handleTicketMessage ) ;
306- }
335+ . then ( async ( ) => {
336+ if ( didInterrupt ) return ;
337+ await refreshChatUnreadCount ( ) ;
338+ streamClient . on ( "notification.message_new" , handleTicketMessage ) ;
339+ streamClient . on ( "notification.mark_read" , handleMarkRead ) ;
307340 } )
308341 . catch ( ( error ) => {
309342 console . error (
@@ -315,6 +348,7 @@ export default function NotificationHandler({
315348 return ( ) => {
316349 didInterrupt = true ;
317350 streamClient . off ( "notification.message_new" , handleTicketMessage ) ;
351+ streamClient . off ( "notification.mark_read" , handleMarkRead ) ;
318352 streamClient
319353 . disconnectUser ( )
320354 . catch ( ( error ) =>
@@ -334,8 +368,13 @@ export default function NotificationHandler({
334368 ] ) ;
335369
336370 const value = useMemo (
337- ( ) => ( { notifications, refreshNotifications, dismissNotification } ) ,
338- [ notifications , refreshNotifications , dismissNotification ]
371+ ( ) => ( {
372+ notifications,
373+ refreshNotifications,
374+ dismissNotification,
375+ chatUnreadCount,
376+ } ) ,
377+ [ notifications , refreshNotifications , dismissNotification , chatUnreadCount ]
339378 ) ;
340379
341380 return (
0 commit comments