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