Merge branch 'pr/238'

This commit is contained in:
Fredrik Burmester
2024-12-02 11:35:22 +01:00
4 changed files with 61 additions and 18 deletions

View File

@@ -2,19 +2,49 @@ import { BaseItemDto } from "@jellyfin/sdk/lib/generated-client/models";
import React, {useEffect, useMemo, useState} from "react";
import {Text} from "@/components/common/Text";
import useDownloadHelper from "@/utils/download";
import {useDownload} from "@/providers/DownloadProvider";
interface DownloadSizeProps {
items: BaseItemDto[];
}
interface DownloadSizes {
knownSize: number;
itemsNeedingSize: BaseItemDto[];
}
export const DownloadSize: React.FC<DownloadSizeProps> = ({ items }) => {
const { downloadedFiles, saveDownloadedItemInfo } = useDownload();
const { getDownloadSize } = useDownloadHelper();
const [size, setSize] = useState<string | undefined>();
const itemIds = useMemo(() => items.map(i => i.Id), [items])
useEffect(() => {
getDownloadSize(...items).then(setSize)
if (!downloadedFiles)
return
const {knownSize, itemsNeedingSize} = downloadedFiles
.filter(f => itemIds.includes(f.item.Id))
?.reduce<DownloadSizes>((acc, file) => {
if (file?.size && file.size > 0)
acc.knownSize += file.size
else
acc.itemsNeedingSize.push(file.item)
return acc
}, {
knownSize: 0,
itemsNeedingSize: []
})
getDownloadSize(
(item, size) => saveDownloadedItemInfo(item, size),
...itemsNeedingSize
).then(sizeSum => {
setSize(bytesToReadable((sizeSum + knownSize)))
})
},
[items]
[items, itemIds]
);
const sizeText = useMemo(() => {
@@ -23,6 +53,14 @@ export const DownloadSize: React.FC<DownloadSizeProps> = ({ items }) => {
return size
}, [size])
const bytesToReadable = (bytes: number) => {
const gb = bytes / 1e+9;
if (gb >= 1)
return `${gb.toFixed(2)} GB`
return `${(bytes / 1024 / 1024).toFixed(2)} MB`
}
return (
<>
<Text className="text-xs text-neutral-500">{sizeText}</Text>

View File

@@ -128,7 +128,8 @@ export const useRemuxHlsToMp4 = () => {
}s`
);
if (!item) throw new Error("Item is undefined");
await saveDownloadedItemInfo(item);
const stat = await session.getLastReceivedStatistics();
await saveDownloadedItemInfo(item, stat.getSize());
toast.success("Download completed");
await queryClient.invalidateQueries({
queryKey: ["downloadedItems"],

View File

@@ -51,6 +51,7 @@ import useDownloadHelper from "@/utils/download";
export type DownloadedItem = {
item: Partial<BaseItemDto>;
mediaSource: MediaSourceInfo;
size: number | undefined;
};
function onAppStateChange(status: AppStateStatus) {
@@ -260,8 +261,8 @@ function useDownloadProvider() {
)
);
})
.done(async () => {
await saveDownloadedItemInfo(process.item);
.done(async (doneHandler) => {
await saveDownloadedItemInfo(process.item, doneHandler.bytesDownloaded);
toast.success(`Download completed for ${process.item.Name}`, {
duration: 3000,
action: {
@@ -522,7 +523,7 @@ function useDownloadProvider() {
}
}
function saveDownloadedItemInfo(item: BaseItemDto) {
function saveDownloadedItemInfo(item: BaseItemDto, size: number = 0) {
try {
const downloadedItems = storage.getString("downloadedItems");
let items: DownloadedItem[] = downloadedItems
@@ -538,7 +539,7 @@ function useDownloadProvider() {
"Media source not found in tmp storage. Did you forget to save it before starting download?"
);
const newItem = { item, mediaSource: data.mediaSource };
const newItem = { item, size, mediaSource: data.mediaSource };
if (existingItemIndex !== -1) {
items[existingItemIndex] = newItem;

View File

@@ -5,9 +5,10 @@ import {apiAtom} from "@/providers/JellyfinProvider";
import {useAtom} from "jotai";
import {storage} from "@/utils/mmkv";
import {getDownloadedFileUrl} from "@/hooks/useDownloadedFileOpener";
import * as FileSystem from 'expo-file-system'
import * as FileSystem from 'expo-file-system';
import {FileInfo} from "expo-file-system";
const useDownloadHelper = () => {
const [api] = useAtom(apiAtom);
const {saveImage} = useImageStorage();
@@ -18,7 +19,10 @@ const useDownloadHelper = () => {
}
}
const getDownloadSize = async (...items: BaseItemDto[]) => {
const getDownloadSize = async (
onNewItemSizeFetched: (item: BaseItemDto, size: number) => void,
...items: BaseItemDto[]
) => {
const sizes: number[] = [];
await Promise.all(items.map(item => {
@@ -26,18 +30,17 @@ const useDownloadHelper = () => {
const url = await getDownloadedFileUrl(item.Id!);
if (url) {
const fileInfo: FileInfo = await FileSystem.getInfoAsync(url);
sizes.push(fileInfo.size);
resolve(sizes);
} else reject();
if (fileInfo.exists) {
onNewItemSizeFetched(item, fileInfo.size)
sizes.push(fileInfo.size);
resolve(sizes)
}
}
reject();
})
}));
const size = sizes.reduce((sum, size) => sum + size, 0);
const gb = size / 1e+9;
if (gb >= 1)
return `${gb.toFixed(2)} GB`;
return `${(size / 1024 / 1024).toFixed(2)} MB`;
return sizes.reduce((sum, size) => sum + size, 0);
}
return { saveSeriesPrimaryImage, getDownloadSize }