mirror of
https://github.com/streamyfin/streamyfin.git
synced 2026-01-15 15:48:05 +00:00
297 lines
8.2 KiB
TypeScript
297 lines
8.2 KiB
TypeScript
import { useMutation } from "@tanstack/react-query";
|
|
import { useAtomValue } from "jotai";
|
|
import { useCallback } from "react";
|
|
import { toast } from "sonner-native";
|
|
import { useNetworkAwareQueryClient } from "@/hooks/useNetworkAwareQueryClient";
|
|
import { apiAtom } from "@/providers/JellyfinProvider";
|
|
import { useSettings } from "@/utils/atoms/settings";
|
|
import { createStreamystatsApi } from "@/utils/streamystats/api";
|
|
import type {
|
|
CreateWatchlistRequest,
|
|
StreamystatsWatchlist,
|
|
UpdateWatchlistRequest,
|
|
} from "@/utils/streamystats/types";
|
|
|
|
/**
|
|
* Hook to create a new watchlist
|
|
*/
|
|
export const useCreateWatchlist = () => {
|
|
const api = useAtomValue(apiAtom);
|
|
const { settings } = useSettings();
|
|
const queryClient = useNetworkAwareQueryClient();
|
|
|
|
const mutation = useMutation({
|
|
mutationFn: async (
|
|
data: CreateWatchlistRequest,
|
|
): Promise<StreamystatsWatchlist> => {
|
|
if (!settings?.streamyStatsServerUrl || !api?.accessToken) {
|
|
throw new Error("Streamystats not configured");
|
|
}
|
|
|
|
const streamystatsApi = createStreamystatsApi({
|
|
serverUrl: settings.streamyStatsServerUrl,
|
|
jellyfinToken: api.accessToken,
|
|
});
|
|
|
|
const response = await streamystatsApi.createWatchlist(data);
|
|
if (response.error) {
|
|
throw new Error(response.error);
|
|
}
|
|
return response.data;
|
|
},
|
|
onSuccess: () => {
|
|
queryClient.invalidateQueries({
|
|
queryKey: ["streamystats", "watchlists"],
|
|
});
|
|
toast.success("Watchlist created");
|
|
},
|
|
onError: (error: Error) => {
|
|
toast.error(error.message || "Failed to create watchlist");
|
|
},
|
|
});
|
|
|
|
return mutation;
|
|
};
|
|
|
|
/**
|
|
* Hook to update a watchlist
|
|
*/
|
|
export const useUpdateWatchlist = () => {
|
|
const api = useAtomValue(apiAtom);
|
|
const { settings } = useSettings();
|
|
const queryClient = useNetworkAwareQueryClient();
|
|
|
|
const mutation = useMutation({
|
|
mutationFn: async ({
|
|
watchlistId,
|
|
data,
|
|
}: {
|
|
watchlistId: number;
|
|
data: UpdateWatchlistRequest;
|
|
}): Promise<StreamystatsWatchlist> => {
|
|
if (!settings?.streamyStatsServerUrl || !api?.accessToken) {
|
|
throw new Error("Streamystats not configured");
|
|
}
|
|
|
|
const streamystatsApi = createStreamystatsApi({
|
|
serverUrl: settings.streamyStatsServerUrl,
|
|
jellyfinToken: api.accessToken,
|
|
});
|
|
|
|
const response = await streamystatsApi.updateWatchlist(watchlistId, data);
|
|
if (response.error) {
|
|
throw new Error(response.error);
|
|
}
|
|
return response.data;
|
|
},
|
|
onSuccess: (_data, variables) => {
|
|
queryClient.invalidateQueries({
|
|
queryKey: ["streamystats", "watchlists"],
|
|
});
|
|
queryClient.invalidateQueries({
|
|
queryKey: ["streamystats", "watchlist", variables.watchlistId],
|
|
});
|
|
toast.success("Watchlist updated");
|
|
},
|
|
onError: (error: Error) => {
|
|
toast.error(error.message || "Failed to update watchlist");
|
|
},
|
|
});
|
|
|
|
return mutation;
|
|
};
|
|
|
|
/**
|
|
* Hook to delete a watchlist
|
|
*/
|
|
export const useDeleteWatchlist = () => {
|
|
const api = useAtomValue(apiAtom);
|
|
const { settings } = useSettings();
|
|
const queryClient = useNetworkAwareQueryClient();
|
|
|
|
const mutation = useMutation({
|
|
mutationFn: async (watchlistId: number): Promise<void> => {
|
|
if (!settings?.streamyStatsServerUrl || !api?.accessToken) {
|
|
throw new Error("Streamystats not configured");
|
|
}
|
|
|
|
const streamystatsApi = createStreamystatsApi({
|
|
serverUrl: settings.streamyStatsServerUrl,
|
|
jellyfinToken: api.accessToken,
|
|
});
|
|
|
|
const response = await streamystatsApi.deleteWatchlist(watchlistId);
|
|
if (response.error) {
|
|
throw new Error(response.error);
|
|
}
|
|
},
|
|
onSuccess: (_data, watchlistId) => {
|
|
queryClient.invalidateQueries({
|
|
queryKey: ["streamystats", "watchlists"],
|
|
});
|
|
queryClient.removeQueries({
|
|
queryKey: ["streamystats", "watchlist", watchlistId],
|
|
});
|
|
toast.success("Watchlist deleted");
|
|
},
|
|
onError: (error: Error) => {
|
|
toast.error(error.message || "Failed to delete watchlist");
|
|
},
|
|
});
|
|
|
|
return mutation;
|
|
};
|
|
|
|
/**
|
|
* Hook to add an item to a watchlist with optimistic update
|
|
*/
|
|
export const useAddToWatchlist = () => {
|
|
const api = useAtomValue(apiAtom);
|
|
const { settings } = useSettings();
|
|
const queryClient = useNetworkAwareQueryClient();
|
|
|
|
const mutation = useMutation({
|
|
mutationFn: async ({
|
|
watchlistId,
|
|
itemId,
|
|
}: {
|
|
watchlistId: number;
|
|
itemId: string;
|
|
watchlistName?: string;
|
|
}): Promise<void> => {
|
|
if (!settings?.streamyStatsServerUrl || !api?.accessToken) {
|
|
throw new Error("Streamystats not configured");
|
|
}
|
|
|
|
const streamystatsApi = createStreamystatsApi({
|
|
serverUrl: settings.streamyStatsServerUrl,
|
|
jellyfinToken: api.accessToken,
|
|
});
|
|
|
|
const response = await streamystatsApi.addWatchlistItem(
|
|
watchlistId,
|
|
itemId,
|
|
);
|
|
if (response.error) {
|
|
throw new Error(response.error);
|
|
}
|
|
},
|
|
onSuccess: (_data, variables) => {
|
|
queryClient.invalidateQueries({
|
|
queryKey: ["streamystats", "watchlist", variables.watchlistId],
|
|
});
|
|
queryClient.invalidateQueries({
|
|
queryKey: ["streamystats", "watchlistItems", variables.watchlistId],
|
|
});
|
|
queryClient.invalidateQueries({
|
|
queryKey: ["streamystats", "itemInWatchlists", variables.itemId],
|
|
});
|
|
if (variables.watchlistName) {
|
|
toast.success(`Added to ${variables.watchlistName}`);
|
|
} else {
|
|
toast.success("Added to watchlist");
|
|
}
|
|
},
|
|
onError: (error: Error) => {
|
|
toast.error(error.message || "Failed to add to watchlist");
|
|
},
|
|
});
|
|
|
|
return mutation;
|
|
};
|
|
|
|
/**
|
|
* Hook to remove an item from a watchlist with optimistic update
|
|
*/
|
|
export const useRemoveFromWatchlist = () => {
|
|
const api = useAtomValue(apiAtom);
|
|
const { settings } = useSettings();
|
|
const queryClient = useNetworkAwareQueryClient();
|
|
|
|
const mutation = useMutation({
|
|
mutationFn: async ({
|
|
watchlistId,
|
|
itemId,
|
|
}: {
|
|
watchlistId: number;
|
|
itemId: string;
|
|
watchlistName?: string;
|
|
}): Promise<void> => {
|
|
if (!settings?.streamyStatsServerUrl || !api?.accessToken) {
|
|
throw new Error("Streamystats not configured");
|
|
}
|
|
|
|
const streamystatsApi = createStreamystatsApi({
|
|
serverUrl: settings.streamyStatsServerUrl,
|
|
jellyfinToken: api.accessToken,
|
|
});
|
|
|
|
const response = await streamystatsApi.removeWatchlistItem(
|
|
watchlistId,
|
|
itemId,
|
|
);
|
|
if (response.error) {
|
|
throw new Error(response.error);
|
|
}
|
|
},
|
|
onSuccess: (_data, variables) => {
|
|
queryClient.invalidateQueries({
|
|
queryKey: ["streamystats", "watchlist", variables.watchlistId],
|
|
});
|
|
queryClient.invalidateQueries({
|
|
queryKey: ["streamystats", "watchlistItems", variables.watchlistId],
|
|
});
|
|
queryClient.invalidateQueries({
|
|
queryKey: ["streamystats", "itemInWatchlists", variables.itemId],
|
|
});
|
|
if (variables.watchlistName) {
|
|
toast.success(`Removed from ${variables.watchlistName}`);
|
|
} else {
|
|
toast.success("Removed from watchlist");
|
|
}
|
|
},
|
|
onError: (error: Error) => {
|
|
toast.error(error.message || "Failed to remove from watchlist");
|
|
},
|
|
});
|
|
|
|
return mutation;
|
|
};
|
|
|
|
/**
|
|
* Hook to toggle an item in a watchlist
|
|
*/
|
|
export const useToggleWatchlistItem = () => {
|
|
const addMutation = useAddToWatchlist();
|
|
const removeMutation = useRemoveFromWatchlist();
|
|
|
|
const toggle = useCallback(
|
|
async (params: {
|
|
watchlistId: number;
|
|
itemId: string;
|
|
isInWatchlist: boolean;
|
|
watchlistName?: string;
|
|
}) => {
|
|
if (params.isInWatchlist) {
|
|
await removeMutation.mutateAsync({
|
|
watchlistId: params.watchlistId,
|
|
itemId: params.itemId,
|
|
watchlistName: params.watchlistName,
|
|
});
|
|
} else {
|
|
await addMutation.mutateAsync({
|
|
watchlistId: params.watchlistId,
|
|
itemId: params.itemId,
|
|
watchlistName: params.watchlistName,
|
|
});
|
|
}
|
|
},
|
|
[addMutation, removeMutation],
|
|
);
|
|
|
|
return {
|
|
toggle,
|
|
isLoading: addMutation.isPending || removeMutation.isPending,
|
|
};
|
|
};
|