add translate again and delete

This commit is contained in:
Julian Freeman
2026-04-05 12:07:18 -04:00
parent e2b6340446
commit a8967809a2
2 changed files with 52 additions and 15 deletions

View File

@@ -132,28 +132,36 @@ const generateCurl = (baseUrl: string, key: string, body: any) => {
return `curl "${fullUrl}" \\\n -H "Content-Type: application/json" \\\n -H "Authorization: Bearer ${maskedKey}" \\\n -d '${JSON.stringify(body, null, 2)}'`; return `curl "${fullUrl}" \\\n -H "Content-Type: application/json" \\\n -H "Authorization: Bearer ${maskedKey}" \\\n -d '${JSON.stringify(body, null, 2)}'`;
}; };
const translateMessage = async (sender: 'me' | 'partner') => { const translateMessage = async (sender: 'me' | 'partner', retranslateId?: string) => {
if (!activeSession.value || isTranslating.value) return; if (!activeSession.value || isTranslating.value) return;
const text = sender === 'me' ? myInput.value.trim() : partnerInput.value.trim(); let text = '';
if (!text) return; let messageId = '';
if (retranslateId) {
const msg = activeSession.value.messages.find(m => m.id === retranslateId);
if (!msg) return;
text = msg.original;
messageId = retranslateId;
settings.updateChatMessage(activeSession.value.id, messageId, { translated: '', evaluation: undefined });
} else {
text = sender === 'me' ? myInput.value.trim() : partnerInput.value.trim();
if (!text) return;
const newId = settings.addMessageToSession(activeSession.value.id, sender, text, '');
if (!newId) return;
messageId = newId;
if (sender === 'me') myInput.value = ''; else partnerInput.value = '';
}
isTranslating.value = true; isTranslating.value = true;
// 1. Add message to session
const messageId = settings.addMessageToSession(activeSession.value.id, sender, text, '');
if (!messageId) {
isTranslating.value = false;
return;
}
currentStreamingMessageId.value = messageId; currentStreamingMessageId.value = messageId;
if (sender === 'me') myInput.value = ''; else partnerInput.value = '';
await scrollToBottom(); await scrollToBottom();
// 2. Prepare Context // 2. Prepare Context
const historyLimit = 10; const historyLimit = 10;
const sessionMessages = activeSession.value.messages; const sessionMessages = activeSession.value.messages;
// 重新翻译时,排除当前这条消息本身作为历史
const recentMessages = sessionMessages.filter(m => m.id !== messageId).slice(-historyLimit); const recentMessages = sessionMessages.filter(m => m.id !== messageId).slice(-historyLimit);
const historyBlock = recentMessages.map(m => { const historyBlock = recentMessages.map(m => {
@@ -187,7 +195,7 @@ const translateMessage = async (sender: 'me' | 'partner') => {
stream: settings.enableStreaming stream: settings.enableStreaming
}; };
settings.addLog('request', { type: 'conversation', ...requestBody }, generateCurl(settings.apiBaseUrl, settings.apiKey, requestBody)); settings.addLog('request', { type: retranslateId ? 'conversation-retranslate' : 'conversation', ...requestBody }, generateCurl(settings.apiBaseUrl, settings.apiKey, requestBody));
try { try {
const response = await invoke<string>('translate', { const response = await invoke<string>('translate', {
@@ -215,6 +223,11 @@ const translateMessage = async (sender: 'me' | 'partner') => {
} }
}; };
const deleteMessage = (messageId: string) => {
if (!activeSession.value) return;
settings.deleteChatMessage(activeSession.value.id, messageId);
};
const evaluateMessage = async (messageId: string, force = false) => { const evaluateMessage = async (messageId: string, force = false) => {
if (!activeSession.value) return; if (!activeSession.value) return;
const msg = activeSession.value.messages.find(m => m.id === messageId); const msg = activeSession.value.messages.find(m => m.id === messageId);
@@ -540,7 +553,7 @@ onUnmounted(() => window.removeEventListener('click', handleGlobalClick));
<!-- Action Tools (Copy, Evaluate, Refine) --> <!-- Action Tools (Copy, Evaluate, Refine) -->
<div :class="cn( <div :class="cn(
'absolute top-0 opacity-0 group-hover:opacity-100 transition-opacity flex items-center bg-white/90 dark:bg-slate-800/90 rounded-full shadow-lg border dark:border-slate-700 px-1 py-1 z-20', 'absolute top-0 opacity-0 group-hover:opacity-100 transition-opacity flex items-center bg-white/90 dark:bg-slate-800/90 rounded-full shadow-lg border dark:border-slate-700 px-1 py-1 z-20',
msg.sender === 'me' ? '-left-24' : '-right-24' msg.sender === 'me' ? '-left-32' : '-right-32'
)"> )">
<button <button
@click="copyWithFeedback(msg.translated, msg.id)" @click="copyWithFeedback(msg.translated, msg.id)"
@@ -550,6 +563,15 @@ onUnmounted(() => window.removeEventListener('click', handleGlobalClick));
<Check v-if="activeCopyId === msg.id" class="w-3.5 h-3.5 text-green-600" /> <Check v-if="activeCopyId === msg.id" class="w-3.5 h-3.5 text-green-600" />
<Copy v-else class="w-3.5 h-3.5 text-slate-400" /> <Copy v-else class="w-3.5 h-3.5 text-slate-400" />
</button> </button>
<button
@click="translateMessage(msg.sender, msg.id)"
:disabled="isTranslating || msg.isEvaluating || msg.isRefining"
class="p-1.5 hover:bg-slate-100 dark:hover:bg-slate-700 rounded-full transition-colors disabled:opacity-30"
title="重新翻译"
>
<RotateCcw v-if="isTranslating && currentStreamingMessageId === msg.id" class="w-3.5 h-3.5 animate-spin text-blue-500" />
<RotateCcw v-else class="w-3.5 h-3.5 text-slate-400" />
</button>
<button <button
@click="evaluateMessage(msg.id)" @click="evaluateMessage(msg.id)"
:disabled="msg.isEvaluating || msg.isRefining" :disabled="msg.isEvaluating || msg.isRefining"
@@ -559,6 +581,13 @@ onUnmounted(() => window.removeEventListener('click', handleGlobalClick));
<Loader2 v-if="msg.isEvaluating" class="w-3.5 h-3.5 animate-spin text-blue-500" /> <Loader2 v-if="msg.isEvaluating" class="w-3.5 h-3.5 animate-spin text-blue-500" />
<ShieldCheck v-else class="w-3.5 h-3.5 text-slate-400" /> <ShieldCheck v-else class="w-3.5 h-3.5 text-slate-400" />
</button> </button>
<button
@click="deleteMessage(msg.id)"
class="p-1.5 hover:bg-red-50 dark:hover:bg-red-900/30 rounded-full transition-colors group/del"
title="删除消息"
>
<Trash2 class="w-3.5 h-3.5 text-slate-400 group-hover/del:text-red-500" />
</button>
</div> </div>
</div> </div>
</div> </div>

View File

@@ -386,6 +386,13 @@ export const useSettingsStore = defineStore('settings', () => {
} }
}; };
const deleteChatMessage = (sessionId: string, messageId: string) => {
const session = chatSessions.value.find(s => s.id === sessionId);
if (session) {
session.messages = session.messages.filter(m => m.id !== messageId);
}
};
return { return {
isDark, isDark,
apiBaseUrl, apiBaseUrl,
@@ -415,6 +422,7 @@ export const useSettingsStore = defineStore('settings', () => {
createSession, createSession,
deleteSession, deleteSession,
addMessageToSession, addMessageToSession,
updateChatMessage updateChatMessage,
deleteChatMessage
}; };
}); });