import { IndeterminateProgress } from "@/components/custom/indeterminateProgress";
import { ProxyImage } from "@/components/custom/proxyImage";
import { AspectRatio } from "@/components/ui/aspect-ratio";
import { Button } from "@/components/ui/button";
import { Progress } from "@/components/ui/progress";
import { toast } from "sonner";
import { useAppContext } from "@/providers/appContextProvider";
import { useDownloadActionStatesStore, useSettingsPageStatesStore } from "@/services/store";
import { formatFileSize, formatSecToTimeString, formatSpeed } from "@/utils";
import { ArrowUpRightIcon, CircleCheck, File, Info, ListVideo, Loader2, Music, Pause, Play, RotateCw, Video, X } from "lucide-react";
import { DownloadState } from "@/types/download";
import { Empty, EmptyDescription, EmptyHeader, EmptyMedia, EmptyTitle } from "@/components/ui/empty";
import { useNavigate } from "react-router-dom";
interface IncompleteDownloadProps {
state: DownloadState;
}
interface IncompleteDownloadsProps {
downloads: DownloadState[];
}
export function IncompleteDownload({ state }: IncompleteDownloadProps) {
const downloadActions = useDownloadActionStatesStore(state => state.downloadActions);
const setIsResumingDownload = useDownloadActionStatesStore(state => state.setIsResumingDownload);
const setIsPausingDownload = useDownloadActionStatesStore(state => state.setIsPausingDownload);
const setIsCancelingDownload = useDownloadActionStatesStore(state => state.setIsCancelingDownload);
const debugMode = useSettingsPageStatesStore(state => state.settings.debug_mode);
const { pauseDownload, resumeDownload, cancelDownload } = useAppContext()
const itemActionStates = downloadActions[state.download_id] || {
isResuming: false,
isPausing: false,
isCanceling: false,
isDeleteFileChecked: false,
};
const isPlaylist = state.playlist_id !== null && state.playlist_indices !== null;
const isMultiplePlaylistItems = isPlaylist && state.playlist_indices && state.playlist_indices.includes(',');
return (
{isMultiplePlaylistItems ? (
) : (
)}
{isMultiplePlaylistItems ? (
Playlist ({state.playlist_indices?.split(',').length})
) : state.ext ? (
{state.filetype && (state.filetype === 'video' || state.filetype === 'video+audio') && (
)}
{state.filetype && state.filetype === 'audio' && (
)}
{(!state.filetype) || (state.filetype && state.filetype !== 'video' && state.filetype !== 'audio' && state.filetype !== 'video+audio') && (
)}
{state.ext ? state.ext.toUpperCase() : 'Unknown'} {state.resolution ? `(${state.resolution})` : null}
) : (
{state.download_status === 'starting' ? (
<> Processing...>
) : (
<> Unknown>
)}
)}
{isMultiplePlaylistItems ? state.playlist_title : state.title}
{((state.download_status === 'starting') || (state.download_status === 'downloading' && state.status === 'finished')) && (
)}
{(state.download_status === 'downloading' || state.download_status === 'paused' || state.download_status === 'errored') && state.progress && state.status !== 'finished' && (
{isMultiplePlaylistItems && state.item ? (
({state.item})
) : null}
{state.progress}%
{
state.downloaded && state.total
? `(${formatFileSize(state.downloaded)} / ${formatFileSize(state.total)})`
: null
}
)}
{state.download_status && state.download_status === 'downloading' && state.status === 'finished' ? (
Processing
) : state.download_status && state.download_status === 'errored' ? (
Errored
) : (
{state.download_status.charAt(0).toUpperCase() + state.download_status.slice(1)}
)} {
(debugMode && state.download_id) || (state.download_status === 'errored' && state.download_id) && (
<>• ID: {state.download_id.toUpperCase()}>
)} {
state.download_status === 'downloading' && state.status !== 'finished' && state.speed && (
<>• Speed: {formatSpeed(state.speed)}>
)} {state.download_status === 'downloading' && state.eta && (
<>• ETA: {formatSecToTimeString(state.eta)}>
)}
{state.download_status === 'paused' ? (
{
setIsResumingDownload(state.download_id, true);
try {
await resumeDownload(state)
// toast.success("Resumed Download", {
// description: "Download resumed, it will re-start shortly.",
// })
} catch (e) {
console.error(e);
toast.error("Failed to Resume Download", {
description: `An error occurred while trying to resume the download for "${state.title}".`,
})
} finally {
setIsResumingDownload(state.download_id, false);
}
}}
disabled={itemActionStates.isResuming || itemActionStates.isCanceling}
>
{itemActionStates.isResuming ? (
<>
Resuming
>
) : (
<>
Resume
>
)}
) : state.download_status === 'errored' ? (
{
setIsResumingDownload(state.download_id, true);
try {
await resumeDownload(state);
} catch (e) {
console.error(e);
toast.error("Failed to Restart Download", {
description: `An error occurred while trying to restart the download for "${state.title}".`,
})
} finally {
setIsResumingDownload(state.download_id, false);
}
}}
disabled={itemActionStates.isResuming || itemActionStates.isCanceling}
>
{itemActionStates.isResuming ? (
<>
Retrying
>
) : (
<>
Retry
>
)}
) : (
{
setIsPausingDownload(state.download_id, true);
try {
await pauseDownload(state)
// toast.success("Paused Download", {
// description: "Download paused successfully.",
// })
} catch (e) {
console.error(e);
toast.error("Failed to Pause Download", {
description: `An error occurred while trying to pause the download for "${state.title}".`,
})
} finally {
setIsPausingDownload(state.download_id, false);
}
}}
disabled={itemActionStates.isPausing || itemActionStates.isCanceling || state.download_status !== 'downloading' || (state.download_status === 'downloading' && state.status === 'finished')}
>
{itemActionStates.isPausing ? (
<>
Pausing
>
) : (
<>
Pause
>
)}
)}
{
setIsCancelingDownload(state.download_id, true);
try {
await cancelDownload(state)
toast.success("Canceled Download", {
description: `The download for "${state.title}" has been canceled.`,
})
} catch (e) {
console.error(e);
toast.error("Failed to Cancel Download", {
description: `An error occurred while trying to cancel the download for "${state.title}".`,
})
} finally {
setIsCancelingDownload(state.download_id, false);
}
}}
disabled={itemActionStates.isCanceling || itemActionStates.isResuming || itemActionStates.isPausing || state.download_status === 'starting' || (state.download_status === 'downloading' && state.status === 'finished')}
>
{itemActionStates.isCanceling ? (
<>
Canceling
>
) : (
<>
Cancel
>
)}
);
}
export function IncompleteDownloads({ downloads }: IncompleteDownloadsProps) {
const navigate = useNavigate();
return (
{downloads.length > 0 ? (
downloads.map((state) => {
return (
);
})
) : (
No Incomplete Downloads
You have all caught up! Sit back and relax or just spin up a new download to see here :)
navigate("/")}
>
Spin Up a New Download
)}
);
}