* feat(chat): add independent copy and collapse controls for code blocks * fix(chat): unify code block rendering styles * fix(chat): refine code block labels * feat(chat): highlight tool call code blocks as json
45 lines
964 B
TypeScript
45 lines
964 B
TypeScript
import { useEffect, useRef, useState } from "react"
|
|
|
|
import { copyText } from "@/lib/clipboard"
|
|
|
|
const DEFAULT_RESET_DELAY_MS = 2000
|
|
|
|
export function useCopyToClipboard(
|
|
resetDelayMs: number = DEFAULT_RESET_DELAY_MS,
|
|
) {
|
|
const [isCopied, setIsCopied] = useState(false)
|
|
const resetTimerRef = useRef<number | null>(null)
|
|
|
|
useEffect(() => {
|
|
return () => {
|
|
if (resetTimerRef.current !== null) {
|
|
window.clearTimeout(resetTimerRef.current)
|
|
}
|
|
}
|
|
}, [])
|
|
|
|
const markCopied = () => {
|
|
if (resetTimerRef.current !== null) {
|
|
window.clearTimeout(resetTimerRef.current)
|
|
}
|
|
|
|
setIsCopied(true)
|
|
resetTimerRef.current = window.setTimeout(() => {
|
|
setIsCopied(false)
|
|
resetTimerRef.current = null
|
|
}, resetDelayMs)
|
|
}
|
|
|
|
const copy = async (text: string) => {
|
|
const didCopy = await copyText(text)
|
|
if (didCopy) {
|
|
markCopied()
|
|
}
|
|
return didCopy
|
|
}
|
|
|
|
return {
|
|
copy,
|
|
isCopied,
|
|
}
|
|
}
|