fix: auto update on download/file actions

This commit is contained in:
Fredrik Burmester
2025-10-03 07:57:45 +02:00
parent c36cd66e36
commit 7fef2ed5e2
4 changed files with 30 additions and 5 deletions

View File

@@ -18,7 +18,10 @@ import ActiveDownloads from "@/components/downloads/ActiveDownloads";
import { DownloadSize } from "@/components/downloads/DownloadSize"; import { DownloadSize } from "@/components/downloads/DownloadSize";
import { MovieCard } from "@/components/downloads/MovieCard"; import { MovieCard } from "@/components/downloads/MovieCard";
import { SeriesCard } from "@/components/downloads/SeriesCard"; 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 { type DownloadedItem } from "@/providers/Downloads/types";
import { queueAtom } from "@/utils/atoms/queue"; import { queueAtom } from "@/utils/atoms/queue";
import { writeToLog } from "@/utils/log"; import { writeToLog } from "@/utils/log";
@@ -27,6 +30,7 @@ export default function page() {
const navigation = useNavigation(); const navigation = useNavigation();
const { t } = useTranslation(); const { t } = useTranslation();
const [queue, setQueue] = useAtom(queueAtom); const [queue, setQueue] = useAtom(queueAtom);
const [refreshKey] = useAtom(downloadsRefreshAtom);
const { const {
removeProcess, removeProcess,
getDownloadedItems, getDownloadedItems,
@@ -64,7 +68,7 @@ export default function page() {
const downloadedFiles = useMemo( const downloadedFiles = useMemo(
() => getDownloadedItems(), () => getDownloadedItems(),
[getDownloadedItems], [getDownloadedItems, refreshKey],
); );
const movies = useMemo(() => { const movies = useMemo(() => {

View File

@@ -16,6 +16,7 @@ import type { JobStatus } from "./Downloads/types";
import { apiAtom } from "./JellyfinProvider"; import { apiAtom } from "./JellyfinProvider";
export const processesAtom = atom<JobStatus[]>([]); export const processesAtom = atom<JobStatus[]>([]);
export const downloadsRefreshAtom = atom<number>(0);
const DownloadContext = createContext<ReturnType< const DownloadContext = createContext<ReturnType<
typeof useDownloadProvider typeof useDownloadProvider
@@ -24,11 +25,17 @@ const DownloadContext = createContext<ReturnType<
function useDownloadProvider() { function useDownloadProvider() {
const [api] = useAtom(apiAtom); const [api] = useAtom(apiAtom);
const [processes, setProcesses] = useAtom<JobStatus[]>(processesAtom); const [processes, setProcesses] = useAtom<JobStatus[]>(processesAtom);
const [, setRefreshKey] = useAtom(downloadsRefreshAtom);
const successHapticFeedback = useHaptic("success"); const successHapticFeedback = useHaptic("success");
// Track task ID to process ID mapping // Track task ID to process ID mapping
const taskMapRef = useRef<Map<number, string>>(new Map()); const taskMapRef = useRef<Map<number, string>>(new Map());
// Trigger refresh of download lists
const triggerRefresh = useCallback(() => {
setRefreshKey((prev) => prev + 1);
}, [setRefreshKey]);
const authHeader = useMemo(() => { const authHeader = useMemo(() => {
return api?.accessToken; return api?.accessToken;
}, [api]); }, [api]);
@@ -81,6 +88,7 @@ function useDownloadProvider() {
updateProcess, updateProcess,
removeProcess, removeProcess,
onSuccess: successHapticFeedback, onSuccess: successHapticFeedback,
onDataChange: triggerRefresh,
api: api || undefined, api: api || undefined,
}); });
@@ -100,6 +108,7 @@ function useDownloadProvider() {
removeProcess, removeProcess,
api, api,
authHeader, authHeader,
onDataChange: triggerRefresh,
}); });
return { return {
@@ -115,6 +124,7 @@ function useDownloadProvider() {
cancelDownload, cancelDownload,
getDownloadedItemSize, getDownloadedItemSize,
getDownloadedItemById, getDownloadedItemById,
triggerRefresh,
APP_CACHE_DOWNLOAD_DIRECTORY: APP_CACHE_DOWNLOAD_DIRECTORY.uri, APP_CACHE_DOWNLOAD_DIRECTORY: APP_CACHE_DOWNLOAD_DIRECTORY.uri,
appSizeUsage, appSizeUsage,
// Deprecated/not implemented in simple version // Deprecated/not implemented in simple version
@@ -142,6 +152,7 @@ export function useDownload() {
deleteFileByType: async () => {}, deleteFileByType: async () => {},
removeProcess: () => {}, removeProcess: () => {},
cancelDownload: async () => {}, cancelDownload: async () => {},
triggerRefresh: () => {},
startDownload: async () => {}, startDownload: async () => {},
pauseDownload: async () => {}, pauseDownload: async () => {},
resumeDownload: async () => {}, resumeDownload: async () => {},

View File

@@ -41,6 +41,7 @@ interface UseDownloadEventHandlersProps {
) => void; ) => void;
removeProcess: (id: string) => void; removeProcess: (id: string) => void;
onSuccess?: () => void; onSuccess?: () => void;
onDataChange?: () => void;
api?: Api; api?: Api;
} }
@@ -53,6 +54,7 @@ export function useDownloadEventHandlers({
updateProcess, updateProcess,
removeProcess, removeProcess,
onSuccess, onSuccess,
onDataChange,
api, api,
}: UseDownloadEventHandlersProps) { }: UseDownloadEventHandlersProps) {
const { t } = useTranslation(); const { t } = useTranslation();
@@ -235,6 +237,7 @@ export function useDownloadEventHandlers({
); );
onSuccess?.(); onSuccess?.();
onDataChange?.();
// Clean up speed data when download completes // Clean up speed data when download completes
clearSpeedData(processId); clearSpeedData(processId);
@@ -259,6 +262,7 @@ export function useDownloadEventHandlers({
updateProcess, updateProcess,
removeProcess, removeProcess,
onSuccess, onSuccess,
onDataChange,
api, api,
saveImage, saveImage,
saveSeriesPrimaryImage, saveSeriesPrimaryImage,

View File

@@ -32,6 +32,7 @@ interface UseDownloadOperationsProps {
removeProcess: (id: string) => void; removeProcess: (id: string) => void;
api: any; api: any;
authHeader?: string; authHeader?: string;
onDataChange?: () => void;
} }
/** /**
@@ -44,6 +45,7 @@ export function useDownloadOperations({
removeProcess, removeProcess,
api, api,
authHeader, authHeader,
onDataChange,
}: UseDownloadOperationsProps) { }: UseDownloadOperationsProps) {
const { t } = useTranslation(); const { t } = useTranslation();
const { saveSeriesPrimaryImage } = useDownloadHelper(); const { saveSeriesPrimaryImage } = useDownloadHelper();
@@ -182,12 +184,13 @@ export function useDownloadOperations({
item: itemToDelete.item.Name, item: itemToDelete.item.Name,
}), }),
); );
onDataChange?.();
} catch (error) { } catch (error) {
console.error("Failed to delete files:", error); console.error("Failed to delete files:", error);
} }
} }
}, },
[t], [t, onDataChange],
); );
const deleteItems = useCallback( const deleteItems = useCallback(
@@ -212,7 +215,8 @@ export function useDownloadOperations({
clearAllDownloadedItems(); clearAllDownloadedItems();
toast.success(t("home.downloads.toasts.all_files_deleted")); toast.success(t("home.downloads.toasts.all_files_deleted"));
}, [t]); onDataChange?.();
}, [t, onDataChange]);
const deleteFileByType = useCallback( const deleteFileByType = useCallback(
async (itemType: string) => { async (itemType: string) => {
@@ -256,8 +260,10 @@ export function useDownloadOperations({
defaultValue: `${itemsToDelete.length} ${itemLabel} deleted`, defaultValue: `${itemsToDelete.length} ${itemLabel} deleted`,
}), }),
); );
onDataChange?.();
}, },
[t], [t, onDataChange],
); );
const appSizeUsage = useCallback(async () => { const appSizeUsage = useCallback(async () => {