@@ -5,21 +5,24 @@ import FileItem from './components/FileItem.vue';
5
5
import { useFileDataStore } from ' ./stores/fileData' ;
6
6
import { storeToRefs } from ' pinia' ;
7
7
import type { FileObj } from ' ./types/file' ;
8
- import { computed , ref } from ' vue' ;
8
+ import { computed , ref , watch , watchEffect } from ' vue' ;
9
9
import { compressFile } from ' ./functions/imageCompression' ;
10
10
import { compressToZip } from ' ./functions/zipCompression' ;
11
- import { paginate } from ' ./functions/paginate' ;
12
11
import { useI18n } from ' ./hooks/useI18n' ;
13
12
14
13
const { t } = useI18n ();
15
14
16
15
const fileDataStore = useFileDataStore ();
17
16
const { files } = storeToRefs (fileDataStore );
18
17
18
+ const getUncompressedFiles = (fileObj : FileObj ) => ! fileObj .isCompressed ;
19
+
19
20
const isCompressing = ref (false );
20
21
const zipData = ref (' ' );
21
22
const isZipCompressing = ref (false );
22
- const anyUncompressed = computed (() => files .value .some ((file ) => ! file .isCompressed ));
23
+ const uncompressedFiles = computed (() => files .value .filter (getUncompressedFiles ));
24
+ const anyUncompressed = computed (() => Boolean (uncompressedFiles .value .length ));
25
+ const toCompress = ref <FileObj []>([]);
23
26
24
27
const availableThreads = Math .max (navigator .hardwareConcurrency - 2 , 1 );
25
28
@@ -34,34 +37,43 @@ async function editFileObj(fileObj: FileObj) {
34
37
}
35
38
}
36
39
37
- async function compressFiles() {
38
- isCompressing .value = true ;
39
-
40
- const uncompressedFiles = files .value .filter ((fileObj : FileObj ) => ! fileObj .isCompressed );
41
-
42
- // option 1 (no errors, slower)
43
- const paginatedFileArray = paginate (uncompressedFiles , availableThreads );
44
-
45
- for (const subArray of paginatedFileArray ) {
46
- const promises = subArray .map (editFileObj );
47
- await Promise .all (promises );
40
+ // add files to toCompress array when a thread is available
41
+ watchEffect (() => {
42
+ if (isCompressing .value ) {
43
+ const amountToPush = availableThreads - toCompress .value .filter (getUncompressedFiles ).length ;
44
+ const pool = uncompressedFiles .value .filter ((item ) => ! toCompress .value .includes (item )).slice (0 , amountToPush );
45
+ if (pool .length ) toCompress .value = [... toCompress .value , ... pool ];
48
46
}
47
+ });
48
+
49
+ // compress new files that are added to the toCompress array
50
+ watch (toCompress , (newVal , oldVal ) => {
51
+ const filesToCompress = newVal .filter ((item ) => ! oldVal .includes (item ));
52
+ filesToCompress .forEach (editFileObj );
53
+ });
54
+
55
+ // set isCompressing to false when compression finished
56
+ watchEffect (() => {
57
+ if (! uncompressedFiles .value .length && isCompressing .value ) {
58
+ isCompressing .value = false ;
59
+ toCompress .value = [];
60
+ }
61
+ });
62
+
63
+ // zip files when everything is compressed
64
+ watch (isCompressing , async (newVal , oldVal ) => {
65
+ if (oldVal && ! newVal ) {
66
+ URL .revokeObjectURL (zipData .value );
67
+ isZipCompressing .value = true ;
68
+ zipData .value = await compressToZip ();
69
+ isZipCompressing .value = false ;
70
+ }
71
+ });
49
72
50
- // option 2 (errors, faster -> better option once the errors are fixed in Firefox)
51
- // const promises = uncompressedFiles.map(editFileObj);
52
- // await Promise.all(promises);
53
-
54
- isCompressing .value = false ;
73
+ // initiate compression
74
+ const compressFiles = () => (isCompressing .value = true );
55
75
56
- URL .revokeObjectURL (zipData .value );
57
- isZipCompressing .value = true ;
58
- zipData .value = await compressToZip ();
59
- isZipCompressing .value = false ;
60
- }
61
-
62
- function removeItem(file : FileObj ) {
63
- files .value = files .value .filter ((item ) => item !== file );
64
- }
76
+ const removeItem = (file : FileObj ) => (files .value = files .value .filter ((item ) => item !== file ));
65
77
</script >
66
78
67
79
<template >
0 commit comments