import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; import { getThreadSubscription, setThreadSubscription } from "~/fns/notification-settings"; import { errorMessage } from "~/lib/error-message"; import type { QueryClient } from "@tanstack/react-query"; type Thread = { owner: string; repo: string; number: number }; type Subscription = Awaited>; export const threadSubscriptionQueryKey = ({ owner, repo, number }: Thread) => ["thread-subscription", owner, repo, number] as const; export async function refreshThreadSubscription(queryClient: QueryClient, thread: Thread): Promise { await queryClient.invalidateQueries({ queryKey: threadSubscriptionQueryKey(thread) }); } export function useThreadSubscription(thread: Thread) { const queryClient = useQueryClient(); const key = threadSubscriptionQueryKey(thread); const query = useQuery({ queryKey: key, queryFn: () => getThreadSubscription({ data: thread }) }); const mutation = useMutation({ mutationFn: (subscribed: boolean) => setThreadSubscription({ data: { ...thread, subscribed } }), onSuccess: (_result, subscribed) => { queryClient.setQueryData(key, { subscribed, reason: "manual" }); return refreshThreadSubscription(queryClient, thread); }, }); const state = query.data ?? null; function toggle() { if (state) mutation.mutate(!state.subscribed); } return { state, toggle, pending: mutation.isPending, error: mutation.error ? errorMessage(mutation.error) : null }; }