Merge pull request #5055 from menloresearch/enhancement/message-toolbar

enhancement: message toolbar using tooltip
This commit is contained in:
Faisal Amir 2025-05-22 10:55:28 +07:00 committed by GitHub
commit 6a6ccc9a9e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 69 additions and 50 deletions

View File

@ -26,6 +26,11 @@ import {
import { Button } from '@/components/ui/button' import { Button } from '@/components/ui/button'
import { Textarea } from '@/components/ui/textarea' import { Textarea } from '@/components/ui/textarea'
import { toast } from 'sonner' import { toast } from 'sonner'
import {
Tooltip,
TooltipContent,
TooltipTrigger,
} from '@/components/ui/tooltip'
const CopyButton = ({ text }: { text: string }) => { const CopyButton = ({ text }: { text: string }) => {
const [copied, setCopied] = useState(false) const [copied, setCopied] = useState(false)
@ -47,12 +52,14 @@ const CopyButton = ({ text }: { text: string }) => {
<span className="opacity-100">Copied!</span> <span className="opacity-100">Copied!</span>
</> </>
) : ( ) : (
<> <Tooltip>
<TooltipTrigger asChild>
<IconCopy size={16} /> <IconCopy size={16} />
<span className="opacity-0 w-0 overflow-hidden whitespace-nowrap group-hover:w-auto group-hover:opacity-100 transition-all duration-300 ease-in-out"> </TooltipTrigger>
Copy <TooltipContent>
</span> <p>Copy</p>
</> </TooltipContent>
</Tooltip>
)} )}
</button> </button>
) )
@ -140,17 +147,16 @@ export const ThreadContent = memo(
<div className="flex items-center justify-end gap-2 text-main-view-fg/60 text-xs mt-2"> <div className="flex items-center justify-end gap-2 text-main-view-fg/60 text-xs mt-2">
<Dialog> <Dialog>
<DialogTrigger asChild> <DialogTrigger asChild>
<button <Tooltip>
className="flex items-center gap-1 hover:text-accent transition-colors cursor-pointer group relative" <TooltipTrigger asChild>
onClick={() => { <button className="flex items-center gap-1 hover:text-accent transition-colors cursor-pointer group relative">
console.log('Edit clicked')
}}
>
<IconPencil size={16} /> <IconPencil size={16} />
<span className="opacity-0 w-0 overflow-hidden whitespace-nowrap group-hover:w-auto group-hover:opacity-100 transition-all duration-300 ease-in-out">
Edit
</span>
</button> </button>
</TooltipTrigger>
<TooltipContent>
<p>Edit</p>
</TooltipContent>
</Tooltip>
</DialogTrigger> </DialogTrigger>
<DialogContent> <DialogContent>
<DialogHeader> <DialogHeader>
@ -195,6 +201,8 @@ export const ThreadContent = memo(
</DialogHeader> </DialogHeader>
</DialogContent> </DialogContent>
</Dialog> </Dialog>
<Tooltip>
<TooltipTrigger asChild>
<button <button
className="flex items-center gap-1 hover:text-accent transition-colors cursor-pointer group relative" className="flex items-center gap-1 hover:text-accent transition-colors cursor-pointer group relative"
onClick={() => { onClick={() => {
@ -202,10 +210,12 @@ export const ThreadContent = memo(
}} }}
> >
<IconTrash size={16} /> <IconTrash size={16} />
<span className="opacity-0 w-0 overflow-hidden whitespace-nowrap group-hover:w-auto group-hover:opacity-100 transition-all duration-300 ease-in-out">
Delete
</span>
</button> </button>
</TooltipTrigger>
<TooltipContent>
<p>Delete</p>
</TooltipContent>
</Tooltip>
</div> </div>
</div> </div>
)} )}
@ -245,6 +255,8 @@ export const ThreadContent = memo(
)} )}
> >
<CopyButton text={item.content?.[0]?.text.value || ''} /> <CopyButton text={item.content?.[0]?.text.value || ''} />
<Tooltip>
<TooltipTrigger asChild>
<button <button
className="flex items-center gap-1 hover:text-accent transition-colors cursor-pointer group relative" className="flex items-center gap-1 hover:text-accent transition-colors cursor-pointer group relative"
onClick={() => { onClick={() => {
@ -252,20 +264,27 @@ export const ThreadContent = memo(
}} }}
> >
<IconTrash size={16} /> <IconTrash size={16} />
<span className="opacity-0 w-0 overflow-hidden whitespace-nowrap group-hover:w-auto group-hover:opacity-100 transition-all duration-300 ease-in-out">
Delete
</span>
</button> </button>
</TooltipTrigger>
<TooltipContent>
<p>Delete</p>
</TooltipContent>
</Tooltip>
{item.isLastMessage && ( {item.isLastMessage && (
<Tooltip>
<TooltipTrigger asChild>
<button <button
className="flex items-center gap-1 hover:text-accent transition-colors cursor-pointer group relative" className="flex items-center gap-1 hover:text-accent transition-colors cursor-pointer group relative"
onClick={regenerate} onClick={regenerate}
> >
<IconRefresh size={16} /> <IconRefresh size={16} />
<span className="opacity-0 w-0 overflow-hidden whitespace-nowrap group-hover:w-auto group-hover:opacity-100 transition-all duration-300 ease-in-out">
Regenerate
</span>
</button> </button>
</TooltipTrigger>
<TooltipContent>
<p>Regenerate</p>
</TooltipContent>
</Tooltip>
)} )}
</div> </div>
</div> </div>

View File

@ -2,7 +2,7 @@ export function ModelLoader() {
return ( return (
<div className="flex items-center justify-center gap-2 py-1 px-2 bg-main-view-fg/5 rounded"> <div className="flex items-center justify-center gap-2 py-1 px-2 bg-main-view-fg/5 rounded">
<span className="animate-spin h-3 w-3 border-2 border-current border-t-transparent rounded-full" /> <span className="animate-spin h-3 w-3 border-2 border-current border-t-transparent rounded-full" />
<h1 className="font-medium text-xs">Loading Model...</h1> <h1 className="font-medium text-xs">Loading model...</h1>
</div> </div>
) )
} }

View File

@ -294,7 +294,7 @@ function Hub() {
</div> </div>
{expandedModels[model.id] && model.models.length > 0 && ( {expandedModels[model.id] && model.models.length > 0 && (
<div className="mt-5"> <div className="mt-5">
{model.models.slice(1).map((variant) => ( {model.models.map((variant) => (
<CardItem <CardItem
key={variant.id} key={variant.id}
title={variant.id} title={variant.id}