From bff2d7b21a278723ad231f07617d8175bb0c3f7e Mon Sep 17 00:00:00 2001 From: Rafael Araujo Lehmkuhl Date: Tue, 20 Feb 2024 17:53:00 -0300 Subject: [PATCH] video: Allow downloading multiple files at once If downloading multiple files, zip them into one. --- src/stores/video.ts | 30 ++++++++++++++++++++++------ src/views/ConfigurationVideoView.vue | 16 +++++++++++---- 2 files changed, 36 insertions(+), 10 deletions(-) diff --git a/src/stores/video.ts b/src/stores/video.ts index a33895c0d..1ccd49ba7 100644 --- a/src/stores/video.ts +++ b/src/stores/video.ts @@ -1,4 +1,5 @@ import { useStorage } from '@vueuse/core' +import { BlobReader, BlobWriter, ZipWriter } from '@zip.js/zip.js' import { format } from 'date-fns' import { saveAs } from 'file-saver' import fixWebmDuration from 'fix-webm-duration' @@ -222,13 +223,30 @@ export const useVideoStore = defineStore('video', () => { } // Used to download a file from the video recovery database - const downloadFileFromVideoDB = async (fileName: string): Promise => { - const file = await videoStoringDB.getItem(fileName) - if (!file) { - Swal.fire({ text: 'File not found.', icon: 'error' }) + const downloadFilesFromVideoDB = async (fileNames: string[]): Promise => { + console.debug(`Downloading files from the video recovery database: ${fileNames.join(', ')}`) + if (fileNames.length === 1) { + const file = await videoStoringDB.getItem(fileNames[0]) + if (!file) { + Swal.fire({ text: 'File not found.', icon: 'error' }) + return + } + saveAs(file as Blob, fileNames[0]) return } - saveAs(file as Blob, fileName) + const zipWriter = new ZipWriter(new BlobWriter('application/zip')) + const filesPromises = fileNames + .filter(async (filename) => await videoStoringDB.getItem(filename)) + .map(async (filename) => { + const file = await videoStoringDB.getItem(filename) + return { filename, file } + }) + const files = await Promise.all(filesPromises) + for (const { filename, file } of files) { + await zipWriter.add(filename, new BlobReader(file as Blob)) + } + const blob = await zipWriter.close() + saveAs(blob, 'Cockpit-Video-Recovery.zip') } // Used to clear the temporary video database @@ -339,7 +357,7 @@ export const useVideoStore = defineStore('video', () => { videoStoringDB, tempVideoChunksDB, discardFilesFromVideoDB, - downloadFileFromVideoDB, + downloadFilesFromVideoDB, clearTemporaryVideoDB, getMediaStream, getStreamData, diff --git a/src/views/ConfigurationVideoView.vue b/src/views/ConfigurationVideoView.vue index 9f4940a76..acb658491 100644 --- a/src/views/ConfigurationVideoView.vue +++ b/src/views/ConfigurationVideoView.vue @@ -49,7 +49,13 @@ @click="discardAndUpdateDB(selectedFilesNames)" /> - + + + @@ -71,8 +77,9 @@ @@ -134,9 +141,10 @@ const discardAndUpdateDB = async (filenames: string[]): Promise => { selectedFilesNames.value = [] } -const downloadAndUpdateDB = async (filename: string): Promise => { - await videoStore.downloadFileFromVideoDB(filename) +const downloadAndUpdateDB = async (filenames: string[]): Promise => { + await videoStore.downloadFilesFromVideoDB(filenames) await fetchVideoAndLogsData() + selectedFilesNames.value = [] } const clearTemporaryVideoFiles = async (): Promise => {