From 9c5a6e6211625ea5f877f46e2d02642a115e2629 Mon Sep 17 00:00:00 2001 From: spencerwooo Date: Fri, 17 Dec 2021 16:31:01 +0800 Subject: [PATCH] add download and compression progress --- components/DownloadBtn.tsx | 9 +-------- components/FileListing.tsx | 4 ++-- utils/tools.ts | 24 ++++++++++++++++++++---- 3 files changed, 23 insertions(+), 14 deletions(-) diff --git a/components/DownloadBtn.tsx b/components/DownloadBtn.tsx index 2aacb53..13b6641 100644 --- a/components/DownloadBtn.tsx +++ b/components/DownloadBtn.tsx @@ -12,14 +12,7 @@ const DownloadBtn: FunctionComponent<{ downloadUrl: string }> = ({ downloadUrl } return (
- + = ({ query }) = } else if (files.length > 1) { setTotalGenerating(true) const toastId = toast.loading('Downloading selected files. Refresh to cancel, this may take some time...') - downloadMultipleFiles(files, folder) + downloadMultipleFiles(toastId, files, folder) .then(() => { setTotalGenerating(false) toast.dismiss(toastId) @@ -320,7 +320,7 @@ const FileListing: FunctionComponent<{ query?: ParsedUrlQuery }> = ({ query }) = setFolderGenerating({ ...folderGenerating, [id]: true }) const toastId = toast.loading('Downloading folder. Refresh to cancel, this may take some time...') - downloadTreelikeMultipleFiles(files, path, name) + downloadTreelikeMultipleFiles(toastId, files, path, name) .then(() => { setFolderGenerating({ ...folderGenerating, [id]: false }) toast.dismiss(toastId) diff --git a/utils/tools.ts b/utils/tools.ts index d7b912d..4603494 100644 --- a/utils/tools.ts +++ b/utils/tools.ts @@ -1,6 +1,7 @@ import axios from 'axios' import sha256 from 'crypto-js/sha256' import useSWR, { cache, Key, useSWRInfinite } from 'swr' +import toast from 'react-hot-toast' import JSZip from 'jszip' import siteConfig from '../config/site.json' @@ -130,7 +131,11 @@ export const matchProtectedRoute = (route: string) => { * @param files Files to be downloaded * @param folder Optional folder name to hold files, otherwise flatten files in the zip */ -export const downloadMultipleFiles = async (files: { name: string; url: string }[], folder?: string) => { +export const downloadMultipleFiles = async ( + toastId: string, + files: { name: string; url: string }[], + folder?: string +) => { const zip = new JSZip() const dir = folder ? zip.folder(folder)! : zip @@ -138,12 +143,18 @@ export const downloadMultipleFiles = async (files: { name: string; url: string } files.forEach(({ name, url }) => { dir.file( name, - fetch(url).then(r => r.blob()) + fetch(url).then(r => { + return r.blob() + }) ) }) // Create zip file and download it - const b = await zip.generateAsync({ type: 'blob' }) + const b = await zip.generateAsync({ type: 'blob' }, metadata => { + toast.loading(`Downloading ${metadata.percent.toFixed(0)}%. Refresh to cancel...`, { + id: toastId, + }) + }) downloadBlob(b, folder ? folder + '.zip' : 'download.zip') } @@ -219,6 +230,7 @@ export async function* traverseFolder(path: string): AsyncGenerator< * @param folder Optional folder name to hold files, otherwise flatten files in the zip */ export const downloadTreelikeMultipleFiles = async ( + toastId: string, files: AsyncGenerator<{ name: string url?: string @@ -259,6 +271,10 @@ export const downloadTreelikeMultipleFiles = async ( } // Create zip file and download it - const b = await zip.generateAsync({ type: 'blob' }) + const b = await zip.generateAsync({ type: 'blob' }, metadata => { + toast.loading(`Downloading ${metadata.percent.toFixed(0)}%. Refresh to cancel...`, { + id: toastId, + }) + }) downloadBlob(b, folder ? folder + '.zip' : 'download.zip') }