feat: ai elements (#1143)
This commit is contained in:
parent
66e8227655
commit
f09be3f286
38 changed files with 3558 additions and 500 deletions
|
|
@ -4,13 +4,7 @@ import { useCopyToClipboard } from 'usehooks-ts';
|
|||
import type { Vote } from '@/lib/db/schema';
|
||||
|
||||
import { CopyIcon, ThumbDownIcon, ThumbUpIcon } from './icons';
|
||||
import { Button } from './ui/button';
|
||||
import {
|
||||
Tooltip,
|
||||
TooltipContent,
|
||||
TooltipProvider,
|
||||
TooltipTrigger,
|
||||
} from './ui/tooltip';
|
||||
import { Actions, Action } from './elements/actions';
|
||||
import { memo } from 'react';
|
||||
import equal from 'fast-deep-equal';
|
||||
import { toast } from 'sonner';
|
||||
|
|
@ -34,42 +28,32 @@ export function PureMessageActions({
|
|||
if (message.role === 'user') return null;
|
||||
|
||||
return (
|
||||
<TooltipProvider delayDuration={0}>
|
||||
<div className="flex flex-row gap-2">
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Button
|
||||
className="py-1 px-2 h-fit text-muted-foreground"
|
||||
variant="outline"
|
||||
onClick={async () => {
|
||||
const textFromParts = message.parts
|
||||
?.filter((part) => part.type === 'text')
|
||||
.map((part) => part.text)
|
||||
.join('\n')
|
||||
.trim();
|
||||
<Actions>
|
||||
<Action
|
||||
tooltip="Copy"
|
||||
onClick={async () => {
|
||||
const textFromParts = message.parts
|
||||
?.filter((part) => part.type === 'text')
|
||||
.map((part) => part.text)
|
||||
.join('\n')
|
||||
.trim();
|
||||
|
||||
if (!textFromParts) {
|
||||
toast.error("There's no text to copy!");
|
||||
return;
|
||||
}
|
||||
if (!textFromParts) {
|
||||
toast.error("There's no text to copy!");
|
||||
return;
|
||||
}
|
||||
|
||||
await copyToClipboard(textFromParts);
|
||||
toast.success('Copied to clipboard!');
|
||||
}}
|
||||
>
|
||||
<CopyIcon />
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>Copy</TooltipContent>
|
||||
</Tooltip>
|
||||
await copyToClipboard(textFromParts);
|
||||
toast.success('Copied to clipboard!');
|
||||
}}
|
||||
>
|
||||
<CopyIcon />
|
||||
</Action>
|
||||
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Button
|
||||
data-testid="message-upvote"
|
||||
className="py-1 px-2 h-fit text-muted-foreground !pointer-events-auto"
|
||||
disabled={vote?.isUpvoted}
|
||||
variant="outline"
|
||||
<Action
|
||||
tooltip="Upvote Response"
|
||||
data-testid="message-upvote"
|
||||
disabled={vote?.isUpvoted}
|
||||
onClick={async () => {
|
||||
const upvote = fetch('/api/vote', {
|
||||
method: 'PATCH',
|
||||
|
|
@ -109,20 +93,14 @@ export function PureMessageActions({
|
|||
error: 'Failed to upvote response.',
|
||||
});
|
||||
}}
|
||||
>
|
||||
<ThumbUpIcon />
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>Upvote Response</TooltipContent>
|
||||
</Tooltip>
|
||||
>
|
||||
<ThumbUpIcon />
|
||||
</Action>
|
||||
|
||||
<Tooltip>
|
||||
<TooltipTrigger asChild>
|
||||
<Button
|
||||
data-testid="message-downvote"
|
||||
className="py-1 px-2 h-fit text-muted-foreground !pointer-events-auto"
|
||||
variant="outline"
|
||||
disabled={vote && !vote.isUpvoted}
|
||||
<Action
|
||||
tooltip="Downvote Response"
|
||||
data-testid="message-downvote"
|
||||
disabled={vote && !vote.isUpvoted}
|
||||
onClick={async () => {
|
||||
const downvote = fetch('/api/vote', {
|
||||
method: 'PATCH',
|
||||
|
|
@ -162,14 +140,10 @@ export function PureMessageActions({
|
|||
error: 'Failed to downvote response.',
|
||||
});
|
||||
}}
|
||||
>
|
||||
<ThumbDownIcon />
|
||||
</Button>
|
||||
</TooltipTrigger>
|
||||
<TooltipContent>Downvote Response</TooltipContent>
|
||||
</Tooltip>
|
||||
</div>
|
||||
</TooltipProvider>
|
||||
>
|
||||
<ThumbDownIcon />
|
||||
</Action>
|
||||
</Actions>
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue