mirror of
https://github.com/yusufipk/OpenFrame.git
synced 2026-09-11 09:36:08 +00:00
feat: show live progress while downloading named files
Bunny/cross-origin downloads are fetched into a blob before saving, which on large files or slow connections looked stuck (spinner only). Stream the body through a counting transform and show real byte progress in a toast: per-file percent for single downloads and file N/M + percent for bulk. - Progress is measured from Content-Length + received bytes (not estimated). - The blob is assembled by the browser from the stream (can be disk-backed), so we don't accumulate chunks in the JS heap. - Only the blob path shows a toast; same-origin (R2/S3/MinIO) and the >10 GB fallback use the browser's native download UI.
This commit is contained in:
@@ -10,7 +10,12 @@ import type {
|
||||
VideoData,
|
||||
} from '@/components/video-page/types';
|
||||
import { resolvePublicBunnyCdnHostname } from '@/lib/bunny-cdn';
|
||||
import { downloadNamedFile, extensionFromUrl, navigateDownload } from '@/lib/client/download-file';
|
||||
import {
|
||||
downloadNamedFile,
|
||||
downloadProgressLabel,
|
||||
extensionFromUrl,
|
||||
navigateDownload,
|
||||
} from '@/lib/client/download-file';
|
||||
|
||||
function sanitizeDownloadFileName(value: string): string {
|
||||
return value
|
||||
@@ -143,8 +148,25 @@ export function useDownloadActions({ activeVersion, video }: UseDownloadActionsP
|
||||
(activeVersion.providerId === 'direct'
|
||||
? extensionFromUrl(activeVersion.originalUrl)
|
||||
: '') || 'mp4';
|
||||
const saved = await downloadNamedFile(downloadUrl, `${baseName}.${fallbackExt}`);
|
||||
if (!saved) {
|
||||
|
||||
// The file is pulled into the browser before it can be saved, which on
|
||||
// a big file / slow connection takes a while with no native download UI
|
||||
// — show live progress so it doesn't look stuck.
|
||||
const toastId = `download-${activeVersion.id}`;
|
||||
toast.loading(`Downloading “${baseName}”…`, { id: toastId, duration: Infinity });
|
||||
const saved = await downloadNamedFile(downloadUrl, `${baseName}.${fallbackExt}`, (p) => {
|
||||
toast.loading(`Downloading “${baseName}”`, {
|
||||
id: toastId,
|
||||
description: downloadProgressLabel(p),
|
||||
duration: Infinity,
|
||||
});
|
||||
});
|
||||
if (saved) {
|
||||
toast.success(`“${baseName}” downloaded`, { id: toastId, duration: 4000 });
|
||||
} else {
|
||||
// Too large to buffer (or fetch blocked): let the browser download it
|
||||
// directly (its own progress UI, CDN filename).
|
||||
toast.dismiss(toastId);
|
||||
navigateDownload(downloadUrl);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user