From 235202383ac82c6b73af93b44a8c4d01cc9cf838 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") {