fix: 修复剪贴板没有统一使用copyToClipboard的问题
This commit is contained in:
parent
5a7de8b148
commit
e5c0e9d584
|
|
@ -1,7 +1,7 @@
|
||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { cn } from "@/lib/utils";
|
import { cn, copyToClipboard } from "@/lib/utils";
|
||||||
import { CheckIcon, CopyIcon } from "lucide-react";
|
import { CheckIcon, CopyIcon } from "lucide-react";
|
||||||
import {
|
import {
|
||||||
type ComponentProps,
|
type ComponentProps,
|
||||||
|
|
@ -146,14 +146,9 @@ export const CodeBlockCopyButton = ({
|
||||||
const [isCopied, setIsCopied] = useState(false);
|
const [isCopied, setIsCopied] = useState(false);
|
||||||
const { code } = useContext(CodeBlockContext);
|
const { code } = useContext(CodeBlockContext);
|
||||||
|
|
||||||
const copyToClipboard = async () => {
|
const handleCopyClick = async () => {
|
||||||
if (typeof window === "undefined" || !navigator?.clipboard?.writeText) {
|
|
||||||
onError?.(new Error("Clipboard API not available"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await navigator.clipboard.writeText(code);
|
await copyToClipboard(code);
|
||||||
setIsCopied(true);
|
setIsCopied(true);
|
||||||
onCopy?.();
|
onCopy?.();
|
||||||
setTimeout(() => setIsCopied(false), timeout);
|
setTimeout(() => setIsCopied(false), timeout);
|
||||||
|
|
@ -167,7 +162,7 @@ export const CodeBlockCopyButton = ({
|
||||||
return (
|
return (
|
||||||
<Button
|
<Button
|
||||||
className={cn("shrink-0", className)}
|
className={cn("shrink-0", className)}
|
||||||
onClick={copyToClipboard}
|
onClick={handleCopyClick}
|
||||||
size="icon"
|
size="icon"
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
{...props}
|
{...props}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ import { useCallback, useState, type ComponentProps } from "react";
|
||||||
|
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { useI18n } from "@/core/i18n/hooks";
|
import { useI18n } from "@/core/i18n/hooks";
|
||||||
|
import { copyToClipboard } from "@/lib/utils";
|
||||||
|
|
||||||
import { Tooltip } from "./tooltip";
|
import { Tooltip } from "./tooltip";
|
||||||
|
|
||||||
|
|
@ -14,10 +15,14 @@ export function CopyButton({
|
||||||
}) {
|
}) {
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const [copied, setCopied] = useState(false);
|
const [copied, setCopied] = useState(false);
|
||||||
const handleCopy = useCallback(() => {
|
const handleCopy = useCallback(async () => {
|
||||||
void navigator.clipboard.writeText(clipboardData);
|
try {
|
||||||
setCopied(true);
|
await copyToClipboard(clipboardData);
|
||||||
setTimeout(() => setCopied(false), 2000);
|
setCopied(true);
|
||||||
|
setTimeout(() => setCopied(false), 2000);
|
||||||
|
} catch {
|
||||||
|
// no-op: caller controls error UI if needed
|
||||||
|
}
|
||||||
}, [clipboardData]);
|
}, [clipboardData]);
|
||||||
return (
|
return (
|
||||||
<Tooltip content={t.clipboard.copyToClipboard}>
|
<Tooltip content={t.clipboard.copyToClipboard}>
|
||||||
|
|
|
||||||
|
|
@ -425,7 +425,7 @@ function ToolCall({
|
||||||
action={shouldCollapse
|
action={shouldCollapse
|
||||||
? (
|
? (
|
||||||
<Button
|
<Button
|
||||||
className="h-7 px-0 text-xs"
|
className="h-7 px-3 text-xs"
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
onClick={(event) => {
|
onClick={(event) => {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,7 @@ import {
|
||||||
import type { AgentThread, AgentThreadState } from "@/core/threads/types";
|
import type { AgentThread, AgentThreadState } from "@/core/threads/types";
|
||||||
import { pathOfThread, titleOfThread } from "@/core/threads/utils";
|
import { pathOfThread, titleOfThread } from "@/core/threads/utils";
|
||||||
import { env } from "@/env";
|
import { env } from "@/env";
|
||||||
|
import { copyToClipboard } from "@/lib/utils";
|
||||||
|
|
||||||
export function RecentChatList() {
|
export function RecentChatList() {
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
@ -119,7 +120,7 @@ export function RecentChatList() {
|
||||||
const baseUrl = isLocalhost ? VERCEL_URL : window.location.origin;
|
const baseUrl = isLocalhost ? VERCEL_URL : window.location.origin;
|
||||||
const shareUrl = `${baseUrl}/workspace/chats/${threadId}`;
|
const shareUrl = `${baseUrl}/workspace/chats/${threadId}`;
|
||||||
try {
|
try {
|
||||||
await navigator.clipboard.writeText(shareUrl);
|
await copyToClipboard(shareUrl);
|
||||||
toast.success(t.clipboard.linkCopied);
|
toast.success(t.clipboard.linkCopied);
|
||||||
} catch {
|
} catch {
|
||||||
toast.error(t.clipboard.failedToCopyToClipboard);
|
toast.error(t.clipboard.failedToCopyToClipboard);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue