import { Download } from "lucide-react"; import { useEffect, useRef, useState } from "react"; import { ProgressCard } from "@/components/common/progress-card"; import { useToolProcessor } from "@/hooks/use-tool-processor"; import { useFileStore } from "@/stores/file-store"; const OUTPUT_FORMATS = [ "jpg", "png", "webp", "avif", "tiff", "gif", "heic", "heif", "jxl", "bmp", "ico", "jp2", "qoi", ] as const; const LOSSY_FORMATS = ["jpg", "jpeg", "webp", "avif", "heic", "heif", "jxl", "jp2"]; const FORMAT_LABELS: Record = { jpg: "JPG", png: "PNG", webp: "WebP", avif: "AVIF", tiff: "TIFF", gif: "GIF", heic: "HEIC", heif: "HEIF", jxl: "JXL", bmp: "BMP", ico: "ICO", jp2: "JP2", qoi: "QOI", }; export interface ConvertControlsProps { settings?: Record; onChange?: (settings: Record) => void; } export function ConvertControls({ settings: initialSettings, onChange }: ConvertControlsProps) { const [format, setFormat] = useState("png"); const [quality, setQuality] = useState(85); const initializedRef = useRef(false); useEffect(() => { if (!initialSettings || initializedRef.current) return; initializedRef.current = true; if (initialSettings.format != null) setFormat(String(initialSettings.format)); if (initialSettings.quality != null) setQuality(Number(initialSettings.quality)); }, [initialSettings]); const isLossy = LOSSY_FORMATS.includes(format); const onChangeRef = useRef(onChange); useEffect(() => { onChangeRef.current = onChange; }); useEffect(() => { const settings: Record = { format }; if (isLossy) { settings.quality = quality; } onChangeRef.current?.(settings); }, [format, quality, isLossy]); return (
{/* Target format */}
{/* Quality slider (lossy only) */} {isLossy && (
{quality}
setQuality(Number(e.target.value))} className="w-full mt-1" />
)}
); } export function ConvertSettings() { const { files } = useFileStore(); const { processFiles, processAllFiles, processing, error, downloadUrl, originalSize, processedSize, progress, } = useToolProcessor("convert"); const [settings, setSettings] = useState>({}); // Detect source format from filename const sourceFile = files[0]; const sourceExt = sourceFile ? sourceFile.name.split(".").pop()?.toLowerCase() || "unknown" : "none"; const hasFile = files.length > 0; const handleProcess = () => { if (files.length > 1) { processAllFiles(files, settings); } else { processFiles(files, settings); } }; const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); if (hasFile && !processing) handleProcess(); }; return (
{/* Source format */} {hasFile && (

Source Format

{sourceExt}
)} {/* Error */} {error &&

{error}

} {/* Size info */} {originalSize != null && processedSize != null && (

Original: {(originalSize / 1024).toFixed(1)} KB

Processed: {(processedSize / 1024).toFixed(1)} KB

)} {/* Process */} {processing ? ( ) : ( )} {/* Download */} {downloadUrl && ( Download )} ); }