initial
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
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;
|
||||
}
|
||||
Reference in New Issue
Block a user