Files
ChatApp/apps/desktop/src/lib/usePeerPresence.ts
T
2026-04-18 23:11:35 +02:00

52 lines
1.4 KiB
TypeScript

import type { PresenceState } from '@chat-app/shared/supabase';
import { useEffect, useState } from 'react';
import { supabase } from './supabase';
// Subscribe to a single peer's presence_state via Supabase realtime.
// Returns null until the first row arrives, or when userId is undefined.
export function usePeerPresence(userId: string | undefined): PresenceState | null {
const [presence, setPresence] = useState<PresenceState | null>(null);
useEffect(() => {
if (!userId) {
setPresence(null);
return;
}
let cancelled = false;
void supabase
.from('profiles')
.select('presence_state')
.eq('user_id', userId)
.maybeSingle()
.then(({ data }) => {
if (!cancelled) setPresence(data?.presence_state ?? null);
});
const channel = supabase
.channel('peer-presence:' + userId)
.on(
'postgres_changes',
{
event: 'UPDATE',
schema: 'public',
table: 'profiles',
filter: 'user_id=eq.' + userId,
},
(payload: { new: Record<string, unknown> }) => {
const next = payload.new['presence_state'];
if (typeof next === 'string') setPresence(next as PresenceState);
},
)
.subscribe();
return () => {
cancelled = true;
void supabase.removeChannel(channel);
};
}, [userId]);
return presence;
}