diff --git a/components/CopyButton.tsx b/components/CopyButton.tsx
index 0a1d268..4a2612b 100644
--- a/components/CopyButton.tsx
+++ b/components/CopyButton.tsx
@@ -1,110 +1,103 @@
-import {useState, useCallback} from "react";
+import { useState, useCallback } from 'react';
+import { copyToClipboard } from '@/utils/chromeUtils';
const CopyButton = ({
- text = '要复制的文本',
- buttonText = '复制文本',
- className = 'action-btn',
- }) => {
- const [btnText, setBtnText] = useState(buttonText);
- const [copyStatus, setCopyStatus] = useState('');
-
- // 重置按钮状态的函数
- const resetButton = useCallback(() => {
- setBtnText(buttonText);
- setCopyStatus('');
- }, [buttonText]);
-
- // 复制成功的处理
- const handleCopySuccess = useCallback(() => {
- setCopyStatus('success');
- setBtnText('复制成功!');
+ text = '要复制的文本',
+ buttonText = '复制文本',
+ className = 'action-btn',
+ successMessage = '复制成功!',
+ errorMessage = '复制失败,请手动复制。',
+ onCopyOverride = null,
+}) => {
+ const [status, setStatus] = useState('idle'); // 'idle' | 'copying' | 'success' | 'error'
+
+ useEffect(() => {
+ let timer;
+ if (status === 'success' || status === 'error') {
+ timer = setTimeout(() => {
+ setStatus('idle');
+ }, 2000);
+ }
+
+ return () => clearTimeout(timer);
+ }, [status]);
+
+ const performCopy = async () => {
+ if (!text) {
+ console.warn('没有提供要复制的文本');
+ return false;
+ }
+
+ const safeText = String(text);
+
+ // 优先使用传入的复制函数
+ if (onCopyOverride) {
+ return await onCopyOverride(safeText);
+ }
+
+ const textArea = document.createElement("textarea");
+ textArea.value = safeText;
- // 2秒后恢复
- setTimeout(() => {
- resetButton();
- }, 2000);
- }, [text, resetButton]);
-
- // 复制失败的处理
- const handleCopyError = useCallback(() => {
- setCopyStatus('error');
+ // 确保元素存在但不可见,且不影响布局
+ textArea.style.position = "fixed";
+ textArea.style.left = "-9999px";
+ textArea.style.top = "0";
+ textArea.style.opacity = "0";
- // 2秒后恢复
- setTimeout(() => {
- resetButton();
- }, 2000);
- }, [resetButton]);
-
- const handleCopy = async () => {
+ document.body.appendChild(textArea);
+ textArea.focus();
+ textArea.select();
+
+ const successful = document.execCommand('copy');
+ document.body.removeChild(textArea);
+
+ // 使用通用的复制函数
+ return true;
+ };
+
+ const handleClick = useCallback(async () => {
+ setStatus('copying');
+
try {
- console.log('开始复制:', text);
+ const isSuccess = await performCopy();
+ setStatus(isSuccess ? 'success' : 'error');
+ } catch (error) {
+ console.error('复制时出错:', error);
+ setStatus('error');
+ }
+ }, [text, onCopyOverride]);
- // 首先尝试直接使用navigator.clipboard(在popup页面中可能可用)
- try {
- console.log('尝试直接使用navigator.clipboard复制');
- await navigator.clipboard.writeText(text.toString());
- console.log('直接复制成功');
- handleCopySuccess();
- return;
- } catch (directError) {
- console.log('直接复制失败,尝试使用Chrome扩展API:', directError);
- }
+ // 根据状态计算当前显示的文本
+ const currentText = status === 'success' ? successMessage
+ : status === 'error' ? errorMessage
+ : buttonText;
- // 如果直接复制失败,尝试使用Chrome扩展API
- if (chrome && chrome.runtime && chrome.runtime.sendMessage) {
- console.log('使用Chrome扩展API复制');
-
- // 使用Chrome扩展API复制
- chrome.runtime.sendMessage({
- action: 'copy',
- text: text
- }, (response) => {
- console.log('收到background响应:', response, 'lastError:', chrome.runtime.lastError);
-
- // 检查是否有运行时错误
- if (chrome.runtime.lastError) {
- console.error('Chrome运行时错误:', chrome.runtime.lastError.message);
- handleCopyError();
- return;
- }
-
- // 检查响应
- if (response && response.success) {
- console.log('通过background复制成功');
- handleCopySuccess();
- } else {
- console.error('通过background复制失败:', response?.error);
- handleCopyError();
- }
- });
- } else {
- console.error('没有可用的复制方法');
- handleCopyError();
- }
- } catch (err) {
- console.error('复制过程中发生错误:', err);
- handleCopyError();
+ // 根据状态计算样式 (建议使用 CSS Module 或 Tailwind,这里为了演示保留内联)
+ const getBackgroundColor = () => {
+ switch (status) {
+ case 'success': return '#4CAF50';
+ case 'error': return '#f44336';
+ default: return '#4CAF50'; // 让 CSS 类控制默认颜色
}
};
-
+
return (
);
};
-export default CopyButton;
\ No newline at end of file
+export default CopyButton;
diff --git a/components/TimestampExecution.tsx b/components/TimestampExecution.tsx
index 7018b78..36e727c 100644
--- a/components/TimestampExecution.tsx
+++ b/components/TimestampExecution.tsx
@@ -127,7 +127,7 @@ export function TimestampExecution() {