mirror of
https://github.com/jamiepine/voicebox.git
synced 2026-09-29 07:05:14 -07:00
Update dependencies and enhance UI components for better functionality
- Added new Tauri plugins: @tauri-apps/plugin-process and @tauri-apps/plugin-updater to improve application capabilities. - Introduced UpdateStatus component to display update information in the UI. - Enhanced GenerationForm to include an optional instruct field for additional input. - Refactored various components for improved styling and responsiveness, including Sidebar, AudioPlayer, and ProfileCard. - Updated API models and schemas to accommodate new instruct parameter in generation requests and responses. - Improved documentation for autoupdater setup and usage.
This commit is contained in:
@@ -35,7 +35,10 @@ export function DownloadSection() {
|
||||
</div>
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-4 sm:gap-6">
|
||||
{downloads.map(({ platform, icon: Icon, link, description }) => (
|
||||
<Card key={platform} className="hover:border-primary/20 hover:shadow-lg hover:shadow-primary/3 transition-all duration-200 hover:-translate-y-0.5">
|
||||
<Card
|
||||
key={platform}
|
||||
className="hover:border-primary/20 hover:shadow-lg hover:shadow-primary/3 transition-all duration-200 hover:-translate-y-0.5"
|
||||
>
|
||||
<CardContent className="p-6">
|
||||
<div className="flex flex-col items-center text-center space-y-4">
|
||||
<div className="p-3 rounded-xl bg-muted/50 backdrop-blur-sm border border-border">
|
||||
@@ -45,11 +48,7 @@ export function DownloadSection() {
|
||||
<h3 className="text-lg font-semibold mb-1">{platform}</h3>
|
||||
<p className="text-sm text-muted-foreground">{description}</p>
|
||||
</div>
|
||||
<Button
|
||||
asChild
|
||||
size="lg"
|
||||
className="w-full"
|
||||
>
|
||||
<Button asChild size="lg" className="w-full">
|
||||
<a href={link} download>
|
||||
<Download className="h-4 w-4 mr-2" />
|
||||
Download
|
||||
|
||||
@@ -10,7 +10,8 @@ export function Footer() {
|
||||
<div>
|
||||
<h3 className="font-bold text-lg mb-4">voicebox</h3>
|
||||
<p className="text-muted-foreground text-sm">
|
||||
Professional voice cloning powered by Qwen3-TTS. Desktop app for Mac, Windows, and Linux.
|
||||
Professional voice cloning powered by Qwen3-TTS. Desktop app for Mac, Windows, and
|
||||
Linux.
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
@@ -27,7 +28,12 @@ export function Footer() {
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<Link href={GITHUB_REPO} target="_blank" rel="noopener noreferrer" className="hover:text-foreground transition-colors">
|
||||
<Link
|
||||
href={GITHUB_REPO}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="hover:text-foreground transition-colors"
|
||||
>
|
||||
GitHub
|
||||
</Link>
|
||||
</li>
|
||||
@@ -37,17 +43,32 @@ export function Footer() {
|
||||
<h4 className="font-semibold mb-3">Resources</h4>
|
||||
<ul className="space-y-2 text-muted-foreground text-sm">
|
||||
<li>
|
||||
<Link href={GITHUB_REPO} target="_blank" rel="noopener noreferrer" className="hover:text-foreground transition-colors">
|
||||
<Link
|
||||
href={GITHUB_REPO}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="hover:text-foreground transition-colors"
|
||||
>
|
||||
Source Code
|
||||
</Link>
|
||||
</li>
|
||||
<li>
|
||||
<Link href={`${GITHUB_REPO}/releases`} target="_blank" rel="noopener noreferrer" className="hover:text-foreground transition-colors">
|
||||
<Link
|
||||
href={`${GITHUB_REPO}/releases`}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="hover:text-foreground transition-colors"
|
||||
>
|
||||
Releases
|
||||
</Link>
|
||||
</li>
|
||||
<li>
|
||||
<Link href={`${GITHUB_REPO}/issues`} target="_blank" rel="noopener noreferrer" className="hover:text-foreground transition-colors">
|
||||
<Link
|
||||
href={`${GITHUB_REPO}/issues`}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="hover:text-foreground transition-colors"
|
||||
>
|
||||
Issues
|
||||
</Link>
|
||||
</li>
|
||||
|
||||
@@ -11,29 +11,22 @@ export function Header() {
|
||||
<div className="container mx-auto px-4">
|
||||
<div className="flex items-center justify-between h-16">
|
||||
{/* Logo */}
|
||||
<Link href="/" className="flex items-center gap-2 font-bold text-xl sm:text-2xl hover:opacity-80 transition-opacity tracking-tight">
|
||||
<Link
|
||||
href="/"
|
||||
className="flex items-center gap-2 font-bold text-xl sm:text-2xl hover:opacity-80 transition-opacity tracking-tight"
|
||||
>
|
||||
voicebox
|
||||
</Link>
|
||||
|
||||
{/* Actions */}
|
||||
<div className="flex items-center gap-2 sm:gap-4">
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
asChild
|
||||
className="hidden sm:flex"
|
||||
>
|
||||
<Button variant="outline" size="sm" asChild className="hidden sm:flex">
|
||||
<a href={GITHUB_REPO} target="_blank" rel="noopener noreferrer">
|
||||
<Github className="h-4 w-4 mr-2" />
|
||||
GitHub
|
||||
</a>
|
||||
</Button>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
asChild
|
||||
className="sm:hidden"
|
||||
>
|
||||
<Button variant="ghost" size="icon" asChild className="sm:hidden">
|
||||
<a href={GITHUB_REPO} target="_blank" rel="noopener noreferrer" aria-label="GitHub">
|
||||
<Github className="h-5 w-5" />
|
||||
</a>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
export function AppleIcon({ className }: { className?: string }) {
|
||||
return (
|
||||
<svg className={className} viewBox="0 0 24 24" fill="currentColor">
|
||||
<path d="M17.05 20.28c-.98.95-2.05.88-3.08.4-1.09-.5-2.08-.48-3.24 0-1.44.62-2.2.44-3.06-.4C2.79 15.25 3.51 7.59 9.05 7.31c1.35.07 2.29.74 3.08.8 1.18-.24 2.31-.93 3.57-.84 1.51.12 2.65.72 3.4 1.8-3.12 1.87-2.38 5.98.48 7.13-.57 1.5-1.31 2.99-2.54 4.09l.01-.01zM12.03 7.25c-.15-2.23 1.66-4.07 3.74-4.25.29 2.58-2.34 4.5-3.74 4.25z"/>
|
||||
<path d="M17.05 20.28c-.98.95-2.05.88-3.08.4-1.09-.5-2.08-.48-3.24 0-1.44.62-2.2.44-3.06-.4C2.79 15.25 3.51 7.59 9.05 7.31c1.35.07 2.29.74 3.08.8 1.18-.24 2.31-.93 3.57-.84 1.51.12 2.65.72 3.4 1.8-3.12 1.87-2.38 5.98.48 7.13-.57 1.5-1.31 2.99-2.54 4.09l.01-.01zM12.03 7.25c-.15-2.23 1.66-4.07 3.74-4.25.29 2.58-2.34 4.5-3.74 4.25z" />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
@@ -9,7 +9,7 @@ export function AppleIcon({ className }: { className?: string }) {
|
||||
export function WindowsIcon({ className }: { className?: string }) {
|
||||
return (
|
||||
<svg className={className} viewBox="0 0 24 24" fill="currentColor">
|
||||
<path d="M3 12V6.75l6-1.32v6.48L3 12zm17-9v8.75l-10 .15V5.21L20 3zM3 13l6 .09v7.81l-6-1.15V13zm17 .25V22l-10-1.8v-7.15l10 .15z"/>
|
||||
<path d="M3 12V6.75l6-1.32v6.48L3 12zm17-9v8.75l-10 .15V5.21L20 3zM3 13l6 .09v7.81l-6-1.15V13zm17 .25V22l-10-1.8v-7.15l10 .15z" />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
@@ -17,7 +17,7 @@ export function WindowsIcon({ className }: { className?: string }) {
|
||||
export function LinuxIcon({ className }: { className?: string }) {
|
||||
return (
|
||||
<svg className={className} viewBox="0 0 24 24" fill="currentColor">
|
||||
<path d="M12.504 0c-.155 0-.315.008-.48.021-4.226.333-3.105 4.807-3.17 6.298-.076 1.092-.3 1.953-1.05 3.02-.885 1.051-2.127 2.75-2.716 4.521-.278.832-.41 1.684-.287 2.489a.424.424 0 00-.11.135c-.26.26-.195.69-.133 1.001.054.27.112.553.077.784-.12.794-.3 1.593-.3 2.406 0 .599.18 1.193.3 1.791.12.599.3 1.193.3 1.792 0 .812.18 1.611.3 2.405.035.23-.023.514-.077.783-.062.312-.127.742.133 1.002a.424.424 0 00.11.135c-.123.805.01 1.657.287 2.489.589 1.771 1.831 3.47 2.716 4.521.75 1.067 0.974 1.928 1.05 3.02.065 1.491-1.056 5.965 3.17 6.298.165.013.325.021.48.021.155 0 .315-.008.48-.021 4.226-.333 3.105-4.807 3.17-6.298.076-1.092.3-1.953 1.05-3.02.885-1.051 2.127-2.75 2.716-4.521.278-.832.41-1.684.287-2.489a.424.424 0 00.11-.135c.26-.26.195-.69.133-1.001-.054-.27-.112-.553-.077-.784.12-.794.3-1.593.3-2.406 0-.599-.18-1.193-.3-1.791-.12-.599-.3-1.193-.3-1.792 0-.812-.18-1.611-.3-2.405-.035-.23.023-.514.077-.783.062-.312.127-.742-.133-1.002a.424.424 0 00-.11-.135c.123-.805-.01-1.657-.287-2.489-.589-1.771-1.831-3.47-2.716-4.521-.75-1.067-.974-1.928-1.05-3.02-.065-1.491 1.056-5.965-3.17-6.298C12.819.008 12.659 0 12.504 0z"/>
|
||||
<path d="M12.504 0c-.155 0-.315.008-.48.021-4.226.333-3.105 4.807-3.17 6.298-.076 1.092-.3 1.953-1.05 3.02-.885 1.051-2.127 2.75-2.716 4.521-.278.832-.41 1.684-.287 2.489a.424.424 0 00-.11.135c-.26.26-.195.69-.133 1.001.054.27.112.553.077.784-.12.794-.3 1.593-.3 2.406 0 .599.18 1.193.3 1.791.12.599.3 1.193.3 1.792 0 .812.18 1.611.3 2.405.035.23-.023.514-.077.783-.062.312-.127.742.133 1.002a.424.424 0 00.11.135c-.123.805.01 1.657.287 2.489.589 1.771 1.831 3.47 2.716 4.521.75 1.067 0.974 1.928 1.05 3.02.065 1.491-1.056 5.965 3.17 6.298.165.013.325.021.48.021.155 0 .315-.008.48-.021 4.226-.333 3.105-4.807 3.17-6.298.076-1.092.3-1.953 1.05-3.02.885-1.051 2.127-2.75 2.716-4.521.278-.832.41-1.684.287-2.489a.424.424 0 00.11-.135c.26-.26.195-.69.133-1.001-.054-.27-.112-.553-.077-.784.12-.794.3-1.593.3-2.406 0-.599-.18-1.193-.3-1.791-.12-.599-.3-1.193-.3-1.792 0-.812-.18-1.611-.3-2.405-.035-.23.023-.514.077-.783.062-.312.127-.742-.133-1.002a.424.424 0 00-.11-.135c.123-.805-.01-1.657-.287-2.489-.589-1.771-1.831-3.47-2.716-4.521-.75-1.067-.974-1.928-1.05-3.02-.065-1.491 1.056-5.965-3.17-6.298C12.819.008 12.659 0 12.504 0z" />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -8,14 +8,16 @@ const buttonVariants = cva(
|
||||
{
|
||||
variants: {
|
||||
variant: {
|
||||
default: 'bg-primary/10 backdrop-blur-sm border border-border text-primary hover:bg-primary/11 hover:border-primary/15 shadow-lg shadow-black/20 active:scale-[0.99]',
|
||||
default:
|
||||
'bg-primary/10 backdrop-blur-sm border border-border text-primary hover:bg-primary/11 hover:border-primary/15 shadow-lg shadow-black/20 active:scale-[0.99]',
|
||||
destructive:
|
||||
'bg-destructive text-destructive-foreground hover:bg-destructive/90 shadow-lg shadow-destructive/20 active:scale-[0.98]',
|
||||
outline:
|
||||
'border border-border bg-background/50 backdrop-blur-sm hover:bg-foreground/5 transition-all active:scale-[0.99]',
|
||||
secondary:
|
||||
'bg-secondary text-secondary-foreground hover:bg-secondary/70 backdrop-blur-sm active:scale-[0.99]',
|
||||
ghost: 'hover:bg-accent/30 hover:text-accent-foreground backdrop-blur-sm active:scale-[0.99]',
|
||||
ghost:
|
||||
'hover:bg-accent/30 hover:text-accent-foreground backdrop-blur-sm active:scale-[0.99]',
|
||||
link: 'text-primary underline-offset-4 hover:underline',
|
||||
},
|
||||
size: {
|
||||
@@ -29,7 +31,7 @@ const buttonVariants = cva(
|
||||
variant: 'default',
|
||||
size: 'default',
|
||||
},
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
export interface ButtonProps
|
||||
@@ -42,13 +44,9 @@ const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
|
||||
({ className, variant, size, asChild = false, ...props }, ref) => {
|
||||
const Comp = asChild ? Slot : 'button';
|
||||
return (
|
||||
<Comp
|
||||
className={cn(buttonVariants({ variant, size, className }))}
|
||||
ref={ref}
|
||||
{...props}
|
||||
/>
|
||||
<Comp className={cn(buttonVariants({ variant, size, className }))} ref={ref} {...props} />
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
Button.displayName = 'Button';
|
||||
|
||||
|
||||
@@ -1,78 +1,58 @@
|
||||
import * as React from 'react';
|
||||
import { cn } from '@/lib/utils';
|
||||
|
||||
const Card = React.forwardRef<
|
||||
HTMLDivElement,
|
||||
React.HTMLAttributes<HTMLDivElement>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<div
|
||||
ref={ref}
|
||||
className={cn(
|
||||
'rounded-2xl border border-border bg-card backdrop-blur-xl text-card-foreground shadow-lg shadow-black/20',
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
const Card = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
|
||||
({ className, ...props }, ref) => (
|
||||
<div
|
||||
ref={ref}
|
||||
className={cn(
|
||||
'rounded-2xl border border-border bg-card backdrop-blur-xl text-card-foreground shadow-lg shadow-black/20',
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
),
|
||||
);
|
||||
Card.displayName = 'Card';
|
||||
|
||||
const CardHeader = React.forwardRef<
|
||||
HTMLDivElement,
|
||||
React.HTMLAttributes<HTMLDivElement>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<div
|
||||
ref={ref}
|
||||
className={cn('flex flex-col space-y-1.5 p-6 pb-4', className)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
const CardHeader = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
|
||||
({ className, ...props }, ref) => (
|
||||
<div ref={ref} className={cn('flex flex-col space-y-1.5 p-6 pb-4', className)} {...props} />
|
||||
),
|
||||
);
|
||||
CardHeader.displayName = 'CardHeader';
|
||||
|
||||
const CardTitle = React.forwardRef<
|
||||
HTMLParagraphElement,
|
||||
React.HTMLAttributes<HTMLHeadingElement>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<h3
|
||||
ref={ref}
|
||||
className={cn(
|
||||
'text-2xl font-semibold leading-none tracking-tight',
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
const CardTitle = React.forwardRef<HTMLParagraphElement, React.HTMLAttributes<HTMLHeadingElement>>(
|
||||
({ className, ...props }, ref) => (
|
||||
<h3
|
||||
ref={ref}
|
||||
className={cn('text-2xl font-semibold leading-none tracking-tight', className)}
|
||||
{...props}
|
||||
/>
|
||||
),
|
||||
);
|
||||
CardTitle.displayName = 'CardTitle';
|
||||
|
||||
const CardDescription = React.forwardRef<
|
||||
HTMLParagraphElement,
|
||||
React.HTMLAttributes<HTMLParagraphElement>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<p
|
||||
ref={ref}
|
||||
className={cn('text-sm text-muted-foreground', className)}
|
||||
{...props}
|
||||
/>
|
||||
<p ref={ref} className={cn('text-sm text-muted-foreground', className)} {...props} />
|
||||
));
|
||||
CardDescription.displayName = 'CardDescription';
|
||||
|
||||
const CardContent = React.forwardRef<
|
||||
HTMLDivElement,
|
||||
React.HTMLAttributes<HTMLDivElement>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<div ref={ref} className={cn('p-6 pt-4', className)} {...props} />
|
||||
));
|
||||
const CardContent = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
|
||||
({ className, ...props }, ref) => (
|
||||
<div ref={ref} className={cn('p-6 pt-4', className)} {...props} />
|
||||
),
|
||||
);
|
||||
CardContent.displayName = 'CardContent';
|
||||
|
||||
const CardFooter = React.forwardRef<
|
||||
HTMLDivElement,
|
||||
React.HTMLAttributes<HTMLDivElement>
|
||||
>(({ className, ...props }, ref) => (
|
||||
<div
|
||||
ref={ref}
|
||||
className={cn('flex items-center p-6 pt-0', className)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
const CardFooter = React.forwardRef<HTMLDivElement, React.HTMLAttributes<HTMLDivElement>>(
|
||||
({ className, ...props }, ref) => (
|
||||
<div ref={ref} className={cn('flex items-center p-6 pt-0', className)} {...props} />
|
||||
),
|
||||
);
|
||||
CardFooter.displayName = 'CardFooter';
|
||||
|
||||
export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent };
|
||||
|
||||
@@ -11,7 +11,12 @@ interface FeatureCardProps {
|
||||
|
||||
export function FeatureCard({ title, description, icon, className }: FeatureCardProps) {
|
||||
return (
|
||||
<Card className={cn('text-center hover:border-primary/20 hover:shadow-lg hover:shadow-primary/3 transition-all duration-200 hover:-translate-y-0.5', className)}>
|
||||
<Card
|
||||
className={cn(
|
||||
'text-center hover:border-primary/20 hover:shadow-lg hover:shadow-primary/3 transition-all duration-200 hover:-translate-y-0.5',
|
||||
className,
|
||||
)}
|
||||
>
|
||||
<CardHeader>
|
||||
{icon && (
|
||||
<div className="flex justify-center mb-3">
|
||||
@@ -23,9 +28,7 @@ export function FeatureCard({ title, description, icon, className }: FeatureCard
|
||||
<CardTitle className="text-xl sm:text-2xl">{title}</CardTitle>
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<CardDescription className="text-sm sm:text-base">
|
||||
{description}
|
||||
</CardDescription>
|
||||
<CardDescription className="text-sm sm:text-base">{description}</CardDescription>
|
||||
</CardContent>
|
||||
</Card>
|
||||
);
|
||||
|
||||
@@ -37,11 +37,9 @@ export function Hero({ title, description, actions, className, showLogo = true }
|
||||
{description}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
||||
{/* Right side - Actions */}
|
||||
<div className="flex flex-col items-start lg:items-end gap-4">
|
||||
{actions}
|
||||
</div>
|
||||
<div className="flex flex-col items-start lg:items-end gap-4">{actions}</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
|
||||
@@ -17,7 +17,12 @@ export function Section({ children, className, id }: SectionProps) {
|
||||
|
||||
export function SectionTitle({ children, className }: { children: ReactNode; className?: string }) {
|
||||
return (
|
||||
<h2 className={cn('text-2xl sm:text-3xl md:text-4xl font-bold text-center md:text-left', className)}>
|
||||
<h2
|
||||
className={cn(
|
||||
'text-2xl sm:text-3xl md:text-4xl font-bold text-center md:text-left',
|
||||
className,
|
||||
)}
|
||||
>
|
||||
{children}
|
||||
</h2>
|
||||
);
|
||||
|
||||
@@ -5,24 +5,19 @@ import { cn } from '@/lib/utils';
|
||||
const Separator = React.forwardRef<
|
||||
React.ElementRef<typeof SeparatorPrimitive.Root>,
|
||||
React.ComponentPropsWithoutRef<typeof SeparatorPrimitive.Root>
|
||||
>(
|
||||
(
|
||||
{ className, orientation = 'horizontal', decorative = true, ...props },
|
||||
ref
|
||||
) => (
|
||||
<SeparatorPrimitive.Root
|
||||
ref={ref}
|
||||
decorative={decorative}
|
||||
orientation={orientation}
|
||||
className={cn(
|
||||
'shrink-0 bg-border',
|
||||
orientation === 'horizontal' ? 'h-[1px] w-full' : 'h-full w-[1px]',
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
)
|
||||
);
|
||||
>(({ className, orientation = 'horizontal', decorative = true, ...props }, ref) => (
|
||||
<SeparatorPrimitive.Root
|
||||
ref={ref}
|
||||
decorative={decorative}
|
||||
orientation={orientation}
|
||||
className={cn(
|
||||
'shrink-0 bg-border',
|
||||
orientation === 'horizontal' ? 'h-[1px] w-full' : 'h-full w-[1px]',
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
/>
|
||||
));
|
||||
Separator.displayName = SeparatorPrimitive.Root.displayName;
|
||||
|
||||
export { Separator };
|
||||
|
||||
Reference in New Issue
Block a user