mirror of
https://github.com/snapotter-hq/SnapOtter.git
synced 2026-08-03 07:46:42 +02:00
refactor: extract RemoveBgControls for DRY reuse in pipeline steps
Extract the settings controls (subject type, quality, background color) from RemoveBgSettings into a shared RemoveBgControls component that accepts settings + onChange props. Both the standalone tool page and the pipeline step configurator now render the same component, so the UI is identical and changes only need to be made in one place.
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
import { RemoveBgControls } from "./remove-bg-settings";
|
||||
|
||||
type FieldType = "number" | "select" | "boolean" | "text" | "color";
|
||||
|
||||
interface FieldDef {
|
||||
@@ -479,27 +481,7 @@ const TOOL_FIELDS: Record<string, FieldDef[]> = {
|
||||
{ key: "background", label: "Background", type: "color", defaultValue: "#FFFFFF" },
|
||||
],
|
||||
|
||||
"remove-background": [
|
||||
{
|
||||
key: "model",
|
||||
label: "AI Model",
|
||||
type: "select",
|
||||
defaultValue: "birefnet-general-lite",
|
||||
options: [
|
||||
{ value: "u2net", label: "Fast (u2net)" },
|
||||
{ value: "birefnet-general-lite", label: "Balanced (general)" },
|
||||
{ value: "birefnet-general", label: "Best (general)" },
|
||||
{ value: "birefnet-portrait", label: "Portrait / Passport" },
|
||||
{ value: "bria-rmbg", label: "Products (bria)" },
|
||||
],
|
||||
},
|
||||
{
|
||||
key: "backgroundColor",
|
||||
label: "Background color",
|
||||
type: "color",
|
||||
defaultValue: "",
|
||||
},
|
||||
],
|
||||
// remove-background uses its own shared controls component (DRY)
|
||||
favicon: [],
|
||||
"color-palette": [],
|
||||
"barcode-read": [],
|
||||
@@ -514,6 +496,11 @@ interface PipelineStepSettingsProps {
|
||||
}
|
||||
|
||||
export function PipelineStepSettings({ toolId, settings, onChange }: PipelineStepSettingsProps) {
|
||||
// Tools with their own shared controls component (DRY - same UI as standalone page)
|
||||
if (toolId === "remove-background") {
|
||||
return <RemoveBgControls settings={settings} onChange={onChange} />;
|
||||
}
|
||||
|
||||
const fields = TOOL_FIELDS[toolId];
|
||||
|
||||
if (!fields || fields.length === 0) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Download, ImageIcon, Package, User } from "lucide-react";
|
||||
import { useState } from "react";
|
||||
import { useEffect, useState } from "react";
|
||||
import { ProgressCard } from "@/components/common/progress-card";
|
||||
import { useToolProcessor } from "@/hooks/use-tool-processor";
|
||||
import { useFileStore } from "@/stores/file-store";
|
||||
@@ -41,25 +41,27 @@ const BG_PRESETS = [
|
||||
{ color: "#0000FF", label: "Blue", preview: "#0000FF" },
|
||||
];
|
||||
|
||||
export function RemoveBgSettings() {
|
||||
const { files } = useFileStore();
|
||||
const { processFiles, processing, error, downloadUrl, originalSize, processedSize, progress } =
|
||||
useToolProcessor("remove-background");
|
||||
// ── Shared controls (used by both standalone page and pipeline steps) ──
|
||||
|
||||
export interface RemoveBgControlsProps {
|
||||
settings: Record<string, unknown>;
|
||||
onChange: (settings: Record<string, unknown>) => void;
|
||||
}
|
||||
|
||||
export function RemoveBgControls({ settings, onChange }: RemoveBgControlsProps) {
|
||||
const [subject, setSubject] = useState<SubjectType>("people");
|
||||
const [quality, setQuality] = useState<Quality>("balanced");
|
||||
const [isPassport, setIsPassport] = useState(false);
|
||||
const [bgColor, setBgColor] = useState("");
|
||||
const [bgColor, setBgColor] = useState((settings.backgroundColor as string) || "");
|
||||
|
||||
const model = isPassport ? "birefnet-portrait" : MODEL_MAP[subject][quality];
|
||||
|
||||
const handleProcess = () => {
|
||||
const settings: Record<string, unknown> = { model };
|
||||
if (bgColor) settings.backgroundColor = bgColor;
|
||||
processFiles(files, settings);
|
||||
};
|
||||
|
||||
const hasFile = files.length > 0;
|
||||
// Sync settings on every control change
|
||||
useEffect(() => {
|
||||
const next: Record<string, unknown> = { model };
|
||||
if (bgColor) next.backgroundColor = bgColor;
|
||||
onChange(next);
|
||||
}, [model, bgColor, onChange]);
|
||||
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
@@ -175,6 +177,28 @@ export function RemoveBgSettings() {
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// ── Standalone tool page wrapper ──────────────────────────────────────
|
||||
|
||||
export function RemoveBgSettings() {
|
||||
const { files } = useFileStore();
|
||||
const { processFiles, processing, error, downloadUrl, originalSize, processedSize, progress } =
|
||||
useToolProcessor("remove-background");
|
||||
|
||||
const [settings, setSettings] = useState<Record<string, unknown>>({});
|
||||
|
||||
const handleProcess = () => {
|
||||
processFiles(files, settings);
|
||||
};
|
||||
|
||||
const hasFile = files.length > 0;
|
||||
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
<RemoveBgControls settings={settings} onChange={setSettings} />
|
||||
|
||||
{/* Error */}
|
||||
{error && <p className="text-xs text-red-500">{error}</p>}
|
||||
|
||||
Reference in New Issue
Block a user