From fbf47fc943aa0ed4191815ee6f3489207f614f35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=87=AA=E7=94=B1=E7=9A=84=E4=B8=96=E7=95=8C=E4=BA=BA?= <3196812536@qq.com> Date: Wed, 7 May 2025 14:19:47 +0800 Subject: [PATCH] fix: chat message translate (#5682) * fix: add updateTranslationBlockThunk --- .../src/hooks/useMessageOperations.ts | 63 ++++++++++++++----- src/renderer/src/store/thunk/messageThunk.ts | 23 +++++++ 2 files changed, 69 insertions(+), 17 deletions(-) diff --git a/src/renderer/src/hooks/useMessageOperations.ts b/src/renderer/src/hooks/useMessageOperations.ts index 7ab0c022ed..1e08c4934e 100644 --- a/src/renderer/src/hooks/useMessageOperations.ts +++ b/src/renderer/src/hooks/useMessageOperations.ts @@ -1,8 +1,7 @@ import { createSelector } from '@reduxjs/toolkit' import { EVENT_NAMES, EventEmitter } from '@renderer/services/EventService' import store, { type RootState, useAppDispatch, useAppSelector } from '@renderer/store' -import { messageBlocksSelectors } from '@renderer/store/messageBlock' -import { updateOneBlock } from '@renderer/store/messageBlock' +import { messageBlocksSelectors, updateOneBlock } from '@renderer/store/messageBlock' import { newMessagesActions, selectMessagesForTopic } from '@renderer/store/newMessage' import { appendAssistantResponseThunk, @@ -14,9 +13,9 @@ import { regenerateAssistantResponseThunk, resendMessageThunk, resendUserMessageWithEditThunk, - updateMessageAndBlocksThunk + updateMessageAndBlocksThunk, + updateTranslationBlockThunk } from '@renderer/store/thunk/messageThunk' -import { throttledBlockDbUpdate } from '@renderer/store/thunk/messageThunk' import type { Assistant, Model, Topic } from '@renderer/types' import type { Message, MessageBlock } from '@renderer/types/newMessage' import { MessageBlockStatus, MessageBlockType } from '@renderer/types/newMessage' @@ -233,21 +232,53 @@ export function useMessageOperations(topic: Topic) { ): Promise<((accumulatedText: string, isComplete?: boolean) => void) | null> => { if (!topic.id) return null - const blockId = await dispatch( - initiateTranslationThunk(messageId, topic.id, targetLanguage, sourceBlockId, sourceLanguage) - ) + const state = store.getState() + const message = state.messages.entities[messageId] + if (!message) { + console.error('[getTranslationUpdater] cannot find message:', messageId) + return null + } + + let existingTranslationBlockId: string | undefined + if (message.blocks && message.blocks.length > 0) { + for (const blockId of message.blocks) { + const block = state.messageBlocks.entities[blockId] + if (block && block.type === MessageBlockType.TRANSLATION) { + existingTranslationBlockId = blockId + break + } + } + } + + let blockId: string | undefined + if (existingTranslationBlockId) { + blockId = existingTranslationBlockId + const changes: Partial = { + content: '', + status: MessageBlockStatus.STREAMING, + metadata: { + targetLanguage, + sourceBlockId, + sourceLanguage + } + } + dispatch(updateOneBlock({ id: blockId, changes })) + await dispatch(updateTranslationBlockThunk(blockId, '', false)) + console.log('[getTranslationUpdater] update existing translation block:', blockId) + } else { + blockId = await dispatch( + initiateTranslationThunk(messageId, topic.id, targetLanguage, sourceBlockId, sourceLanguage) + ) + console.log('[getTranslationUpdater] create new translation block:', blockId) + } if (!blockId) { - console.error('[getTranslationUpdater] Failed to initiate translation block.') + console.error('[getTranslationUpdater] Failed to create translation block.') return null } return (accumulatedText: string, isComplete: boolean = false) => { - const status = isComplete ? MessageBlockStatus.SUCCESS : MessageBlockStatus.STREAMING - const changes: Partial = { content: accumulatedText, status: status } - - dispatch(updateOneBlock({ id: blockId, changes })) - throttledBlockDbUpdate(blockId, changes) + dispatch(updateTranslationBlockThunk(blockId!, accumulatedText, isComplete)) } }, [dispatch, topic.id] @@ -321,11 +352,9 @@ export function useMessageOperations(topic: Topic) { } export const useTopicMessages = (topicId: string) => { - const messages = useAppSelector((state) => selectMessagesForTopic(state, topicId)) - return messages + return useAppSelector((state) => selectMessagesForTopic(state, topicId)) } export const useTopicLoading = (topic: Topic) => { - const loading = useAppSelector((state) => selectNewTopicLoading(state, topic.id)) - return loading + return useAppSelector((state) => selectNewTopicLoading(state, topic.id)) } diff --git a/src/renderer/src/store/thunk/messageThunk.ts b/src/renderer/src/store/thunk/messageThunk.ts index d465b64030..20de6d804b 100644 --- a/src/renderer/src/store/thunk/messageThunk.ts +++ b/src/renderer/src/store/thunk/messageThunk.ts @@ -1068,6 +1068,29 @@ export const initiateTranslationThunk = } } +// --- Thunk to update the translation block with new content --- +export const updateTranslationBlockThunk = + (blockId: string, accumulatedText: string, isComplete: boolean = false) => + async (dispatch: AppDispatch) => { + console.log(`[updateTranslationBlockThunk] 更新翻译块 ${blockId}, isComplete: ${isComplete}`) + try { + const status = isComplete ? MessageBlockStatus.SUCCESS : MessageBlockStatus.STREAMING + const changes: Partial = { + content: accumulatedText, + status: status + } + + // 更新Redux状态 + dispatch(updateOneBlock({ id: blockId, changes })) + + // 更新数据库 + await db.message_blocks.update(blockId, changes) + console.log(`[updateTranslationBlockThunk] Successfully updated translation block ${blockId}.`) + } catch (error) { + console.error(`[updateTranslationBlockThunk] Failed to update translation block ${blockId}:`, error) + } + } + /** * Thunk to append a new assistant response (using a potentially different model) * in reply to the same user query as an existing assistant message.