import { Download, Info } from "lucide-react"; import { useCallback, 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"; function HintIcon({ text }: { text: string }) { return ( {text} ); } export interface ContentAwareResizeControlsProps { settings?: Record; onChange?: (settings: Record) => void; } export function ContentAwareResizeControls({ settings: initialSettings, onChange, }: ContentAwareResizeControlsProps) { const [width, setWidth] = useState(""); const [height, setHeight] = useState(""); const [protectFaces, setProtectFaces] = useState(false); const [blurRadius, setBlurRadius] = useState(4); const [sobelThreshold, setSobelThreshold] = useState(2); const [squareMode, setSquareMode] = useState(false); const initializedRef = useRef(false); useEffect(() => { if (!initialSettings || initializedRef.current) return; initializedRef.current = true; if (initialSettings.width != null) setWidth(String(initialSettings.width)); if (initialSettings.height != null) setHeight(String(initialSettings.height)); if (initialSettings.protectFaces != null) setProtectFaces(Boolean(initialSettings.protectFaces)); if (initialSettings.blurRadius != null) setBlurRadius(Number(initialSettings.blurRadius)); if (initialSettings.sobelThreshold != null) setSobelThreshold(Number(initialSettings.sobelThreshold)); if (initialSettings.square != null) setSquareMode(Boolean(initialSettings.square)); }, [initialSettings]); const onChangeRef = useRef(onChange); useEffect(() => { onChangeRef.current = onChange; }); useEffect(() => { const settings: Record = {}; if (!squareMode) { if (width) settings.width = Number(width); if (height) settings.height = Number(height); } settings.protectFaces = protectFaces; settings.blurRadius = blurRadius; settings.sobelThreshold = sobelThreshold; settings.square = squareMode; onChangeRef.current?.(settings); }, [width, height, protectFaces, blurRadius, sobelThreshold, squareMode]); return (
{/* Dimensions */}
setWidth(e.target.value)} placeholder="Auto" disabled={squareMode} className="w-full mt-0.5 px-2 py-1.5 rounded border border-border bg-background text-sm text-foreground disabled:opacity-50" />
setHeight(e.target.value)} placeholder="Auto" disabled={squareMode} className="w-full mt-0.5 px-2 py-1.5 rounded border border-border bg-background text-sm text-foreground disabled:opacity-50" />
{/* Square mode */} {/* Face protection */} {/* Blur radius */}
{blurRadius}
setBlurRadius(Number(e.target.value))} className="w-full mt-1 h-1.5 rounded-full appearance-none bg-muted accent-primary" />
{/* Sobel threshold */}
{sobelThreshold}
setSobelThreshold(Number(e.target.value))} className="w-full mt-1 h-1.5 rounded-full appearance-none bg-muted accent-primary" />
); } export function ContentAwareResizeSettings() { const { files } = useFileStore(); const { processFiles, processAllFiles, processing, error, downloadUrl, progress } = useToolProcessor("content-aware-resize"); const [settings, setSettings] = useState>({}); const handleSettingsChange = useCallback((newSettings: Record) => { setSettings(newSettings); }, []); const handleProcess = () => { if (files.length > 1) { processAllFiles(files, settings); } else { processFiles(files, settings); } }; const hasFile = files.length > 0; const canProcess = hasFile && !processing && (Boolean(settings.width) || Boolean(settings.height) || Boolean(settings.square)); const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); if (canProcess) handleProcess(); }; return (
{error &&

{error}

} {processing ? ( ) : ( )} {downloadUrl && ( Download )} ); }