From 5e81576c68f99dc0fcfe65d2ba00b81c4f5ac6de Mon Sep 17 00:00:00 2001 From: Uruk Date: Wed, 11 Feb 2026 19:09:01 +0100 Subject: [PATCH] feat(home): adds pull to refresh functionality Adds pull-to-refresh functionality on the home screen. This change enhances user experience by allowing users to manually refresh the home screen content. It also ensures that the loading indicator is correctly managed during refresh operations, using a try-finally block. --- components/home/Home.tsx | 11 ++++++---- components/home/HomeWithCarousel.tsx | 30 ++++++++++++++++++++++++---- 2 files changed, 33 insertions(+), 8 deletions(-) diff --git a/components/home/Home.tsx b/components/home/Home.tsx index 047bfe7e..c0435d08 100644 --- a/components/home/Home.tsx +++ b/components/home/Home.tsx @@ -200,10 +200,13 @@ export const Home = () => { const refetch = async () => { setLoading(true); - setLoadedSections(new Set()); - await refreshStreamyfinPluginSettings(); - await invalidateCache(); - setLoading(false); + try { + setLoadedSections(new Set()); + await refreshStreamyfinPluginSettings(); + await invalidateCache(); + } finally { + setLoading(false); + } }; const createCollectionConfig = useCallback( diff --git a/components/home/HomeWithCarousel.tsx b/components/home/HomeWithCarousel.tsx index 802107f7..0d8907da 100644 --- a/components/home/HomeWithCarousel.tsx +++ b/components/home/HomeWithCarousel.tsx @@ -19,6 +19,7 @@ import { useTranslation } from "react-i18next"; import { ActivityIndicator, Platform, + RefreshControl, TouchableOpacity, View, } from "react-native"; @@ -68,7 +69,8 @@ export const HomeWithCarousel = () => { const api = useAtomValue(apiAtom); const user = useAtomValue(userAtom); const insets = useSafeAreaInsets(); - const { settings } = useSettings(); + const { settings, refreshStreamyfinPluginSettings } = useSettings(); + const [loading, setLoading] = useState(false); const headerOverlayOffset = Platform.isTV ? 0 : 60; const navigation = useNavigation(); const animatedScrollRef = useAnimatedRef(); @@ -94,6 +96,16 @@ export const HomeWithCarousel = () => { // Refresh home data on mount (cold start) and when app returns to foreground useRefetchHomeOnForeground(); + const refetch = async () => { + setLoading(true); + try { + await refreshStreamyfinPluginSettings(); + await invalidateCache(); + } finally { + setLoading(false); + } + }; + const hasDownloads = useMemo(() => { if (Platform.isTV) return false; return downloadedItems.length > 0; @@ -536,8 +548,18 @@ export const HomeWithCarousel = () => { nestedScrollEnabled contentInsetAdjustmentBehavior='never' scrollEventThrottle={16} - bounces={false} + bounces={!Platform.isTV} overScrollMode='never' + refreshControl={ + !Platform.isTV ? ( + + ) : undefined + } style={{ marginTop: -headerOverlayOffset }} contentContainerStyle={{ paddingTop: headerOverlayOffset }} onScroll={(event) => { @@ -566,7 +588,7 @@ export const HomeWithCarousel = () => { settings.streamyStatsPromotedWatchlists; const streamystatsSections = index === streamystatsIndex && hasStreamystatsContent ? ( - <> + {settings.streamyStatsMovieRecommendations && ( { {settings.streamyStatsPromotedWatchlists && ( )} - + ) : null; if (section.type === "InfiniteScrollingCollectionList") {