136 lines
5.0 KiB
TypeScript
136 lines
5.0 KiB
TypeScript
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<OutlookNotificationData | null>(null);
|
|
const lastMessageIdsRef = useRef<Set<string>>(new Set());
|
|
const notificationQueueRef = useRef<OutlookNotificationData[]>([]);
|
|
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,
|
|
};
|
|
}
|