diff --git a/src/app/(tools)/size-compressor/compressor-tool.tsx b/src/app/(tools)/size-compressor/compressor-tool.tsx index 76fb460..3dda19a 100644 --- a/src/app/(tools)/size-compressor/compressor-tool.tsx +++ b/src/app/(tools)/size-compressor/compressor-tool.tsx @@ -1,12 +1,16 @@ "use client"; +import { FileDropzone } from "@/components/shared/file-dropzone"; +import { UploadBox } from "@/components/shared/upload-box"; import { useState, type ChangeEvent, useEffect } from "react"; export default function ImageSizeCompressor() { const [images, setImages] = useState([]); - const [quality, setQuality] = useState(0.8); + const [globalQuality, setGlobalQuality] = useState(0.8); + const [quality, setQuality] = useState([0.8]); const [compressedPreview, setCompressedPreview] = useState( null, ); + const [currentIndex, setCurrentIndex] = useState(0); const [originalSize, setOriginalSize] = useState(""); const [compressedSize, setCompressedSize] = useState(""); const [isCompressing, setIsCompressing] = useState(false); @@ -19,8 +23,14 @@ export default function ImageSizeCompressor() { return `${parseFloat((bytes / Math.pow(k, i)).toFixed(2))} ${sizes[i]}`; } - async function compressImage(image: File, quality: number): Promise { + async function compressImage( + image: File, + quality: number | undefined, + ): Promise { return new Promise((resolve, reject) => { + if (quality === undefined) { + return reject(new Error("Quaility can't be undefined")); + } const img = new Image(); const imageUrl = URL.createObjectURL(image); @@ -73,18 +83,31 @@ export default function ImageSizeCompressor() { if (!e.target.files) return; const newFiles = Array.from(e.target.files); + const newQualities = new Array(newFiles.length).fill(0.8); + setImages((prev) => [...prev, ...newFiles]); + setQuality((prev) => [...prev, ...newQualities]); + } + + function handleImageDrop(files: FileList) { + const newQualities = new Array(files.length).fill(0.8); + + setImages((prev) => [...prev, ...files]); + setQuality((prev) => [...prev, ...newQualities]); } useEffect(() => { - if (images[0] === undefined) return; - setOriginalSize(formatFileSize(images[0].size)); + if (images[currentIndex] === undefined) return; + setOriginalSize(formatFileSize(images[currentIndex].size)); async function generateCompressedPreview() { - if (images[0] === undefined) return; + if (images[currentIndex] === undefined) return; setIsCompressing(true); try { - const compressedFile = await compressImage(images[0], quality); + const compressedFile = await compressImage( + images[currentIndex], + globalQuality ?? quality[currentIndex], + ); setCompressedPreview(URL.createObjectURL(compressedFile)); setCompressedSize(formatFileSize(compressedFile.size)); } finally { @@ -99,7 +122,7 @@ export default function ImageSizeCompressor() { return () => { clearTimeout(debounceTimeout); }; - }, [images, quality]); + }, [images, quality, currentIndex, globalQuality]); function removeImage(index: number) { setImages((prev) => prev.filter((_, i) => i !== index)); @@ -114,7 +137,9 @@ export default function ImageSizeCompressor() { try { setIsCompressing(true); const compressedFiles = await Promise.all( - images.map((image) => compressImage(image, quality)), + images.map((image, i) => + compressImage(image, globalQuality ?? quality[i]), + ), ); compressedFiles.forEach((file, index) => { @@ -132,7 +157,15 @@ export default function ImageSizeCompressor() { } function onChangeQuality(e: ChangeEvent) { - setQuality(parseFloat(e.target.value)); + console.log(`globalQuality -> ${globalQuality}`); + console.log(`quality -> ${quality[currentIndex]}`); + if (globalQuality === undefined) { + const newQuantity = [...quality]; + newQuantity[currentIndex] = parseFloat(e.target.value); + setQuality(newQuantity); + } else { + setGlobalQuality(parseFloat(e.target.value)); + } } function onCancel() { @@ -144,21 +177,26 @@ export default function ImageSizeCompressor() { if (images.length === 0) { return ( -
-

Compress your images to reduce file size.

-
- -
-
+ + + ); } @@ -171,6 +209,10 @@ export default function ImageSizeCompressor() { src={URL.createObjectURL(image)} alt={`Preview ${index + 1}`} className="h-32 w-32 rounded-lg object-cover" + role="button" + onClick={() => { + setCurrentIndex(index); + }} />