mirror of
https://github.com/streamyfin/streamyfin.git
synced 2026-06-14 18:00:32 +01:00
some cleanups
This commit is contained in:
@@ -33,7 +33,7 @@ interface FavoritesProps {
|
||||
emptyTitleKey?: string;
|
||||
emptyTextKey?: string;
|
||||
/** Namespace for the see-all page headers ("favorites" or "kefintweaksWatchlist"). */
|
||||
seeAllNamespace?: string;
|
||||
seeAllNamespace?: "kefintweaksWatchlist" | "favorites";
|
||||
}
|
||||
|
||||
export const Favorites = ({
|
||||
@@ -143,71 +143,18 @@ export const Favorites = ({
|
||||
[fetchFavoritesByType, pageSize],
|
||||
);
|
||||
|
||||
const handleSeeAllSeries = useCallback(() => {
|
||||
router.push({
|
||||
pathname: "/(auth)/(tabs)/(favorites)/see-all",
|
||||
params: {
|
||||
type: "Series",
|
||||
title: t(`${seeAllNamespace}.seeAllSeries`),
|
||||
filter,
|
||||
},
|
||||
} as any);
|
||||
}, [router, filter, seeAllNamespace]);
|
||||
|
||||
const handleSeeAllMovies = useCallback(() => {
|
||||
router.push({
|
||||
pathname: "/(auth)/(tabs)/(favorites)/see-all",
|
||||
params: {
|
||||
type: "Movie",
|
||||
title: t(`${seeAllNamespace}.seeAllMovies`),
|
||||
filter,
|
||||
},
|
||||
} as any);
|
||||
}, [router, filter, seeAllNamespace]);
|
||||
|
||||
const handleSeeAllEpisodes = useCallback(() => {
|
||||
router.push({
|
||||
pathname: "/(auth)/(tabs)/(favorites)/see-all",
|
||||
params: {
|
||||
type: "Episode",
|
||||
title: t(`${seeAllNamespace}.seeAllEpisodes`),
|
||||
filter,
|
||||
},
|
||||
} as any);
|
||||
}, [router, filter, seeAllNamespace]);
|
||||
|
||||
const handleSeeAllVideos = useCallback(() => {
|
||||
router.push({
|
||||
pathname: "/(auth)/(tabs)/(favorites)/see-all",
|
||||
params: {
|
||||
type: "Video",
|
||||
title: t(`${seeAllNamespace}.seeAllVideos`),
|
||||
filter,
|
||||
},
|
||||
} as any);
|
||||
}, [router, filter, seeAllNamespace]);
|
||||
|
||||
const handleSeeAllBoxsets = useCallback(() => {
|
||||
router.push({
|
||||
pathname: "/(auth)/(tabs)/(favorites)/see-all",
|
||||
params: {
|
||||
type: "BoxSet",
|
||||
title: t(`${seeAllNamespace}.seeAllBoxsets`),
|
||||
filter,
|
||||
},
|
||||
} as any);
|
||||
}, [router, filter, seeAllNamespace]);
|
||||
|
||||
const handleSeeAllPlaylists = useCallback(() => {
|
||||
router.push({
|
||||
pathname: "/(auth)/(tabs)/(favorites)/see-all",
|
||||
params: {
|
||||
type: "Playlist",
|
||||
title: t(`${seeAllNamespace}.seeAllPlaylists`),
|
||||
filter,
|
||||
},
|
||||
} as any);
|
||||
}, [router, filter, seeAllNamespace]);
|
||||
// Navigate to the shared see-all screen. `titleKey` is the see-all header
|
||||
// segment in the active namespace (e.g. "seeAllSeries"). The cast is needed
|
||||
// because the route's custom params aren't part of expo-router's typed Href.
|
||||
const seeAll = useCallback(
|
||||
(type: FavoriteTypes, titleKey: string) => {
|
||||
router.push({
|
||||
pathname: "/(auth)/(tabs)/(favorites)/see-all",
|
||||
params: { type, title: t(`${seeAllNamespace}.${titleKey}`), filter },
|
||||
} as any);
|
||||
},
|
||||
[router, filter, seeAllNamespace],
|
||||
);
|
||||
|
||||
return (
|
||||
<View className='flex flex-co gap-y-4'>
|
||||
@@ -233,7 +180,7 @@ export const Favorites = ({
|
||||
title={t("favorites.series")}
|
||||
hideIfEmpty
|
||||
pageSize={pageSize}
|
||||
onPressSeeAll={handleSeeAllSeries}
|
||||
onPressSeeAll={() => seeAll("Series", "seeAllSeries")}
|
||||
/>
|
||||
<InfiniteScrollingCollectionList
|
||||
queryFn={fetchFavoriteMovies}
|
||||
@@ -242,7 +189,7 @@ export const Favorites = ({
|
||||
hideIfEmpty
|
||||
orientation='vertical'
|
||||
pageSize={pageSize}
|
||||
onPressSeeAll={handleSeeAllMovies}
|
||||
onPressSeeAll={() => seeAll("Movie", "seeAllMovies")}
|
||||
/>
|
||||
<InfiniteScrollingCollectionList
|
||||
queryFn={fetchFavoriteEpisodes}
|
||||
@@ -250,7 +197,7 @@ export const Favorites = ({
|
||||
title={t("favorites.episodes")}
|
||||
hideIfEmpty
|
||||
pageSize={pageSize}
|
||||
onPressSeeAll={handleSeeAllEpisodes}
|
||||
onPressSeeAll={() => seeAll("Episode", "seeAllEpisodes")}
|
||||
/>
|
||||
<InfiniteScrollingCollectionList
|
||||
queryFn={fetchFavoriteVideos}
|
||||
@@ -258,7 +205,7 @@ export const Favorites = ({
|
||||
title={t("favorites.videos")}
|
||||
hideIfEmpty
|
||||
pageSize={pageSize}
|
||||
onPressSeeAll={handleSeeAllVideos}
|
||||
onPressSeeAll={() => seeAll("Video", "seeAllVideos")}
|
||||
/>
|
||||
<InfiniteScrollingCollectionList
|
||||
queryFn={fetchFavoriteBoxsets}
|
||||
@@ -266,7 +213,7 @@ export const Favorites = ({
|
||||
title={t("favorites.boxsets")}
|
||||
hideIfEmpty
|
||||
pageSize={pageSize}
|
||||
onPressSeeAll={handleSeeAllBoxsets}
|
||||
onPressSeeAll={() => seeAll("BoxSet", "seeAllBoxsets")}
|
||||
/>
|
||||
<InfiniteScrollingCollectionList
|
||||
queryFn={fetchFavoritePlaylists}
|
||||
@@ -274,7 +221,7 @@ export const Favorites = ({
|
||||
title={t("favorites.playlists")}
|
||||
hideIfEmpty
|
||||
pageSize={pageSize}
|
||||
onPressSeeAll={handleSeeAllPlaylists}
|
||||
onPressSeeAll={() => seeAll("Playlist", "seeAllPlaylists")}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
|
||||
@@ -2,6 +2,7 @@ import type { BaseItemDto } from "@jellyfin/sdk/lib/generated-client";
|
||||
import { useMutation, useQueryClient } from "@tanstack/react-query";
|
||||
import { atom, useAtom } from "jotai";
|
||||
import { useCallback, useEffect, useMemo, useRef } from "react";
|
||||
import { toast } from "sonner-native";
|
||||
import { apiAtom, userAtom } from "@/providers/JellyfinProvider";
|
||||
|
||||
// Shared atom to store watchlist (Likes) status across all components
|
||||
@@ -92,7 +93,7 @@ export const useWatchlist = (item: BaseItemDto) => {
|
||||
const currentItem = itemRef.current;
|
||||
|
||||
if (!currentApi || !currentUser?.Id || !currentItem?.Id) {
|
||||
return;
|
||||
throw new Error("Cannot update watchlist: not signed in");
|
||||
}
|
||||
|
||||
// Watchlist == Jellyfin "Likes" rating:
|
||||
@@ -120,13 +121,15 @@ export const useWatchlist = (item: BaseItemDto) => {
|
||||
|
||||
return { previousIsWatchlisted, previousQueries };
|
||||
},
|
||||
onError: (_err, _nextIsWatchlisted, context) => {
|
||||
onError: (error: Error, _nextIsWatchlisted, context) => {
|
||||
// Roll back the optimistic Likes flip applied in onMutate.
|
||||
if (context?.previousQueries) {
|
||||
for (const [queryKey, data] of context.previousQueries) {
|
||||
queryClient.setQueryData(queryKey, data);
|
||||
}
|
||||
}
|
||||
setIsWatchlisted(context?.previousIsWatchlisted);
|
||||
toast.error(error.message || "Failed to update watchlist");
|
||||
},
|
||||
onSettled: () => {
|
||||
queryClient.invalidateQueries({ queryKey: itemQueryKeyPrefix });
|
||||
|
||||
Reference in New Issue
Block a user