fix: 修复剪贴板没有统一使用copyToClipboard的问题

This commit is contained in:
肖应宇 2026-04-11 10:21:29 +08:00
parent 5a7de8b148
commit e5c0e9d584
4 changed files with 16 additions and 15 deletions

View File

@ -1,7 +1,7 @@
"use client";
import { Button } from "@/components/ui/button";
import { cn } from "@/lib/utils";
import { cn, copyToClipboard } from "@/lib/utils";
import { CheckIcon, CopyIcon } from "lucide-react";
import {
type ComponentProps,
@ -146,14 +146,9 @@ export const CodeBlockCopyButton = ({
const [isCopied, setIsCopied] = useState(false);
const { code } = useContext(CodeBlockContext);
const copyToClipboard = async () => {
if (typeof window === "undefined" || !navigator?.clipboard?.writeText) {
onError?.(new Error("Clipboard API not available"));
return;
}
const handleCopyClick = async () => {
try {
await navigator.clipboard.writeText(code);
await copyToClipboard(code);
setIsCopied(true);
onCopy?.();
setTimeout(() => setIsCopied(false), timeout);
@ -167,7 +162,7 @@ export const CodeBlockCopyButton = ({
return (
<Button
className={cn("shrink-0", className)}
onClick={copyToClipboard}
onClick={handleCopyClick}
size="icon"
variant="ghost"
{...props}

View File

@ -3,6 +3,7 @@ import { useCallback, useState, type ComponentProps } from "react";
import { Button } from "@/components/ui/button";
import { useI18n } from "@/core/i18n/hooks";
import { copyToClipboard } from "@/lib/utils";
import { Tooltip } from "./tooltip";
@ -14,10 +15,14 @@ export function CopyButton({
}) {
const { t } = useI18n();
const [copied, setCopied] = useState(false);
const handleCopy = useCallback(() => {
void navigator.clipboard.writeText(clipboardData);
setCopied(true);
setTimeout(() => setCopied(false), 2000);
const handleCopy = useCallback(async () => {
try {
await copyToClipboard(clipboardData);
setCopied(true);
setTimeout(() => setCopied(false), 2000);
} catch {
// no-op: caller controls error UI if needed
}
}, [clipboardData]);
return (
<Tooltip content={t.clipboard.copyToClipboard}>

View File

@ -425,7 +425,7 @@ function ToolCall({
action={shouldCollapse
? (
<Button
className="h-7 px-0 text-xs"
className="h-7 px-3 text-xs"
variant="ghost"
onClick={(event) => {
event.stopPropagation();

View File

@ -56,6 +56,7 @@ import {
import type { AgentThread, AgentThreadState } from "@/core/threads/types";
import { pathOfThread, titleOfThread } from "@/core/threads/utils";
import { env } from "@/env";
import { copyToClipboard } from "@/lib/utils";
export function RecentChatList() {
const { t } = useI18n();
@ -119,7 +120,7 @@ export function RecentChatList() {
const baseUrl = isLocalhost ? VERCEL_URL : window.location.origin;
const shareUrl = `${baseUrl}/workspace/chats/${threadId}`;
try {
await navigator.clipboard.writeText(shareUrl);
await copyToClipboard(shareUrl);
toast.success(t.clipboard.linkCopied);
} catch {
toast.error(t.clipboard.failedToCopyToClipboard);