diff --git a/web/package-lock.json b/web/package-lock.json index cfcf542d4a..3d71979faa 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -42,7 +42,7 @@ "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "cmdk": "^1.0.0", - "copy-to-clipboard": "^3.3.3", + "copy-to-clipboard": "^4.0.2", "date-fns": "^3.6.0", "date-fns-tz": "^3.2.0", "framer-motion": "^13.2.0", @@ -7353,12 +7353,10 @@ } }, "node_modules/copy-to-clipboard": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.3.tgz", - "integrity": "sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==", - "dependencies": { - "toggle-selection": "^1.0.6" - } + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-4.0.2.tgz", + "integrity": "sha512-gklSft7IuhriZKHKpuoA1fpJSLPNgvUMWMo5BlnzAJm0zNKnznoSv23IjtNqclx8eKi6ZcdvFFzYEER/+U1LoQ==", + "license": "MIT" }, "node_modules/cross-spawn": { "version": "7.0.6", @@ -13435,11 +13433,6 @@ "node": ">=8.0" } }, - "node_modules/toggle-selection": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz", - "integrity": "sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==" - }, "node_modules/tough-cookie": { "version": "4.1.4", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz", diff --git a/web/package.json b/web/package.json index 481a9fa804..369c814a44 100644 --- a/web/package.json +++ b/web/package.json @@ -56,7 +56,7 @@ "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "cmdk": "^1.0.0", - "copy-to-clipboard": "^3.3.3", + "copy-to-clipboard": "^4.0.2", "date-fns": "^3.6.0", "date-fns-tz": "^3.2.0", "framer-motion": "^13.2.0", diff --git a/web/src/components/ErrorBoundaries.tsx b/web/src/components/ErrorBoundaries.tsx index 506dbe4923..f1746c8127 100644 --- a/web/src/components/ErrorBoundaries.tsx +++ b/web/src/components/ErrorBoundaries.tsx @@ -92,10 +92,12 @@ function PagePanel({ failure }: PanelProps) { const stale = isStaleAsset(failure); - const onCopy = () => { - // copy() falls back to a prompt and returns false when the clipboard is + const onCopy = async () => { + // copy() falls back to a prompt and resolves false when the clipboard is // refused, so a success toast has to wait on the result. - const copied = copy(crashReport(failure, stats?.service.version)); + const copied = await copy(crashReport(failure, stats?.service.version), { + fallbackToPrompt: true, + }); if (copied) { toast.success(t("button.copiedToClipboard"), { position: "top-center" }); diff --git a/web/src/components/chat/ChatMessage.tsx b/web/src/components/chat/ChatMessage.tsx index 0a5c02763f..f9f441b92f 100644 --- a/web/src/components/chat/ChatMessage.tsx +++ b/web/src/components/chat/ChatMessage.tsx @@ -71,10 +71,10 @@ export function MessageBubble({ const [copied, setCopied] = useState(false); - const handleCopy = useCallback(() => { + const handleCopy = useCallback(async () => { const text = content?.trim() || ""; if (!text) return; - if (copy(text)) { + if (await copy(text)) { setCopied(true); toast.success(t("button.copiedToClipboard", { ns: "common" })); setTimeout(() => setCopied(false), 2000); diff --git a/web/src/pages/Logs.tsx b/web/src/pages/Logs.tsx index 7167b61688..e482874c73 100644 --- a/web/src/pages/Logs.tsx +++ b/web/src/pages/Logs.tsx @@ -362,10 +362,10 @@ function Logs() { }); }, [isLoading, logState]); - const handleCopyLogs = useCallback(() => { + const handleCopyLogs = useCallback(async () => { if (!logState.entries.length) return; - if (copy(logState.entries.map((entry) => entry.text).join("\n"))) { + if (await copy(logState.entries.map((entry) => entry.text).join("\n"))) { toast.success(t("logs.copy.success")); } else { toast.error(t("logs.copy.error"));