feat: voice clone audio generation + podcast workspace architecture
- Voice clone integration: When user selects voice clone in Write phase, backend uses their uploaded voice sample + scene script text to generate audio via qwen3/minimax/cosyvoice voice clone APIs - Multi-tenant workspace storage: All podcast assets (audio, video, images, charts) now use workspace-specific directories per user - Chart preview improvements: Card-based B-Roll charts UI with thumbnails, takeaway text, and action buttons; public endpoint for image serving - Voice clone caching: In-memory LRU cache for voice samples (avoids re-downloading per scene); frontend caches voice clone metadata - Thread pool for voice clone: Audio generation uses ThreadPoolExecutor to avoid blocking the FastAPI event loop - Auto-detect voice clone IDs (vc_*, MY_VOICE_CLONE) to route correctly - DB fallback for voice sample URL: Fetches from ContentAsset if not passed - Fixed API URL resolution for chart previews - Fixed GlassyCard DOM warnings for motion props - Fixed ScriptGenerationProgressView syntax error - Fixed usePodcastWorkflow scriptData reference
This commit is contained in:
@@ -5,12 +5,40 @@ interface GlassyCardProps {
|
||||
children?: React.ReactNode;
|
||||
sx?: SxProps<Theme>;
|
||||
onClick?: () => void;
|
||||
[key: string]: any; // Allow other props for framer-motion
|
||||
// Allow motion props (framer-motion) - they'll be filtered out to avoid DOM warnings
|
||||
whileHover?: any;
|
||||
whileTap?: any;
|
||||
initial?: any;
|
||||
animate?: any;
|
||||
exit?: any;
|
||||
transition?: any;
|
||||
variants?: any;
|
||||
layout?: any;
|
||||
layoutId?: any;
|
||||
className?: string;
|
||||
'aria-label'?: string;
|
||||
}
|
||||
|
||||
export const GlassyCard: React.FC<GlassyCardProps> = ({ children, sx, ...props }) => {
|
||||
// Filter out motion props to avoid DOM warnings - these won't work with MUI Paper anyway
|
||||
const {
|
||||
whileHover,
|
||||
whileTap,
|
||||
initial,
|
||||
animate,
|
||||
exit,
|
||||
transition,
|
||||
variants,
|
||||
layout,
|
||||
layoutId,
|
||||
className,
|
||||
'aria-label': ariaLabel,
|
||||
...filteredProps
|
||||
} = props;
|
||||
return (
|
||||
<Paper
|
||||
className={className}
|
||||
aria-label={ariaLabel}
|
||||
sx={{
|
||||
borderRadius: 3,
|
||||
border: "1px solid rgba(15, 23, 42, 0.06)",
|
||||
@@ -25,7 +53,7 @@ export const GlassyCard: React.FC<GlassyCardProps> = ({ children, sx, ...props }
|
||||
},
|
||||
...sx
|
||||
}}
|
||||
{...props}
|
||||
{...filteredProps}
|
||||
>
|
||||
{children}
|
||||
</Paper>
|
||||
|
||||
Reference in New Issue
Block a user