mirror of
https://github.com/streamyfin/streamyfin.git
synced 2026-06-01 19:48:28 +01:00
fix: auto update on download/file actions
This commit is contained in:
@@ -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(() => {
|
||||||
|
|||||||
@@ -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 () => {},
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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 () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user