import { apiAtom, userAtom } from "@/providers/JellyfinProvider"; import { markAsNotPlayed } from "@/utils/jellyfin/playstate/markAsNotPlayed"; import { markAsPlayed } from "@/utils/jellyfin/playstate/markAsPlayed"; import type { BaseItemDto } from "@jellyfin/sdk/lib/generated-client/models"; import { useQueryClient } from "@tanstack/react-query"; import { useAtom } from "jotai"; import { useHaptic } from "./useHaptic"; export const useMarkAsPlayed = (items: BaseItemDto[]) => { const [api] = useAtom(apiAtom); const [user] = useAtom(userAtom); const queryClient = useQueryClient(); const lightHapticFeedback = useHaptic("light"); const invalidateQueries = () => { const queriesToInvalidate = [ ["resumeItems"], ["continueWatching"], ["nextUp-all"], ["nextUp"], ["episodes"], ["seasons"], ["home"], ]; items.forEach((item) => { if (!item.Id) return; queriesToInvalidate.push(["item", item.Id]); }); queriesToInvalidate.forEach((queryKey) => { queryClient.invalidateQueries({ queryKey }); }); }; const markAsPlayedStatus = async (played: boolean) => { lightHapticFeedback(); items.forEach((item) => { // Optimistic update queryClient.setQueryData( ["item", item.Id], (oldData: BaseItemDto | undefined) => { if (oldData) { return { ...oldData, UserData: { ...oldData.UserData, Played: played, }, }; } return oldData; }, ); }); try { // Process all items await Promise.all( items.map((item) => played ? markAsPlayed({ api, item, userId: user?.Id }) : markAsNotPlayed({ api, itemId: item?.Id, userId: user?.Id }), ), ); // Bulk invalidate queryClient.invalidateQueries({ queryKey: [ "resumeItems", "continueWatching", "nextUp-all", "nextUp", "episodes", "seasons", "home", ...items.map((item) => ["item", item.Id]), ].flat(), }); } catch (error) { // Revert all optimistic updates on any failure items.forEach((item) => { queryClient.setQueryData( ["item", item.Id], (oldData: BaseItemDto | undefined) => oldData ? { ...oldData, UserData: { ...oldData.UserData, Played: played }, } : oldData, ); }); console.error("Error updating played status:", error); } invalidateQueries(); }; return markAsPlayedStatus; };