import React, { useMemo } from 'react'
import { Box, Button, Chip, Divider, LinearProgress, Paper, Typography } from '@mui/material'
import type { DownloadOverlayItem } from '../components/DownloadsOverlay'
import { formatBytes } from '../utils/formatBytes'
type DownloadsPageProps = {
downloads: DownloadOverlayItem[]
onCancel: (id: string) => void
onSaveAgain: (id: string) => void
onDismiss: (id: string) => void
onClearFinished: () => void
}
function getProgressPercent(download: DownloadOverlayItem) {
if (!download.totalBytes || download.totalBytes <= 0) return null
return Math.max(0, Math.min(100, (download.receivedBytes / download.totalBytes) * 100))
}
function getStatusTone(download: DownloadOverlayItem): 'primary' | 'success' | 'warning' | 'error' | 'default' {
if (download.status === 'completed') return 'success'
if (download.status === 'cancelled') return 'warning'
if (download.status === 'error') return 'error'
if (download.status === 'downloading') return 'primary'
return 'default'
}
function renderProgressText(download: DownloadOverlayItem) {
const received = formatBytes(download.receivedBytes)
const total = formatBytes(download.totalBytes)
if (download.status === 'downloading') {
if (download.note) return download.note
if (received && total) return `${received} of ${total}`
if (received) return `${received} received`
return 'Preparing download...'
}
if (download.status === 'completed') {
const parts = ['Saved in browser storage']
if (total || received) parts.push(total || received || '')
if (download.note) parts.push(download.note)
return parts.join(' • ')
}
if (download.status === 'cancelled') return 'Cancelled before completion'
return download.error || 'Download failed'
}
function DownloadRow({ download, onCancel, onSaveAgain, onDismiss }: {
download: DownloadOverlayItem
onCancel: (id: string) => void
onSaveAgain: (id: string) => void
onDismiss: (id: string) => void
}) {
const progressPercent = getProgressPercent(download)
return (
{download.title}
{download.fileName && (
{download.fileName}
)}
{download.status === 'downloading' && (
)}
{download.status === 'downloading' && progressPercent != null
? `Downloading ${progressPercent.toFixed(0)}% • ${renderProgressText(download)}`
: renderProgressText(download)}
{download.status === 'downloading' ? (
) : null}
{download.status === 'completed' && download.saveHref ? (
) : null}
)
}
export default function DownloadsPage({ downloads, onCancel, onSaveAgain, onDismiss, onClearFinished }: DownloadsPageProps) {
const activeDownloads = useMemo(() => downloads.filter((download) => download.status === 'downloading'), [downloads])
const finishedDownloads = useMemo(() => downloads.filter((download) => download.status !== 'downloading'), [downloads])
return (
Downloads
Finished downloads stay available across refreshes until you remove them from this page.
{finishedDownloads.length > 0 && (
)}
Active
{activeDownloads.length > 0 ? (
{activeDownloads.map((download) => (
))}
) : (
No active downloads.
)}
Stored
{finishedDownloads.length > 0 ? (
{finishedDownloads.map((download) => (
))}
) : (
Completed and failed downloads will appear here for later download or cleanup.
)}
)
}