translateMessage method
Future<void>
translateMessage(
- ChatMessage message, {
- MessageTranslationSource source = MessageTranslationSource.manual,
Implementation
Future<void> translateMessage(
ChatMessage message, {
MessageTranslationSource source = MessageTranslationSource.manual,
}) async {
if (!IMKitClient.enableMessageTranslation) {
return;
}
final nimMessage = message.nimMessage;
final text = nimMessage.text?.trim();
if (nimMessage.messageType != NIMMessageType.text ||
text?.isNotEmpty != true) {
return;
}
final translationContent =
MessageTranslationHelper.buildTextTranslationContent(
nimMessage.text!,
serverExtension: nimMessage.serverExtension,
);
final translatableParts = translationContent.translatableParts;
if (translatableParts.isEmpty) {
return;
}
final messageId = MessageTranslationHelper.messageIdentity(nimMessage);
if (messageId.isEmpty || _translatingMessageIds.contains(messageId)) {
return;
}
final targetLanguage = await ConfigRepo.getMessageTranslateTargetLanguage();
final existing = MessageTranslationHelper.parseMessageTranslation(
nimMessage,
);
final existingMemoryState = _messageTranslationStates[messageId];
if (existing != null &&
existing.text.isNotEmpty &&
existing.targetLanguage == targetLanguage) {
if (existing.hidden) {
await _saveMessageTranslation(
nimMessage,
existing.copyWith(hidden: false),
messageId,
existing.source,
);
if (!_isDisposed) {
notifyListeners();
}
}
return;
}
if (existingMemoryState?.translation?.text.isNotEmpty == true &&
existingMemoryState?.translation?.targetLanguage == targetLanguage) {
final memoryTranslation = existingMemoryState!.translation!;
if (memoryTranslation.hidden) {
await _saveMessageTranslation(
nimMessage,
memoryTranslation.copyWith(hidden: false),
messageId,
memoryTranslation.source,
);
if (!_isDisposed) {
notifyListeners();
}
}
return;
}
final isManual = source == MessageTranslationSource.manual;
var manualSerial = _manualTranslationSerial;
if (isManual) {
final previousMessageId = _activeManualTranslationMessageId;
if (previousMessageId?.isNotEmpty == true &&
previousMessageId != messageId) {
_translatingMessageIds.remove(previousMessageId);
_messageTranslationStates.remove(previousMessageId);
}
_activeManualTranslationMessageId = messageId;
manualSerial = ++_manualTranslationSerial;
}
if (isManual && manualSerial != _manualTranslationSerial) {
return;
}
if (!await haveConnectivity()) {
if (isManual && manualSerial == _manualTranslationSerial) {
_activeManualTranslationMessageId = null;
}
return;
}
if (isManual && manualSerial != _manualTranslationSerial) {
return;
}
_translatingMessageIds.add(messageId);
_messageTranslationStates.remove(messageId);
notifyListeners();
try {
final translatedParts = <String>[];
String? sourceLanguage;
var resolvedTargetLanguage = targetLanguage;
for (final part in translatableParts) {
final result = await NimCore.instance.messageService.translateText(
params: NIMTextTranslateParams(
text: part.textToTranslate,
targetLanguage: targetLanguage,
),
config: NIMTranslatorConfig(strictMode: false),
);
if (_isDisposed ||
(isManual && manualSerial != _manualTranslationSerial)) {
return;
}
final translatedPart = result.data?.translatedText?.trim();
if (!result.isSuccess || translatedPart?.isNotEmpty != true) {
_setMessageTranslationFailed(messageId, source);
return;
}
translatedParts.add(translatedPart!);
sourceLanguage ??= result.data?.sourceLanguage;
if (result.data?.targetLanguage?.isNotEmpty == true) {
resolvedTargetLanguage = result.data!.targetLanguage!;
}
}
final translatedText = translationContent.combine(translatedParts).trim();
if (translatedText.isEmpty) {
_setMessageTranslationFailed(messageId, source);
return;
}
final info = MessageTranslationInfo(
targetLanguage: resolvedTargetLanguage,
sourceLanguage: sourceLanguage,
text: translatedText,
translatedAt: DateTime.now().millisecondsSinceEpoch,
source: source,
);
await _saveMessageTranslation(nimMessage, info, messageId, source);
} catch (e) {
Alog.e(
tag: logTag,
moduleName: 'message translation',
content: 'translate message failed: $e',
);
if (!_isDisposed &&
(!isManual || manualSerial == _manualTranslationSerial)) {
_setMessageTranslationFailed(messageId, source);
}
} finally {
if (!_isDisposed) {
_translatingMessageIds.remove(messageId);
if (isManual && manualSerial == _manualTranslationSerial) {
_activeManualTranslationMessageId = null;
}
notifyListeners();
}
}
}