From 34e72f6cbb0f866abe64dfa58e0d4275b645c5f4 Mon Sep 17 00:00:00 2001 From: yusufipk Date: Fri, 10 Jul 2026 20:03:47 +0700 Subject: [PATCH] fix: bulk video download (original quality, latest version by default) - Accept source=auto in the version download route (was 400 Bad Request), so bulk/project downloads of Bunny videos no longer fail. - Bulk/project downloads now request the original (uncompressed) Bunny file so quality never drops (was source=auto which could fall back to compressed). - Project/selected downloads default to the latest version of each video and add a separate "All versions" option in the download dropdowns. --- .../[projectId]/project-content-client.tsx | 95 +++++++++++++------ .../projects/[projectId]/download/route.ts | 3 +- .../versions/[versionId]/download/route.ts | 9 +- lib/project-download.ts | 28 +++++- 4 files changed, 98 insertions(+), 37 deletions(-) diff --git a/app/(dashboard)/projects/[projectId]/project-content-client.tsx b/app/(dashboard)/projects/[projectId]/project-content-client.tsx index a75edc2..54c844f 100644 --- a/app/(dashboard)/projects/[projectId]/project-content-client.tsx +++ b/app/(dashboard)/projects/[projectId]/project-content-client.tsx @@ -18,11 +18,18 @@ import { Download, Loader2, Trash2, + ChevronDown, } from 'lucide-react'; import { toast } from 'sonner'; import { Button } from '@/components/ui/button'; import { Card, CardContent } from '@/components/ui/card'; import { Badge } from '@/components/ui/badge'; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuTrigger, +} from '@/components/ui/dropdown-menu'; import { AlertDialog, AlertDialogAction, @@ -167,13 +174,17 @@ export function ProjectContentClient({ }, []); const startProjectDownload = useCallback( - async (videoIds?: string[]) => { + async (videoIds?: string[], options?: { allVersions?: boolean }) => { if (!canDownloadProject || isDownloading) return; - const query = - videoIds && videoIds.length > 0 - ? `?videoIds=${encodeURIComponent(videoIds.join(','))}` - : ''; + const searchParams = new URLSearchParams(); + if (videoIds && videoIds.length > 0) { + searchParams.set('videoIds', videoIds.join(',')); + } + if (options?.allVersions) { + searchParams.set('versions', 'all'); + } + const query = searchParams.toString() ? `?${searchParams.toString()}` : ''; setIsDownloading(true); try { @@ -325,19 +336,27 @@ export function ProjectContentClient({ )} {canDownloadProject && localVideos.length > 0 && !selectionMode && ( - + + + + + + startProjectDownload()}> + Latest version only + + startProjectDownload(undefined, { allVersions: true })}> + All versions + + + )} {canEdit && ( {canDownloadProject && ( - + + + + + + startProjectDownload(selectedVideoIds)}> + Latest version only + + startProjectDownload(selectedVideoIds, { allVersions: true })} + > + All versions + + + )} {canEdit && (