mirror of
https://github.com/jamiepine/voicebox.git
synced 2026-09-29 15:15:27 -07:00
fix(captures): Play As autoplay + default voice + orphan recovery
- Hand /generate ids to the global SSE watcher so playback fires on completion. The mutation onSuccess was checking audio_path on a queued row, which is always empty — autoplay never ran. - Bind the Play As voice selection to capture_settings.default_playback_voice_id, kept in sync with the Settings → Captures and Settings → MCP pickers. Picking from the split-button dropdown writes back to settings. - Extract AudioBars from HistoryTable into a shared component; use it for the Play As generating state in place of Loader2. - Stop the active-state hover from flashing white text when the button is in its lighter accent/10 fill. - Drop the gradient avatar swatches from the Settings → Captures voice dropdown. - Backend: when the gen worker exits without writing a terminal status (e.g. SQLite lock racing the failed-status write inside its own exception handler), the cancel endpoint now flips the row to failed instead of 409-ing. Worker also force-fails on its way out as a belt-and-suspenders.
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
import { motion } from 'framer-motion';
|
||||
|
||||
import { cn } from '@/lib/utils/cn';
|
||||
|
||||
export type AudioBarsMode = 'idle' | 'generating' | 'playing';
|
||||
|
||||
interface AudioBarsProps {
|
||||
mode: AudioBarsMode;
|
||||
className?: string;
|
||||
barClassName?: string;
|
||||
}
|
||||
|
||||
export function AudioBars({ mode, className, barClassName }: AudioBarsProps) {
|
||||
const activeColor = mode !== 'idle' ? 'bg-accent' : 'bg-muted-foreground/40';
|
||||
return (
|
||||
<div className={cn('flex items-center gap-[2px] h-5', className)}>
|
||||
{[0, 1, 2, 3, 4].map((i) => (
|
||||
<motion.div
|
||||
key={`${mode}-${i}`}
|
||||
className={cn('w-[3px] rounded-full', activeColor, barClassName)}
|
||||
animate={
|
||||
mode === 'generating'
|
||||
? { height: ['6px', '16px', '6px'] }
|
||||
: mode === 'playing'
|
||||
? { height: ['8px', '14px', '4px', '12px', '8px'] }
|
||||
: { height: '8px' }
|
||||
}
|
||||
transition={
|
||||
mode === 'generating'
|
||||
? { duration: 0.6, repeat: Infinity, delay: i * 0.08, ease: 'easeInOut' }
|
||||
: mode === 'playing'
|
||||
? { duration: 1.2, repeat: Infinity, delay: i * 0.15, ease: 'easeInOut' }
|
||||
: { duration: 0.4, ease: 'easeOut' }
|
||||
}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user