mirror of
https://github.com/jamiepine/voicebox.git
synced 2026-10-02 16:45:15 -07:00
Merge pull request #44 from selop/feature/delivery-instructions
Enhances floating generate box UX
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
import { useMatchRoute } from '@tanstack/react-router';
|
import { useMatchRoute } from '@tanstack/react-router';
|
||||||
import { AnimatePresence, motion } from 'framer-motion';
|
import { AnimatePresence, motion } from 'framer-motion';
|
||||||
import { Loader2, MessageSquare, Sparkles } from 'lucide-react';
|
import { Loader2, SlidersHorizontal, Sparkles } from 'lucide-react';
|
||||||
import { useEffect, useRef, useState } from 'react';
|
import { useEffect, useRef, useState } from 'react';
|
||||||
import { Button } from '@/components/ui/button';
|
import { Button } from '@/components/ui/button';
|
||||||
import { Form, FormControl, FormField, FormItem, FormMessage } from '@/components/ui/form';
|
import { Form, FormControl, FormField, FormItem, FormMessage } from '@/components/ui/form';
|
||||||
@@ -187,7 +187,7 @@ export function FloatingGenerateBox({
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<motion.div
|
<motion.div
|
||||||
className="bg-background/30 backdrop-blur-2xl border border-accent/20 rounded-[2rem] shadow-2xl hover:bg-background/40 hover:border-accent/20 transition-all duration-300 overflow-hidden p-3"
|
className="bg-background/30 backdrop-blur-2xl border border-accent/20 rounded-[2rem] shadow-2xl hover:bg-background/40 hover:border-accent/20 transition-all duration-300 p-3"
|
||||||
transition={{ duration: 0.6, ease: 'easeInOut' }}
|
transition={{ duration: 0.6, ease: 'easeInOut' }}
|
||||||
>
|
>
|
||||||
<Form {...form}>
|
<Form {...form}>
|
||||||
@@ -274,7 +274,7 @@ export function FloatingGenerateBox({
|
|||||||
field.ref(node);
|
field.ref(node);
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
placeholder="Add delivery instructions..."
|
placeholder="e.g. very happy and excited"
|
||||||
className="resize-none bg-transparent border-none focus-visible:ring-0 focus-visible:ring-offset-0 focus:outline-none focus:ring-0 outline-none ring-0 rounded-2xl text-sm placeholder:text-muted-foreground/60 w-full"
|
className="resize-none bg-transparent border-none focus-visible:ring-0 focus-visible:ring-offset-0 focus:outline-none focus:ring-0 outline-none ring-0 rounded-2xl text-sm placeholder:text-muted-foreground/60 w-full"
|
||||||
style={{
|
style={{
|
||||||
minHeight: isExpanded ? '100px' : '32px',
|
minHeight: isExpanded ? '100px' : '32px',
|
||||||
@@ -294,18 +294,27 @@ export function FloatingGenerateBox({
|
|||||||
</motion.div>
|
</motion.div>
|
||||||
|
|
||||||
<div className="relative shrink-0">
|
<div className="relative shrink-0">
|
||||||
<Button
|
<div className="group relative">
|
||||||
type="submit"
|
<Button
|
||||||
disabled={isPending || !selectedProfileId}
|
type="submit"
|
||||||
className="h-10 w-10 rounded-full bg-accent hover:bg-accent/90 hover:scale-105 text-accent-foreground shadow-lg hover:shadow-accent/50 transition-all duration-200"
|
disabled={isPending || !selectedProfileId}
|
||||||
size="icon"
|
className="h-10 w-10 rounded-full bg-accent hover:bg-accent/90 hover:scale-105 text-accent-foreground shadow-lg hover:shadow-accent/50 transition-all duration-200"
|
||||||
>
|
size="icon"
|
||||||
{isPending ? (
|
>
|
||||||
<Loader2 className="h-4 w-4 animate-spin" />
|
{isPending ? (
|
||||||
) : (
|
<Loader2 className="h-4 w-4 animate-spin" />
|
||||||
<Sparkles className="h-4 w-4" />
|
) : (
|
||||||
)}
|
<Sparkles className="h-4 w-4" />
|
||||||
</Button>
|
)}
|
||||||
|
</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]">
|
||||||
|
{isPending
|
||||||
|
? 'Generating...'
|
||||||
|
: !selectedProfileId
|
||||||
|
? 'Select a voice profile first'
|
||||||
|
: 'Generate speech'}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
<AnimatePresence>
|
<AnimatePresence>
|
||||||
{isExpanded && (
|
{isExpanded && (
|
||||||
<motion.div
|
<motion.div
|
||||||
@@ -315,20 +324,25 @@ export function FloatingGenerateBox({
|
|||||||
transition={{ duration: 0.2 }}
|
transition={{ duration: 0.2 }}
|
||||||
className="absolute top-0 right-[calc(100%+0.5rem)]"
|
className="absolute top-0 right-[calc(100%+0.5rem)]"
|
||||||
>
|
>
|
||||||
<Button
|
<div className="group relative">
|
||||||
type="button"
|
<Button
|
||||||
variant="ghost"
|
type="button"
|
||||||
size="icon"
|
variant="ghost"
|
||||||
onClick={() => setIsInstructMode(!isInstructMode)}
|
size="icon"
|
||||||
className={cn(
|
onClick={() => setIsInstructMode(!isInstructMode)}
|
||||||
'h-10 w-10 rounded-full transition-all duration-200',
|
className={cn(
|
||||||
isInstructMode
|
'h-10 w-10 rounded-full transition-all duration-200',
|
||||||
? 'bg-accent text-accent-foreground border border-accent hover:bg-accent/90'
|
isInstructMode
|
||||||
: 'bg-card border border-border hover:bg-background/50',
|
? 'bg-accent text-accent-foreground border border-accent hover:bg-accent/90'
|
||||||
)}
|
: 'bg-card border border-border hover:bg-background/50',
|
||||||
>
|
)}
|
||||||
<MessageSquare className="h-4 w-4" />
|
>
|
||||||
</Button>
|
<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>
|
</motion.div>
|
||||||
)}
|
)}
|
||||||
</AnimatePresence>
|
</AnimatePresence>
|
||||||
|
|||||||
Reference in New Issue
Block a user