diff --git a/components/home/Home.tsx b/components/home/Home.tsx index 1da3b358..047bfe7e 100644 --- a/components/home/Home.tsx +++ b/components/home/Home.tsx @@ -35,6 +35,7 @@ import { MediaListSection } from "@/components/medialists/MediaListSection"; import { Colors } from "@/constants/Colors"; import useRouter from "@/hooks/useAppRouter"; import { useNetworkStatus } from "@/hooks/useNetworkStatus"; +import { useRefetchHomeOnForeground } from "@/hooks/useRefetchHomeOnForeground"; import { useInvalidatePlaybackProgressCache } from "@/hooks/useRevalidatePlaybackProgressCache"; import { useDownload } from "@/providers/DownloadProvider"; import { useIntroSheet } from "@/providers/IntroSheetProvider"; @@ -107,6 +108,9 @@ export const Home = () => { prevIsConnected.current = isConnected; }, [isConnected, invalidateCache]); + // Refresh home data on mount (cold start) and when app returns to foreground + useRefetchHomeOnForeground(); + const hasDownloads = useMemo(() => { if (Platform.isTV) return false; return downloadedItems.length > 0; diff --git a/components/home/HomeWithCarousel.tsx b/components/home/HomeWithCarousel.tsx index c513294f..802107f7 100644 --- a/components/home/HomeWithCarousel.tsx +++ b/components/home/HomeWithCarousel.tsx @@ -37,6 +37,7 @@ import { MediaListSection } from "@/components/medialists/MediaListSection"; import { Colors } from "@/constants/Colors"; import useRouter from "@/hooks/useAppRouter"; import { useNetworkStatus } from "@/hooks/useNetworkStatus"; +import { useRefetchHomeOnForeground } from "@/hooks/useRefetchHomeOnForeground"; import { useInvalidatePlaybackProgressCache } from "@/hooks/useRevalidatePlaybackProgressCache"; import { useDownload } from "@/providers/DownloadProvider"; import { apiAtom, userAtom } from "@/providers/JellyfinProvider"; @@ -67,8 +68,7 @@ export const HomeWithCarousel = () => { const api = useAtomValue(apiAtom); const user = useAtomValue(userAtom); const insets = useSafeAreaInsets(); - const [_loading, setLoading] = useState(false); - const { settings, refreshStreamyfinPluginSettings } = useSettings(); + const { settings } = useSettings(); const headerOverlayOffset = Platform.isTV ? 0 : 60; const navigation = useNavigation(); const animatedScrollRef = useAnimatedRef(); @@ -91,6 +91,9 @@ export const HomeWithCarousel = () => { prevIsConnected.current = isConnected; }, [isConnected, invalidateCache]); + // Refresh home data on mount (cold start) and when app returns to foreground + useRefetchHomeOnForeground(); + const hasDownloads = useMemo(() => { if (Platform.isTV) return false; return downloadedItems.length > 0; @@ -178,13 +181,6 @@ export const HomeWithCarousel = () => { ); }, [userViews]); - const _refetch = async () => { - setLoading(true); - await refreshStreamyfinPluginSettings(); - await invalidateCache(); - setLoading(false); - }; - const createCollectionConfig = useCallback( ( title: string, diff --git a/hooks/useRefetchHomeOnForeground.ts b/hooks/useRefetchHomeOnForeground.ts new file mode 100644 index 00000000..4f9b3e89 --- /dev/null +++ b/hooks/useRefetchHomeOnForeground.ts @@ -0,0 +1,32 @@ +import { useQueryClient } from "@tanstack/react-query"; +import { useEffect } from "react"; +import { AppState } from "react-native"; + +/** + * Refetches active home queries on mount (cold start) and whenever + * the app returns to the foreground from background. + */ +export function useRefetchHomeOnForeground() { + const queryClient = useQueryClient(); + + useEffect(() => { + // On mount (cold start), use cancelRefetch: false so we don't cancel + // an in-flight initial fetch that React Query already started. + queryClient.refetchQueries( + { queryKey: ["home"], type: "active" }, + { cancelRefetch: false }, + ); + + const subscription = AppState.addEventListener("change", (state) => { + if (state === "active") { + // On foreground return, force a fresh refetch + queryClient.refetchQueries( + { queryKey: ["home"], type: "active" }, + { cancelRefetch: true }, + ); + } + }); + + return () => subscription.remove(); + }, [queryClient]); +}