|
|
@@ -2,7 +2,7 @@
|
|
|
|
|
|
import { useCallback } from "react";
|
|
|
import type { RealtimePostgresChangesPayload } from "@supabase/supabase-js";
|
|
|
-import { useQueryClient } from "@tanstack/react-query";
|
|
|
+import { useQueryClient, type InfiniteData } from "@tanstack/react-query";
|
|
|
import type { Database } from "@/types/database";
|
|
|
import { useRealtimeChannel } from "./use-realtime-channel";
|
|
|
import { buildEqFilter } from "@/lib/realtime/subscription-manager";
|
|
|
@@ -10,7 +10,7 @@ import { buildEqFilter } from "@/lib/realtime/subscription-manager";
|
|
|
type MovieRow = Database["public"]["Tables"]["movies"]["Row"];
|
|
|
|
|
|
function moviesQueryKey(groupId: string): readonly [string, string] {
|
|
|
- return ["movies", groupId] as const;
|
|
|
+ return ["group-movies", groupId] as const;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -29,24 +29,39 @@ export function useRealtimeMovies(groupId: string | null) {
|
|
|
|
|
|
if (payload.eventType === "INSERT") {
|
|
|
const newMovie = payload.new;
|
|
|
- queryClient.setQueryData<MovieRow[]>(key, (old) => {
|
|
|
- if (!old) return [newMovie];
|
|
|
- // Avoid duplicates (e.g., if the local optimistic update already added it)
|
|
|
- if (old.some((m) => m.id === newMovie.id)) return old;
|
|
|
- return [...old, newMovie];
|
|
|
+ queryClient.setQueryData<InfiniteData<MovieRow[]>>(key, (old) => {
|
|
|
+ if (!old) return undefined;
|
|
|
+ // Avoid duplicates across all pages
|
|
|
+ if (old.pages.some((page) => page.some((m) => m.id === newMovie.id)))
|
|
|
+ return old;
|
|
|
+ // Prepend to first page (ordered by added_at DESC)
|
|
|
+ return {
|
|
|
+ pages: [[newMovie, ...old.pages[0]], ...old.pages.slice(1)],
|
|
|
+ pageParams: old.pageParams,
|
|
|
+ };
|
|
|
});
|
|
|
} else if (payload.eventType === "UPDATE") {
|
|
|
const updated = payload.new;
|
|
|
- queryClient.setQueryData<MovieRow[]>(key, (old) => {
|
|
|
- if (!old) return old;
|
|
|
- return old.map((m) => (m.id === updated.id ? updated : m));
|
|
|
+ queryClient.setQueryData<InfiniteData<MovieRow[]>>(key, (old) => {
|
|
|
+ if (!old) return undefined;
|
|
|
+ return {
|
|
|
+ pages: old.pages.map((page) =>
|
|
|
+ page.map((m) => (m.id === updated.id ? updated : m)),
|
|
|
+ ),
|
|
|
+ pageParams: old.pageParams,
|
|
|
+ };
|
|
|
});
|
|
|
} else if (payload.eventType === "DELETE") {
|
|
|
const deleted = payload.old;
|
|
|
if (deleted && "id" in deleted) {
|
|
|
- queryClient.setQueryData<MovieRow[]>(key, (old) => {
|
|
|
- if (!old) return old;
|
|
|
- return old.filter((m) => m.id !== deleted.id);
|
|
|
+ queryClient.setQueryData<InfiniteData<MovieRow[]>>(key, (old) => {
|
|
|
+ if (!old) return undefined;
|
|
|
+ return {
|
|
|
+ pages: old.pages.map((page) =>
|
|
|
+ page.filter((m) => m.id !== deleted.id),
|
|
|
+ ),
|
|
|
+ pageParams: old.pageParams,
|
|
|
+ };
|
|
|
});
|
|
|
}
|
|
|
}
|