import { useState, useEffect, useRef } from 'react'; import { MessageSquare } from 'lucide-react'; import { OutlookNotificationData } from '@/components/outlook-notification'; /** * Hook to manage RocketChat message notifications and show Outlook-style notifications */ export function useRocketChatMessageNotifications() { const [messageNotification, setMessageNotification] = useState(null); const lastMessageIdsRef = useRef>(new Set()); const notificationQueueRef = useRef([]); const isShowingRef = useRef(false); const isInitializedRef = useRef(false); useEffect(() => { // Listen for new messages via custom event const handleNewMessages = (event: CustomEvent) => { const messages = event.detail?.messages || []; const previousCount = event.detail?.previousCount ?? -1; const currentCount = event.detail?.currentCount ?? 0; if (!messages || messages.length === 0) return; // On first load, just store all message IDs without showing notifications if (!isInitializedRef.current) { console.log('[useRocketChatMessageNotifications] Initializing - storing existing message IDs without notifications'); lastMessageIdsRef.current = new Set(messages.map((m: any) => m.id)); isInitializedRef.current = true; return; } // Find new messages by comparing IDs (more reliable than count comparison) // This works even if previousCount is -1 (first load after initialization) const newMessages = messages .filter((message: any) => { const messageId = message.id; return !lastMessageIdsRef.current.has(messageId); }) .slice(0, 5); // Limit to 5 most recent new messages // Update lastMessageIdsRef with all current messages lastMessageIdsRef.current = new Set(messages.map((m: any) => m.id)); // If there are new messages, queue them for notification // This works regardless of previousCount value if (newMessages.length > 0) { console.log('[useRocketChatMessageNotifications] 💬 New messages detected:', { newMessagesCount: newMessages.length, previousCount, currentCount, newMessageIds: newMessages.map((m: any) => m.id), }); newMessages.forEach((message: any) => { const senderName = message.sender?.name || message.sender?.username || 'Inconnu'; const roomName = message.roomName || 'Chat'; const messageText = message.text || message.message || ''; const notification: OutlookNotificationData = { id: `rocketchat-${message.id}-${Date.now()}`, source: 'rocketchat', title: 'Parole', subtitle: 'Nouveau message', message: `${senderName} dans ${roomName}: ${messageText.length > 50 ? messageText.substring(0, 50) + '...' : messageText}`, icon: MessageSquare, iconColor: 'text-purple-600', iconBgColor: 'bg-purple-100', borderColor: 'border-purple-500', link: '/parole', timestamp: new Date(message.rawTimestamp || message.timestamp), autoDismiss: 10000, // 10 seconds for messages actions: [ { label: 'Ouvrir', onClick: () => { window.location.href = '/parole'; }, variant: 'default', className: 'bg-purple-600 hover:bg-purple-700 text-white', }, ], }; notificationQueueRef.current.push(notification); }); // Show the first notification if none is currently showing if (!isShowingRef.current && notificationQueueRef.current.length > 0) { showNextNotification(); } } else { console.log('[useRocketChatMessageNotifications] ⏭️ No new messages detected', { previousCount, currentCount, totalMessages: messages.length, lastMessageIdsCount: lastMessageIdsRef.current.size, }); } }; window.addEventListener('new-messages-detected', handleNewMessages as EventListener); return () => { window.removeEventListener('new-messages-detected', handleNewMessages as EventListener); }; }, []); const showNextNotification = () => { if (notificationQueueRef.current.length === 0) { isShowingRef.current = false; return; } const nextNotification = notificationQueueRef.current.shift(); if (nextNotification) { isShowingRef.current = true; setMessageNotification(nextNotification); } }; const handleDismiss = () => { setMessageNotification(null); isShowingRef.current = false; // Show next notification after a short delay setTimeout(() => { showNextNotification(); }, 500); }; return { messageNotification, setMessageNotification: handleDismiss, }; }