From 7fef2ed5e21457bce4b863d9f565190852ef6506 Mon Sep 17 00:00:00 2001 From: Fredrik Burmester Date: Fri, 3 Oct 2025 07:57:45 +0200 Subject: [PATCH] fix: auto update on download/file actions --- app/(auth)/(tabs)/(home)/downloads/index.tsx | 8 ++++++-- providers/DownloadProvider.tsx | 11 +++++++++++ .../Downloads/hooks/useDownloadEventHandlers.ts | 4 ++++ providers/Downloads/hooks/useDownloadOperations.ts | 12 +++++++++--- 4 files changed, 30 insertions(+), 5 deletions(-) diff --git a/app/(auth)/(tabs)/(home)/downloads/index.tsx b/app/(auth)/(tabs)/(home)/downloads/index.tsx index 26d90486..2c68ac01 100644 --- a/app/(auth)/(tabs)/(home)/downloads/index.tsx +++ b/app/(auth)/(tabs)/(home)/downloads/index.tsx @@ -18,7 +18,10 @@ import ActiveDownloads from "@/components/downloads/ActiveDownloads"; import { DownloadSize } from "@/components/downloads/DownloadSize"; import { MovieCard } from "@/components/downloads/MovieCard"; import { SeriesCard } from "@/components/downloads/SeriesCard"; -import { useDownload } from "@/providers/DownloadProvider"; +import { + downloadsRefreshAtom, + useDownload, +} from "@/providers/DownloadProvider"; import { type DownloadedItem } from "@/providers/Downloads/types"; import { queueAtom } from "@/utils/atoms/queue"; import { writeToLog } from "@/utils/log"; @@ -27,6 +30,7 @@ export default function page() { const navigation = useNavigation(); const { t } = useTranslation(); const [queue, setQueue] = useAtom(queueAtom); + const [refreshKey] = useAtom(downloadsRefreshAtom); const { removeProcess, getDownloadedItems, @@ -64,7 +68,7 @@ export default function page() { const downloadedFiles = useMemo( () => getDownloadedItems(), - [getDownloadedItems], + [getDownloadedItems, refreshKey], ); const movies = useMemo(() => { diff --git a/providers/DownloadProvider.tsx b/providers/DownloadProvider.tsx index c9014178..491f28fd 100644 --- a/providers/DownloadProvider.tsx +++ b/providers/DownloadProvider.tsx @@ -16,6 +16,7 @@ import type { JobStatus } from "./Downloads/types"; import { apiAtom } from "./JellyfinProvider"; export const processesAtom = atom([]); +export const downloadsRefreshAtom = atom(0); const DownloadContext = createContext(processesAtom); + const [, setRefreshKey] = useAtom(downloadsRefreshAtom); const successHapticFeedback = useHaptic("success"); // Track task ID to process ID mapping const taskMapRef = useRef>(new Map()); + // Trigger refresh of download lists + const triggerRefresh = useCallback(() => { + setRefreshKey((prev) => prev + 1); + }, [setRefreshKey]); + const authHeader = useMemo(() => { return api?.accessToken; }, [api]); @@ -81,6 +88,7 @@ function useDownloadProvider() { updateProcess, removeProcess, onSuccess: successHapticFeedback, + onDataChange: triggerRefresh, api: api || undefined, }); @@ -100,6 +108,7 @@ function useDownloadProvider() { removeProcess, api, authHeader, + onDataChange: triggerRefresh, }); return { @@ -115,6 +124,7 @@ function useDownloadProvider() { cancelDownload, getDownloadedItemSize, getDownloadedItemById, + triggerRefresh, APP_CACHE_DOWNLOAD_DIRECTORY: APP_CACHE_DOWNLOAD_DIRECTORY.uri, appSizeUsage, // Deprecated/not implemented in simple version @@ -142,6 +152,7 @@ export function useDownload() { deleteFileByType: async () => {}, removeProcess: () => {}, cancelDownload: async () => {}, + triggerRefresh: () => {}, startDownload: async () => {}, pauseDownload: async () => {}, resumeDownload: async () => {}, diff --git a/providers/Downloads/hooks/useDownloadEventHandlers.ts b/providers/Downloads/hooks/useDownloadEventHandlers.ts index 9c89fe58..9adb9bc6 100644 --- a/providers/Downloads/hooks/useDownloadEventHandlers.ts +++ b/providers/Downloads/hooks/useDownloadEventHandlers.ts @@ -41,6 +41,7 @@ interface UseDownloadEventHandlersProps { ) => void; removeProcess: (id: string) => void; onSuccess?: () => void; + onDataChange?: () => void; api?: Api; } @@ -53,6 +54,7 @@ export function useDownloadEventHandlers({ updateProcess, removeProcess, onSuccess, + onDataChange, api, }: UseDownloadEventHandlersProps) { const { t } = useTranslation(); @@ -235,6 +237,7 @@ export function useDownloadEventHandlers({ ); onSuccess?.(); + onDataChange?.(); // Clean up speed data when download completes clearSpeedData(processId); @@ -259,6 +262,7 @@ export function useDownloadEventHandlers({ updateProcess, removeProcess, onSuccess, + onDataChange, api, saveImage, saveSeriesPrimaryImage, diff --git a/providers/Downloads/hooks/useDownloadOperations.ts b/providers/Downloads/hooks/useDownloadOperations.ts index 7d15537c..8682f56f 100644 --- a/providers/Downloads/hooks/useDownloadOperations.ts +++ b/providers/Downloads/hooks/useDownloadOperations.ts @@ -32,6 +32,7 @@ interface UseDownloadOperationsProps { removeProcess: (id: string) => void; api: any; authHeader?: string; + onDataChange?: () => void; } /** @@ -44,6 +45,7 @@ export function useDownloadOperations({ removeProcess, api, authHeader, + onDataChange, }: UseDownloadOperationsProps) { const { t } = useTranslation(); const { saveSeriesPrimaryImage } = useDownloadHelper(); @@ -182,12 +184,13 @@ export function useDownloadOperations({ item: itemToDelete.item.Name, }), ); + onDataChange?.(); } catch (error) { console.error("Failed to delete files:", error); } } }, - [t], + [t, onDataChange], ); const deleteItems = useCallback( @@ -212,7 +215,8 @@ export function useDownloadOperations({ clearAllDownloadedItems(); toast.success(t("home.downloads.toasts.all_files_deleted")); - }, [t]); + onDataChange?.(); + }, [t, onDataChange]); const deleteFileByType = useCallback( async (itemType: string) => { @@ -256,8 +260,10 @@ export function useDownloadOperations({ defaultValue: `${itemsToDelete.length} ${itemLabel} deleted`, }), ); + + onDataChange?.(); }, - [t], + [t, onDataChange], ); const appSizeUsage = useCallback(async () => {