optimize copy feedback

This commit is contained in:
Julian Freeman
2026-03-25 19:02:48 -04:00
parent 69a8047743
commit 31dd4ee2b2

View File

@@ -88,14 +88,6 @@ const deleteHistoryItem = (id: string) => {
}
};
const copyHistoryText = async (text: string) => {
try {
await navigator.clipboard.writeText(text);
} catch (err) {
console.error('Failed to copy history text: ', err);
}
};
// Logs Management
const selectedLogId = ref<string | null>(null);
const selectedLogItem = computed(() =>
@@ -116,6 +108,23 @@ const getLogSummary = (log: any) => {
return 'JSON Data';
};
// Universal Copy with Feedback
const activeCopyId = ref<string | null>(null);
const copyWithFeedback = async (text: string, id: string) => {
try {
await navigator.clipboard.writeText(text);
activeCopyId.value = id;
setTimeout(() => {
if (activeCopyId.value === id) {
activeCopyId.value = null;
}
}, 2000);
} catch (err) {
console.error('Failed to copy text: ', err);
}
};
// Profile Management
const newProfileName = ref('');
const isSavingProfile = ref(false);
@@ -197,7 +206,6 @@ const sourceText = ref('');
const context = ref('');
const targetText = ref('');
const isTranslating = ref(false);
const showCopyFeedback = ref(false);
interface Suggestion {
id: number;
@@ -287,18 +295,6 @@ const clearSource = () => {
evaluationResult.value = null;
};
const copyTarget = async () => {
try {
await navigator.clipboard.writeText(targetText.value);
showCopyFeedback.value = true;
setTimeout(() => {
showCopyFeedback.value = false;
}, 2000);
} catch (err) {
console.error('Failed to copy text: ', err);
}
};
const evaluateTranslation = async () => {
if (!targetText.value) return;
@@ -776,8 +772,8 @@ const translate = async () => {
</div>
<div class="ml-auto flex items-center gap-2">
<button @click="copyTarget" class="p-1.5 hover:bg-slate-200 dark:hover:bg-slate-700 rounded-md transition-colors relative" title="复制结果">
<Check v-if="showCopyFeedback" class="w-4 h-4 text-green-600" />
<button @click="copyWithFeedback(targetText, 'main-target')" class="p-1.5 hover:bg-slate-200 dark:hover:bg-slate-700 rounded-md transition-colors relative" title="复制结果">
<Check v-if="activeCopyId === 'main-target'" class="w-4 h-4 text-green-600" />
<Copy v-else class="w-4 h-4 text-slate-500 dark:text-slate-400" />
</button>
</div>
@@ -1008,10 +1004,11 @@ const translate = async () => {
<h3 class="text-xs font-black text-slate-400 uppercase tracking-widest">{{ selectedHistoryItem.sourceLang.displayName }} (原文)</h3>
</div>
<button
@click="copyHistoryText(selectedHistoryItem.sourceText)"
@click="copyWithFeedback(selectedHistoryItem.sourceText, `history-source-${selectedHistoryItem.id}`)"
class="p-2 hover:bg-slate-100 dark:hover:bg-slate-800 rounded-lg text-slate-400 transition-colors"
>
<Copy class="w-4 h-4" />
<Check v-if="activeCopyId === `history-source-${selectedHistoryItem.id}`" class="w-4 h-4 text-green-600" />
<Copy v-else class="w-4 h-4" />
</button>
</div>
<div class="bg-slate-50 dark:bg-slate-800/30 p-6 rounded-2xl border border-slate-100 dark:border-slate-800 text-lg leading-relaxed text-slate-700 dark:text-slate-200 whitespace-pre-wrap">
@@ -1038,10 +1035,11 @@ const translate = async () => {
<h3 class="text-xs font-black text-blue-500/60 uppercase tracking-widest">{{ selectedHistoryItem.targetLang.displayName }} (译文)</h3>
</div>
<button
@click="copyHistoryText(selectedHistoryItem.targetText)"
@click="copyWithFeedback(selectedHistoryItem.targetText, `history-target-${selectedHistoryItem.id}`)"
class="p-2 bg-blue-50 dark:bg-blue-900/30 hover:bg-blue-100 dark:hover:bg-blue-900/50 rounded-lg text-blue-600 dark:text-blue-400 transition-colors"
>
<Copy class="w-4 h-4" />
<Check v-if="activeCopyId === `history-target-${selectedHistoryItem.id}`" class="w-4 h-4 text-green-600" />
<Copy v-else class="w-4 h-4" />
</button>
</div>
<div class="bg-blue-50/20 dark:bg-blue-900/10 p-6 rounded-2xl border border-blue-100/50 dark:border-blue-900/20 text-xl leading-relaxed font-medium text-slate-800 dark:text-slate-100 whitespace-pre-wrap shadow-sm">
@@ -1385,10 +1383,11 @@ const translate = async () => {
>{{ selectedLogItem.type === 'request' ? 'Request' : selectedLogItem.type === 'response' ? 'Response' : 'Error' }}</span>
</div>
<button
@click="copyHistoryText(typeof selectedLogItem.content === 'object' ? JSON.stringify(selectedLogItem.content, null, 2) : String(selectedLogItem.content))"
@click="copyWithFeedback(typeof selectedLogItem.content === 'object' ? JSON.stringify(selectedLogItem.content, null, 2) : String(selectedLogItem.content), `log-${selectedLogItem.id}`)"
class="flex items-center gap-2 px-3 py-2 text-xs font-medium text-slate-600 hover:bg-slate-100 dark:text-slate-300 dark:hover:bg-slate-800 rounded-lg transition-colors border border-slate-200 dark:border-slate-700"
>
<Copy class="w-4 h-4" />
<Check v-if="activeCopyId === `log-${selectedLogItem.id}`" class="w-4 h-4 text-green-600" />
<Copy v-else class="w-4 h-4" />
复制内容
</button>
</div>