226 lines
9.2 KiB
Objective-C
226 lines
9.2 KiB
Objective-C
//
|
|
// TUITranslationDataProvider.m
|
|
// TUITranslation
|
|
//
|
|
// Created by xia on 2023/3/21.
|
|
// Copyright © 2023 Tencent. All rights reserved.
|
|
//
|
|
|
|
#import "TUITranslationDataProvider.h"
|
|
#import <TIMCommon/NSString+TUIEmoji.h>
|
|
#import <TUICore/TUICore.h>
|
|
#import <TUICore/TUILogin.h>
|
|
#import "TUITranslationConfig.h"
|
|
|
|
#pragma GCC diagnostic ignored "-Wundeclared-selector"
|
|
|
|
static NSString *const kKeyTranslationText = @"translation";
|
|
static NSString *const kKeyTranslationViewStatus = @"translation_view_status";
|
|
|
|
@interface TUITranslationDataProvider () <TUINotificationProtocol, V2TIMAdvancedMsgListener>
|
|
|
|
@end
|
|
|
|
@implementation TUITranslationDataProvider
|
|
#pragma mark - Public
|
|
+ (void)translateMessage:(TUIMessageCellData *)data completion:(TUITranslateMessageCompletion)completion {
|
|
V2TIMMessage *msg = data.innerMessage;
|
|
if (msg.elemType != V2TIM_ELEM_TYPE_TEXT) {
|
|
return;
|
|
}
|
|
V2TIMTextElem *textElem = msg.textElem;
|
|
if (textElem == nil) {
|
|
return;
|
|
}
|
|
|
|
/// Get at user's nickname by userID
|
|
NSMutableArray *atUserIDs = [msg.groupAtUserList mutableCopy];
|
|
if (atUserIDs.count == 0) {
|
|
/// There's no any @user info.
|
|
[self translateMessage:data atUsers:nil completion:completion];
|
|
return;
|
|
}
|
|
|
|
/// Find @All info.
|
|
NSMutableArray *atUserIDsExcludingAtAll = [NSMutableArray new];
|
|
NSMutableIndexSet *atAllIndex = [NSMutableIndexSet new];
|
|
for (int i = 0; i < atUserIDs.count; i++) {
|
|
NSString *userID = atUserIDs[i];
|
|
if (![userID isEqualToString:kImSDK_MesssageAtALL]) {
|
|
/// Exclude @All.
|
|
[atUserIDsExcludingAtAll addObject:userID];
|
|
} else {
|
|
/// Record @All's location for later restore.
|
|
[atAllIndex addIndex:i];
|
|
}
|
|
}
|
|
if (atUserIDsExcludingAtAll.count == 0) {
|
|
/// There's only @All info.
|
|
NSMutableArray *atAllNames = [NSMutableArray new];
|
|
for (int i = 0; i < atAllIndex.count; i++) {
|
|
[atAllNames addObject:TIMCommonLocalizableString(All)];
|
|
}
|
|
[self translateMessage:data atUsers:atAllNames completion:completion];
|
|
return;
|
|
}
|
|
[[V2TIMManager sharedInstance] getUsersInfo:atUserIDsExcludingAtAll
|
|
succ:^(NSArray<V2TIMUserFullInfo *> *infoList) {
|
|
NSMutableArray *atUserNames = [NSMutableArray new];
|
|
for (NSString *userID in atUserIDsExcludingAtAll) {
|
|
for (V2TIMUserFullInfo *user in infoList) {
|
|
if ([userID isEqualToString:user.userID]) {
|
|
[atUserNames addObject:user.nickName ?: user.userID];
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Restore @All.
|
|
if (atAllIndex.count > 0) {
|
|
[atAllIndex enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *_Nonnull stop) {
|
|
[atUserNames insertObject:TIMCommonLocalizableString(All) atIndex:idx];
|
|
}];
|
|
}
|
|
[self translateMessage:data atUsers:atUserNames completion:completion];
|
|
}
|
|
fail:^(int code, NSString *desc) {
|
|
[self translateMessage:data atUsers:atUserIDs completion:completion];
|
|
}];
|
|
}
|
|
|
|
+ (void)translateMessage:(TUIMessageCellData *)data atUsers:(NSArray *)atUsers completion:(TUITranslateMessageCompletion)completion {
|
|
V2TIMMessage *msg = data.innerMessage;
|
|
V2TIMTextElem *textElem = msg.textElem;
|
|
|
|
NSString *target = [TUITranslationConfig defaultConfig].targetLanguageCode;
|
|
NSDictionary *splitResult = [textElem.text splitTextByEmojiAndAtUsers:atUsers];
|
|
NSArray *textArray = splitResult[kSplitStringTextKey];
|
|
|
|
if (textArray.count == 0) {
|
|
/// Nothing need to be translated.
|
|
[self saveTranslationResult:msg text:textElem.text status:TUITranslationViewStatusShown];
|
|
if (completion) {
|
|
completion(0, @"", data, TUITranslationViewStatusShown, textElem.text);
|
|
}
|
|
return;
|
|
}
|
|
|
|
NSDictionary *dict = [TUITool jsonData2Dictionary:msg.localCustomData];
|
|
NSString *translatedText = nil;
|
|
if ([dict.allKeys containsObject:kKeyTranslationText]) {
|
|
translatedText = dict[kKeyTranslationText];
|
|
}
|
|
|
|
if (translatedText.length > 0) {
|
|
[self saveTranslationResult:msg text:translatedText status:TUITranslationViewStatusShown];
|
|
if (completion) {
|
|
completion(0, @"", data, TUITranslationViewStatusShown, translatedText);
|
|
}
|
|
} else {
|
|
[self saveTranslationResult:msg text:@"" status:TUITranslationViewStatusLoading];
|
|
if (completion) {
|
|
completion(0, @"", data, TUITranslationViewStatusLoading, @"");
|
|
}
|
|
}
|
|
|
|
/// Send translate request.
|
|
@weakify(self);
|
|
[[V2TIMManager sharedInstance] translateText:textArray
|
|
sourceLanguage:nil
|
|
targetLanguage:target
|
|
completion:^(int code, NSString *desc, NSDictionary<NSString *, NSString *> *result) {
|
|
@strongify(self);
|
|
/// Translate failed.
|
|
if (code != 0 || result.count == 0) {
|
|
if (code == 30007) {
|
|
[TUITool makeToast:TIMCommonLocalizableString(TranslateLanguageNotSupport)];
|
|
} else {
|
|
[TUITool makeToastError:code msg:desc];
|
|
}
|
|
|
|
[self saveTranslationResult:msg text:@"" status:TUITranslationViewStatusHidden];
|
|
if (completion) {
|
|
completion(code, desc, data, TUITranslationViewStatusHidden, @"");
|
|
}
|
|
return;
|
|
}
|
|
|
|
/// Translate succeeded.
|
|
NSString *text = [NSString replacedStringWithArray:splitResult[kSplitStringResultKey]
|
|
index:splitResult[kSplitStringTextIndexKey]
|
|
replaceDict:result];
|
|
[self saveTranslationResult:msg text:text status:TUITranslationViewStatusShown];
|
|
|
|
if (completion) {
|
|
completion(0, @"", data, TUITranslationViewStatusShown, text);
|
|
}
|
|
}];
|
|
}
|
|
|
|
+ (void)saveTranslationResult:(V2TIMMessage *)message text:(NSString *)text status:(TUITranslationViewStatus)status {
|
|
if (text.length > 0) {
|
|
[self saveToLocalCustomDataOfMessage:message key:kKeyTranslationText value:text];
|
|
}
|
|
[self saveToLocalCustomDataOfMessage:message key:kKeyTranslationViewStatus value:@(status)];
|
|
}
|
|
|
|
+ (void)saveToLocalCustomDataOfMessage:(V2TIMMessage *)message key:(NSString *)key value:(id)value {
|
|
if (key.length == 0 || value == nil) {
|
|
return;
|
|
}
|
|
NSData *customData = message.localCustomData;
|
|
NSMutableDictionary *dict = [[TUITool jsonData2Dictionary:customData] mutableCopy];
|
|
if (dict == nil) {
|
|
dict = [[NSMutableDictionary alloc] init];
|
|
}
|
|
dict[key] = value;
|
|
[message setLocalCustomData:[TUITool dictionary2JsonData:dict]];
|
|
}
|
|
|
|
+ (BOOL)shouldShowTranslation:(V2TIMMessage *)message {
|
|
if (message.localCustomData.length == 0) {
|
|
return NO;
|
|
}
|
|
NSDictionary *dict = [TUITool jsonData2Dictionary:message.localCustomData];
|
|
TUITranslationViewStatus status;
|
|
if ([dict.allKeys containsObject:kKeyTranslationViewStatus]) {
|
|
status = [dict[kKeyTranslationViewStatus] integerValue];
|
|
} else {
|
|
status = TUITranslationViewStatusHidden;
|
|
}
|
|
NSArray *hiddenStatus = @[ @(TUITranslationViewStatusUnknown), @(TUITranslationViewStatusHidden) ];
|
|
return ![hiddenStatus containsObject:@(status)] || status == TUITranslationViewStatusLoading;
|
|
}
|
|
|
|
+ (NSString *)getTranslationText:(V2TIMMessage *)message {
|
|
BOOL hasRiskContent = message.hasRiskContent;
|
|
if (hasRiskContent){
|
|
return TIMCommonLocalizableString(TUIKitMessageTypeSecurityStrikeTranslate);
|
|
}
|
|
if (message.localCustomData.length == 0) {
|
|
return nil;
|
|
}
|
|
NSDictionary *dict = [TUITool jsonData2Dictionary:message.localCustomData];
|
|
if ([dict.allKeys containsObject:kKeyTranslationText]) {
|
|
return dict[kKeyTranslationText];
|
|
}
|
|
return nil;
|
|
}
|
|
|
|
+ (TUITranslationViewStatus)getTranslationStatus:(V2TIMMessage *)message {
|
|
BOOL hasRiskContent = message.hasRiskContent;
|
|
if (hasRiskContent){
|
|
return TUITranslationViewStatusSecurityStrike;
|
|
}
|
|
if (message.localCustomData.length == 0) {
|
|
return TUITranslationViewStatusUnknown;
|
|
}
|
|
NSDictionary *dict = [TUITool jsonData2Dictionary:message.localCustomData];
|
|
if ([dict.allKeys containsObject:kKeyTranslationViewStatus]) {
|
|
return [dict[kKeyTranslationViewStatus] integerValue];
|
|
}
|
|
return TUITranslationViewStatusUnknown;
|
|
}
|
|
|
|
@end
|