// CRITICAL "use client"; import { useCallback, useEffect, useId } from "react"; import * as Icons from "../icons"; import { CodePreview } from "./code-preview"; import { useAppStore } from "@/store"; import { DEFAULT_CODE_BLOCK_ENTRY } from "@/store/chat-slice-defaults"; interface EnhancedCodeBlockProps { children: string; className?: string; isStreaming?: boolean; language?: string; } export function EnhancedCodeBlock({ children, className, language, isStreaming, }: EnhancedCodeBlockProps) { const blockId = useId(); const blockState = useAppStore( (state) => state.codeBlockState[blockId] ?? DEFAULT_CODE_BLOCK_ENTRY, ); const updateCodeBlockState = useAppStore((state) => state.updateCodeBlockState); const deleteCodeBlockState = useAppStore((state) => state.deleteCodeBlockState); const { copied, isExpanded } = blockState; // Prevent `codeBlockState` from growing unbounded as Virtuoso mounts/unmounts blocks. useEffect(() => { return () => deleteCodeBlockState(blockId); }, [blockId, deleteCodeBlockState]); const lang = language || className?.replace("language-", "") || "text"; const code = String(children).replace(/\n$/, ""); const setCopied = useCallback( (value: boolean) => { updateCodeBlockState(blockId, (prev) => ({ ...prev, copied: value })); }, [blockId, updateCodeBlockState], ); const setExpanded = useCallback( (value: boolean) => { updateCodeBlockState(blockId, (prev) => ({ ...prev, isExpanded: value })); }, [blockId, updateCodeBlockState], ); const copyCode = useCallback(() => { navigator.clipboard.writeText(code); setCopied(true); setTimeout(() => setCopied(false), 2000); }, [code, setCopied]); if (isStreaming) { return (
{lang || "code"}
          {code}
        
); } const lineCount = code.split("\n").length; const isLongCode = lineCount > 20; const shouldCollapse = isLongCode && !isExpanded; return (
{/* Header */}
{lang || "code"} {isLongCode && {lineCount} lines}
{isLongCode && ( )}
{/* Code */}
{shouldCollapse && (
)}
); }