mirror of
https://github.com/jamiepine/voicebox.git
synced 2026-09-15 04:40:40 -07:00
Fix player not loading new version after applying effects
Reload the player with the version-specific audio URL when effects are applied to the currently playing generation. Also consolidate the instruct/effects buttons into a single button with the effects editor shown inline when instruct mode is open.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { useMatchRoute } from '@tanstack/react-router';
|
||||
import { AnimatePresence, motion } from 'framer-motion';
|
||||
import { Loader2, SlidersHorizontal, Sparkles, Wand2 } from 'lucide-react';
|
||||
import { Loader2, SlidersHorizontal, Sparkles } from 'lucide-react';
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
import { EffectsChainEditor } from '@/components/Effects/EffectsChainEditor';
|
||||
import { Button } from '@/components/ui/button';
|
||||
@@ -39,7 +39,6 @@ export function FloatingGenerateBox({
|
||||
const { data: profiles } = useProfiles();
|
||||
const [isExpanded, setIsExpanded] = useState(false);
|
||||
const [isInstructMode, setIsInstructMode] = useState(false);
|
||||
const [isEffectsMode, setIsEffectsMode] = useState(false);
|
||||
const [effectsChain, setEffectsChain] = useState<EffectConfig[]>([]);
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
const textareaRef = useRef<HTMLTextAreaElement | null>(null);
|
||||
@@ -360,7 +359,9 @@ export function FloatingGenerateBox({
|
||||
'h-10 w-10 rounded-full transition-all duration-200',
|
||||
isInstructMode
|
||||
? 'bg-accent text-accent-foreground border border-accent hover:bg-accent/90'
|
||||
: 'bg-card border border-border hover:bg-background/50',
|
||||
: effectsChain.length > 0
|
||||
? 'bg-accent/50 text-accent-foreground border border-accent/50 hover:bg-accent/70'
|
||||
: 'bg-card border border-border hover:bg-background/50',
|
||||
)}
|
||||
aria-label={
|
||||
isInstructMode ? 'Fine tune instructions, on' : 'Fine tune instructions'
|
||||
@@ -369,47 +370,7 @@ export function FloatingGenerateBox({
|
||||
<SlidersHorizontal className="h-4 w-4" />
|
||||
</Button>
|
||||
<span className="pointer-events-none absolute bottom-full left-1/2 -translate-x-1/2 mb-2 whitespace-nowrap rounded-md bg-popover px-3 py-1.5 text-xs text-popover-foreground border border-border opacity-0 transition-opacity group-hover:opacity-100 z-[9999]">
|
||||
Fine tune instructions
|
||||
</span>
|
||||
</div>
|
||||
</motion.div>
|
||||
)}
|
||||
{isExpanded && (
|
||||
<motion.div
|
||||
initial={{ opacity: 0, scale: 0.8 }}
|
||||
animate={{ opacity: 1, scale: 1 }}
|
||||
exit={{ opacity: 0, scale: 0.8 }}
|
||||
transition={{ duration: 0.2 }}
|
||||
className={cn(
|
||||
'absolute top-0',
|
||||
form.watch('engine') === 'qwen'
|
||||
? 'right-[calc(100%+3.5rem)]'
|
||||
: 'right-[calc(100%+0.5rem)]',
|
||||
)}
|
||||
>
|
||||
<div className="group relative">
|
||||
<Button
|
||||
type="button"
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
onClick={() => {
|
||||
const next = !isEffectsMode;
|
||||
setIsEffectsMode(next);
|
||||
if (next) setIsInstructMode(false);
|
||||
}}
|
||||
className={cn(
|
||||
'h-10 w-10 rounded-full transition-all duration-200',
|
||||
isEffectsMode || effectsChain.length > 0
|
||||
? 'bg-accent text-accent-foreground border border-accent hover:bg-accent/90'
|
||||
: 'bg-card border border-border hover:bg-background/50',
|
||||
)}
|
||||
aria-label={isEffectsMode ? 'Effects, on' : 'Post-processing effects'}
|
||||
>
|
||||
<Wand2 className="h-4 w-4" />
|
||||
</Button>
|
||||
<span className="pointer-events-none absolute bottom-full left-1/2 -translate-x-1/2 mb-2 whitespace-nowrap rounded-md bg-popover px-3 py-1.5 text-xs text-popover-foreground border border-border opacity-0 transition-opacity group-hover:opacity-100 z-[9999]">
|
||||
Post-processing effects
|
||||
{effectsChain.length > 0 && ` (${effectsChain.length} active)`}
|
||||
Fine tune instructions & effects
|
||||
</span>
|
||||
</div>
|
||||
</motion.div>
|
||||
@@ -418,9 +379,9 @@ export function FloatingGenerateBox({
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Effects chain editor panel */}
|
||||
{/* Effects chain editor panel - shown alongside instruct */}
|
||||
<AnimatePresence>
|
||||
{isExpanded && isEffectsMode && (
|
||||
{isExpanded && isInstructMode && (
|
||||
<motion.div
|
||||
initial={{ height: 0, opacity: 0 }}
|
||||
animate={{ height: 'auto', opacity: 1 }}
|
||||
|
||||
@@ -234,11 +234,26 @@ export function HistoryTable() {
|
||||
if (!effectsTargetId || effectsChain.length === 0) return;
|
||||
setApplyingEffects(true);
|
||||
try {
|
||||
await apiClient.applyEffectsToGeneration(effectsTargetId, {
|
||||
const newVersion = await apiClient.applyEffectsToGeneration(effectsTargetId, {
|
||||
effects_chain: effectsChain,
|
||||
set_as_default: true,
|
||||
});
|
||||
queryClient.invalidateQueries({ queryKey: ['history'] });
|
||||
|
||||
// If the player is currently on this generation, reload with the new version audio
|
||||
if (currentAudioId === effectsTargetId) {
|
||||
const gen = allHistory.find((g) => g.id === effectsTargetId);
|
||||
if (gen) {
|
||||
const versionUrl = apiClient.getVersionAudioUrl(newVersion.id);
|
||||
setAudioWithAutoPlay(
|
||||
versionUrl,
|
||||
effectsTargetId,
|
||||
gen.profile_id,
|
||||
gen.text.substring(0, 50),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
setEffectsDialogOpen(false);
|
||||
toast({ title: 'Effects applied', description: 'A new version has been created.' });
|
||||
} catch (error) {
|
||||
|
||||
Reference in New Issue
Block a user