mirror of
https://github.com/langgenius/dify.git
synced 2026-04-16 02:16:57 +08:00
Co-authored-by: Brian Wang <BrianWang1990@users.noreply.github.com> Co-authored-by: test <test@testdeMac-mini.local> Co-authored-by: BrianWang1990 <512dabing99@163.com> Co-authored-by: Stephen Zhou <hi@hyoban.cc> Co-authored-by: Stephen Zhou <38493346+hyoban@users.noreply.github.com>
73 lines
2.2 KiB
TypeScript
73 lines
2.2 KiB
TypeScript
import { useRef, useState } from 'react'
|
|
import { writeTextToClipboard } from '@/utils/clipboard'
|
|
import { noop } from './noop'
|
|
import { useStableHandler } from './use-stable-handler-only-when-you-know-what-you-are-doing-or-you-will-be-fired'
|
|
import { useCallback } from './use-typescript-happy-callback'
|
|
import 'client-only'
|
|
|
|
type UseClipboardOption = {
|
|
timeout?: number
|
|
usePromptAsFallback?: boolean
|
|
promptFallbackText?: string
|
|
onCopyError?: (error: Error) => void
|
|
}
|
|
|
|
/** @see https://foxact.skk.moe/use-clipboard */
|
|
export function useClipboard({
|
|
timeout = 1000,
|
|
usePromptAsFallback = false,
|
|
promptFallbackText = 'Failed to copy to clipboard automatically, please manually copy the text below.',
|
|
onCopyError,
|
|
}: UseClipboardOption = {}) {
|
|
const [error, setError] = useState<Error | null>(null)
|
|
const [copied, setCopied] = useState(false)
|
|
const copyTimeoutRef = useRef<number | null>(null)
|
|
|
|
const stablizedOnCopyError = useStableHandler<[e: Error], void>(onCopyError || noop)
|
|
|
|
const handleCopyResult = useCallback((isCopied: boolean) => {
|
|
if (copyTimeoutRef.current) {
|
|
clearTimeout(copyTimeoutRef.current)
|
|
}
|
|
if (isCopied) {
|
|
copyTimeoutRef.current = window.setTimeout(() => setCopied(false), timeout)
|
|
}
|
|
setCopied(isCopied)
|
|
}, [timeout])
|
|
|
|
const handleCopyError = useCallback((e: Error) => {
|
|
setError(e)
|
|
stablizedOnCopyError(e)
|
|
}, [stablizedOnCopyError])
|
|
|
|
const copy = useCallback(async (valueToCopy: string) => {
|
|
try {
|
|
await writeTextToClipboard(valueToCopy)
|
|
}
|
|
catch (e) {
|
|
if (usePromptAsFallback) {
|
|
try {
|
|
// eslint-disable-next-line no-alert -- prompt as fallback in case of copy error
|
|
window.prompt(promptFallbackText, valueToCopy)
|
|
}
|
|
catch (e2) {
|
|
handleCopyError(e2 as Error)
|
|
}
|
|
}
|
|
else {
|
|
handleCopyError(e as Error)
|
|
}
|
|
}
|
|
}, [handleCopyResult, promptFallbackText, handleCopyError, usePromptAsFallback])
|
|
|
|
const reset = useCallback(() => {
|
|
setCopied(false)
|
|
setError(null)
|
|
if (copyTimeoutRef.current) {
|
|
clearTimeout(copyTimeoutRef.current)
|
|
}
|
|
}, [])
|
|
|
|
return { copy, reset, error, copied }
|
|
}
|