UNPKG

@raphab3/hermes-notifier

Version:

JavaScript/React plugin for Hermes notifications system with SSE support

161 lines (160 loc) 5.42 kB
/** * React hooks for Hermes notifications */ import { useEffect, useState, useCallback, useRef } from 'react'; import { HermesNotifier } from './index'; /** * Hook for managing Hermes notifications in React components */ export function useHermesNotifications(config) { const [notifications, setNotifications] = useState([]); const [connectionStatus, setConnectionStatus] = useState({ connected: false, reconnecting: false, }); const [unreadCount, setUnreadCount] = useState(0); const notifierRef = useRef(null); // Initialize the notifier useEffect(() => { notifierRef.current = new HermesNotifier(config); return () => { if (notifierRef.current) { notifierRef.current.disconnect(); } }; }, [config]); // Set up event handlers useEffect(() => { const notifier = notifierRef.current; if (!notifier) return; // Handle new notifications const unsubscribeNotifications = notifier.onNotification((notification) => { setNotifications(prev => [notification, ...prev]); // Update unread count if notification is unread if (!notification.is_read) { setUnreadCount(prev => prev + 1); } }); // Handle connection status changes const unsubscribeConnection = notifier.onConnectionChange((status) => { setConnectionStatus(status); }); // Handle errors const unsubscribeErrors = notifier.onError((error) => { console.error('Hermes notification error:', error); }); return () => { unsubscribeNotifications(); unsubscribeConnection(); unsubscribeErrors(); }; }, []); // Connect to notifications const connect = useCallback(async () => { if (notifierRef.current) { await notifierRef.current.connect(); // Get initial unread count try { const count = await notifierRef.current.getUnreadCount(); setUnreadCount(count); } catch (error) { console.error('Failed to get initial unread count:', error); } } }, []); // Disconnect from notifications const disconnect = useCallback(() => { if (notifierRef.current) { notifierRef.current.disconnect(); } }, []); // Mark notification as read const markAsRead = useCallback(async (notificationId) => { if (notifierRef.current) { try { await notifierRef.current.markAsRead(notificationId); // Update local state setNotifications(prev => prev.map(n => n.id === notificationId ? { ...n, is_read: true, read_at: new Date().toISOString() } : n)); // Update unread count setUnreadCount(prev => Math.max(0, prev - 1)); } catch (error) { console.error('Failed to mark notification as read:', error); throw error; } } }, []); // Clear all notifications from local state const clearNotifications = useCallback(() => { setNotifications([]); }, []); // Send test notification (for development) const sendTestNotification = useCallback(async (title, body) => { if (notifierRef.current) { await notifierRef.current.sendTestNotification(title, body); } }, []); return { notifications, connectionStatus, unreadCount, connect, disconnect, markAsRead, clearNotifications, sendTestNotification, isConnected: connectionStatus.connected, }; } /** * Hook for simple notification display (just the latest notification) */ export function useLatestNotification(config) { const [latestNotification, setLatestNotification] = useState(null); const [connectionStatus, setConnectionStatus] = useState({ connected: false, reconnecting: false, }); const notifierRef = useRef(null); useEffect(() => { notifierRef.current = new HermesNotifier(config); const unsubscribeNotifications = notifierRef.current.onNotification((notification) => { setLatestNotification(notification); }); const unsubscribeConnection = notifierRef.current.onConnectionChange((status) => { setConnectionStatus(status); }); return () => { if (notifierRef.current) { notifierRef.current.disconnect(); } unsubscribeNotifications(); unsubscribeConnection(); }; }, [config]); const connect = useCallback(async () => { if (notifierRef.current) { await notifierRef.current.connect(); } }, []); const disconnect = useCallback(() => { if (notifierRef.current) { notifierRef.current.disconnect(); } }, []); const clearLatest = useCallback(() => { setLatestNotification(null); }, []); return { latestNotification, connectionStatus, connect, disconnect, clearLatest, isConnected: connectionStatus.connected, }; }