124 lines
3.7 KiB
TypeScript
124 lines
3.7 KiB
TypeScript
import { useState, useEffect, useCallback } from 'react'
|
|
import { notificationService } from '@/lib/notificationService'
|
|
import type { Notification } from '@/lib/notificationService'
|
|
|
|
const MAX_NOTIFICATIONS = 100
|
|
const POLL_INTERVAL_MS = 30_000
|
|
|
|
export function useNotifications(userPubkey: string | null): {
|
|
notifications: Notification[]
|
|
unreadCount: number
|
|
loading: boolean
|
|
markAsRead: (notificationId: string) => void
|
|
markAllAsRead: () => void
|
|
deleteNotification: (notificationId: string) => void
|
|
} {
|
|
const [notifications, setNotifications] = useState<Notification[]>([])
|
|
const [loading, setLoading] = useState(true)
|
|
|
|
useEffect(() => {
|
|
if (!userPubkey) {
|
|
return
|
|
}
|
|
|
|
void loadAndSetNotifications({ setNotifications, setLoading })
|
|
const interval = setInterval(() => {
|
|
void loadAndSetNotifications({ setNotifications, setLoading })
|
|
}, POLL_INTERVAL_MS)
|
|
return () => clearInterval(interval)
|
|
}, [userPubkey])
|
|
|
|
const effectiveNotifications = userPubkey ? notifications : []
|
|
const effectiveLoading = userPubkey ? loading : false
|
|
const unreadCount = effectiveNotifications.filter((n) => !n.read).length
|
|
|
|
const markAsRead = useCallback(
|
|
(notificationId: string): void => {
|
|
if (!userPubkey) {
|
|
return
|
|
}
|
|
void markAsReadAndRefresh({ notificationId, setNotifications })
|
|
},
|
|
[userPubkey]
|
|
)
|
|
|
|
const markAllAsReadHandler = useCallback((): void => {
|
|
if (!userPubkey) {
|
|
return
|
|
}
|
|
void markAllAsReadAndRefresh({ setNotifications })
|
|
}, [userPubkey])
|
|
|
|
const deleteNotificationHandler = useCallback(
|
|
(notificationId: string): void => {
|
|
if (!userPubkey) {
|
|
return
|
|
}
|
|
void deleteNotificationAndRefresh({ notificationId, setNotifications })
|
|
},
|
|
[userPubkey]
|
|
)
|
|
|
|
return {
|
|
notifications: effectiveNotifications,
|
|
unreadCount,
|
|
loading: effectiveLoading,
|
|
markAsRead,
|
|
markAllAsRead: markAllAsReadHandler,
|
|
deleteNotification: deleteNotificationHandler,
|
|
}
|
|
}
|
|
|
|
async function loadAndSetNotifications(params: {
|
|
setNotifications: (value: Notification[]) => void
|
|
setLoading: (value: boolean) => void
|
|
}): Promise<void> {
|
|
try {
|
|
params.setLoading(true)
|
|
params.setNotifications(await notificationService.getAllNotifications(MAX_NOTIFICATIONS))
|
|
} catch (error) {
|
|
console.error('[useNotifications] Error loading notifications:', error)
|
|
} finally {
|
|
params.setLoading(false)
|
|
}
|
|
}
|
|
|
|
async function refreshNotifications(params: { setNotifications: (value: Notification[]) => void }): Promise<void> {
|
|
params.setNotifications(await notificationService.getAllNotifications(MAX_NOTIFICATIONS))
|
|
}
|
|
|
|
async function markAsReadAndRefresh(params: {
|
|
notificationId: string
|
|
setNotifications: (value: Notification[]) => void
|
|
}): Promise<void> {
|
|
try {
|
|
await notificationService.markAsRead(params.notificationId)
|
|
await refreshNotifications({ setNotifications: params.setNotifications })
|
|
} catch (error) {
|
|
console.error('[useNotifications] Error marking notification as read:', error)
|
|
}
|
|
}
|
|
|
|
async function markAllAsReadAndRefresh(params: {
|
|
setNotifications: (value: Notification[]) => void
|
|
}): Promise<void> {
|
|
try {
|
|
await notificationService.markAllAsRead()
|
|
await refreshNotifications({ setNotifications: params.setNotifications })
|
|
} catch (error) {
|
|
console.error('[useNotifications] Error marking all as read:', error)
|
|
}
|
|
}
|
|
|
|
async function deleteNotificationAndRefresh(params: {
|
|
notificationId: string
|
|
setNotifications: (value: Notification[]) => void
|
|
}): Promise<void> {
|
|
try {
|
|
await notificationService.deleteNotification(params.notificationId)
|
|
await refreshNotifications({ setNotifications: params.setNotifications })
|
|
} catch (error) {
|
|
console.error('[useNotifications] Error deleting notification:', error)
|
|
}
|
|
}
|