import { listPeerDeliveriesForMessages, markMessagesDelivered, } from '@chat-app/shared/chat'; import { useCallback, useEffect, useMemo, useState } from 'react'; import { supabase } from './supabase'; // Tracks peer delivery acknowledgements for our own messages. Single peer // (DM). For groups this would need a per-user map; keep parity with // `useMessageReads` for now. export function useMessageDeliveries( messageIds: string[], peerUserId: string | undefined, ): { peerDeliveredSet: Set; refresh: () => Promise } { const idsKey = useMemo(() => messageIds.join(','), [messageIds]); const [peerDeliveredSet, setPeerDeliveredSet] = useState>(new Set()); const refresh = useCallback(async () => { if (!peerUserId || messageIds.length === 0) { setPeerDeliveredSet(new Set()); return; } try { const s = await listPeerDeliveriesForMessages(supabase, messageIds, peerUserId); setPeerDeliveredSet(s); } catch (err: unknown) { console.error('listPeerDeliveriesForMessages failed', err); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [peerUserId, idsKey]); useEffect(() => { void refresh(); if (!peerUserId) return; const channel = supabase .channel('deliveries:' + peerUserId) .on( 'postgres_changes', { event: 'INSERT', schema: 'public', table: 'message_deliveries', filter: 'user_id=eq.' + peerUserId, }, () => { void refresh(); }, ) .subscribe(); return () => { void supabase.removeChannel(channel); }; }, [peerUserId, refresh]); return { peerDeliveredSet, refresh }; } export async function markDelivered(messageIds: string[]): Promise { await markMessagesDelivered(supabase, messageIds); }