| import React, { useState } from 'react' |
| import ParamSlider from './ParamSlider' |
|
|
| export default function ACEStepParams({ params, onParamChange, detection }) { |
| const [showAdvanced, setShowAdvanced] = useState(false) |
|
|
| return ( |
| <div className="space-y-3"> |
| <div className="text-[10px] text-gray-500 bg-white/[0.02] rounded-lg px-3 py-2"> |
| Caption is auto-generated from your seed's analysis (BPM, key, brightness, instruments) for musical coherence. Override below if needed. |
| </div> |
| |
| {/* Optional caption override (collapsed by default) */} |
| <button |
| onClick={() => setShowAdvanced(!showAdvanced)} |
| className="text-xs text-gray-500 hover:text-gray-300 transition-colors flex items-center gap-1" |
| > |
| <span className={`transition-transform ${showAdvanced ? 'rotate-90' : ''}`}>▶</span> |
| Custom Caption & Advanced |
| </button> |
| |
| {showAdvanced && ( |
| <div className="space-y-3 pl-3 border-l border-white/[0.06]"> |
| <div> |
| <label className="text-xs text-gray-400 font-medium mb-1 block">Caption Override</label> |
| <textarea |
| value={params.caption} |
| onChange={e => onParamChange('caption', e.target.value)} |
| placeholder="Leave empty for auto-generated caption" |
| className="w-full bg-surface-elevated border border-white/[0.08] rounded-lg px-3 py-2 text-sm text-white placeholder-gray-600 focus:outline-none focus:border-accent-500/40 resize-none font-mono" |
| rows={2} |
| /> |
| </div> |
| |
| <ParamSlider |
| label="CFG Scale" |
| value={params.cfg_scale || 7} |
| min={1} |
| max={15} |
| step={0.5} |
| onChange={v => onParamChange('cfg_scale', v)} |
| /> |
| |
| <div> |
| <label className="text-xs text-gray-400 font-medium mb-1 block">Scheduler</label> |
| <select |
| value={params.scheduler} |
| onChange={e => onParamChange('scheduler', e.target.value)} |
| className="bg-surface-elevated border border-white/[0.08] rounded-lg px-3 py-1.5 text-sm text-white focus:outline-none focus:border-accent-500/40" |
| > |
| <option value="ode">ODE (recommended)</option> |
| <option value="sde">SDE</option> |
| </select> |
| </div> |
| </div> |
| )} |
| |
| <ParamSlider |
| label="Duration" |
| value={params.duration} |
| min={10} |
| max={120} |
| step={5} |
| onChange={v => onParamChange('duration', v)} |
| leftLabel="10s" |
| rightLabel="120s" |
| /> |
| |
| <ParamSlider |
| label="Source Fidelity" |
| value={params.audio_cover_strength} |
| min={0} |
| max={1} |
| step={0.05} |
| onChange={v => onParamChange('audio_cover_strength', v)} |
| leftLabel="Creative" |
| rightLabel="Faithful" |
| /> |
| |
| {/* Model Variant */} |
| <div> |
| <label className="text-xs text-gray-400 font-medium mb-1 block">Model Variant</label> |
| <select |
| value={params.model_variant} |
| onChange={e => onParamChange('model_variant', e.target.value)} |
| className="bg-surface-elevated border border-white/[0.08] rounded-lg px-3 py-1.5 text-sm text-white focus:outline-none focus:border-accent-500/40" |
| > |
| <option value="xl-turbo">XL Turbo (best for 32GB)</option> |
| <option value="standard-turbo">Standard Turbo (faster)</option> |
| <option value="standard-sft">Standard SFT (balanced)</option> |
| </select> |
| </div> |
| |
| <ParamSlider |
| label="Inference Steps" |
| value={params.inference_steps} |
| min={1} |
| max={50} |
| step={1} |
| onChange={v => onParamChange('inference_steps', v)} |
| leftLabel="Fast (1)" |
| rightLabel="Quality (50)" |
| /> |
| |
| {/* Seed */} |
| <div> |
| <label className="text-xs text-gray-400 font-medium mb-1 block">Seed</label> |
| <div className="flex gap-2"> |
| <input |
| type="number" |
| value={params.seed} |
| onChange={e => onParamChange('seed', parseInt(e.target.value) || -1)} |
| className="flex-1 bg-surface-elevated border border-white/[0.08] rounded-lg px-3 py-1.5 text-sm text-white font-mono focus:outline-none focus:border-accent-500/40" |
| /> |
| <button |
| onClick={() => onParamChange('seed', Math.floor(Math.random() * 999999))} |
| className="px-2 py-1.5 rounded-lg bg-white/[0.06] hover:bg-white/[0.1] text-sm transition-colors" |
| title="Random seed" |
| > |
| 🎲 |
| </button> |
| </div> |
| <span className="text-[10px] text-gray-600 mt-0.5 block">-1 = random</span> |
| </div> |
| </div> |
| ) |
| } |
|
|