Browse Source

fix(web): album download progress bar (#925)

Jason Rasmussen 2 years ago
parent
commit
86e50f97ba

+ 2 - 1
server/apps/immich/src/api-v1/album/album.controller.ts

@@ -121,8 +121,9 @@ export class AlbumController {
     @Param('albumId', new ParseUUIDPipe({ version: '4' })) albumId: string,
     @Response({ passthrough: true }) res: Res,
   ): Promise<any> {
-    const { stream, filename } = await this.albumService.downloadArchive(authUser, albumId);
+    const { stream, filename, filesize } = await this.albumService.downloadArchive(authUser, albumId);
     res.attachment(filename);
+    res.setHeader('X-Immich-Content-Length-Hint', filesize);
     return stream;
   }
 }

+ 3 - 0
server/apps/immich/src/api-v1/album/album.service.ts

@@ -171,11 +171,13 @@ export class AlbumService {
     try {
       const archive = archiver('zip', { store: true });
       const stream = new StreamableFile(archive);
+      let totalSize = 0;
 
       for (const { assetInfo } of album.assets) {
         const { originalPath } = assetInfo;
         const name = `${assetInfo.exifInfo?.imageName || assetInfo.id}${extname(originalPath)}`;
         archive.file(originalPath, { name });
+        totalSize += Number(assetInfo.exifInfo?.fileSizeInByte || 0);
       }
 
       archive.finalize();
@@ -183,6 +185,7 @@ export class AlbumService {
       return {
         stream,
         filename: `${album.albumName}.zip`,
+        filesize: totalSize,
       };
     } catch (e) {
       Logger.error(`Error downloading album ${e}`, 'downloadArchive');

+ 13 - 1
web/src/lib/components/album-page/album-viewer.svelte

@@ -322,8 +322,20 @@
 
 			$downloadAssets[fileName] = 0;
 
+			let total = 0;
 			const { data, status } = await api.albumApi.downloadArchive(album.id, {
-				responseType: 'blob'
+				responseType: 'blob',
+				onDownloadProgress: function (progressEvent) {
+					const request = this as XMLHttpRequest;
+					if (!total) {
+						total = Number(request.getResponseHeader('X-Immich-Content-Length-Hint')) || 0;
+					}
+
+					if (total) {
+						const current = progressEvent.loaded;
+						$downloadAssets[fileName] = Math.floor((current / total) * 100);
+					}
+				}
 			});
 
 			if (!(data instanceof Blob)) {