diff --git a/src/components/CodeBlock.tsx b/src/components/CodeBlock.tsx index 0cf1566..6160e2f 100644 --- a/src/components/CodeBlock.tsx +++ b/src/components/CodeBlock.tsx @@ -1,4 +1,4 @@ -import { useState, useCallback, type HTMLAttributes, type ReactElement } from 'react'; +import { useState, useCallback, memo, type HTMLAttributes, type ReactElement } from 'react'; import { Check, Copy, Hash, WrapText, AlignLeft, ChevronDown, ChevronUp } from 'lucide-react'; import { copyToClipboard } from '../lib/clipboard'; @@ -49,7 +49,7 @@ const LINE_THRESHOLD = 3; // Only show line numbers for blocks with more than th const COLLAPSE_THRESHOLD = 25; // Collapse code blocks longer than this const COLLAPSE_PREVIEW_LINES = 10; // Lines to show when collapsed -export function CodeBlock(props: HTMLAttributes) { +export const CodeBlock = memo(function CodeBlock(props: HTMLAttributes) { const [copied, setCopied] = useState(false); const [showLineNumbers, setShowLineNumbers] = useState(() => { const stored = localStorage.getItem(LINE_NUMBER_KEY); @@ -181,4 +181,4 @@ export function CodeBlock(props: HTMLAttributes) { ); -} +}); diff --git a/src/components/ImageBlock.tsx b/src/components/ImageBlock.tsx index a276dd3..174bddd 100644 --- a/src/components/ImageBlock.tsx +++ b/src/components/ImageBlock.tsx @@ -1,4 +1,4 @@ -import { useState, useEffect, useCallback } from 'react'; +import { useState, useEffect, useCallback, memo } from 'react'; import { X, ImageOff } from 'lucide-react'; interface ImageBlockProps { @@ -41,7 +41,7 @@ function Lightbox({ src, alt, onClose }: ImageBlockProps & { onClose: () => void ); } -export function ImageBlock({ src, alt }: ImageBlockProps) { +export const ImageBlock = memo(function ImageBlock({ src, alt }: ImageBlockProps) { const [lightbox, setLightbox] = useState(false); const [error, setError] = useState(false); const [loading, setLoading] = useState(true); @@ -81,6 +81,6 @@ export function ImageBlock({ src, alt }: ImageBlockProps) { {lightbox && setLightbox(false)} />} ); -} +}); // buildImageSrc moved to ../lib/image.ts diff --git a/src/components/ThinkingBlock.tsx b/src/components/ThinkingBlock.tsx index 6834385..a449daf 100644 --- a/src/components/ThinkingBlock.tsx +++ b/src/components/ThinkingBlock.tsx @@ -1,8 +1,8 @@ -import { useState } from 'react'; +import { useState, memo } from 'react'; import { ChevronRight, ChevronDown, Brain } from 'lucide-react'; import { useT } from '../hooks/useLocale'; -export function ThinkingBlock({ text }: { text: string }) { +export const ThinkingBlock = memo(function ThinkingBlock({ text }: { text: string }) { const t = useT(); const [open, setOpen] = useState(false); @@ -25,4 +25,4 @@ export function ThinkingBlock({ text }: { text: string }) { )} ); -} +}); diff --git a/src/components/ToolCall.tsx b/src/components/ToolCall.tsx index e3dcc9d..7e371ff 100644 --- a/src/components/ToolCall.tsx +++ b/src/components/ToolCall.tsx @@ -1,4 +1,4 @@ -import { useState, useCallback, useMemo, useEffect, useRef } from 'react'; +import { useState, useCallback, useMemo, useEffect, useRef, memo } from 'react'; import { ChevronRight, ChevronDown, Check, Copy, WrapText, AlignLeft } from 'lucide-react'; import hljs from '../lib/highlight'; import { copyToClipboard } from '../lib/clipboard'; @@ -260,7 +260,7 @@ function extractImageFromResult(result: string): { src: string; remaining: strin return null; } -export function ToolCall({ name, input, result }: { name: string; input?: Record; result?: string }) { +export const ToolCall = memo(function ToolCall({ name, input, result }: { name: string; input?: Record; result?: string }) { const t = useT(); const [open, setOpen] = useState(false); const [wrap, setWrap] = useState(true); @@ -359,4 +359,4 @@ export function ToolCall({ name, input, result }: { name: string; input?: Record )} ); -} +});