This commit is contained in:
2026-04-18 23:11:35 +02:00
commit f7cfd2a86e
196 changed files with 35538 additions and 0 deletions
+53
View File
@@ -0,0 +1,53 @@
import { type Friendship, listFriendships } from '@chat-app/shared/friends';
import { useCallback, useEffect, useState } from 'react';
import { supabase } from './supabase';
interface FriendshipsState {
friendships: Friendship[];
loading: boolean;
error: string | null;
}
// Subscribes to the `friendships` realtime channel and re-pulls the typed
// list whenever an INSERT/UPDATE/DELETE touches one of the caller's rows.
export function useFriendships(userId: string | undefined): FriendshipsState & {
refresh: () => Promise<void>;
} {
const [state, setState] = useState<FriendshipsState>({
friendships: [],
loading: true,
error: null,
});
const refresh = useCallback(async () => {
try {
const items = await listFriendships(supabase);
setState({ friendships: items, loading: false, error: null });
} catch (err: unknown) {
setState((prev) => ({
...prev,
loading: false,
error: err instanceof Error ? err.message : 'failed to load friendships',
}));
}
}, []);
useEffect(() => {
if (!userId) return;
void refresh();
const channel = supabase
.channel('friendships:' + userId)
.on('postgres_changes', { event: '*', schema: 'public', table: 'friendships' }, () => {
void refresh();
})
.subscribe();
return () => {
void supabase.removeChannel(channel);
};
}, [userId, refresh]);
return { ...state, refresh };
}