Pages corrections widget

This commit is contained in:
alma 2026-01-16 17:19:59 +01:00
parent 8f5a63042c
commit 430940cc12
2 changed files with 122 additions and 103 deletions

View File

@ -48,6 +48,7 @@ export function Parole() {
const { data: session, status } = useSession(); const { data: session, status } = useSession();
const { triggerNotification } = useWidgetNotification(); const { triggerNotification } = useWidgetNotification();
const lastUnreadCountRef = useRef<number>(-1); // Initialize to -1 to detect first load const lastUnreadCountRef = useRef<number>(-1); // Initialize to -1 to detect first load
const lastMessageIdsRef = useRef<Set<string>>(new Set());
const isInitializedRef = useRef<boolean>(false); const isInitializedRef = useRef<boolean>(false);
const fetchMessages = async (forceRefresh = false) => { const fetchMessages = async (forceRefresh = false) => {
@ -74,68 +75,77 @@ export function Parole() {
if (Array.isArray(data.messages)) { if (Array.isArray(data.messages)) {
// Utiliser le totalUnreadCount de l'API (plus fiable) // Utiliser le totalUnreadCount de l'API (plus fiable)
const currentUnreadCount = data.totalUnreadCount || 0; const currentUnreadCount = data.totalUnreadCount || 0;
const currentMessageIds = new Set(data.messages.map((m: any) => m.id));
// Update unread count state for badge display // Update unread count state for badge display
setUnreadCount(currentUnreadCount); setUnreadCount(currentUnreadCount);
// On initialise le count au premier chargement // Detect new messages by comparing IDs (more reliable than count)
if (!isInitializedRef.current) { const newMessageIds = new Set(
isInitializedRef.current = true; Array.from(currentMessageIds).filter(id => !lastMessageIdsRef.current.has(id))
lastUnreadCountRef.current = -1; // Set to -1 to trigger on first load );
console.log('[Parole] Initial unread count:', currentUnreadCount); const hasNewMessages = newMessageIds.size > 0;
}
// Si le count a changé (ou premier chargement), déclencher notification // On initialise au premier chargement
if (currentUnreadCount !== lastUnreadCountRef.current) { if (!isInitializedRef.current) {
const previousCount = lastUnreadCountRef.current; console.log('[Parole Widget] 💬 Initializing - storing existing message IDs without notifications', {
lastUnreadCountRef.current = currentUnreadCount; messageCount: data.messages.length,
unreadCount: 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,
}); });
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) // Déclencher notification update (for badge)
// We detect new messages by comparing message count, not unread count await triggerNotification({
// because new messages might be read immediately source: 'rocketchat',
if (previousCount >= 0 && data.messages.length > 0) { count: currentUnreadCount,
// Get the most recent messages (first ones in the array, sorted by date desc) items: notificationItems,
// 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,
}); });
window.dispatchEvent(new CustomEvent('new-messages-detected', { // Dispatch event for Outlook-style notifications (for new messages detected by ID)
detail: { if (hasNewMessages) {
messages: data.messages, console.log('[Parole Widget] 💬 Dispatching new messages event', {
previousCount: previousCount, newMessagesCount: newMessageIds.size,
newMessageIds: Array.from(newMessageIds),
previousCount,
currentCount: currentUnreadCount, 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); setMessages(data.messages);
} else { } else {
console.warn('Unexpected data format:', data); console.warn('Unexpected data format:', data);
@ -160,12 +170,14 @@ export function Parole() {
}, [status]); }, [status]);
// Integrate unified refresh for automatic polling // Integrate unified refresh for automatic polling
// Use forceRefresh=true to ensure we get the latest messages immediately
const { refresh } = useUnifiedRefresh({ const { refresh } = useUnifiedRefresh({
resource: 'parole', resource: 'parole',
interval: REFRESH_INTERVALS.PAROLE, // 30 seconds interval: REFRESH_INTERVALS.PAROLE, // 30 seconds
enabled: status === 'authenticated', enabled: status === 'authenticated',
onRefresh: async () => { 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', priority: 'high',
}); });

View File

@ -29,65 +29,72 @@ export function useRocketChatMessageNotifications() {
return; return;
} }
// Only show notifications if the count increased (new messages arrived) // Find new messages by comparing IDs (more reliable than count comparison)
// AND we have a previous count to compare with // This works even if previousCount is -1 (first load after initialization)
if (previousCount >= 0 && currentCount > previousCount) { const newMessages = messages
// Find new messages (not in lastMessageIdsRef) - these are the ones that just arrived .filter((message: any) => {
const newMessages = messages const messageId = message.id;
.filter((message: any) => { return !lastMessageIdsRef.current.has(messageId);
const messageId = message.id; })
return !lastMessageIdsRef.current.has(messageId); .slice(0, 5); // Limit to 5 most recent new messages
})
.slice(0, 5); // Limit to 5 most recent new messages
// Update lastMessageIdsRef with all current messages // Update lastMessageIdsRef with all current messages
lastMessageIdsRef.current = new Set(messages.map((m: any) => m.id)); lastMessageIdsRef.current = new Set(messages.map((m: any) => m.id));
// If there are new messages, queue them for notification // If there are new messages, queue them for notification
if (newMessages.length > 0) { // This works regardless of previousCount value
console.log('[useRocketChatMessageNotifications] 💬 New messages detected:', newMessages.length); 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 notification: OutlookNotificationData = {
const senderName = message.sender?.name || message.sender?.username || 'Inconnu'; id: `rocketchat-${message.id}-${Date.now()}`,
const roomName = message.roomName || 'Chat'; source: 'rocketchat',
const messageText = message.text || message.message || ''; title: 'Parole',
subtitle: 'Nouveau message',
const notification: OutlookNotificationData = { message: `${senderName} dans ${roomName}: ${messageText.length > 50 ? messageText.substring(0, 50) + '...' : messageText}`,
id: `rocketchat-${message.id}-${Date.now()}`, icon: MessageSquare,
source: 'rocketchat', iconColor: 'text-purple-600',
title: 'Parole', iconBgColor: 'bg-purple-100',
subtitle: 'Nouveau message', borderColor: 'border-purple-500',
message: `${senderName} dans ${roomName}: ${messageText.length > 50 ? messageText.substring(0, 50) + '...' : messageText}`, link: '/parole',
icon: MessageSquare, timestamp: new Date(message.rawTimestamp || message.timestamp),
iconColor: 'text-purple-600', autoDismiss: 10000, // 10 seconds for messages
iconBgColor: 'bg-purple-100', actions: [
borderColor: 'border-purple-500', {
link: '/parole', label: 'Ouvrir',
timestamp: new Date(message.rawTimestamp || message.timestamp), onClick: () => {
autoDismiss: 10000, // 10 seconds for messages window.location.href = '/parole';
actions: [
{
label: 'Ouvrir',
onClick: () => {
window.location.href = '/parole';
},
variant: 'default',
className: 'bg-purple-600 hover:bg-purple-700 text-white',
}, },
], variant: 'default',
}; className: 'bg-purple-600 hover:bg-purple-700 text-white',
},
notificationQueueRef.current.push(notification); ],
}); };
notificationQueueRef.current.push(notification);
});
// Show the first notification if none is currently showing // Show the first notification if none is currently showing
if (!isShowingRef.current && notificationQueueRef.current.length > 0) { if (!isShowingRef.current && notificationQueueRef.current.length > 0) {
showNextNotification(); showNextNotification();
}
} }
} else { } else {
// Just update the message IDs without showing notifications console.log('[useRocketChatMessageNotifications] ⏭️ No new messages detected', {
lastMessageIdsRef.current = new Set(messages.map((m: any) => m.id)); previousCount,
currentCount,
totalMessages: messages.length,
lastMessageIdsCount: lastMessageIdsRef.current.size,
});
} }
}; };