Rename to blocks (#502)
This commit is contained in:
parent
22a09de6e6
commit
729634e1d6
10 changed files with 108 additions and 111 deletions
|
|
@ -21,8 +21,8 @@ export const models: Array<Model> = [
|
|||
description: 'For complex, multi-step tasks',
|
||||
},
|
||||
{
|
||||
id: 'gpt-4o-canvas',
|
||||
label: 'GPT 4o with Canvas',
|
||||
id: 'gpt-4o-blocks',
|
||||
label: 'GPT 4o with Blocks',
|
||||
apiIdentifier: 'gpt-4o',
|
||||
description: 'Collaborate with writing',
|
||||
},
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
export const canvasPrompt = `
|
||||
Canvas is a special user interface mode that helps users with writing, editing, and other content creation tasks. When canvas is open, it is on the right side of the screen, while the conversation is on the left side. When creating or updating documents, changes are reflected in real-time on the canvas and visible to the user.
|
||||
export const blocksPrompt = `
|
||||
Blocks is a special user interface mode that helps users with writing, editing, and other content creation tasks. When block is open, it is on the right side of the screen, while the conversation is on the left side. When creating or updating documents, changes are reflected in real-time on the blocks and visible to the user.
|
||||
|
||||
This is a guide for using canvas tools: \`createDocument\` and \`updateDocument\`, which render content on a canvas beside the conversation.
|
||||
This is a guide for using blocks tools: \`createDocument\` and \`updateDocument\`, which render content on a blocks beside the conversation.
|
||||
|
||||
**When to use \`createDocument\`:**
|
||||
- For substantial content (>10 lines)
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import { z } from 'zod';
|
|||
|
||||
import { customModel } from '@/ai';
|
||||
import { models } from '@/ai/models';
|
||||
import { canvasPrompt, regularPrompt } from '@/ai/prompts';
|
||||
import { blocksPrompt, regularPrompt } from '@/ai/prompts';
|
||||
import { auth } from '@/app/(auth)/auth';
|
||||
import {
|
||||
deleteChatById,
|
||||
|
|
@ -37,7 +37,7 @@ type AllowedTools =
|
|||
| 'requestSuggestions'
|
||||
| 'getWeather';
|
||||
|
||||
const canvasTools: AllowedTools[] = [
|
||||
const blocksTools: AllowedTools[] = [
|
||||
'createDocument',
|
||||
'updateDocument',
|
||||
'requestSuggestions',
|
||||
|
|
@ -89,11 +89,11 @@ export async function POST(request: Request) {
|
|||
|
||||
const result = await streamText({
|
||||
model: customModel(model.apiIdentifier),
|
||||
system: modelId === 'gpt-4o-canvas' ? canvasPrompt : regularPrompt,
|
||||
system: modelId === 'gpt-4o-blocks' ? blocksPrompt : regularPrompt,
|
||||
messages: coreMessages,
|
||||
maxSteps: 5,
|
||||
experimental_activeTools:
|
||||
modelId === 'gpt-4o-canvas' ? canvasTools : weatherTools,
|
||||
modelId === 'gpt-4o-blocks' ? blocksTools : weatherTools,
|
||||
tools: {
|
||||
getWeather: {
|
||||
description: 'Get the current weather at a location',
|
||||
|
|
|
|||
|
|
@ -1,29 +1,29 @@
|
|||
import { JSONValue } from 'ai';
|
||||
import { Dispatch, memo, SetStateAction } from 'react';
|
||||
|
||||
import { UICanvas } from './canvas';
|
||||
import { useCanvasStream } from './use-canvas-stream';
|
||||
import { UIBlock } from './block';
|
||||
import { useBlockStream } from './use-block-stream';
|
||||
|
||||
interface CanvasStreamHandlerProps {
|
||||
setCanvas: Dispatch<SetStateAction<UICanvas>>;
|
||||
interface BlockStreamHandlerProps {
|
||||
setBlock: Dispatch<SetStateAction<UIBlock>>;
|
||||
streamingData: JSONValue[] | undefined;
|
||||
}
|
||||
|
||||
export function PureCanvasStreamHandler({
|
||||
setCanvas,
|
||||
export function PureBlockStreamHandler({
|
||||
setBlock,
|
||||
streamingData,
|
||||
}: CanvasStreamHandlerProps) {
|
||||
useCanvasStream({
|
||||
}: BlockStreamHandlerProps) {
|
||||
useBlockStream({
|
||||
streamingData,
|
||||
setCanvas,
|
||||
setBlock,
|
||||
});
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function areEqual(
|
||||
prevProps: CanvasStreamHandlerProps,
|
||||
nextProps: CanvasStreamHandlerProps
|
||||
prevProps: BlockStreamHandlerProps,
|
||||
nextProps: BlockStreamHandlerProps
|
||||
) {
|
||||
if (!prevProps.streamingData && !nextProps.streamingData) {
|
||||
return true;
|
||||
|
|
@ -40,4 +40,4 @@ function areEqual(
|
|||
return true;
|
||||
}
|
||||
|
||||
export const CanvasStreamHandler = memo(PureCanvasStreamHandler, areEqual);
|
||||
export const BlockStreamHandler = memo(PureBlockStreamHandler, areEqual);
|
||||
|
|
@ -31,7 +31,7 @@ import { useScrollToBottom } from './use-scroll-to-bottom';
|
|||
import { VersionFooter } from './version-footer';
|
||||
import { Button } from '../ui/button';
|
||||
import { Tooltip, TooltipContent, TooltipTrigger } from '../ui/tooltip';
|
||||
export interface UICanvas {
|
||||
export interface UIBlock {
|
||||
title: string;
|
||||
documentId: string;
|
||||
content: string;
|
||||
|
|
@ -45,7 +45,7 @@ export interface UICanvas {
|
|||
};
|
||||
}
|
||||
|
||||
export function Canvas({
|
||||
export function Block({
|
||||
chatId,
|
||||
input,
|
||||
setInput,
|
||||
|
|
@ -55,8 +55,8 @@ export function Canvas({
|
|||
attachments,
|
||||
setAttachments,
|
||||
append,
|
||||
canvas,
|
||||
setCanvas,
|
||||
block,
|
||||
setBlock,
|
||||
messages,
|
||||
setMessages,
|
||||
votes,
|
||||
|
|
@ -68,8 +68,8 @@ export function Canvas({
|
|||
stop: () => void;
|
||||
attachments: Array<Attachment>;
|
||||
setAttachments: Dispatch<SetStateAction<Array<Attachment>>>;
|
||||
canvas: UICanvas;
|
||||
setCanvas: Dispatch<SetStateAction<UICanvas>>;
|
||||
block: UIBlock;
|
||||
setBlock: Dispatch<SetStateAction<UIBlock>>;
|
||||
messages: Array<Message>;
|
||||
setMessages: Dispatch<SetStateAction<Array<Message>>>;
|
||||
votes: Array<Vote> | undefined;
|
||||
|
|
@ -92,15 +92,15 @@ export function Canvas({
|
|||
isLoading: isDocumentsFetching,
|
||||
mutate: mutateDocuments,
|
||||
} = useSWR<Array<Document>>(
|
||||
canvas && canvas.status !== 'streaming'
|
||||
? `/api/document?id=${canvas.documentId}`
|
||||
block && block.status !== 'streaming'
|
||||
? `/api/document?id=${block.documentId}`
|
||||
: null,
|
||||
fetcher
|
||||
);
|
||||
|
||||
const { data: suggestions } = useSWR<Array<Suggestion>>(
|
||||
documents && canvas && canvas.status !== 'streaming'
|
||||
? `/api/suggestions?documentId=${canvas.documentId}`
|
||||
documents && block && block.status !== 'streaming'
|
||||
? `/api/suggestions?documentId=${block.documentId}`
|
||||
: null,
|
||||
fetcher,
|
||||
{
|
||||
|
|
@ -119,27 +119,27 @@ export function Canvas({
|
|||
if (mostRecentDocument) {
|
||||
setDocument(mostRecentDocument);
|
||||
setCurrentVersionIndex(documents.length - 1);
|
||||
setCanvas((currentCanvas) => ({
|
||||
...currentCanvas,
|
||||
setBlock((currentBlock) => ({
|
||||
...currentBlock,
|
||||
content: mostRecentDocument.content ?? '',
|
||||
}));
|
||||
}
|
||||
}
|
||||
}, [documents, setCanvas]);
|
||||
}, [documents, setBlock]);
|
||||
|
||||
useEffect(() => {
|
||||
mutateDocuments();
|
||||
}, [canvas.status, mutateDocuments]);
|
||||
}, [block.status, mutateDocuments]);
|
||||
|
||||
const { mutate } = useSWRConfig();
|
||||
const [isContentDirty, setIsContentDirty] = useState(false);
|
||||
|
||||
const handleContentChange = useCallback(
|
||||
(updatedContent: string) => {
|
||||
if (!canvas) return;
|
||||
if (!block) return;
|
||||
|
||||
mutate<Array<Document>>(
|
||||
`/api/document?id=${canvas.documentId}`,
|
||||
`/api/document?id=${block.documentId}`,
|
||||
async (currentDocuments) => {
|
||||
if (!currentDocuments) return undefined;
|
||||
|
||||
|
|
@ -151,10 +151,10 @@ export function Canvas({
|
|||
}
|
||||
|
||||
if (currentDocument.content !== updatedContent) {
|
||||
await fetch(`/api/document?id=${canvas.documentId}`, {
|
||||
await fetch(`/api/document?id=${block.documentId}`, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
title: canvas.title,
|
||||
title: block.title,
|
||||
content: updatedContent,
|
||||
}),
|
||||
});
|
||||
|
|
@ -175,7 +175,7 @@ export function Canvas({
|
|||
{ revalidate: false }
|
||||
);
|
||||
},
|
||||
[canvas, mutate]
|
||||
[block, mutate]
|
||||
);
|
||||
|
||||
const debouncedHandleContentChange = useDebounceCallback(
|
||||
|
|
@ -295,8 +295,8 @@ export function Canvas({
|
|||
chatId={chatId}
|
||||
key={message.id}
|
||||
message={message}
|
||||
canvas={canvas}
|
||||
setCanvas={setCanvas}
|
||||
block={block}
|
||||
setBlock={setBlock}
|
||||
isLoading={isLoading && index === messages.length - 1}
|
||||
vote={
|
||||
votes
|
||||
|
|
@ -346,10 +346,10 @@ export function Canvas({
|
|||
}
|
||||
: {
|
||||
opacity: 0,
|
||||
x: canvas.boundingBox.left,
|
||||
y: canvas.boundingBox.top,
|
||||
height: canvas.boundingBox.height,
|
||||
width: canvas.boundingBox.width,
|
||||
x: block.boundingBox.left,
|
||||
y: block.boundingBox.top,
|
||||
height: block.boundingBox.height,
|
||||
width: block.boundingBox.width,
|
||||
borderRadius: 50,
|
||||
}
|
||||
}
|
||||
|
|
@ -401,8 +401,8 @@ export function Canvas({
|
|||
variant="outline"
|
||||
className="h-fit p-2 dark:hover:bg-zinc-700"
|
||||
onClick={() => {
|
||||
setCanvas((currentCanvas) => ({
|
||||
...currentCanvas,
|
||||
setBlock((currentBlock) => ({
|
||||
...currentBlock,
|
||||
isVisible: false,
|
||||
}));
|
||||
}}
|
||||
|
|
@ -412,7 +412,7 @@ export function Canvas({
|
|||
|
||||
<div className="flex flex-col">
|
||||
<div className="font-medium">
|
||||
{document?.title ?? canvas.title}
|
||||
{document?.title ?? block.title}
|
||||
</div>
|
||||
|
||||
{isContentDirty ? (
|
||||
|
|
@ -442,10 +442,10 @@ export function Canvas({
|
|||
variant="outline"
|
||||
className="p-2 h-fit dark:hover:bg-zinc-700"
|
||||
onClick={() => {
|
||||
copyToClipboard(canvas.content);
|
||||
copyToClipboard(block.content);
|
||||
toast.success('Copied to clipboard!');
|
||||
}}
|
||||
disabled={canvas.status === 'streaming'}
|
||||
disabled={block.status === 'streaming'}
|
||||
>
|
||||
<CopyIcon size={18} />
|
||||
</Button>
|
||||
|
|
@ -461,7 +461,7 @@ export function Canvas({
|
|||
handleVersionChange('prev');
|
||||
}}
|
||||
disabled={
|
||||
currentVersionIndex === 0 || canvas.status === 'streaming'
|
||||
currentVersionIndex === 0 || block.status === 'streaming'
|
||||
}
|
||||
>
|
||||
<UndoIcon size={18} />
|
||||
|
|
@ -477,7 +477,7 @@ export function Canvas({
|
|||
onClick={() => {
|
||||
handleVersionChange('next');
|
||||
}}
|
||||
disabled={isCurrentVersion || canvas.status === 'streaming'}
|
||||
disabled={isCurrentVersion || block.status === 'streaming'}
|
||||
>
|
||||
<RedoIcon size={18} />
|
||||
</Button>
|
||||
|
|
@ -498,7 +498,7 @@ export function Canvas({
|
|||
handleVersionChange('toggle');
|
||||
}}
|
||||
disabled={
|
||||
canvas.status === 'streaming' || currentVersionIndex === 0
|
||||
block.status === 'streaming' || currentVersionIndex === 0
|
||||
}
|
||||
>
|
||||
<DeltaIcon size={18} />
|
||||
|
|
@ -511,18 +511,18 @@ export function Canvas({
|
|||
|
||||
<div className="prose dark:prose-invert dark:bg-muted bg-background h-full overflow-y-scroll px-4 py-8 md:p-20 !max-w-full pb-40 items-center">
|
||||
<div className="flex flex-row max-w-[600px] mx-auto">
|
||||
{isDocumentsFetching && !canvas.content ? (
|
||||
{isDocumentsFetching && !block.content ? (
|
||||
<DocumentSkeleton />
|
||||
) : mode === 'edit' ? (
|
||||
<Editor
|
||||
content={
|
||||
isCurrentVersion
|
||||
? canvas.content
|
||||
? block.content
|
||||
: getDocumentContentById(currentVersionIndex)
|
||||
}
|
||||
isCurrentVersion={isCurrentVersion}
|
||||
currentVersionIndex={currentVersionIndex}
|
||||
status={canvas.status}
|
||||
status={block.status}
|
||||
saveContent={saveContent}
|
||||
suggestions={isCurrentVersion ? (suggestions ?? []) : []}
|
||||
/>
|
||||
|
|
@ -555,7 +555,7 @@ export function Canvas({
|
|||
<AnimatePresence>
|
||||
{!isCurrentVersion && (
|
||||
<VersionFooter
|
||||
canvas={canvas}
|
||||
block={block}
|
||||
currentVersionIndex={currentVersionIndex}
|
||||
documents={documents}
|
||||
handleVersionChange={handleVersionChange}
|
||||
|
|
@ -13,8 +13,8 @@ import { useScrollToBottom } from '@/components/custom/use-scroll-to-bottom';
|
|||
import { Vote } from '@/db/schema';
|
||||
import { fetcher } from '@/lib/utils';
|
||||
|
||||
import { Canvas, UICanvas } from './canvas';
|
||||
import { CanvasStreamHandler } from './canvas-stream-handler';
|
||||
import { Block, UIBlock } from './block';
|
||||
import { BlockStreamHandler } from './block-stream-handler';
|
||||
import { MultimodalInput } from './multimodal-input';
|
||||
import { Overview } from './overview';
|
||||
|
||||
|
|
@ -50,7 +50,7 @@ export function Chat({
|
|||
const { width: windowWidth = 1920, height: windowHeight = 1080 } =
|
||||
useWindowSize();
|
||||
|
||||
const [canvas, setCanvas] = useState<UICanvas>({
|
||||
const [block, setBlock] = useState<UIBlock>({
|
||||
documentId: 'init',
|
||||
content: '',
|
||||
title: '',
|
||||
|
|
@ -89,8 +89,8 @@ export function Chat({
|
|||
key={message.id}
|
||||
chatId={id}
|
||||
message={message}
|
||||
canvas={canvas}
|
||||
setCanvas={setCanvas}
|
||||
block={block}
|
||||
setBlock={setBlock}
|
||||
isLoading={isLoading && messages.length - 1 === index}
|
||||
vote={
|
||||
votes
|
||||
|
|
@ -129,8 +129,8 @@ export function Chat({
|
|||
</div>
|
||||
|
||||
<AnimatePresence>
|
||||
{canvas && canvas.isVisible && (
|
||||
<Canvas
|
||||
{block && block.isVisible && (
|
||||
<Block
|
||||
chatId={id}
|
||||
input={input}
|
||||
setInput={setInput}
|
||||
|
|
@ -140,8 +140,8 @@ export function Chat({
|
|||
attachments={attachments}
|
||||
setAttachments={setAttachments}
|
||||
append={append}
|
||||
canvas={canvas}
|
||||
setCanvas={setCanvas}
|
||||
block={block}
|
||||
setBlock={setBlock}
|
||||
messages={messages}
|
||||
setMessages={setMessages}
|
||||
votes={votes}
|
||||
|
|
@ -149,10 +149,7 @@ export function Chat({
|
|||
)}
|
||||
</AnimatePresence>
|
||||
|
||||
<CanvasStreamHandler
|
||||
streamingData={streamingData}
|
||||
setCanvas={setCanvas}
|
||||
/>
|
||||
<BlockStreamHandler streamingData={streamingData} setBlock={setBlock} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { SetStateAction } from 'react';
|
||||
|
||||
import { UICanvas } from './canvas';
|
||||
import { UIBlock } from './block';
|
||||
import { FileIcon, LoaderIcon, MessageIcon, PencilEditIcon } from './icons';
|
||||
|
||||
const getActionText = (type: 'create' | 'update' | 'request-suggestions') => {
|
||||
|
|
@ -19,15 +19,15 @@ const getActionText = (type: 'create' | 'update' | 'request-suggestions') => {
|
|||
interface DocumentToolResultProps {
|
||||
type: 'create' | 'update' | 'request-suggestions';
|
||||
result: any;
|
||||
canvas: UICanvas;
|
||||
setCanvas: (value: SetStateAction<UICanvas>) => void;
|
||||
block: UIBlock;
|
||||
setBlock: (value: SetStateAction<UIBlock>) => void;
|
||||
}
|
||||
|
||||
export function DocumentToolResult({
|
||||
type,
|
||||
result,
|
||||
canvas,
|
||||
setCanvas,
|
||||
block,
|
||||
setBlock,
|
||||
}: DocumentToolResultProps) {
|
||||
return (
|
||||
<div
|
||||
|
|
@ -42,7 +42,7 @@ export function DocumentToolResult({
|
|||
height: rect.height,
|
||||
};
|
||||
|
||||
setCanvas({
|
||||
setBlock({
|
||||
documentId: result.id,
|
||||
content: '',
|
||||
title: result.title,
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import { Dispatch, SetStateAction } from 'react';
|
|||
|
||||
import { Vote } from '@/db/schema';
|
||||
|
||||
import { UICanvas } from './canvas';
|
||||
import { UIBlock } from './block';
|
||||
import { DocumentToolCall, DocumentToolResult } from './document';
|
||||
import { SparklesIcon } from './icons';
|
||||
import { Markdown } from './markdown';
|
||||
|
|
@ -18,15 +18,15 @@ import { Weather } from './weather';
|
|||
export const PreviewMessage = ({
|
||||
chatId,
|
||||
message,
|
||||
canvas,
|
||||
setCanvas,
|
||||
block,
|
||||
setBlock,
|
||||
vote,
|
||||
isLoading,
|
||||
}: {
|
||||
chatId: string;
|
||||
message: Message;
|
||||
canvas: UICanvas;
|
||||
setCanvas: Dispatch<SetStateAction<UICanvas>>;
|
||||
block: UIBlock;
|
||||
setBlock: Dispatch<SetStateAction<UIBlock>>;
|
||||
vote: Vote | undefined;
|
||||
isLoading: boolean;
|
||||
}) => {
|
||||
|
|
@ -71,22 +71,22 @@ export const PreviewMessage = ({
|
|||
<DocumentToolResult
|
||||
type="create"
|
||||
result={result}
|
||||
canvas={canvas}
|
||||
setCanvas={setCanvas}
|
||||
block={block}
|
||||
setBlock={setBlock}
|
||||
/>
|
||||
) : toolName === 'updateDocument' ? (
|
||||
<DocumentToolResult
|
||||
type="update"
|
||||
result={result}
|
||||
canvas={canvas}
|
||||
setCanvas={setCanvas}
|
||||
block={block}
|
||||
setBlock={setBlock}
|
||||
/>
|
||||
) : toolName === 'requestSuggestions' ? (
|
||||
<DocumentToolResult
|
||||
type="request-suggestions"
|
||||
result={result}
|
||||
canvas={canvas}
|
||||
setCanvas={setCanvas}
|
||||
block={block}
|
||||
setBlock={setBlock}
|
||||
/>
|
||||
) : (
|
||||
<pre>{JSON.stringify(result, null, 2)}</pre>
|
||||
|
|
|
|||
|
|
@ -4,19 +4,19 @@ import { useSWRConfig } from 'swr';
|
|||
|
||||
import { Suggestion } from '@/db/schema';
|
||||
|
||||
import { UICanvas } from './canvas';
|
||||
import { UIBlock } from './block';
|
||||
|
||||
type StreamingDelta = {
|
||||
type: 'text-delta' | 'title' | 'id' | 'suggestion' | 'clear' | 'finish';
|
||||
content: string | Suggestion;
|
||||
};
|
||||
|
||||
export function useCanvasStream({
|
||||
export function useBlockStream({
|
||||
streamingData,
|
||||
setCanvas,
|
||||
setBlock,
|
||||
}: {
|
||||
streamingData: JSONValue[] | undefined;
|
||||
setCanvas: Dispatch<SetStateAction<UICanvas>>;
|
||||
setBlock: Dispatch<SetStateAction<UIBlock>>;
|
||||
}) {
|
||||
const { mutate } = useSWRConfig();
|
||||
const [optimisticSuggestions, setOptimisticSuggestions] = useState<
|
||||
|
|
@ -37,30 +37,30 @@ export function useCanvasStream({
|
|||
|
||||
const delta = mostRecentDelta as StreamingDelta;
|
||||
|
||||
setCanvas((draftCanvas) => {
|
||||
setBlock((draftBlock) => {
|
||||
switch (delta.type) {
|
||||
case 'id':
|
||||
return {
|
||||
...draftCanvas,
|
||||
...draftBlock,
|
||||
documentId: delta.content as string,
|
||||
};
|
||||
|
||||
case 'title':
|
||||
return {
|
||||
...draftCanvas,
|
||||
...draftBlock,
|
||||
title: delta.content as string,
|
||||
};
|
||||
|
||||
case 'text-delta':
|
||||
return {
|
||||
...draftCanvas,
|
||||
content: draftCanvas.content + (delta.content as string),
|
||||
...draftBlock,
|
||||
content: draftBlock.content + (delta.content as string),
|
||||
isVisible:
|
||||
draftCanvas.status === 'streaming' &&
|
||||
draftCanvas.content.length > 200 &&
|
||||
draftCanvas.content.length < 250
|
||||
draftBlock.status === 'streaming' &&
|
||||
draftBlock.content.length > 200 &&
|
||||
draftBlock.content.length < 250
|
||||
? true
|
||||
: draftCanvas.isVisible,
|
||||
: draftBlock.isVisible,
|
||||
status: 'streaming',
|
||||
};
|
||||
|
||||
|
|
@ -72,24 +72,24 @@ export function useCanvasStream({
|
|||
]);
|
||||
}, 0);
|
||||
|
||||
return draftCanvas;
|
||||
return draftBlock;
|
||||
|
||||
case 'clear':
|
||||
return {
|
||||
...draftCanvas,
|
||||
...draftBlock,
|
||||
content: '',
|
||||
status: 'streaming',
|
||||
};
|
||||
|
||||
case 'finish':
|
||||
return {
|
||||
...draftCanvas,
|
||||
...draftBlock,
|
||||
status: 'idle',
|
||||
};
|
||||
|
||||
default:
|
||||
return draftCanvas;
|
||||
return draftBlock;
|
||||
}
|
||||
});
|
||||
}, [streamingData, setCanvas]);
|
||||
}, [streamingData, setBlock]);
|
||||
}
|
||||
|
|
@ -9,19 +9,19 @@ import { useWindowSize } from 'usehooks-ts';
|
|||
import { Document } from '@/db/schema';
|
||||
import { getDocumentTimestampByIndex } from '@/lib/utils';
|
||||
|
||||
import { UICanvas } from './canvas';
|
||||
import { UIBlock } from './block';
|
||||
import { LoaderIcon } from './icons';
|
||||
import { Button } from '../ui/button';
|
||||
|
||||
interface VersionFooterProps {
|
||||
canvas: UICanvas;
|
||||
block: UIBlock;
|
||||
handleVersionChange: (type: 'next' | 'prev' | 'toggle' | 'latest') => void;
|
||||
documents: Array<Document> | undefined;
|
||||
currentVersionIndex: number;
|
||||
}
|
||||
|
||||
export const VersionFooter = ({
|
||||
canvas,
|
||||
block,
|
||||
handleVersionChange,
|
||||
documents,
|
||||
currentVersionIndex,
|
||||
|
|
@ -56,8 +56,8 @@ export const VersionFooter = ({
|
|||
setIsMutating(true);
|
||||
|
||||
mutate(
|
||||
`/api/document?id=${canvas.documentId}`,
|
||||
await fetch(`/api/document?id=${canvas.documentId}`, {
|
||||
`/api/document?id=${block.documentId}`,
|
||||
await fetch(`/api/document?id=${block.documentId}`, {
|
||||
method: 'PATCH',
|
||||
body: JSON.stringify({
|
||||
timestamp: getDocumentTimestampByIndex(
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue