fix: load active downloads on app open

This commit is contained in:
Fredrik Burmester
2025-02-17 17:24:11 +01:00
parent f30f53f566
commit ec153ebfc6
3 changed files with 45 additions and 27 deletions

View File

@@ -34,6 +34,14 @@ async function cancelDownload(id: string): Promise<void> {
return HlsDownloaderModule.cancelDownload(id);
}
/**
*
* @returns A list of active downloads.
*/
async function getActiveDownloads(): Promise<DownloadInfo[]> {
return HlsDownloaderModule.getActiveDownloads();
}
/**
* Subscribes to download progress events.
* @param listener A callback invoked with progress updates.
@@ -104,4 +112,5 @@ export {
addProgressListener,
HlsDownloaderModule,
cancelDownload,
getActiveDownloads,
};

View File

@@ -73,6 +73,18 @@ public class HlsDownloaderModule: Module {
Events("onProgress", "onError", "onComplete")
Function("getActiveDownloads") { () -> [[String: Any]] in
return activeDownloads.map { (taskId, downloadInfo) in
return [
"id": downloadInfo.delegate.providedId,
"state": "DOWNLOADING",
"metadata": downloadInfo.metadata,
"startTime": downloadInfo.startTime,
"taskId": taskId,
]
}
}
Function("downloadHLSAsset") {
(providedId: String, url: String, metadata: [String: Any]?) -> Void in
let startTime = Date().timeIntervalSince1970

View File

@@ -1,10 +1,10 @@
import useImageStorage from "@/hooks/useImageStorage";
import {
addCompleteListener,
addErrorListener,
addProgressListener,
downloadHLSAsset,
cancelDownload,
downloadHLSAsset,
getActiveDownloads,
} from "@/modules/hls-downloader";
import {
DownloadInfo,
@@ -12,13 +12,12 @@ import {
} from "@/modules/hls-downloader/src/HlsDownloader.types";
import { getItemImage } from "@/utils/getItemImage";
import { getStreamUrl } from "@/utils/jellyfin/media/getStreamUrl";
import { rewriteM3U8Files } from "@/utils/movpkg-to-vlc/tools";
import download from "@/utils/profiles/download";
import {
BaseItemDto,
MediaSourceInfo,
} from "@jellyfin/sdk/lib/generated-client/models";
import { useQuery, useQueryClient } from "@tanstack/react-query";
import { useQuery } from "@tanstack/react-query";
import * as FileSystem from "expo-file-system";
import { useAtomValue } from "jotai";
import { createContext, useContext, useEffect, useState } from "react";
@@ -55,28 +54,6 @@ const DownloadContext = createContext<DownloadContextType | undefined>(
undefined
);
/**
* Marks a file as done by creating a file with the same name in the downloads directory.
* @param doneFile - The name of the file to mark as done.
*/
const markFileAsDone = async (id: string) => {
await FileSystem.writeAsStringAsync(
`${FileSystem.documentDirectory}downloads/${id}-done`,
"done"
);
};
/**
* Checks if a file is marked as done by checking if a file with the same name exists in the downloads directory.
* @param doneFile - The name of the file to check.
* @returns True if the file is marked as done, false otherwise.
*/
const isFileMarkedAsDone = async (id: string) => {
const fileUri = `${FileSystem.documentDirectory}downloads/${id}-done`;
const fileInfo = await FileSystem.getInfoAsync(fileUri);
return fileInfo.exists;
};
export type DownloadedFileInfo = {
id: string;
path: string;
@@ -129,7 +106,6 @@ export const NativeDownloadProvider: React.FC<{
}> = ({ children }) => {
const [downloads, setDownloads] = useState<Record<string, DownloadInfo>>({});
const { saveImage } = useImageStorage();
const queryClient = useQueryClient();
const user = useAtomValue(userAtom);
const api = useAtomValue(apiAtom);
@@ -144,6 +120,27 @@ export const NativeDownloadProvider: React.FC<{
});
useEffect(() => {
const _getActiveDownloads = async () => {
const activeDownloads = await getActiveDownloads();
setDownloads((prev) => {
const newDownloads = { ...prev };
activeDownloads.forEach((download) => {
newDownloads[download.id] = {
id: download.id,
progress: download.progress,
state: download.state,
secondsDownloaded: download.secondsDownloaded,
secondsTotal: download.secondsTotal,
metadata: download.metadata,
startTime: download.startTime,
};
});
return newDownloads;
});
};
_getActiveDownloads();
const progressListener = addProgressListener((download) => {
if (!download.metadata) throw new Error("No metadata found in download");