'use client'
import { Check, Copy, Download, History, X } from 'lucide-react'
import { useState } from 'react'
import { useCopyToClipboard } from '../../hook/use-copy-to-clipboard'
import { cn } from '../../lib/utils'
import { Badge } from '../../ui/badge'
import { Button } from '../../ui/button'
import { Popover, PopoverContent, PopoverTrigger } from '../../ui/popover'
import { useChatCanvas } from './context'
import {
Artifact,
DocumentArtifact,
CodeArtifact,
isEqualArtifact,
} from './artifacts'
interface ChatCanvasActionsProps {
children?: React.ReactNode
className?: string
}
function ChatCanvasActions(props: ChatCanvasActionsProps) {
const children = props.children ?? (
<>
>
)
return (
{children}
)
}
function ArtifactVersionHistory() {
const {
getArtifactsByType,
openArtifactInCanvas,
displayedArtifact,
getArtifactVersion,
restoreArtifact,
} = useChatCanvas()
const [isOpen, setIsOpen] = useState(false)
if (!displayedArtifact) return null
const allArtifactsByCurrentType = getArtifactsByType(displayedArtifact.type)
return (
Version History
{allArtifactsByCurrentType.map((artifact, index) => {
const isCurrent = isEqualArtifact(artifact, displayedArtifact)
const { versionNumber, isLatest } = getArtifactVersion(artifact)
return (
{
openArtifactInCanvas(artifact)
setIsOpen(false)
}}
>
Version {versionNumber}
{isLatest ? (
Latest
) : (
)}
)
})}
)
}
function ArtifactContentCopy() {
const { isCopied, copyToClipboard } = useCopyToClipboard({ timeout: 1000 })
const { displayedArtifact } = useChatCanvas()
if (!displayedArtifact) return null
const content = getArtifactContent(displayedArtifact)
if (!content) return null
const handleCopy = () => {
if (isCopied) return
copyToClipboard(content)
}
return (
)
}
function getArtifactContent(artifact: Artifact) {
if (artifact.type === 'code') {
return (artifact as CodeArtifact).data.code
}
if (artifact.type === 'document') {
return (artifact as DocumentArtifact).data.content
}
return null
}
function ArtifactDownloadButton() {
const { displayedArtifact } = useChatCanvas()
if (!displayedArtifact) return null
const content = getArtifactContent(displayedArtifact)
const fileName = getArtifactDownloadFileName(displayedArtifact)
if (!content || !fileName) return null
const handleDownload = () => {
const blob = new Blob([content], { type: 'text/plain' })
const url = URL.createObjectURL(blob)
const link = document.createElement('a')
link.href = url
link.download = fileName
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
URL.revokeObjectURL(url)
}
return (
)
}
function getArtifactDownloadFileName(artifact: Artifact) {
if (artifact.type === 'code') {
return (artifact as CodeArtifact).data.file_name
}
if (artifact.type === 'document') {
return (artifact as DocumentArtifact).data.title
}
return null
}
function CanvasCloseButton() {
const { closeCanvas } = useChatCanvas()
return (
)
}
ChatCanvasActions.History = ArtifactVersionHistory
ChatCanvasActions.Copy = ArtifactContentCopy
ChatCanvasActions.Download = ArtifactDownloadButton
ChatCanvasActions.Close = CanvasCloseButton
export { ChatCanvasActions }