diff --git a/package-lock.json b/package-lock.json index 41055b4..9ab50c1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,6 +19,7 @@ "cl-editor": "^2.3.0", "daisyui": "^4.12.10", "dayjs": "^1.11.12", + "file-saver": "^2.0.5", "firebase": "^10.12.5", "jszip": "^3.10.1", "p-limit": "^6.1.0", @@ -39,6 +40,7 @@ "@sveltejs/kit": "^2.5.20", "@sveltejs/vite-plugin-svelte": "^3.1.1", "@types/byte-size": "^8.1.2", + "@types/file-saver": "^2.0.7", "@types/uuid": "^10.0.0", "@typescript-eslint/eslint-plugin": "^7.18.0", "@typescript-eslint/parser": "^7.18.0", @@ -2047,6 +2049,12 @@ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==" }, + "node_modules/@types/file-saver": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@types/file-saver/-/file-saver-2.0.7.tgz", + "integrity": "sha512-dNKVfHd/jk0SkR/exKGj2ggkB45MAkzvWCaqLUUgkyjITkGNzH8H+yUwr+BLJUBjZOe9w8X3wgmXhZDRg1ED6A==", + "dev": true + }, "node_modules/@types/json-schema": { "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", @@ -5304,6 +5312,11 @@ "node": "^10.12.0 || >=12.0.0" } }, + "node_modules/file-saver": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/file-saver/-/file-saver-2.0.5.tgz", + "integrity": "sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA==" + }, "node_modules/filesize": { "version": "6.4.0", "resolved": "https://registry.npmjs.org/filesize/-/filesize-6.4.0.tgz", diff --git a/package.json b/package.json index ee92f72..94c659c 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ "@sveltejs/kit": "^2.5.20", "@sveltejs/vite-plugin-svelte": "^3.1.1", "@types/byte-size": "^8.1.2", + "@types/file-saver": "^2.0.7", "@types/uuid": "^10.0.0", "@typescript-eslint/eslint-plugin": "^7.18.0", "@typescript-eslint/parser": "^7.18.0", @@ -52,6 +53,7 @@ "cl-editor": "^2.3.0", "daisyui": "^4.12.10", "dayjs": "^1.11.12", + "file-saver": "^2.0.5", "firebase": "^10.12.5", "jszip": "^3.10.1", "p-limit": "^6.1.0", diff --git a/src/components/photoAlbum/PhotoAlbumViewer.svelte b/src/components/photoAlbum/PhotoAlbumViewer.svelte index b528cc7..1e3653a 100644 --- a/src/components/photoAlbum/PhotoAlbumViewer.svelte +++ b/src/components/photoAlbum/PhotoAlbumViewer.svelte @@ -20,6 +20,10 @@ import Time from "svelte-time/Time.svelte" import BiggerPictureThumbnails from "./thumbnails.svelte" + import pkg from "file-saver" + import pLimit from "p-limit" + const { saveAs } = pkg + export let photoAlbum: PhotoAlbum export let preview = false @@ -70,29 +74,41 @@ }) } + // -- Download -- + let downloading = false + let amountFinished = 0 + async function downloadHandler() { + ;(document.activeElement as HTMLElement).blur() + downloading = true + amountFinished = 0 const zip = new JSZip() - const imgFolder = zip.folder("images") - if (!imgFolder) throw new Error("No image folder") - - for (const [index, url] of photoAlbum.imageUrls.entries()) { - const response = await fetch(url) - const blob = await response.blob() - imgFolder.file(`image${index + 1}.jpg`, blob) - } + const limit = pLimit(4) + + await Promise.all( + photoAlbum.imageUrls.map(async (url, index) => { + return limit(async () => { + const response = await fetch(url) + const blob = await response.blob() + amountFinished++ + zip.file(`image${index + 1}.webp`, blob) + }) + }), + ) const content = await zip.generateAsync({ type: "blob" }) - saveAs(content, "images.zip") + saveAs(content, `${photoAlbum.title}.zip`) + downloading = false } - function saveAs(blob: Blob, name: string) { - var a = document.createElement("a") - document.body.append(a) - a.download = name - a.href = URL.createObjectURL(blob) - a.click() - a.remove() - } + onMount(() => { + // Prevent user accidentally leaving page when album is downloading + window.addEventListener("beforeunload", (e) => { + if (downloading) { + e.preventDefault() + } + }) + }) @@ -107,14 +123,14 @@ -
-
+
+
-
+
@@ -124,7 +140,7 @@ >
{#if photoAlbum.author} -
+
@@ -137,6 +153,21 @@ {/if}
{/if} + {#if downloading} +
+ + {amountFinished} / {photoAlbum.imageUrls.length} + Voltooid +
+ {/if} + {#if $authStore && !preview}