diff --git a/components/FileListing.tsx b/components/FileListing.tsx
index 08b741a..bcbb9d3 100644
--- a/components/FileListing.tsx
+++ b/components/FileListing.tsx
@@ -12,7 +12,7 @@ import dynamic from 'next/dynamic'
import { getExtension, getFileIcon, hasKey } from '../utils/getFileIcon'
import { extensions, preview } from '../utils/getPreviewType'
-import { getBaseUrl, useProtectedSWRInfinite } from '../utils/tools'
+import { getBaseUrl, saveFiles, useProtectedSWRInfinite } from '../utils/tools'
import { VideoPreview } from './previews/VideoPreview'
import { AudioPreview } from './previews/AudioPreview'
@@ -235,6 +235,15 @@ const FileListing: FunctionComponent<{ query?: ParsedUrlQuery }> = ({ query }) =
}
}
+ // Selected file download
+ const handleDownloadSelected = () => {
+ const folderName = path.substr(path.lastIndexOf('/') + 1)
+ const folder = folderName ? folderName : undefined
+ const files = children.filter((c: any) => selected[c.id])
+ .map((c: any) => ({ name: c.name, url: c['@microsoft.graph.downloadUrl'] }))
+ saveFiles(files, folder)
+ }
+
return (
@@ -250,12 +259,15 @@ const FileListing: FunctionComponent<{ query?: ParsedUrlQuery }> = ({ query }) =
indeterminate={true}
title={"Select files"}
/>
-
-
-
+ {totalSelected ? (
+
+
+
+ ) : ''}
diff --git a/package-lock.json b/package-lock.json
index 14744c7..7da8e35 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -17,6 +17,7 @@
"axios": "^0.21.1",
"crypto-js": "^4.1.1",
"emoji-regex": "^9.2.2",
+ "jszip": "^3.7.1",
"next": "^11.1.0",
"preview-office-docs": "^1.0.2",
"prismjs": "^1.23.0",
diff --git a/package.json b/package.json
index ca4de1c..4fbfae6 100644
--- a/package.json
+++ b/package.json
@@ -18,6 +18,7 @@
"axios": "^0.21.1",
"crypto-js": "^4.1.1",
"emoji-regex": "^9.2.2",
+ "jszip": "^3.7.1",
"next": "^11.1.0",
"preview-office-docs": "^1.0.2",
"prismjs": "^1.23.0",
diff --git a/utils/tools.ts b/utils/tools.ts
index 904e263..c9dd3e1 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 JSZip from 'jszip'
import siteConfig from '../config/site.json'
@@ -123,3 +124,27 @@ export const matchProtectedRoute = (route: string) => {
}
return authTokenPath
}
+
+/**
+ * Download multiple files after compressing them into a zip
+ * @param files Files to be downloaded
+ * @param folder Optional folder name to hold files, otherwise flatten files in the zip
+ */
+export const saveFiles = (files: { name: string, url: string }[], folder?: string) => {
+ const zip = new JSZip()
+ const dir = folder ? zip.folder(folder)! : zip
+ files.forEach(({ name, url }) => {
+ dir.file(name, fetch(url).then(r => r.blob()))
+ })
+ dir.generateAsync({ type: 'blob' }).then(b => {
+ const el = document.createElement('a')
+ el.style.display = 'none'
+ document.body.appendChild(el)
+ const bUrl = window.URL.createObjectURL(b)
+ el.href = bUrl
+ el.download = folder ? folder + '.zip' : 'download.zip'
+ el.click()
+ window.URL.revokeObjectURL(bUrl)
+ el.remove()
+ })
+}