From 430940cc12daaed760a4843cffb3f1f0eae0aa54 Mon Sep 17 00:00:00 2001 From: alma Date: Fri, 16 Jan 2026 17:19:59 +0100 Subject: [PATCH] Pages corrections widget --- components/parole.tsx | 114 ++++++++++-------- hooks/use-rocketchat-message-notifications.ts | 111 +++++++++-------- 2 files changed, 122 insertions(+), 103 deletions(-) diff --git a/components/parole.tsx b/components/parole.tsx index 6fb80cd..df455c3 100644 --- a/components/parole.tsx +++ b/components/parole.tsx @@ -48,6 +48,7 @@ export function Parole() { const { data: session, status } = useSession(); const { triggerNotification } = useWidgetNotification(); const lastUnreadCountRef = useRef(-1); // Initialize to -1 to detect first load + const lastMessageIdsRef = useRef>(new Set()); const isInitializedRef = useRef(false); const fetchMessages = async (forceRefresh = false) => { @@ -74,68 +75,77 @@ export function Parole() { if (Array.isArray(data.messages)) { // Utiliser le totalUnreadCount de l'API (plus fiable) const currentUnreadCount = data.totalUnreadCount || 0; + const currentMessageIds = new Set(data.messages.map((m: any) => m.id)); // Update unread count state for badge display setUnreadCount(currentUnreadCount); - // On initialise le count au premier chargement - if (!isInitializedRef.current) { - isInitializedRef.current = true; - lastUnreadCountRef.current = -1; // Set to -1 to trigger on first load - console.log('[Parole] Initial unread count:', currentUnreadCount); - } + // Detect new messages by comparing IDs (more reliable than count) + const newMessageIds = new Set( + Array.from(currentMessageIds).filter(id => !lastMessageIdsRef.current.has(id)) + ); + const hasNewMessages = newMessageIds.size > 0; - // Si le count a changé (ou premier chargement), déclencher notification - if (currentUnreadCount !== lastUnreadCountRef.current) { - const previousCount = lastUnreadCountRef.current; - lastUnreadCountRef.current = currentUnreadCount; - - // Préparer les items pour les notifications (messages, max 10) - const notificationItems = data.messages - .slice(0, 10) - .map((msg: any) => ({ - id: msg.id, - title: msg.sender.name || msg.sender.username, - message: msg.text || msg.message || '', - link: '/parole', - timestamp: new Date(msg.rawTimestamp || msg.timestamp), - metadata: { - roomName: msg.roomName, - roomType: msg.roomType, - }, - })); - - // Déclencher notification update (for badge) - await triggerNotification({ - source: 'rocketchat', - count: currentUnreadCount, - items: notificationItems, + // On initialise au premier chargement + if (!isInitializedRef.current) { + console.log('[Parole Widget] 💬 Initializing - storing existing message IDs without notifications', { + messageCount: data.messages.length, + unreadCount: currentUnreadCount, }); + lastMessageIdsRef.current = currentMessageIds; + lastUnreadCountRef.current = currentUnreadCount; + isInitializedRef.current = true; + } else { + // Si le count a changé ou nouveaux messages détectés, déclencher notification + if (currentUnreadCount !== lastUnreadCountRef.current || hasNewMessages) { + const previousCount = lastUnreadCountRef.current; + lastUnreadCountRef.current = currentUnreadCount; + + // Préparer les items pour les notifications (messages, max 10) + const notificationItems = data.messages + .slice(0, 10) + .map((msg: any) => ({ + id: msg.id, + title: msg.sender.name || msg.sender.username, + message: msg.text || msg.message || '', + link: '/parole', + timestamp: new Date(msg.rawTimestamp || msg.timestamp), + metadata: { + roomName: msg.roomName, + roomType: msg.roomType, + }, + })); - // Dispatch event for Outlook-style notifications (only for new messages) - // We detect new messages by comparing message count, not unread count - // because new messages might be read immediately - if (previousCount >= 0 && data.messages.length > 0) { - // Get the most recent messages (first ones in the array, sorted by date desc) - // We'll let the hook determine which are truly new - const totalMessages = data.messages.length; - - console.log('[Parole Widget] 💬 Dispatching messages event', { - totalMessages, - previousUnreadCount: previousCount, - currentUnreadCount, + // Déclencher notification update (for badge) + await triggerNotification({ + source: 'rocketchat', + count: currentUnreadCount, + items: notificationItems, }); - - window.dispatchEvent(new CustomEvent('new-messages-detected', { - detail: { - messages: data.messages, - previousCount: previousCount, + + // Dispatch event for Outlook-style notifications (for new messages detected by ID) + if (hasNewMessages) { + console.log('[Parole Widget] 💬 Dispatching new messages event', { + newMessagesCount: newMessageIds.size, + newMessageIds: Array.from(newMessageIds), + previousCount, currentCount: currentUnreadCount, - } - })); + previousMessageIds: Array.from(lastMessageIdsRef.current), + }); + + window.dispatchEvent(new CustomEvent('new-messages-detected', { + detail: { + messages: data.messages, + previousCount: previousCount, + currentCount: currentUnreadCount, + } + })); + } } } + // Always update lastMessageIdsRef to track current state + lastMessageIdsRef.current = currentMessageIds; setMessages(data.messages); } else { console.warn('Unexpected data format:', data); @@ -160,12 +170,14 @@ export function Parole() { }, [status]); // Integrate unified refresh for automatic polling + // Use forceRefresh=true to ensure we get the latest messages immediately const { refresh } = useUnifiedRefresh({ resource: 'parole', interval: REFRESH_INTERVALS.PAROLE, // 30 seconds enabled: status === 'authenticated', onRefresh: async () => { - await fetchMessages(false); // Use cache for auto-refresh + // Use forceRefresh to bypass cache and get latest messages immediately + await fetchMessages(true); // Force refresh to get new messages immediately }, priority: 'high', }); diff --git a/hooks/use-rocketchat-message-notifications.ts b/hooks/use-rocketchat-message-notifications.ts index 855bbde..9a37d14 100644 --- a/hooks/use-rocketchat-message-notifications.ts +++ b/hooks/use-rocketchat-message-notifications.ts @@ -29,65 +29,72 @@ export function useRocketChatMessageNotifications() { return; } - // Only show notifications if the count increased (new messages arrived) - // AND we have a previous count to compare with - if (previousCount >= 0 && currentCount > previousCount) { - // Find new messages (not in lastMessageIdsRef) - these are the ones that just arrived - 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 + // 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)); + // 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 - if (newMessages.length > 0) { - console.log('[useRocketChatMessageNotifications] 💬 New messages detected:', newMessages.length); + // 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 || ''; - 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', + 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'; }, - ], - }; - - notificationQueueRef.current.push(notification); - }); + 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(); - } + // Show the first notification if none is currently showing + if (!isShowingRef.current && notificationQueueRef.current.length > 0) { + showNextNotification(); } } else { - // Just update the message IDs without showing notifications - lastMessageIdsRef.current = new Set(messages.map((m: any) => m.id)); + console.log('[useRocketChatMessageNotifications] ⏭️ No new messages detected', { + previousCount, + currentCount, + totalMessages: messages.length, + lastMessageIdsCount: lastMessageIdsRef.current.size, + }); } };