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 { Separator } from "@/components/ui/separator"; import { useToast } from "@/hooks/use-toast"; import { useAppContext } from "@/providers/appContextProvider"; import { useDownloadActionStatesStore, useDownloadStatesStore } from "@/services/store"; import { formatBitrate, formatCodec, formatDurationString, formatFileSize, formatSecToTimeString, formatSpeed } from "@/utils"; import { AudioLines, Clock, CloudDownload, File, FileAudio2, FileQuestion, FileVideo2, FolderInput, ListVideo, Loader2, Music, PackageCheck, Pause, Play, Trash2, Video, X } from "lucide-react"; import { invoke } from "@tauri-apps/api/core"; import * as fs from "@tauri-apps/plugin-fs"; import { DownloadState } from "@/types/download"; import { useQueryClient } from "@tanstack/react-query"; import { useDeleteDownloadState } from "@/services/mutations"; import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, AlertDialogTrigger } from "@/components/ui/alert-dialog"; import { Checkbox } from "@/components/ui/checkbox"; import { Label } from "@/components/ui/label"; import Heading from "@/components/heading"; export default function LibraryPage() { const downloadStates = useDownloadStatesStore(state => state.downloadStates); 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 setIsDeleteFileChecked = useDownloadActionStatesStore(state => state.setIsDeleteFileChecked); const { pauseDownload, resumeDownload, cancelDownload } = useAppContext() const { toast } = useToast(); const queryClient = useQueryClient(); const downloadStateDeleter = useDeleteDownloadState(); const incompleteDownloads = downloadStates.filter(state => state.download_status !== 'completed'); const completedDownloads = downloadStates.filter(state => state.download_status === 'completed'); const openFile = async (filePath: string | null, app: string | null) => { if (filePath && await fs.exists(filePath)) { try { await invoke('open_file_with_app', { filePath: filePath, appName: app }).then(() => { toast({ title: 'Opening file', description: `Opening the file with ${app ? app : 'default app'}.`, }) }); } catch (e) { console.error(e); toast({ title: 'Failed to open file', description: 'An error occurred while trying to open the file.', variant: "destructive" }) } } else { toast({ title: 'File unavailable', description: 'The file you are trying to open does not exist.', variant: "destructive" }) } } const removeFromDownloads = async (downloadState: DownloadState, delete_file: boolean) => { if (delete_file && downloadState.filepath) { try { if (await fs.exists(downloadState.filepath)) { await fs.remove(downloadState.filepath); } else { console.error(`File not found: ${downloadState.filepath}`); } } catch (e) { console.error(e); } } downloadStateDeleter.mutate(downloadState.download_id, { onSuccess: (data) => { console.log("Download State deleted successfully:", data); queryClient.invalidateQueries({ queryKey: ['download-states'] }); toast({ title: 'Removed from downloads', description: 'The download has been removed successfully.', }) }, onError: (error) => { console.error("Failed to delete download state:", error); toast({ title: 'Failed to remove download', description: 'An error occurred while trying to remove the download.', variant: "destructive" }) } }) } return (

Incomplete Downloads

{incompleteDownloads.length > 0 ? ( incompleteDownloads.map((state) => { const itemActionStates = downloadActions[state.download_id] || { isResuming: false, isPausing: false, isCanceling: false, isDeleteFileChecked: false, }; return (
{state.ext && ( {state.filetype && (state.filetype === 'video' || state.filetype === 'video+audio') && ( )}

{state.title}

{((state.download_status === 'starting') || (state.download_status === 'downloading' && state.status === 'finished')) && ( )} {(state.download_status === 'downloading' || state.download_status === 'paused') && state.progress && state.status !== 'finished' && (
{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.charAt(0).toUpperCase() + state.download_status.slice(1)} ${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' ? ( ) : ( )}
) }) ) : (
No Incomplete downloads!
)}

Completed Downloads

{completedDownloads.length > 0 ? ( completedDownloads.map((state) => { const itemActionStates = downloadActions[state.download_id] || { isResuming: false, isPausing: false, isCanceling: false, isDeleteFileChecked: false, }; return (
{state.filetype && (state.filetype === 'video' || state.filetype === 'video+audio') && (

{state.title}

{state.channel ? state.channel : 'unknown'} {state.host ? `• ${state.host}` : 'unknown'}

{state.duration_string ? formatDurationString(state.duration_string) : 'unknown'} {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.filesize ? formatFileSize(state.filesize) : 'unknown'} {state.vbr && state.abr ? ( formatBitrate(state.vbr + state.abr) ) : state.vbr ? ( formatBitrate(state.vbr) ) : state.abr ? ( formatBitrate(state.abr) ) : ( 'unknown' )}
{state.playlist_id && state.playlist_index && ( Playlist ({state.playlist_index} of {state.playlist_n_entries}) )} {state.vcodec && ( {formatCodec(state.vcodec)} )} {state.acodec && ( {formatCodec(state.acodec)} )} {state.dynamic_range && state.dynamic_range !== 'SDR' && ( {state.dynamic_range} )} {state.subtitle_id && ( ESUB )}
Are you absolutely sure? This action cannot be undone! it will permanently remove this from downloads.
{setIsDeleteFileChecked(state.download_id, !itemActionStates.isDeleteFileChecked)}} />
Cancel removeFromDownloads(state, itemActionStates.isDeleteFileChecked).then(() => { setIsDeleteFileChecked(state.download_id, false); }) }>Remove
) }) ) : (
No Completed downloads!
)}
); }