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 MODEL_OPTIONS = [ { value: "gfpgan", label: "Fast" }, { value: "auto", label: "Balanced" }, { value: "codeformer", label: "Best" }, ] as const; export interface EnhanceFacesControlsProps { settings?: Record; onChange?: (settings: Record) => void; } export function EnhanceFacesControls({ settings: initialSettings, onChange, }: EnhanceFacesControlsProps) { const [model, setModel] = useState<"gfpgan" | "auto" | "codeformer">("auto"); const [strength, setStrength] = useState(80); const [onlyCenterFace, setOnlyCenterFace] = useState(false); const [sensitivity, setSensitivity] = useState(50); const initializedRef = useRef(false); useEffect(() => { if (!initialSettings || initializedRef.current) return; initializedRef.current = true; if (initialSettings.model != null) setModel(initialSettings.model as "gfpgan" | "auto" | "codeformer"); if (initialSettings.strength != null) setStrength(Number(initialSettings.strength) * 100); if (initialSettings.onlyCenterFace != null) setOnlyCenterFace(Boolean(initialSettings.onlyCenterFace)); if (initialSettings.sensitivity != null) setSensitivity(Number(initialSettings.sensitivity) * 100); }, [initialSettings]); const onChangeRef = useRef(onChange); useEffect(() => { onChangeRef.current = onChange; }); useEffect(() => { onChangeRef.current?.({ model, strength: strength / 100, onlyCenterFace, sensitivity: sensitivity / 100, }); }, [model, strength, onlyCenterFace, sensitivity]); return (
{/* Quality */}

Quality

{MODEL_OPTIONS.map(({ value, label }) => ( ))}
{/* Enhancement Strength */}
{strength}%
setStrength(Number(e.target.value))} className="w-full mt-1" />
Subtle Maximum
{/* Only enhance main face (only works with GFPGAN / Fast mode) */} {model !== "codeformer" && (

For portraits - ignores background faces

)} {/* Detection Sensitivity */}
{sensitivity}%
setSensitivity(Number(e.target.value))} className="w-full mt-1" />
Fewer faces More faces
); } export function EnhanceFacesSettings() { const { files } = useFileStore(); const { processFiles, processAllFiles, processing, error, downloadUrl, originalSize, processedSize, progress, } = useToolProcessor("enhance-faces"); const [settings, setSettings] = useState>({}); const handleProcess = () => { if (files.length > 1) { processAllFiles(files, settings); } else { processFiles(files, settings); } }; const hasFile = files.length > 0; const hasMultiple = files.length > 1; return (
{/* Error */} {error &&

{error}

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

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

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

)} {/* Process buttons / progress */} {processing ? ( ) : ( )} {/* Download (single file - batch uses Download All ZIP in tool-page) */} {!hasMultiple && downloadUrl && ( Download )}
); }