feat: modularize block system (#718)

This commit is contained in:
Jeremy 2025-01-27 14:19:47 +05:30 committed by GitHub
parent 5e8cddc886
commit 38527ff92e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
18 changed files with 684 additions and 604 deletions

View file

@ -1,20 +1,18 @@
import { cn } from '@/lib/utils';
import { ClockRewind, CopyIcon, RedoIcon, UndoIcon } from './icons';
import { Button } from './ui/button';
import { Tooltip, TooltipContent, TooltipTrigger } from './ui/tooltip';
import { toast } from 'sonner';
import { ConsoleOutput, UIBlock } from './block';
import { blockDefinitions, UIBlock } from './block';
import { Dispatch, memo, SetStateAction } from 'react';
import { RunCodeButton } from './run-code-button';
import { useMultimodalCopyToClipboard } from '@/hooks/use-multimodal-copy-to-clipboard';
import { BlockActionContext } from './create-block';
import { cn } from '@/lib/utils';
interface BlockActionsProps {
block: UIBlock;
handleVersionChange: (type: 'next' | 'prev' | 'toggle' | 'latest') => void;
currentVersionIndex: number;
isCurrentVersion: boolean;
mode: 'read-only' | 'edit' | 'diff';
setConsoleOutputs: Dispatch<SetStateAction<Array<ConsoleOutput>>>;
mode: 'edit' | 'diff';
metadata: any;
setMetadata: Dispatch<SetStateAction<any>>;
}
function PureBlockActions({
@ -23,95 +21,50 @@ function PureBlockActions({
currentVersionIndex,
isCurrentVersion,
mode,
setConsoleOutputs,
metadata,
setMetadata,
}: BlockActionsProps) {
const { copyTextToClipboard, copyImageToClipboard } =
useMultimodalCopyToClipboard();
const blockDefinition = blockDefinitions.find(
(definition) => definition.kind === block.kind,
);
if (!blockDefinition) {
throw new Error('Block definition not found!');
}
const actionContext: BlockActionContext = {
content: block.content,
handleVersionChange,
currentVersionIndex,
isCurrentVersion,
mode,
metadata,
setMetadata,
};
return (
<div className="flex flex-row gap-1">
{block.kind === 'code' && (
<RunCodeButton block={block} setConsoleOutputs={setConsoleOutputs} />
)}
{block.kind === 'text' && (
<Tooltip>
{blockDefinition.actions.map((action) => (
<Tooltip key={action.description}>
<TooltipTrigger asChild>
<Button
variant="outline"
className={cn(
'p-2 h-fit !pointer-events-auto dark:hover:bg-zinc-700',
{
'bg-muted': mode === 'diff',
},
)}
onClick={() => {
handleVersionChange('toggle');
}}
className={cn('h-fit dark:hover:bg-zinc-700', {
'p-2': !action.label,
'py-1.5 px-2': action.label,
})}
onClick={() => action.onClick(actionContext)}
disabled={
block.status === 'streaming' || currentVersionIndex === 0
action.isDisabled ? action.isDisabled(actionContext) : false
}
>
<ClockRewind size={18} />
{action.icon}
{action.label}
</Button>
</TooltipTrigger>
<TooltipContent>View changes</TooltipContent>
<TooltipContent>{action.description}</TooltipContent>
</Tooltip>
)}
<Tooltip>
<TooltipTrigger asChild>
<Button
variant="outline"
className="p-2 h-fit dark:hover:bg-zinc-700 !pointer-events-auto"
onClick={() => {
handleVersionChange('prev');
}}
disabled={currentVersionIndex === 0 || block.status === 'streaming'}
>
<UndoIcon size={18} />
</Button>
</TooltipTrigger>
<TooltipContent>View Previous version</TooltipContent>
</Tooltip>
<Tooltip>
<TooltipTrigger asChild>
<Button
variant="outline"
className="p-2 h-fit dark:hover:bg-zinc-700 !pointer-events-auto"
onClick={() => {
handleVersionChange('next');
}}
disabled={isCurrentVersion || block.status === 'streaming'}
>
<RedoIcon size={18} />
</Button>
</TooltipTrigger>
<TooltipContent>View Next version</TooltipContent>
</Tooltip>
<Tooltip>
<TooltipTrigger asChild>
<Button
variant="outline"
className="p-2 h-fit dark:hover:bg-zinc-700"
onClick={() => {
if (block.kind === 'image') {
copyImageToClipboard(block.content);
} else {
copyTextToClipboard(block.content);
}
toast.success('Copied to clipboard!');
}}
disabled={block.status === 'streaming'}
>
<CopyIcon size={18} />
</Button>
</TooltipTrigger>
<TooltipContent>Copy to clipboard</TooltipContent>
</Tooltip>
))}
</div>
);
}