Merge pull request #6346 from menloresearch/fix/btn-copy-codeblock
chore: fix id code-block for avoid duplicate same state
This commit is contained in:
commit
8c4a88a182
@ -375,11 +375,8 @@ const ChatInput = ({ model, className, initialMessage }: ChatInputProps) => {
|
||||
}
|
||||
|
||||
const handlePaste = async (e: React.ClipboardEvent) => {
|
||||
// Only allow paste if model supports mmproj
|
||||
if (!hasMmproj) {
|
||||
return
|
||||
}
|
||||
|
||||
// Only process images if model supports mmproj
|
||||
if (hasMmproj) {
|
||||
const clipboardItems = e.clipboardData?.items
|
||||
let hasProcessedImage = false
|
||||
|
||||
@ -427,9 +424,11 @@ const ChatInput = ({ model, className, initialMessage }: ChatInputProps) => {
|
||||
}
|
||||
|
||||
// Modern Clipboard API fallback (for Linux, images copied from web, etc.)
|
||||
if (navigator.clipboard && 'read' in navigator.clipboard) {
|
||||
e.preventDefault()
|
||||
|
||||
if (
|
||||
navigator.clipboard &&
|
||||
'read' in navigator.clipboard &&
|
||||
!hasProcessedImage
|
||||
) {
|
||||
try {
|
||||
const clipboardContents = await navigator.clipboard.read()
|
||||
const files: File[] = []
|
||||
@ -457,6 +456,7 @@ const ChatInput = ({ model, className, initialMessage }: ChatInputProps) => {
|
||||
}
|
||||
|
||||
if (files.length > 0) {
|
||||
e.preventDefault()
|
||||
const syntheticEvent = {
|
||||
target: {
|
||||
files: files,
|
||||
@ -471,10 +471,12 @@ const ChatInput = ({ model, className, initialMessage }: ChatInputProps) => {
|
||||
}
|
||||
}
|
||||
|
||||
// If we reach here, no image was found or processed
|
||||
if (!hasProcessedImage) {
|
||||
console.log('No image data found in clipboard or clipboard access failed')
|
||||
// If we reach here, no image was found - allow normal text pasting to continue
|
||||
console.log(
|
||||
'No image data found in clipboard, allowing normal text paste'
|
||||
)
|
||||
}
|
||||
// If hasMmproj is false or no images found, allow normal text pasting to continue
|
||||
}
|
||||
|
||||
return (
|
||||
@ -569,7 +571,7 @@ const ChatInput = ({ model, className, initialMessage }: ChatInputProps) => {
|
||||
// When Shift+Enter is pressed, a new line is added (default behavior)
|
||||
}
|
||||
}}
|
||||
onPaste={hasMmproj ? handlePaste : undefined}
|
||||
onPaste={handlePaste}
|
||||
placeholder={t('common:placeholder.chatInput')}
|
||||
autoFocus
|
||||
spellCheck={spellCheckChatInput}
|
||||
|
||||
@ -6,7 +6,7 @@ import remarkMath from 'remark-math'
|
||||
import rehypeKatex from 'rehype-katex'
|
||||
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter'
|
||||
import * as prismStyles from 'react-syntax-highlighter/dist/cjs/styles/prism'
|
||||
import { memo, useState, useMemo } from 'react'
|
||||
import { memo, useState, useMemo, useRef, useEffect } from 'react'
|
||||
import { getReadableLanguageName } from '@/lib/utils'
|
||||
import { cn } from '@/lib/utils'
|
||||
import { useCodeblock } from '@/hooks/useCodeblock'
|
||||
@ -37,6 +37,13 @@ function RenderMarkdownComponent({
|
||||
|
||||
// State for tracking which code block has been copied
|
||||
const [copiedId, setCopiedId] = useState<string | null>(null)
|
||||
// Map to store unique IDs for code blocks based on content and position
|
||||
const codeBlockIds = useRef(new Map<string, string>())
|
||||
|
||||
// Clear ID map when content changes
|
||||
useEffect(() => {
|
||||
codeBlockIds.current.clear()
|
||||
}, [content])
|
||||
|
||||
// Function to handle copying code to clipboard
|
||||
const handleCopy = (code: string, id: string) => {
|
||||
@ -49,17 +56,6 @@ function RenderMarkdownComponent({
|
||||
}, 2000)
|
||||
}
|
||||
|
||||
// Simple hash function for strings
|
||||
const hashString = (str: string): string => {
|
||||
let hash = 0
|
||||
for (let i = 0; i < str.length; i++) {
|
||||
const char = str.charCodeAt(i)
|
||||
hash = (hash << 5) - hash + char
|
||||
hash = hash & hash // Convert to 32bit integer
|
||||
}
|
||||
return Math.abs(hash).toString(36)
|
||||
}
|
||||
|
||||
// Default components for syntax highlighting and emoji rendering
|
||||
const defaultComponents: Components = useMemo(
|
||||
() => ({
|
||||
@ -70,8 +66,13 @@ function RenderMarkdownComponent({
|
||||
|
||||
const code = String(children).replace(/\n$/, '')
|
||||
|
||||
// Generate a stable ID based on code content and language
|
||||
const codeId = `code-${hashString(code.substring(0, 40) + language)}`
|
||||
// Generate a unique ID based on content and language
|
||||
const contentKey = `${code}-${language}`
|
||||
let codeId = codeBlockIds.current.get(contentKey)
|
||||
if (!codeId) {
|
||||
codeId = `code-${codeBlockIds.current.size}`
|
||||
codeBlockIds.current.set(contentKey, codeId)
|
||||
}
|
||||
|
||||
return !isInline && !isUser ? (
|
||||
<div className="relative overflow-hidden border rounded-md border-main-view-fg/2">
|
||||
@ -155,7 +156,7 @@ function RenderMarkdownComponent({
|
||||
)
|
||||
},
|
||||
}),
|
||||
[codeBlockStyle, showLineNumbers, copiedId, handleCopy, hashString]
|
||||
[codeBlockStyle, showLineNumbers, copiedId]
|
||||
)
|
||||
|
||||
// Memoize the remarkPlugins to prevent unnecessary re-renders
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user