From 000b1d9d817dd435121beac4ac5abd6cd6ba0cc2 Mon Sep 17 00:00:00 2001 From: summeryxia Date: Thu, 27 Apr 2023 16:01:53 +0800 Subject: [PATCH] iOS TUITranslation upgrade version 7.2.4123 --- iOS/Podspec/TUITranslation.podspec | 56 +++ .../CommonModel/TUITranslationConfig.h | 31 ++ .../CommonModel/TUITranslationConfig.m | 91 +++++ .../TUITranslation.bundle/icon_copy@2x.png | Bin 0 -> 1583 bytes .../TUITranslation.bundle/icon_copy@3x.png | Bin 0 -> 1999 bytes .../TUITranslation.bundle/icon_forward@2x.png | Bin 0 -> 2696 bytes .../TUITranslation.bundle/icon_forward@3x.png | Bin 0 -> 4082 bytes .../TUITranslation.bundle/icon_hide@2x.png | Bin 0 -> 1169 bytes .../TUITranslation.bundle/icon_hide@3x.png | Bin 0 -> 1631 bytes .../icon_translate@2x.png | Bin 0 -> 562 bytes .../icon_translate@3x.png | Bin 0 -> 658 bytes .../translation_loading@3x.png | Bin 0 -> 1034 bytes .../translation_tips@3x.png | Bin 0 -> 530 bytes .../dark/manifest.plist | 28 ++ .../dark/resource/icon_copy@3x.png | Bin 0 -> 2125 bytes .../dark/resource/icon_forward@3x.png | Bin 0 -> 4399 bytes .../dark/resource/icon_hide@3x.png | Bin 0 -> 1514 bytes .../dark/resource/icon_translate@3x.png | Bin 0 -> 644 bytes .../dark/resource/translation_loading@3x.png | Bin 0 -> 1034 bytes .../dark/resource/translation_tips@3x.png | Bin 0 -> 1545 bytes .../light/manifest.plist | 28 ++ .../light/resource/icon_copy@3x.png | Bin 0 -> 1999 bytes .../light/resource/icon_forward@3x.png | Bin 0 -> 4082 bytes .../light/resource/icon_hide@3x.png | Bin 0 -> 1631 bytes .../light/resource/icon_translate@3x.png | Bin 0 -> 658 bytes .../icon_translate_minimalist@3x .png | Bin 0 -> 1113 bytes .../light/resource/translation_loading@3x.png | Bin 0 -> 1034 bytes .../light/resource/translation_tips@3x.png | Bin 0 -> 530 bytes .../lively/manifest.plist | 28 ++ .../lively/resource/icon_copy@3x.png | Bin 0 -> 1999 bytes .../lively/resource/icon_forward@3x.png | Bin 0 -> 4082 bytes .../lively/resource/icon_hide@3x.png | Bin 0 -> 1631 bytes .../lively/resource/icon_translate@3x.png | Bin 0 -> 658 bytes .../resource/translation_loading@3x.png | Bin 0 -> 1034 bytes .../lively/resource/translation_tips@3x.png | Bin 0 -> 530 bytes .../serious/manifest.plist | 28 ++ .../serious/resource/icon_copy@3x.png | Bin 0 -> 1999 bytes .../serious/resource/icon_forward@3x.png | Bin 0 -> 4082 bytes .../serious/resource/icon_hide@3x.png | Bin 0 -> 1631 bytes .../serious/resource/icon_translate@3x.png | Bin 0 -> 658 bytes .../resource/translation_loading@3x.png | Bin 0 -> 1034 bytes .../serious/resource/translation_tips@3x.png | Bin 0 -> 530 bytes .../TUITranslation/TUITranslation.podspec | 26 ++ .../DataProvider/TUITranslationDataProvider.h | 38 +++ .../DataProvider/TUITranslationDataProvider.m | 218 ++++++++++++ .../Service/TUITranslationExtensionObserver.h | 16 + .../Service/TUITranslationExtensionObserver.m | 233 +++++++++++++ .../UI/UI/TUITranslationLanguageController.h | 18 + .../UI/UI/TUITranslationLanguageController.m | 111 ++++++ .../TUITranslation/UI/UI/TUITranslationView.h | 21 ++ .../TUITranslation/UI/UI/TUITranslationView.m | 319 ++++++++++++++++++ 51 files changed, 1290 insertions(+) create mode 100644 iOS/Podspec/TUITranslation.podspec create mode 100644 iOS/TUIKit/TUITranslation/CommonModel/TUITranslationConfig.h create mode 100644 iOS/TUIKit/TUITranslation/CommonModel/TUITranslationConfig.m create mode 100644 iOS/TUIKit/TUITranslation/Resources/TUITranslation.bundle/icon_copy@2x.png create mode 100644 iOS/TUIKit/TUITranslation/Resources/TUITranslation.bundle/icon_copy@3x.png create mode 100644 iOS/TUIKit/TUITranslation/Resources/TUITranslation.bundle/icon_forward@2x.png create mode 100644 iOS/TUIKit/TUITranslation/Resources/TUITranslation.bundle/icon_forward@3x.png create mode 100644 iOS/TUIKit/TUITranslation/Resources/TUITranslation.bundle/icon_hide@2x.png create mode 100644 iOS/TUIKit/TUITranslation/Resources/TUITranslation.bundle/icon_hide@3x.png create mode 100644 iOS/TUIKit/TUITranslation/Resources/TUITranslation.bundle/icon_translate@2x.png create mode 100644 iOS/TUIKit/TUITranslation/Resources/TUITranslation.bundle/icon_translate@3x.png create mode 100644 iOS/TUIKit/TUITranslation/Resources/TUITranslation.bundle/translation_loading@3x.png create mode 100644 iOS/TUIKit/TUITranslation/Resources/TUITranslation.bundle/translation_tips@3x.png create mode 100644 iOS/TUIKit/TUITranslation/Resources/TUITranslationTheme.bundle/dark/manifest.plist create mode 100644 iOS/TUIKit/TUITranslation/Resources/TUITranslationTheme.bundle/dark/resource/icon_copy@3x.png create mode 100644 iOS/TUIKit/TUITranslation/Resources/TUITranslationTheme.bundle/dark/resource/icon_forward@3x.png create mode 100644 iOS/TUIKit/TUITranslation/Resources/TUITranslationTheme.bundle/dark/resource/icon_hide@3x.png create mode 100644 iOS/TUIKit/TUITranslation/Resources/TUITranslationTheme.bundle/dark/resource/icon_translate@3x.png create mode 100644 iOS/TUIKit/TUITranslation/Resources/TUITranslationTheme.bundle/dark/resource/translation_loading@3x.png create mode 100644 iOS/TUIKit/TUITranslation/Resources/TUITranslationTheme.bundle/dark/resource/translation_tips@3x.png create mode 100644 iOS/TUIKit/TUITranslation/Resources/TUITranslationTheme.bundle/light/manifest.plist create mode 100644 iOS/TUIKit/TUITranslation/Resources/TUITranslationTheme.bundle/light/resource/icon_copy@3x.png create mode 100644 iOS/TUIKit/TUITranslation/Resources/TUITranslationTheme.bundle/light/resource/icon_forward@3x.png create mode 100644 iOS/TUIKit/TUITranslation/Resources/TUITranslationTheme.bundle/light/resource/icon_hide@3x.png create mode 100644 iOS/TUIKit/TUITranslation/Resources/TUITranslationTheme.bundle/light/resource/icon_translate@3x.png create mode 100644 iOS/TUIKit/TUITranslation/Resources/TUITranslationTheme.bundle/light/resource/icon_translate_minimalist@3x .png create mode 100644 iOS/TUIKit/TUITranslation/Resources/TUITranslationTheme.bundle/light/resource/translation_loading@3x.png create mode 100644 iOS/TUIKit/TUITranslation/Resources/TUITranslationTheme.bundle/light/resource/translation_tips@3x.png create mode 100644 iOS/TUIKit/TUITranslation/Resources/TUITranslationTheme.bundle/lively/manifest.plist create mode 100644 iOS/TUIKit/TUITranslation/Resources/TUITranslationTheme.bundle/lively/resource/icon_copy@3x.png create mode 100644 iOS/TUIKit/TUITranslation/Resources/TUITranslationTheme.bundle/lively/resource/icon_forward@3x.png create mode 100644 iOS/TUIKit/TUITranslation/Resources/TUITranslationTheme.bundle/lively/resource/icon_hide@3x.png create mode 100644 iOS/TUIKit/TUITranslation/Resources/TUITranslationTheme.bundle/lively/resource/icon_translate@3x.png create mode 100644 iOS/TUIKit/TUITranslation/Resources/TUITranslationTheme.bundle/lively/resource/translation_loading@3x.png create mode 100644 iOS/TUIKit/TUITranslation/Resources/TUITranslationTheme.bundle/lively/resource/translation_tips@3x.png create mode 100644 iOS/TUIKit/TUITranslation/Resources/TUITranslationTheme.bundle/serious/manifest.plist create mode 100644 iOS/TUIKit/TUITranslation/Resources/TUITranslationTheme.bundle/serious/resource/icon_copy@3x.png create mode 100644 iOS/TUIKit/TUITranslation/Resources/TUITranslationTheme.bundle/serious/resource/icon_forward@3x.png create mode 100644 iOS/TUIKit/TUITranslation/Resources/TUITranslationTheme.bundle/serious/resource/icon_hide@3x.png create mode 100644 iOS/TUIKit/TUITranslation/Resources/TUITranslationTheme.bundle/serious/resource/icon_translate@3x.png create mode 100644 iOS/TUIKit/TUITranslation/Resources/TUITranslationTheme.bundle/serious/resource/translation_loading@3x.png create mode 100644 iOS/TUIKit/TUITranslation/Resources/TUITranslationTheme.bundle/serious/resource/translation_tips@3x.png create mode 100644 iOS/TUIKit/TUITranslation/TUITranslation.podspec create mode 100644 iOS/TUIKit/TUITranslation/UI/DataProvider/TUITranslationDataProvider.h create mode 100644 iOS/TUIKit/TUITranslation/UI/DataProvider/TUITranslationDataProvider.m create mode 100644 iOS/TUIKit/TUITranslation/UI/Service/TUITranslationExtensionObserver.h create mode 100644 iOS/TUIKit/TUITranslation/UI/Service/TUITranslationExtensionObserver.m create mode 100644 iOS/TUIKit/TUITranslation/UI/UI/TUITranslationLanguageController.h create mode 100644 iOS/TUIKit/TUITranslation/UI/UI/TUITranslationLanguageController.m create mode 100644 iOS/TUIKit/TUITranslation/UI/UI/TUITranslationView.h create mode 100644 iOS/TUIKit/TUITranslation/UI/UI/TUITranslationView.m diff --git a/iOS/Podspec/TUITranslation.podspec b/iOS/Podspec/TUITranslation.podspec new file mode 100644 index 00000000000..31dc4ec9fc3 --- /dev/null +++ b/iOS/Podspec/TUITranslation.podspec @@ -0,0 +1,56 @@ +Pod::Spec.new do |spec| + spec.name = 'TUITranslation' + spec.version = '7.2.4123' + spec.platform = :ios + spec.ios.deployment_target = '9.0' + spec.license = { :type => 'Proprietary', + :text => <<-LICENSE + copyright 2017 tencent Ltd. All rights reserved. + LICENSE + } + spec.homepage = 'https://cloud.tencent.com/document/product/269/3794' + spec.documentation_url = 'https://cloud.tencent.com/document/product/269/9147' + spec.authors = 'tencent video cloud' + spec.summary = 'TUITranslation' + spec.xcconfig = { 'VALID_ARCHS' => 'armv7 arm64 x86_64', } + + spec.requires_arc = true + + spec.source = { :http => 'https://im.sdk.cloud.tencent.cn/download/tuikit/7.2.4123/ios/TUITranslation.zip'} + + spec.subspec 'CommonModel' do |commonModel| + commonModel.source_files = '**/TUITranslation/CommonModel/*.{h,m,mm}' + commonModel.dependency 'TUICore','7.2.4123' + commonModel.dependency 'TIMCommon','7.2.4123' + commonModel.dependency 'TUIChat','7.2.4123' + end + + spec.subspec 'UI' do |commonUI| + commonUI.subspec 'DataProvider' do |dataProvider| + dataProvider.source_files = '**/TUITranslation/UI/DataProvider/*.{h,m,mm}' + dataProvider.dependency "TUITranslation/CommonModel" + end + commonUI.subspec 'UI' do |subUI| + subUI.source_files = '**/TUITranslation/UI/UI/*.{h,m,mm}' + subUI.dependency "TUITranslation/UI/DataProvider" + end + commonUI.subspec 'Service' do |service| + service.source_files = '**/TUITranslation/UI/Service/*.{h,m,mm}' + service.dependency "TUITranslation/UI/UI" + end + commonUI.resource = [ + '**/TUITranslation/Resources/*.bundle' + ] + end + + spec.pod_target_xcconfig = { + 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'arm64', + 'GENERATE_INFOPLIST_FILE' => 'YES' + } + spec.user_target_xcconfig = { + 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'arm64', + 'GENERATE_INFOPLIST_FILE' => 'YES' + } +end + +# pod trunk push TUITranslation.podspec --use-libraries --allow-warnings \ No newline at end of file diff --git a/iOS/TUIKit/TUITranslation/CommonModel/TUITranslationConfig.h b/iOS/TUIKit/TUITranslation/CommonModel/TUITranslationConfig.h new file mode 100644 index 00000000000..79f011fbeda --- /dev/null +++ b/iOS/TUIKit/TUITranslation/CommonModel/TUITranslationConfig.h @@ -0,0 +1,31 @@ +// +// TUITranslationConfig.h +// TUITranslation +// +// Created by xia on 2023/4/7. +// + +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface TUITranslationConfig : NSObject + ++ (TUITranslationConfig *)defaultConfig; + +/** + * 翻译目标语言码 + * Translation target language code. + */ +@property(nonatomic, copy) NSString *targetLanguageCode; + +/** + * 翻译目标语言名称。 + * Translation target language name. + */ +@property(nonatomic, copy, readonly) NSString *targetLanguageName; + +@end + +NS_ASSUME_NONNULL_END diff --git a/iOS/TUIKit/TUITranslation/CommonModel/TUITranslationConfig.m b/iOS/TUIKit/TUITranslation/CommonModel/TUITranslationConfig.m new file mode 100644 index 00000000000..77ddab5845d --- /dev/null +++ b/iOS/TUIKit/TUITranslation/CommonModel/TUITranslationConfig.m @@ -0,0 +1,91 @@ +// +// TUITranslationConfig.m +// TUITranslation +// +// Created by xia on 2023/4/7. +// + +#import "TUITranslationConfig.h" + +static NSString * const kTransaltionTargetLanguageCode = @"translation_target_language_code"; + +@interface TUITranslationConfig() +@property(nonatomic, copy, readwrite) NSString *targetLanguageName; +@end + +@implementation TUITranslationConfig + ++ (TUITranslationConfig *)defaultConfig { + static dispatch_once_t onceToken; + static TUITranslationConfig *config; + dispatch_once(&onceToken, ^{ + config = [[TUITranslationConfig alloc] init]; + }); + return config; +} + +- (id)init { + self = [super init]; + if (self) { + [self loadSavedLanguage]; + } + return self; +} + +- (void)setTargetLanguageCode:(NSString *)targetLanguageCode { + if (targetLanguageCode.length == 0 || ![targetLanguageCode isKindOfClass:NSString.class]) { + return; + } + if (_targetLanguageCode == targetLanguageCode) { + return; + } + _targetLanguageCode = targetLanguageCode; + _targetLanguageName = self.languageDict[self.targetLanguageCode]; + [[NSUserDefaults standardUserDefaults] setObject:targetLanguageCode forKey:kTransaltionTargetLanguageCode]; + [[NSUserDefaults standardUserDefaults] synchronize]; +} + +- (void)loadSavedLanguage { + NSString *lang = [[NSUserDefaults standardUserDefaults] stringForKey:kTransaltionTargetLanguageCode]; + if (lang.length == 0) { + [self setTargetLanguageCode:[self defalutTargetLanguageCode]]; + self.targetLanguageName = self.languageDict[self.targetLanguageCode]; + } else { + self.targetLanguageCode = lang; + } +} + +- (NSString *)defalutTargetLanguageCode { + NSString *target = nil; + NSString *currentAppLanguage = [TUIGlobalization getPreferredLanguage]; + if ([currentAppLanguage isEqualToString:@"zh-Hans"] || [currentAppLanguage isEqualToString:@"zh-Hant"]) { + target = @"zh"; + } else { + target = @"en"; + } + return target; +} + +- (NSDictionary *)languageDict { + return @{ + @"zh": @"简体中文", + @"zh-TW": @"繁體中文", + @"en": @"English", + @"ja": @"日本語", + @"ko": @"한국어", + @"fr": @"Français", + @"es": @"Español", + @"it": @"Italiano", + @"de": @"Deutsch", + @"tr": @"Türkçe", + @"ru": @"Русский", + @"pt": @"Português", + @"vi": @"Tiếng Việt", + @"id": @"Bahasa Indonesia", + @"th": @"ภาษาไทย", + @"ms": @"Bahasa Melayu", + @"hi": @"हिन्दी" + }; +} + +@end diff --git a/iOS/TUIKit/TUITranslation/Resources/TUITranslation.bundle/icon_copy@2x.png b/iOS/TUIKit/TUITranslation/Resources/TUITranslation.bundle/icon_copy@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..27913979855bdbc0d25ccbf9d8507234993b5c88 GIT binary patch literal 1583 zcmY*ZdpJ~S82`ph3=)>dEyi(1E^TJUrCQTam>9}shSiiPG{$|#%(&BHhbAT2-B=k? zQl#9HhV*!nTdXaMtkepntsW_qMAHq=5ow#af8l z{tz#wfa$uI9LR|v_#fc}un2JxTxk`c#E}sg!4mjGaS`E>d~%!(ysRK2SV|LNXjvi% zvw@ke9*_fv$AY#INCXmWs{la|g?A)~%%D21mLoeGI9MRyl8MCF*jPfWC4s|Z6V0uy zt%)QHqJ@PSqA=sfM+*Go%p&>t6_bB`s4RXUFN7-y;Y31GU;hA3w7>?2rH$6s$~^@k zL0>yX@>j<~1|&*Ph~@+mam^bkrAS$_J1>NVbe8(tnp2jQ|KnEsP>9mz|GCV{q{}Qa zs;vTrxc1p>6}0_EZp`^I1&R`>7S?k#tODHuyX8%@mnzHg77t&)uiKZL zqKjvDsSY)4IjwNX?D|f$H(I&5#JeZ2@mvrzsr`JO@*uM!cz81A8l(ImK4C{IdQ_Fi zom*T?5)vlUC#<}b=i$;yp{|j5_@$t~^NdR=nKo2L%JUm@xY~&-PD)H1ZdK_Sbm{0y z%Dl(IZ!IDXMM5+mjSJ}=M=$BQdgPR_?~cATo~}Sw9YxM3)lQJo6QHK{m+x*Pqh@vIG_rkeS%*y*sjf5XKi8HZ>mnXT_i z^aA1DK8xd6N9C;{dkGVqk0+j%ZRXSk_;p7srK_F5(*unYys^evPz}~GCRXds;QNHn zK@?n|&}B>ne@`K3E-Wk@IzJ~rtW_uubJupAzvqc16-<$4aOb-lY4g`bKRxWdTfPv~ zU212Y`b1c(i=z*O>B++PGeRtT@1H0x-98n3OHDcI`jC3Jk(PF0X_IAjQRyuMNjP)6 z>SHQ*2)m`C`QDu+gEUmVLvr1CDop3yY!uGU2x7Ppy*xuLyOGk?b2ST6)@QTX+p`?U z@uJ%pQ{0s7KXfm-`kt5IC$qWa8zt`V-ZjOepx~))iW%C1?$K*I<%*TO_+)Hjm|= zN`q=<2Mx1`Ei{!@!9G97-f@+o#cc-mXNlA*QFoGnt{9&WiLmd`rTYkZFQZLs^H1mB z$1f;}Mia(WZ$4G4NF*7O+Psqb`oVyX sCDne#7gs8?-l=fy+BdX_HQaw`W+%iCZ|T>)CjAXM?{=eB+8<8)2ODo-0ssI2 literal 0 HcmV?d00001 diff --git a/iOS/TUIKit/TUITranslation/Resources/TUITranslation.bundle/icon_copy@3x.png b/iOS/TUIKit/TUITranslation/Resources/TUITranslation.bundle/icon_copy@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..f3d51c5242d7925f0d2d3a8d5016b1ebdb403a80 GIT binary patch literal 1999 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 Zg?$`Z2>@6_0RSu=04{iB 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 literal 0 HcmV?d00001 diff --git a/iOS/TUIKit/TUITranslation/Resources/TUITranslation.bundle/icon_hide@3x.png b/iOS/TUIKit/TUITranslation/Resources/TUITranslation.bundle/icon_hide@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..0566f314fd2948240f0fe13ef9f1671a2f0c14e6 GIT binary patch literal 1631 zcmV-l2B7(gP)bojbl0S67r(S!()uETDS!b2AdxVtJqbyR`w z!po)r?nDvOkFm{Fg>MJ3F(U-+c4}7dL=Jxh4(Z+yqYs-re1e4h#%Lr>CcL6PzKE zfjc@nqHS$$u`oJ1nl<1BCh~ga$ll%_!NPQTd6{^)w6sKHV`Iwv5`zCRf}4SUCPx@f z2`npHz|BA>R99D*@>w>37n#Vrh~VN#UteF$(hR63IelnoNKTRv{Jp)s!B8j^dxuIR zL~J%&1nFUpBkU9u6a=rXu7ZI;AWRm@W;CO4JU&qzASSkGDsWbNd%F^xj*pLNaBz^0 zj*iHTL_-7$3kw&~2xx;qgzh23(Bj7>T>SJ6z?14R!wrDnU7$2%3R?W2M2`Sm)Fq7I zTU%S3F;lLPOv>l;MbOHpPN&mTQc@C2YieqWf$&nMCQj$)oR7ujIKH{LNf#Fvl&&xb z*bzLHm6hEHr*gM)+qjg5_1#lJN;O9@|5QLz{fhc(B%Vd&P@ z*4MD`ABZ~no@Z|>!Ozdn!$>+nm`9hL$MqN>oXtT7#qgN%`>U#|Xn%iyJykwkXjs=? zTU+}pqCX=PE1y{jzO}Vw$NL=mre4Y!j>r}Tlj zB9qtG*Y9L!Aw$bqU}a^cIaT?VmX>bRbJ&1!x>r|MXF2{Av=LyuUIcUR;JXvP94` z>+kHcii(Q#x`|H@n1y$Qap5i*meUxB!BQ!CcUD?jO5@|>-GfaY}=7cC$kzmyD024{=ON*BDWtV|+zD zVsJiTu>#!6{dfWz>)|`Rcv2&;7h^_iyr}Brk zdvVcn+8O*8GNIes+jR!MFE|-Efe}Mg6Bvxm=`LBZ!bVOsxaCDfViud2n2;?Oli69F z;*(>um^0)$+hN`J6nBnNif3-rIr!BX8G|s8IIU0>Hwbk)4r;#BN)jqGP7xdE^} z^q>)5pnMs;p<<-}j_&pk@*E3rht=ThD#OCv09HMOGkkIa@V|tmp6XdWN$f{DQRW3& zpS$-fj*E9VthD&{_Vy0O_z##oe`8~%s*vf^P?pi{oEc?mIa5;LJ8k`*T~6mKx^o%d1} z$O4P=(0MA~WCb)U9dMlICE_;m9}(+OcWJ=@&eT=Ms9hW@k83aNpsC>YJPk92jwa}QXS0G~nlSHN;3cqy;E d^2#fh^#u^SaKc|~vitx5002ovPDHLkV1m!p1Q!4R literal 0 HcmV?d00001 diff --git a/iOS/TUIKit/TUITranslation/Resources/TUITranslation.bundle/icon_translate@2x.png b/iOS/TUIKit/TUITranslation/Resources/TUITranslation.bundle/icon_translate@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..0ddaef6d92a6d396dc039eaf562a0c7993bb2a19 GIT binary patch literal 562 zcmV-20?qx2P){>2&(-{I!&-R3f%m zEO@D+C@MV0xY+f2r635ne>$BCk25ZIxm>tyx7+m*!%R7jL*wz7mof}PvTeK2SfgV5 z{hnJ$K@ObH=R#wfx@ul}A4>9gJh;VjV#bgJtyYV2#Z1;b0TLhyVr{ux=8n;}^Jj59 z9;wsma33)?pU-*LWMam%Qb++T;=l|U-i@As+O?Q&lf z+AiE zsz6C>y+S;+cDY0@Zq@nJBHs`Tzg`07*qoM6N<$f^VPv AQ~&?~ literal 0 HcmV?d00001 diff --git a/iOS/TUIKit/TUITranslation/Resources/TUITranslation.bundle/icon_translate@3x.png b/iOS/TUIKit/TUITranslation/Resources/TUITranslation.bundle/icon_translate@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..2ae4e9ba84bac827ba807af4a8c288f24af180fb GIT binary patch literal 658 zcmV;D0&V??P)ltN)K4zPQxGpHo`Rg%&r1-KlN0YcUDZ=fb#F~i@66n7{Uw^A%Bep0 z%)LDYN`Ypx`So}i6A#7(N`Z&SZ(_s;y#Ya_FT91wPs)(pZbxa-YPGbV2fO-0sL8yz zUaz#-Y{a_JXi&9UB^OwVTr3u}-EPJDcs$a4J|`Dg+VyZaJgx8dJGsD4Bz6#XRavc8 zsj&AO^+wIB1wy+Y3z>z>?x7&^0FPBS73M-Lvw_wwH zy-uZ4iE6c4bS-HBeP%hun|jMv%H?vjs}L$dZT9s~bINdt&o z$1@s@MChnM*l;)$YwRTI)dqGu`6>`VluH2p8@r-W2e7Pdb6~V2w;6K_;YaUx9_=9%0y~ZXAMLb>QSoo%2qoQ`9sM1_Kd35=;^%n`eo&NYt0w zdO?&FiPlR^R~%(<5E<;M18J)6PMmbjnTfSX^pCw>PkYUjt~TuV`#*ogAMC2b>vZjO zIwCo7k`^~z0eV|`NSqh3Md~K@G=7r?;UTOqgmjGqLPefx=N&L6oJAsCaqHkrs7YTi s+BJ;{JuiY?eIbbS1&EvwA5!@*KX>cdOIesDMF0Q*07*qoM6N<$g6@?bl>h($ literal 0 HcmV?d00001 diff --git a/iOS/TUIKit/TUITranslation/Resources/TUITranslation.bundle/translation_loading@3x.png b/iOS/TUIKit/TUITranslation/Resources/TUITranslation.bundle/translation_loading@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..761f4341932b16576ebf5454525e6d07542109e7 GIT binary patch literal 1034 zcmV+l1oiugP))(Xt##~!pBaxVYh}IKpYLxK95cVK*ObOKG?sW;;is!TTzDbA|2|eNI6%P>6<=3M z_c*86m6T?F=U5%0ARZhsbBCW9f(3tJPk%!}oQPhi=>rZ~HCJPeorQh9f&w@Zt%1!! z+Vh436riwZ>9yRw9P_Y9ho+R(fD5ep<_;^NM%PnlzqSDE<;oDNxl;M8tKF}vjUlj# z7O}Jjr=Va8gHlGI%->e8jP=SVeq$RoTPfa}4s0L9*O>iwCo>FYG{NzodaZyLkieiwhId-i$0B|T|r z-0X!|?xw^a?1bg$f2;Uw*HKDpMvFIXAdl$qr9hg)1`iG6@!}Dqsl*Ig(P*R+X!sQL zk^g&@W)2f3HhSPC^59`Lj~Le^rbi^=BI`yO?r{hf`kFjCk1ZbTbC2`37nn93ys~*iK=6Q@FJ6Dh4Db@^-&|Sy#!F44LX_;#<`^CYXj$hj$v%S z^Gt&;(VvK(XeXhb>5DTSkH5Au?rLI;NXW~idY7fOhQ#7Vl4QjtkNKb_y~;Uz?sL(%S)(3%ECQ>OeMGHZw8fmncClLBNgYZhl4 zVc1`uL z2FFN#K^*p{r!`{@w&5_9u z6LU)D+kH7l1q%7fwlT6s7y~V9Zjws26qI32^HkPDXKqpF*2SWdLVAcF!5sXonB;v; zZ+j0pXC-S<4TG~C+n9b<#}v}bEb}@Fz?|*a#`Lo~Vh!k^s&IsJ(c(G#{myVV_x#Sn zz35pq61xE!zg#*a=b~laawBL}DpXN^dDxrHzmJoLe{ZsJLbjFdF8}}l07*qoM6N<$ Ef@8hj5C8xG literal 0 HcmV?d00001 diff --git a/iOS/TUIKit/TUITranslation/Resources/TUITranslation.bundle/translation_tips@3x.png b/iOS/TUIKit/TUITranslation/Resources/TUITranslation.bundle/translation_tips@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..3d6af40fa20bef7448a9beb497a8ae63cc86f71c GIT binary patch literal 530 zcmV+t0`2{YP)YJ@g;Bj^UT!E*y@f@%WXpf)hBVuySvh!^CZ^Znom+)qTk zdVsiKnv>?Jxif8U9d8X^nm5g-X(tV#k(w@o3k)Yzl++Xj!-{VXyj&HL)RfB19~B&i zv+NS0;QwANMl4E@XB1l{$aWC31sC^Vs?8rtH79o5S!_hOMplvrt=4d0=w z*JKjoR!$MJdVB}5ki6^$h~9Gx(Q5ADx+;0_jO&Yp8q%#8mP*`__%UECdXZHdE-@A< zhJ0XW1^)elcb6~&a)^z2y`Ag=kp&1+h>dtV@JW&-K}xY8IoJEnB}gsS%c+1)XOCbC zG4u-FLo(aYNE~y=oI6*8593cvkn=Ro|mQNwnunM6t>#Db4nrZ@nD(mp1p^%p Uf3w(_*Z=?k07*qoM6N<$f`c8{MF0Q* literal 0 HcmV?d00001 diff --git a/iOS/TUIKit/TUITranslation/Resources/TUITranslationTheme.bundle/dark/manifest.plist b/iOS/TUIKit/TUITranslation/Resources/TUITranslationTheme.bundle/dark/manifest.plist new file mode 100644 index 00000000000..9baea4552f5 --- /dev/null +++ b/iOS/TUIKit/TUITranslation/Resources/TUITranslationTheme.bundle/dark/manifest.plist @@ -0,0 +1,28 @@ + + + + + id + dark + name + 黑夜 + name_en + Dark + translation_view_bg_color + #1F1F1F + translation_view_text_color + #D9D9D9 + translation_view_tips_color + #D9D9D9 + translation_view_icon_loading_img + translation_loading.png + translation_view_icon_tips_img + translation_tips.png + translation_view_pop_menu_copy_img + icon_copy.png + translation_view_pop_menu_hide_img + icon_hide.png + translation_view_pop_menu_forward_img + icon_forward.png + + diff --git a/iOS/TUIKit/TUITranslation/Resources/TUITranslationTheme.bundle/dark/resource/icon_copy@3x.png b/iOS/TUIKit/TUITranslation/Resources/TUITranslationTheme.bundle/dark/resource/icon_copy@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..a8083af179575d223bf70543ced6cd979e545a6b GIT binary patch literal 2125 zcmY*aeLRzEAHVL6Vd!OEl621UPPn~PSex<^Yiq1Uc`2E-yezY48`~+BJkt`TR34eo z$!jO2Qlw}-ouXIN6ZVlxM+jwBh*sy^s~+chuKV-5f8XnSe}CWK^}GJLv*^J=hFEhf z0Kjl9Ie>v=A`&EB4Duc?#daY{E6$hZ3&6!(eKk`X+2dJc1`U9nwg99{0GL6j^dSIJ zTmcx40f0~dzye-T<9dyegdM(iJB2tpnJnFEa*f&c|tG>aLK{SOTa z0BHiy`k{$LvSyKy(A0d-=u+r!$5Pa+npldS#UxGHn#`IpBY`L9m^TfpKc@PrA;T)f7Y8JnCUBw1Q&8qKcn z=M*Mv|GN`c@MA1wKv?qyc5`usXT6b9qJ|}e@DtcbXN|v)8}Xa+|F|E0h_I&l{~YG~ zq~BO%R39u6p1n37?84|i9RRc+uMO}Gjn{q`MGYAVG)|4RgPy1;;q+>T18Pb5))ak4 z*E?+3RP>hW5tpT5y(ZlgKR-V|gD#c5Z>)~la7DlKhK;pEGOtOZl}Y5{raogrhOJX; zTY@t#xaSG(vf8`{R}MZDM|ad6c``Y9m0LJ)xuJ?mt}RmR;BxPtDoIN(S0*}9YEcf< zTJk_&Utip~Sgiv>UN^hhThSL-FRm*fTkk27$(H)t#V#w~U~qDMnZcVzrWt%mF)DhN z7*@M)^_tXMXQ6YLEp^wgudL~aS8H+E`HBfWY&a@sknjDDgu`Mwi{D14d#vU+p7(4@ z^kmtmGij(3Ss62LUsvpdIs=~mDw44o4r|fSi=Lii^1!@%Wg8t&eDda**k(@VMfNS7 z7@lXMs~jFaYak=~k*SqWcWXbGoK`B^p|erGczMio{D;_!pBDUk$ncVb#Q2ioCjAe) zZEwV>NKaaDV>gwt1}U7XqtH;vEi1j@thQqZN#&S+db1rfWL))GtyZU%F{;(sLzLUV zPp6+Xv9k$Sr8U;p(&M{eo-WSmDD1SP;s16ZhpFs8HszS2o#fK z0ks#d{hFcXNa`$dCl|ZQjBwKZGaVfrQ{ao~)TrqAzIt%=1}9^>C1!@t=RX0; zTzvbZ7!s@#pOlzL@n5A{E@`^M<|ZYrUt-hloL)Yu`-hib!)AM9v*3vp@-M4jYM~Vq zJv}|^z0L%GsnTyc?A;LBwID?+r?^8BrucBs#DIT1V>Q*dJ6r2TOpL2- zkUSVRa>}9mi@#(IhM8F@OUr3DO_)BJ88EK! z_41Tnw&z6TV(tAxr+UYEdGbQK?T!)YqqYv8W@sfpi{3YnCn+i~8*aZ%*`7@=KP|QD zcd`kS{0s?fovF(UXFbXssAqic$9Ahay>H zAkNkF^}B&{F&BL@Gt6(rIy*u4-CLd&koSMQdv`y`xpTm4vZUf}OG`?T4|%+>px{+t zOukGn^|#hEYm&j6%&Aw8L=Af$41OqKB~0BZcruTgot^DoW@FM|rPux5Eq%~5XRy4t6`eYAlx^I7=yqB^bRFX8IF2pe zr_SXp-Sl{;_QM(mb|J~zd)lN91xtG^%$A3>o~*=|b z=+JI`xb?Ff+r97zjKP@)&sAjmKiY+HDv$MW{^)w_MpB*K3!6W=Oo!O+ir?jz;(aVE z_y3xEM(XCmmeC^K<@XejE{i>vM$)7zg+LH!>~#fHfQsqqY4!N{_^N_m&M}|%q(dlu z1{<6iA*LPnII;Iw%j3s~Kc!WxMwAveFOt=j6wHQmu$%o6H6bzZYEiPam_|)i?l?9lU%zdIN-crOvYb;!Ec2C literal 0 HcmV?d00001 diff --git a/iOS/TUIKit/TUITranslation/Resources/TUITranslationTheme.bundle/dark/resource/icon_forward@3x.png b/iOS/TUIKit/TUITranslation/Resources/TUITranslationTheme.bundle/dark/resource/icon_forward@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..5d33d3fa25e11c1bc0859d0fc1c2cf1b14e6826a GIT binary patch literal 4399 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 Sn7+7Y0CaB{YSn8v#{LfnjlO{Z literal 0 HcmV?d00001 diff --git a/iOS/TUIKit/TUITranslation/Resources/TUITranslationTheme.bundle/dark/resource/icon_hide@3x.png b/iOS/TUIKit/TUITranslation/Resources/TUITranslationTheme.bundle/dark/resource/icon_hide@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..18bf7ead225e7c84f1e12b73309f7fc24561d147 GIT binary patch literal 1514 zcmVRwwx)NU^pt0-cj7%RaC z(MG{Sv*lu8O7XehZ#)wwa z*LsO;1@7$Zl!=LnOn7~Loq2|C-hykiySsZcl}eRmSJ#G)#bRNM-woq8L1$-YrM4rF0NTlTzP`Sm2@UYAt*!Hp zj*f_m7Pcfyt1HD2R^S5Z&SCq{hlYky5}>qA7FwzW1y2&dc*YiW0;kT-&a&VXCp*ps z3_TSx6iOjTpdvO=hD0Vg zoNwaO_Q+08PrsmB|ApI6{LR_Br>7_5g*`kxWa99i0CZmL#OG$ujp=yLe43h?QW&TI zpx{3c{y_MzO7@HBi<9mA+}s=+vw{QhTK}+6l1 zxw(1z?(XhaE-Q`a1R|J|te%@q#kBzLfaNf!<75R>#s3<`570WmbP=DQpGWP+OEJLNssjT938(a` z%yHaKiiT3-Ukj&4-9FiC67){PU48W;1VSbUp|^Mrco2F z-2^rMH6Jj=ts-t21vSQzPfRp~-VjIdS>6{ec4|S7_&Wuy9~T*qkY#KDQ7iOm_)Y9H*}DMJPRO}y#Q&d2r&uCoKfA&Pje!1U65nJit$o?^|b zf&}8Z+3l+*m#pki)yy1TNkyrdW{PUi%`w~`-t+Hgm0 z-B2BHN_F>J{;^v;pYG&qQ<2u~@>f?^7b`0(UkcfXZ~`wXbfF4j2S$NM&8MC`ojEDB zcyxnDI5=E*q=V1Aeo$aKR9qvzsqY$b${Lyq0v!4T=s%4gzD^>PT7LK3Ov>>hD*~GG z3ck0um%TTqp(+NN(gi2585+Z4&HTRX$Fx;WW1Od*c%ID)%+=QZ{{A24Jj&W+xyjC) zSw&!e@w6V&typNv4crNss<`fLmZ__^D)0t%5^0fL8t)&Zs;a80>i?+!0Jw^6Ye*d- Q>Hq)$07*qoM6N<$f;*wyivR!s literal 0 HcmV?d00001 diff --git a/iOS/TUIKit/TUITranslation/Resources/TUITranslationTheme.bundle/dark/resource/icon_translate@3x.png b/iOS/TUIKit/TUITranslation/Resources/TUITranslationTheme.bundle/dark/resource/icon_translate@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..c5dd5382cfcfcd74156d1d0bef582e6a9e8ac3b3 GIT binary patch literal 644 zcmV-~0(upzbyb_{Dg9&gHPc^}nqfwj zQ+@jMy*&~tf&G5}o2KcU1dt@jJfRZU?RF^%;)iNL6j>E&A+kXqWHy^onJg9y?dQ?1 zRUyvFP_)}^>h*fr`SEz9^Z86Zh!i;*jUFPq-7YPcOY%XaT_H?8Z#J9cgE)~GLD*Gg zI2@7>B1JNn%OyJw1_Sazlt_#qTlLY5PksslS`+wJ!89%~mb&M2O_n+ND5ifsN#tVLpOsihYz%p%qD z3+VQ1LJ;k$1GS?%Iwt8Fl6$}WXDt$Qa5|l8uN9@M4gG%q?T`4QU3FACU6H6rPKYo~ zR{)W!@DNyuw8iB+We^|2R)v_ZCLmOJ!#8xm6!BJ(Qi*f2DkReWwi#<>luhhP2`U0000)(Xt##~!pBaxVYh}IKpYLxK95cVK*ObOKG?sW;;is!TTzDbA|2|eNI6%P>6<=3M z_c*86m6T?F=U5%0ARZhsbBCW9f(3tJPk%!}oQPhi=>rZ~HCJPeorQh9f&w@Zt%1!! z+Vh436riwZ>9yRw9P_Y9ho+R(fD5ep<_;^NM%PnlzqSDE<;oDNxl;M8tKF}vjUlj# z7O}Jjr=Va8gHlGI%->e8jP=SVeq$RoTPfa}4s0L9*O>iwCo>FYG{NzodaZyLkieiwhId-i$0B|T|r z-0X!|?xw^a?1bg$f2;Uw*HKDpMvFIXAdl$qr9hg)1`iG6@!}Dqsl*Ig(P*R+X!sQL zk^g&@W)2f3HhSPC^59`Lj~Le^rbi^=BI`yO?r{hf`kFjCk1ZbTbC2`37nn93ys~*iK=6Q@FJ6Dh4Db@^-&|Sy#!F44LX_;#<`^CYXj$hj$v%S z^Gt&;(VvK(XeXhb>5DTSkH5Au?rLI;NXW~idY7fOhQ#7Vl4QjtkNKb_y~;Uz?sL(%S)(3%ECQ>OeMGHZw8fmncClLBNgYZhl4 zVc1`uL z2FFN#K^*p{r!`{@w&5_9u z6LU)D+kH7l1q%7fwlT6s7y~V9Zjws26qI32^HkPDXKqpF*2SWdLVAcF!5sXonB;v; zZ+j0pXC-S<4TG~C+n9b<#}v}bEb}@Fz?|*a#`Lo~Vh!k^s&IsJ(c(G#{myVV_x#Sn zz35pq61xE!zg#*a=b~laawBL}DpXN^dDxrHzmJoLe{ZsJLbjFdF8}}l07*qoM6N<$ Ef@8hj5C8xG literal 0 HcmV?d00001 diff --git a/iOS/TUIKit/TUITranslation/Resources/TUITranslationTheme.bundle/dark/resource/translation_tips@3x.png b/iOS/TUIKit/TUITranslation/Resources/TUITranslationTheme.bundle/dark/resource/translation_tips@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..f488f313c551c89b65759138f1c857d2e336858b GIT binary patch literal 1545 zcmV+k2KM=hP)SFTy-_R}XGto({hb4{9yaLnt*5F=WW$Ce*^&$~91iX0=jZCy)>d`)T%}TRYqgpy86g#M zN>KCl^|b*>f8kIAKep!EUA)J|dvCCHug2{d~|XaWvl2T>7E5mx`D*0YR0vgufV2F;CxS8T!E$e1d^v!I52q@TpD3ueCNID zT&yJy4f5|&Y-v6Xb+2n#D-MnGFDN~mQWAKttTC*+Ze<>a4`|_o{*!XjIy^kQT6S`& zxDpfw>lmT1I9XO$EKRDacf*$QQbqsX($uz49FwSItcN2FRDRc5bk17xhA*vMnZtBY!a!SI2H=ne3bm7+cmWA{6bi-^Q$JFI8`X* z9qs zB(OAG-&rSgCQ;a`a=w$YU5|TDK>Q^ ze7kTJsY@e>xJJc99*58PjCNdS`WPyTJ;Ou3G9gV-tw_XSSsZ&dD~+fwm=-z?xEobo zmZXs?^SDUj#^dq-tIk7e3!5tm38MK1ePJgVl18eLhItW0+-Ti3VdYWU-rinwx&v_) z2}$!XAx^7Q4k|Cp(ufIh7rNsubme7T8lgB>qG6--yf!5-57LBF0>lgr6Y_E*jf^Pn zM$8aNUXG-B1tJ^yu9zc~JhnRWB8_k!87si9n8la(K}Up=r%l?@6rA>CIbxnbk*7;W zq%m9RTRS^DE?#RTk$@PLmlbJ*j~y*0C*(1Gi3cO{vLwxaChI?}`62NUNnVzu5&SP+ z+uTw+j>JnSd0CT2@G#rqb~1J(p>ZR9^mJ&Iwpo-0T+{+;d@xnp3x;l~!o;)>X#e*U_zaXp9*wa1TnL0Znv#Ca8CW&7a zvL(B-tJ%|ia(sL|skY6{bHKNLU8b2dn)Fa8oJ}8?>sAUocC5%C`NDol0_0-x>m``*@I|Jbfu(IlbA&7_4@g; z^DCb@pi<1S{jQV`7u{_uSBF?Bj!Bk752RfAop;ac+S6;Faxsl_c?l^G=Q_hJv>p$# zilT;Y6&l_nD!M(LYqg)NLSDDX@;FqD_o#b);FWIBo^7E$Tc~;ZYR*?T$a_Mqt)xb( z7hy?_ky;+ek${9=lq&CYTRC!oa~8rbhZcGLxWQo1;fN*45p0XIS*bg6U=fkU5!H{! ze9x9_vv3Y;7>tPXi7<&aZkU&S+uz^sM2WI#jEW;!S&>y?T$qn>aXwQ5Il<1BWQk3f vPi*3*K`+ax{Eom=i4Simhg!DQk(l`fC>p%v9{ggd00000NkvXXu0mjfxo60V literal 0 HcmV?d00001 diff --git a/iOS/TUIKit/TUITranslation/Resources/TUITranslationTheme.bundle/light/manifest.plist b/iOS/TUIKit/TUITranslation/Resources/TUITranslationTheme.bundle/light/manifest.plist new file mode 100644 index 00000000000..a63d449f296 --- /dev/null +++ b/iOS/TUIKit/TUITranslation/Resources/TUITranslationTheme.bundle/light/manifest.plist @@ -0,0 +1,28 @@ + + + + + id + light + name + 轻量 + name_en + Light + translation_view_bg_color + #F2F7FF + translation_view_text_color + #000000 + translation_view_tips_color + #000000 + translation_view_icon_loading_img + translation_loading.png + translation_view_icon_tips_img + translation_tips.png + translation_view_pop_menu_copy_img + icon_copy.png + translation_view_pop_menu_hide_img + icon_hide.png + translation_view_pop_menu_forward_img + icon_forward.png + + diff --git a/iOS/TUIKit/TUITranslation/Resources/TUITranslationTheme.bundle/light/resource/icon_copy@3x.png b/iOS/TUIKit/TUITranslation/Resources/TUITranslationTheme.bundle/light/resource/icon_copy@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..f3d51c5242d7925f0d2d3a8d5016b1ebdb403a80 GIT binary patch literal 1999 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 literal 0 HcmV?d00001 diff --git a/iOS/TUIKit/TUITranslation/Resources/TUITranslationTheme.bundle/light/resource/icon_translate@3x.png b/iOS/TUIKit/TUITranslation/Resources/TUITranslationTheme.bundle/light/resource/icon_translate@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..2ae4e9ba84bac827ba807af4a8c288f24af180fb GIT binary patch literal 658 zcmV;D0&V??P)ltN)K4zPQxGpHo`Rg%&r1-KlN0YcUDZ=fb#F~i@66n7{Uw^A%Bep0 z%)LDYN`Ypx`So}i6A#7(N`Z&SZ(_s;y#Ya_FT91wPs)(pZbxa-YPGbV2fO-0sL8yz zUaz#-Y{a_JXi&9UB^OwVTr3u}-EPJDcs$a4J|`Dg+VyZaJgx8dJGsD4Bz6#XRavc8 zsj&AO^+wIB1wy+Y3z>z>?x7&^0FPBS73M-Lvw_wwH zy-uZ4iE6c4bS-HBeP%hun|jMv%H?vjs}L$dZT9s~bINdt&o z$1@s@MChnM*l;)$YwRTI)dqGu`6>`VluH2p8@r-W2e7Pdb6~V2w;6K_;YaUx9_=9%0y~ZXAMLb>QSoo%2qoQ`9sM1_Kd35=;^%n`eo&NYt0w zdO?&FiPlR^R~%(<5E<;M18J)6PMmbjnTfSX^pCw>PkYUjt~TuV`#*ogAMC2b>vZjO zIwCo7k`^~z0eV|`NSqh3Md~K@G=7r?;UTOqgmjGqLPefx=N&L6oJAsCaqHkrs7YTi s+BJ;{JuiY?eIbbS1&EvwA5!@*KX>cdOIesDMF0Q*07*qoM6N<$g6@?bl>h($ literal 0 HcmV?d00001 diff --git a/iOS/TUIKit/TUITranslation/Resources/TUITranslationTheme.bundle/light/resource/icon_translate_minimalist@3x .png b/iOS/TUIKit/TUITranslation/Resources/TUITranslationTheme.bundle/light/resource/icon_translate_minimalist@3x .png new file mode 100644 index 0000000000000000000000000000000000000000..8b0a6c336766980dca03cab8d34a4df5dfe21f91 GIT binary patch literal 1113 zcmV-f1g86mP)osh-aY#6?)%>F-@V5uB*ju}SQ3%AtXW9;FNp#Lo0&t?uN;?e{r`cvG0q3UpkE9;n=D&#R zZKTPCDLy8?#wcOL0H#wFIxt8Rp?t#IHr!jK?lh-XvQuP~T}{Z@fK^12qi!coiH8w7-m#DuzUn&B>!IpxgNqb)^_X9 zLMQ=p_Vgw#*^J;Px&js-9y!Md(U_Ralgc;c&N=3;DD6di0)GKYY zXJBF3)$BLAUNeH&dS!AwOaTr2NLzqx|5q<^bDF(CgdJuPRTeePNCzze-qPVku5rY$ zON-8q)|BU3J|LG4TK!sBT4>FHTp~1DjY9~v%?zg+G+K?z zU*a^fWnCUZV0x-64}Ju^ofVV?Khl5 znoU^$2?ERO*yvEYsvJ7~l2;INQnTu(=7=!&2C6iGW2Gy~m8VW=AeY!cF2O^==#%*S z92*N?2!v^R;--OM0twu$)v2gK>H%9<^U?%&jvDxrH1FJPT=JKIQpm zd@07=c7Hgn?9H-1-EO86mn-yGd=)4ugz1#Ixy&D;s{}T&IipcAl^KcwVY&q_%;xtj f`#`6hk_`U)(Xt##~!pBaxVYh}IKpYLxK95cVK*ObOKG?sW;;is!TTzDbA|2|eNI6%P>6<=3M z_c*86m6T?F=U5%0ARZhsbBCW9f(3tJPk%!}oQPhi=>rZ~HCJPeorQh9f&w@Zt%1!! z+Vh436riwZ>9yRw9P_Y9ho+R(fD5ep<_;^NM%PnlzqSDE<;oDNxl;M8tKF}vjUlj# z7O}Jjr=Va8gHlGI%->e8jP=SVeq$RoTPfa}4s0L9*O>iwCo>FYG{NzodaZyLkieiwhId-i$0B|T|r z-0X!|?xw^a?1bg$f2;Uw*HKDpMvFIXAdl$qr9hg)1`iG6@!}Dqsl*Ig(P*R+X!sQL zk^g&@W)2f3HhSPC^59`Lj~Le^rbi^=BI`yO?r{hf`kFjCk1ZbTbC2`37nn93ys~*iK=6Q@FJ6Dh4Db@^-&|Sy#!F44LX_;#<`^CYXj$hj$v%S z^Gt&;(VvK(XeXhb>5DTSkH5Au?rLI;NXW~idY7fOhQ#7Vl4QjtkNKb_y~;Uz?sL(%S)(3%ECQ>OeMGHZw8fmncClLBNgYZhl4 zVc1`uL z2FFN#K^*p{r!`{@w&5_9u z6LU)D+kH7l1q%7fwlT6s7y~V9Zjws26qI32^HkPDXKqpF*2SWdLVAcF!5sXonB;v; zZ+j0pXC-S<4TG~C+n9b<#}v}bEb}@Fz?|*a#`Lo~Vh!k^s&IsJ(c(G#{myVV_x#Sn zz35pq61xE!zg#*a=b~laawBL}DpXN^dDxrHzmJoLe{ZsJLbjFdF8}}l07*qoM6N<$ Ef@8hj5C8xG literal 0 HcmV?d00001 diff --git a/iOS/TUIKit/TUITranslation/Resources/TUITranslationTheme.bundle/light/resource/translation_tips@3x.png b/iOS/TUIKit/TUITranslation/Resources/TUITranslationTheme.bundle/light/resource/translation_tips@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..3d6af40fa20bef7448a9beb497a8ae63cc86f71c GIT binary patch literal 530 zcmV+t0`2{YP)YJ@g;Bj^UT!E*y@f@%WXpf)hBVuySvh!^CZ^Znom+)qTk zdVsiKnv>?Jxif8U9d8X^nm5g-X(tV#k(w@o3k)Yzl++Xj!-{VXyj&HL)RfB19~B&i zv+NS0;QwANMl4E@XB1l{$aWC31sC^Vs?8rtH79o5S!_hOMplvrt=4d0=w z*JKjoR!$MJdVB}5ki6^$h~9Gx(Q5ADx+;0_jO&Yp8q%#8mP*`__%UECdXZHdE-@A< zhJ0XW1^)elcb6~&a)^z2y`Ag=kp&1+h>dtV@JW&-K}xY8IoJEnB}gsS%c+1)XOCbC zG4u-FLo(aYNE~y=oI6*8593cvkn=Ro|mQNwnunM6t>#Db4nrZ@nD(mp1p^%p Uf3w(_*Z=?k07*qoM6N<$f`c8{MF0Q* literal 0 HcmV?d00001 diff --git a/iOS/TUIKit/TUITranslation/Resources/TUITranslationTheme.bundle/lively/manifest.plist b/iOS/TUIKit/TUITranslation/Resources/TUITranslationTheme.bundle/lively/manifest.plist new file mode 100644 index 00000000000..0d001c7473e --- /dev/null +++ b/iOS/TUIKit/TUITranslation/Resources/TUITranslationTheme.bundle/lively/manifest.plist @@ -0,0 +1,28 @@ + + + + + id + lively + name + 活泼 + name_en + Lively + translation_view_bg_color + #F2F7FF + translation_view_text_color + #000000 + translation_view_tips_color + #000000 + translation_view_icon_loading_img + translation_loading.png + translation_view_icon_tips_img + translation_tips.png + translation_view_pop_menu_copy_img + icon_copy.png + translation_view_pop_menu_hide_img + icon_hide.png + translation_view_pop_menu_forward_img + icon_forward.png + + diff --git a/iOS/TUIKit/TUITranslation/Resources/TUITranslationTheme.bundle/lively/resource/icon_copy@3x.png b/iOS/TUIKit/TUITranslation/Resources/TUITranslationTheme.bundle/lively/resource/icon_copy@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..f3d51c5242d7925f0d2d3a8d5016b1ebdb403a80 GIT binary patch literal 1999 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 literal 0 HcmV?d00001 diff --git a/iOS/TUIKit/TUITranslation/Resources/TUITranslationTheme.bundle/lively/resource/icon_translate@3x.png b/iOS/TUIKit/TUITranslation/Resources/TUITranslationTheme.bundle/lively/resource/icon_translate@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..2ae4e9ba84bac827ba807af4a8c288f24af180fb GIT binary patch literal 658 zcmV;D0&V??P)ltN)K4zPQxGpHo`Rg%&r1-KlN0YcUDZ=fb#F~i@66n7{Uw^A%Bep0 z%)LDYN`Ypx`So}i6A#7(N`Z&SZ(_s;y#Ya_FT91wPs)(pZbxa-YPGbV2fO-0sL8yz zUaz#-Y{a_JXi&9UB^OwVTr3u}-EPJDcs$a4J|`Dg+VyZaJgx8dJGsD4Bz6#XRavc8 zsj&AO^+wIB1wy+Y3z>z>?x7&^0FPBS73M-Lvw_wwH zy-uZ4iE6c4bS-HBeP%hun|jMv%H?vjs}L$dZT9s~bINdt&o z$1@s@MChnM*l;)$YwRTI)dqGu`6>`VluH2p8@r-W2e7Pdb6~V2w;6K_;YaUx9_=9%0y~ZXAMLb>QSoo%2qoQ`9sM1_Kd35=;^%n`eo&NYt0w zdO?&FiPlR^R~%(<5E<;M18J)6PMmbjnTfSX^pCw>PkYUjt~TuV`#*ogAMC2b>vZjO zIwCo7k`^~z0eV|`NSqh3Md~K@G=7r?;UTOqgmjGqLPefx=N&L6oJAsCaqHkrs7YTi s+BJ;{JuiY?eIbbS1&EvwA5!@*KX>cdOIesDMF0Q*07*qoM6N<$g6@?bl>h($ literal 0 HcmV?d00001 diff --git a/iOS/TUIKit/TUITranslation/Resources/TUITranslationTheme.bundle/lively/resource/translation_loading@3x.png b/iOS/TUIKit/TUITranslation/Resources/TUITranslationTheme.bundle/lively/resource/translation_loading@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..761f4341932b16576ebf5454525e6d07542109e7 GIT binary patch literal 1034 zcmV+l1oiugP))(Xt##~!pBaxVYh}IKpYLxK95cVK*ObOKG?sW;;is!TTzDbA|2|eNI6%P>6<=3M z_c*86m6T?F=U5%0ARZhsbBCW9f(3tJPk%!}oQPhi=>rZ~HCJPeorQh9f&w@Zt%1!! z+Vh436riwZ>9yRw9P_Y9ho+R(fD5ep<_;^NM%PnlzqSDE<;oDNxl;M8tKF}vjUlj# z7O}Jjr=Va8gHlGI%->e8jP=SVeq$RoTPfa}4s0L9*O>iwCo>FYG{NzodaZyLkieiwhId-i$0B|T|r z-0X!|?xw^a?1bg$f2;Uw*HKDpMvFIXAdl$qr9hg)1`iG6@!}Dqsl*Ig(P*R+X!sQL zk^g&@W)2f3HhSPC^59`Lj~Le^rbi^=BI`yO?r{hf`kFjCk1ZbTbC2`37nn93ys~*iK=6Q@FJ6Dh4Db@^-&|Sy#!F44LX_;#<`^CYXj$hj$v%S z^Gt&;(VvK(XeXhb>5DTSkH5Au?rLI;NXW~idY7fOhQ#7Vl4QjtkNKb_y~;Uz?sL(%S)(3%ECQ>OeMGHZw8fmncClLBNgYZhl4 zVc1`uL z2FFN#K^*p{r!`{@w&5_9u z6LU)D+kH7l1q%7fwlT6s7y~V9Zjws26qI32^HkPDXKqpF*2SWdLVAcF!5sXonB;v; zZ+j0pXC-S<4TG~C+n9b<#}v}bEb}@Fz?|*a#`Lo~Vh!k^s&IsJ(c(G#{myVV_x#Sn zz35pq61xE!zg#*a=b~laawBL}DpXN^dDxrHzmJoLe{ZsJLbjFdF8}}l07*qoM6N<$ Ef@8hj5C8xG literal 0 HcmV?d00001 diff --git a/iOS/TUIKit/TUITranslation/Resources/TUITranslationTheme.bundle/lively/resource/translation_tips@3x.png b/iOS/TUIKit/TUITranslation/Resources/TUITranslationTheme.bundle/lively/resource/translation_tips@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..3d6af40fa20bef7448a9beb497a8ae63cc86f71c GIT binary patch literal 530 zcmV+t0`2{YP)YJ@g;Bj^UT!E*y@f@%WXpf)hBVuySvh!^CZ^Znom+)qTk zdVsiKnv>?Jxif8U9d8X^nm5g-X(tV#k(w@o3k)Yzl++Xj!-{VXyj&HL)RfB19~B&i zv+NS0;QwANMl4E@XB1l{$aWC31sC^Vs?8rtH79o5S!_hOMplvrt=4d0=w z*JKjoR!$MJdVB}5ki6^$h~9Gx(Q5ADx+;0_jO&Yp8q%#8mP*`__%UECdXZHdE-@A< zhJ0XW1^)elcb6~&a)^z2y`Ag=kp&1+h>dtV@JW&-K}xY8IoJEnB}gsS%c+1)XOCbC zG4u-FLo(aYNE~y=oI6*8593cvkn=Ro|mQNwnunM6t>#Db4nrZ@nD(mp1p^%p Uf3w(_*Z=?k07*qoM6N<$f`c8{MF0Q* literal 0 HcmV?d00001 diff --git a/iOS/TUIKit/TUITranslation/Resources/TUITranslationTheme.bundle/serious/manifest.plist b/iOS/TUIKit/TUITranslation/Resources/TUITranslationTheme.bundle/serious/manifest.plist new file mode 100644 index 00000000000..8bc165c1fc6 --- /dev/null +++ b/iOS/TUIKit/TUITranslation/Resources/TUITranslationTheme.bundle/serious/manifest.plist @@ -0,0 +1,28 @@ + + + + + id + serious + name + 严肃 + name_en + Business + translation_view_bg_color + #F2F7FF + translation_view_text_color + #000000 + translation_view_tips_color + #000000 + translation_view_icon_loading_img + translation_loading.png + translation_view_icon_tips_img + translation_tips.png + translation_view_pop_menu_copy_img + icon_copy.png + translation_view_pop_menu_hide_img + icon_hide.png + translation_view_pop_menu_forward_img + icon_forward.png + + diff --git a/iOS/TUIKit/TUITranslation/Resources/TUITranslationTheme.bundle/serious/resource/icon_copy@3x.png b/iOS/TUIKit/TUITranslation/Resources/TUITranslationTheme.bundle/serious/resource/icon_copy@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..f3d51c5242d7925f0d2d3a8d5016b1ebdb403a80 GIT binary patch literal 1999 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 literal 0 HcmV?d00001 diff --git a/iOS/TUIKit/TUITranslation/Resources/TUITranslationTheme.bundle/serious/resource/icon_translate@3x.png b/iOS/TUIKit/TUITranslation/Resources/TUITranslationTheme.bundle/serious/resource/icon_translate@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..2ae4e9ba84bac827ba807af4a8c288f24af180fb GIT binary patch literal 658 zcmV;D0&V??P)ltN)K4zPQxGpHo`Rg%&r1-KlN0YcUDZ=fb#F~i@66n7{Uw^A%Bep0 z%)LDYN`Ypx`So}i6A#7(N`Z&SZ(_s;y#Ya_FT91wPs)(pZbxa-YPGbV2fO-0sL8yz zUaz#-Y{a_JXi&9UB^OwVTr3u}-EPJDcs$a4J|`Dg+VyZaJgx8dJGsD4Bz6#XRavc8 zsj&AO^+wIB1wy+Y3z>z>?x7&^0FPBS73M-Lvw_wwH zy-uZ4iE6c4bS-HBeP%hun|jMv%H?vjs}L$dZT9s~bINdt&o z$1@s@MChnM*l;)$YwRTI)dqGu`6>`VluH2p8@r-W2e7Pdb6~V2w;6K_;YaUx9_=9%0y~ZXAMLb>QSoo%2qoQ`9sM1_Kd35=;^%n`eo&NYt0w zdO?&FiPlR^R~%(<5E<;M18J)6PMmbjnTfSX^pCw>PkYUjt~TuV`#*ogAMC2b>vZjO zIwCo7k`^~z0eV|`NSqh3Md~K@G=7r?;UTOqgmjGqLPefx=N&L6oJAsCaqHkrs7YTi s+BJ;{JuiY?eIbbS1&EvwA5!@*KX>cdOIesDMF0Q*07*qoM6N<$g6@?bl>h($ literal 0 HcmV?d00001 diff --git a/iOS/TUIKit/TUITranslation/Resources/TUITranslationTheme.bundle/serious/resource/translation_loading@3x.png b/iOS/TUIKit/TUITranslation/Resources/TUITranslationTheme.bundle/serious/resource/translation_loading@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..761f4341932b16576ebf5454525e6d07542109e7 GIT binary patch literal 1034 zcmV+l1oiugP))(Xt##~!pBaxVYh}IKpYLxK95cVK*ObOKG?sW;;is!TTzDbA|2|eNI6%P>6<=3M z_c*86m6T?F=U5%0ARZhsbBCW9f(3tJPk%!}oQPhi=>rZ~HCJPeorQh9f&w@Zt%1!! z+Vh436riwZ>9yRw9P_Y9ho+R(fD5ep<_;^NM%PnlzqSDE<;oDNxl;M8tKF}vjUlj# z7O}Jjr=Va8gHlGI%->e8jP=SVeq$RoTPfa}4s0L9*O>iwCo>FYG{NzodaZyLkieiwhId-i$0B|T|r z-0X!|?xw^a?1bg$f2;Uw*HKDpMvFIXAdl$qr9hg)1`iG6@!}Dqsl*Ig(P*R+X!sQL zk^g&@W)2f3HhSPC^59`Lj~Le^rbi^=BI`yO?r{hf`kFjCk1ZbTbC2`37nn93ys~*iK=6Q@FJ6Dh4Db@^-&|Sy#!F44LX_;#<`^CYXj$hj$v%S z^Gt&;(VvK(XeXhb>5DTSkH5Au?rLI;NXW~idY7fOhQ#7Vl4QjtkNKb_y~;Uz?sL(%S)(3%ECQ>OeMGHZw8fmncClLBNgYZhl4 zVc1`uL z2FFN#K^*p{r!`{@w&5_9u z6LU)D+kH7l1q%7fwlT6s7y~V9Zjws26qI32^HkPDXKqpF*2SWdLVAcF!5sXonB;v; zZ+j0pXC-S<4TG~C+n9b<#}v}bEb}@Fz?|*a#`Lo~Vh!k^s&IsJ(c(G#{myVV_x#Sn zz35pq61xE!zg#*a=b~laawBL}DpXN^dDxrHzmJoLe{ZsJLbjFdF8}}l07*qoM6N<$ Ef@8hj5C8xG literal 0 HcmV?d00001 diff --git a/iOS/TUIKit/TUITranslation/Resources/TUITranslationTheme.bundle/serious/resource/translation_tips@3x.png b/iOS/TUIKit/TUITranslation/Resources/TUITranslationTheme.bundle/serious/resource/translation_tips@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..3d6af40fa20bef7448a9beb497a8ae63cc86f71c GIT binary patch literal 530 zcmV+t0`2{YP)YJ@g;Bj^UT!E*y@f@%WXpf)hBVuySvh!^CZ^Znom+)qTk zdVsiKnv>?Jxif8U9d8X^nm5g-X(tV#k(w@o3k)Yzl++Xj!-{VXyj&HL)RfB19~B&i zv+NS0;QwANMl4E@XB1l{$aWC31sC^Vs?8rtH79o5S!_hOMplvrt=4d0=w z*JKjoR!$MJdVB}5ki6^$h~9Gx(Q5ADx+;0_jO&Yp8q%#8mP*`__%UECdXZHdE-@A< zhJ0XW1^)elcb6~&a)^z2y`Ag=kp&1+h>dtV@JW&-K}xY8IoJEnB}gsS%c+1)XOCbC zG4u-FLo(aYNE~y=oI6*8593cvkn=Ro|mQNwnunM6t>#Db4nrZ@nD(mp1p^%p Uf3w(_*Z=?k07*qoM6N<$f`c8{MF0Q* literal 0 HcmV?d00001 diff --git a/iOS/TUIKit/TUITranslation/TUITranslation.podspec b/iOS/TUIKit/TUITranslation/TUITranslation.podspec new file mode 100644 index 00000000000..ec316c2d790 --- /dev/null +++ b/iOS/TUIKit/TUITranslation/TUITranslation.podspec @@ -0,0 +1,26 @@ +Pod::Spec.new do |spec| + spec.name = 'TUITranslation' + spec.version = '7.2.4123' + spec.platform = :ios + spec.ios.deployment_target = '9.0' + spec.license = { :type => 'Proprietary', + :text => <<-LICENSE + copyright 2017 tencent Ltd. All rights reserved. + LICENSE + } + spec.homepage = 'https://cloud.tencent.com/document/product/269/3794' + spec.documentation_url = 'https://cloud.tencent.com/document/product/269/9147' + spec.authors = 'tencent video cloud' + spec.summary = 'TUITranslation' + spec.dependency 'TUICore' + spec.dependency 'TIMCommon' + spec.dependency 'TUIChat' + + spec.requires_arc = true + + spec.source = { :git => 'https://git.woa.com/lynxzhang/tui-components.git', :tag => spec.version} + spec.source_files = '**/*.{h,m,mm,c}' + spec.resource = [ + 'Resources/*.bundle' + ] +end diff --git a/iOS/TUIKit/TUITranslation/UI/DataProvider/TUITranslationDataProvider.h b/iOS/TUIKit/TUITranslation/UI/DataProvider/TUITranslationDataProvider.h new file mode 100644 index 00000000000..a2112a9538d --- /dev/null +++ b/iOS/TUIKit/TUITranslation/UI/DataProvider/TUITranslationDataProvider.h @@ -0,0 +1,38 @@ +// +// TUITranslationDataProvider.h +// TUITranslation +// +// Created by xia on 2023/3/21. +// + +#import +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +typedef NS_ENUM(NSInteger, TUITranslationViewStatus) { + TUITranslationViewStatusUnknown = 0, + TUITranslationViewStatusHidden = 1, + TUITranslationViewStatusLoading = 2, + TUITranslationViewStatusShown = 3, +}; + +typedef void (^TUITranslateMessageCompletion)(NSInteger code, NSString *desc, TUIMessageCellData *data, NSInteger status, NSString *text); + +@interface TUITranslationDataProvider : NSObject + ++ (void)translateMessage:(TUIMessageCellData *)data + completion:(TUITranslateMessageCompletion _Nullable)completion; + ++ (void)saveTranslationResult:(V2TIMMessage *)message + text:(NSString *)text + status:(TUITranslationViewStatus)status; + ++ (BOOL)shouldShowTranslation:(V2TIMMessage *)message; ++ (NSString *)getTranslationText:(V2TIMMessage *)message; ++ (TUITranslationViewStatus)getTranslationStatus:(V2TIMMessage *)message; + +@end + +NS_ASSUME_NONNULL_END diff --git a/iOS/TUIKit/TUITranslation/UI/DataProvider/TUITranslationDataProvider.m b/iOS/TUIKit/TUITranslation/UI/DataProvider/TUITranslationDataProvider.m new file mode 100644 index 00000000000..328086cebd7 --- /dev/null +++ b/iOS/TUIKit/TUITranslation/UI/DataProvider/TUITranslationDataProvider.m @@ -0,0 +1,218 @@ +// +// TUITranslationDataProvider.m +// TUITranslation +// +// Created by xia on 2023/3/21. +// + +#import "TUITranslationDataProvider.h" +#import +#import +#import +#import "TUITranslationConfig.h" + +#pragma GCC diagnostic ignored "-Wundeclared-selector" + +static NSString * const kKeyTranslationText = @"translation"; +static NSString * const kKeyTranslationViewStatus = @"translation_view_status"; + +@interface TUITranslationDataProvider() + +@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 *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 *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 { + 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 { + 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 diff --git a/iOS/TUIKit/TUITranslation/UI/Service/TUITranslationExtensionObserver.h b/iOS/TUIKit/TUITranslation/UI/Service/TUITranslationExtensionObserver.h new file mode 100644 index 00000000000..46357534a69 --- /dev/null +++ b/iOS/TUIKit/TUITranslation/UI/Service/TUITranslationExtensionObserver.h @@ -0,0 +1,16 @@ +// +// TUITranslationExtensionObserver.h +// TUITranslation +// +// Created by xia on 2023/4/4. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface TUITranslationExtensionObserver : NSObject + +@end + +NS_ASSUME_NONNULL_END diff --git a/iOS/TUIKit/TUITranslation/UI/Service/TUITranslationExtensionObserver.m b/iOS/TUIKit/TUITranslation/UI/Service/TUITranslationExtensionObserver.m new file mode 100644 index 00000000000..6d21dccc4bf --- /dev/null +++ b/iOS/TUIKit/TUITranslation/UI/Service/TUITranslationExtensionObserver.m @@ -0,0 +1,233 @@ +// +// TUITranslationExtensionObserver.m +// TUITranslation +// +// Created by xia on 2023/4/4. +// + +#import "TUITranslationExtensionObserver.h" + +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import "TUITranslationConfig.h" +#import "TUITranslationLanguageController.h" +#import "TUITranslationView.h" +#import "TUITranslationDataProvider.h" + +@interface TUITranslationExtensionObserver () + +@property (nonatomic, weak) UINavigationController *navVC; +@property (nonatomic, weak) TUICommonTextCellData *cellData; + +@end + +@implementation TUITranslationExtensionObserver + +static id _instance = nil; + ++ (void)load { + TUIRegisterThemeResourcePath(TUITranslationThemePath, TUIThemeModuleTranslation); + + // UI extensions in pop menu when message is long pressed. + [TUICore registerExtension:TUICore_TUIChatExtension_PopMenuActionItem_ClassicExtensionID object:TUITranslationExtensionObserver.shareInstance]; + [TUICore registerExtension:TUICore_TUIChatExtension_PopMenuActionItem_MinimalistExtensionID object:TUITranslationExtensionObserver.shareInstance]; + + // UI extensions of setting. + [TUICore registerExtension:TUICore_TUIContactExtension_MeSettingMenu_ClassicExtensionID object:TUITranslationExtensionObserver.shareInstance]; + [TUICore registerExtension:TUICore_TUIContactExtension_MeSettingMenu_MinimalistExtensionID object:TUITranslationExtensionObserver.shareInstance]; +} + ++ (instancetype)shareInstance { + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + _instance = [[self alloc] init]; + }); + return _instance; +} + +- (instancetype)init { + if (self = [super init]) { + [TUICore registerExtension:TUICore_TUIChatExtension_BottomContainer_ClassicExtensionID object:self]; + [TUICore registerExtension:TUICore_TUIChatExtension_BottomContainer_MinimalistExtensionID object:self]; + } + return self; +} + +#pragma mark - TUIExtensionProtocol +- (void)onRaiseExtension:(NSString *)extensionID parentView:(UIView *)parentView param:(nullable NSDictionary *)param { + if ([extensionID isEqualToString:TUICore_TUIChatExtension_BottomContainer_ClassicExtensionID] || + [extensionID isEqualToString:TUICore_TUIChatExtension_BottomContainer_MinimalistExtensionID]) { + NSObject *data = [param objectForKey:TUICore_TUIChatExtension_BottomContainer_CellData]; + if (![parentView isKindOfClass:UIView.class] || ![data isKindOfClass:TUIMessageCellData.class]) { + return; + } + + TUIMessageCellData *cellData = (TUIMessageCellData *)data; + if (cellData.innerMessage.elemType != V2TIM_ELEM_TYPE_TEXT) { + return; + } + + TUITranslationView *view = [[TUITranslationView alloc] initWithData:cellData]; + [parentView addSubview:view]; + } +} + +- (NSArray *)onGetExtension:(NSString *)extensionID param:(NSDictionary *)param { + if (![extensionID isKindOfClass:NSString.class]) { + return nil; + } + + if ([extensionID isEqualToString:TUICore_TUIChatExtension_PopMenuActionItem_ClassicExtensionID] || + [extensionID isEqualToString:TUICore_TUIChatExtension_PopMenuActionItem_MinimalistExtensionID]) { + // Extension entrance in pop menu when message is long pressed. + if (![param isKindOfClass:NSDictionary.class]) { + return nil; + } + TUIMessageCell *cell = param[TUICore_TUIChatExtension_PopMenuActionItem_ClickCell]; + if ([extensionID isEqualToString:TUICore_TUIChatExtension_PopMenuActionItem_ClassicExtensionID]) { + if (![cell isKindOfClass:TUITextMessageCell.class] && + ![cell isKindOfClass:TUIReferenceMessageCell.class] && + ![cell isKindOfClass:TUIReplyMessageCell.class]) { + return nil; + } + } else if ([extensionID isEqualToString:TUICore_TUIChatExtension_PopMenuActionItem_MinimalistExtensionID]) { + if (![cell isKindOfClass:TUITextMessageCell_Minimalist.class] && + ![cell isKindOfClass:TUIReferenceMessageCell_Minimalist.class] && + ![cell isKindOfClass:TUIReplyMessageCell_Minimalist.class]) { + return nil; + } + } + if (cell.messageData.innerMessage.elemType != V2TIM_ELEM_TYPE_TEXT) { + return nil; + } + if ([TUITranslationDataProvider shouldShowTranslation:cell.messageData.innerMessage]) { + return nil; + } + if (![self isSelectAllContentOfMessage:cell]) { + return nil; + } + + TUIExtensionInfo *info = [[TUIExtensionInfo alloc] init]; + info.weight = 2000; + info.text = TIMCommonLocalizableString(TUIKitTranslate); + if ([extensionID isEqualToString:TUICore_TUIChatExtension_PopMenuActionItem_ClassicExtensionID]) { + info.icon = TUIChatBundleThemeImage(@"chat_icon_translate_img", @"icon_translate"); + } else if ([extensionID isEqualToString:TUICore_TUIChatExtension_PopMenuActionItem_MinimalistExtensionID]) { + info.icon = [UIImage imageNamed:TUIChatImagePath_Minimalist(@"icon_translate")]; + } + info.onClicked = ^(NSDictionary * _Nonnull action) { + TUIMessageCellData *cellData = cell.messageData; + V2TIMMessage *message = cellData.innerMessage; + if (message.elemType != V2TIM_ELEM_TYPE_TEXT) { + return; + } + [TUITranslationDataProvider translateMessage:cellData + completion:^(NSInteger code, NSString * _Nonnull desc, TUIMessageCellData * _Nonnull data, NSInteger status, NSString * _Nonnull text) { + NSDictionary *param = @{TUICore_TUITranslationNotify_DidChangeTranslationSubKey_Data: cellData}; + [TUICore notifyEvent:TUICore_TUITranslationNotify + subKey:TUICore_TUITranslationNotify_DidChangeTranslationSubKey + object:nil + param:param]; + }]; + }; + return @[info]; + } else if ([extensionID isEqualToString:TUICore_TUIContactExtension_MeSettingMenu_ClassicExtensionID] || + [extensionID isEqualToString:TUICore_TUIContactExtension_MeSettingMenu_MinimalistExtensionID]) { + // Extension entrance in Me setting VC. + if (![param isKindOfClass:NSDictionary.class]) { + return nil; + } + if (param[TUICore_TUIContactExtension_MeSettingMenu_Nav]) { + self.navVC = param[TUICore_TUIContactExtension_MeSettingMenu_Nav]; + } + + TUICommonTextCellData *data = [TUICommonTextCellData new]; + data.key = TIMCommonLocalizableString(TranslateMessage); + data.showAccessory = YES; + data.value = [TUITranslationConfig defaultConfig].targetLanguageName; + self.cellData = data; + + TUICommonTextCell *cell = [[TUICommonTextCell alloc] init]; + [cell fillWithData:data]; + cell.mm_height(60).mm_width(Screen_Width); + UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onClickedTargetLanguageCell:)]; + [cell addGestureRecognizer:tap]; + + TUIExtensionInfo *info = [[TUIExtensionInfo alloc] init]; + NSMutableDictionary *param = [NSMutableDictionary dictionary]; + [param setObject:@450 forKey:TUICore_TUIContactExtension_MeSettingMenu_Weight]; + if (cell) { + [param setObject:cell forKey:TUICore_TUIContactExtension_MeSettingMenu_View]; + } + if (data) { + [param setObject:data forKey:TUICore_TUIContactExtension_MeSettingMenu_Data]; + } + info.data = param; + return @[info]; + } + return nil; +} + +- (void)onClickedTargetLanguageCell:(TUICommonTextCell *)cell { + TUITranslationLanguageController *vc = [[TUITranslationLanguageController alloc] init]; + vc.onSelectedLanguage = ^(NSString * _Nonnull languageName) { + self.cellData.value = languageName; + }; + if (self.navVC) { + [self.navVC pushViewController:vc animated:YES]; + } +} + +- (BOOL)isSelectAllContentOfMessage:(TUIMessageCell *)cell { + if ([cell isKindOfClass:TUITextMessageCell.class]) { + TUITextMessageCell *textCell = (TUITextMessageCell *)cell; + if (textCell.selectContent.length == 0) { + return YES; + } else { + NSAttributedString *selectedString = [textCell.textView.attributedText attributedSubstringFromRange:textCell.textView.selectedRange]; + if (selectedString.length == 0) { + return YES; + } + return selectedString.length == textCell.textView.attributedText.length; + } + } else if ([cell isKindOfClass:TUIReferenceMessageCell.class]) { + TUIReferenceMessageCell *refCell = (TUIReferenceMessageCell *)cell; + if (refCell.selectContent.length == 0) { + return YES; + } else { + NSAttributedString *selectedString = [refCell.textView.attributedText attributedSubstringFromRange:refCell.textView.selectedRange]; + if (selectedString.length == 0) { + return YES; + } + return selectedString.length == refCell.textView.attributedText.length; + } + } else if ([cell isKindOfClass:TUIReplyMessageCell.class]) { + TUIReplyMessageCell *replyCell = (TUIReplyMessageCell *)cell; + if (replyCell.selectContent.length == 0) { + return YES; + } else { + NSAttributedString *selectedString = [replyCell.textView.attributedText attributedSubstringFromRange:replyCell.textView.selectedRange]; + if (selectedString.length == 0) { + return YES; + } + return selectedString.length == replyCell.textView.attributedText.length; + } + } + if ([cell isKindOfClass:TUITextMessageCell_Minimalist.class] || + [cell isKindOfClass:TUIReferenceMessageCell_Minimalist.class] || + [cell isKindOfClass:TUIReplyMessageCell_Minimalist.class]) { + return YES; + } + return NO; +} + +@end + diff --git a/iOS/TUIKit/TUITranslation/UI/UI/TUITranslationLanguageController.h b/iOS/TUIKit/TUITranslation/UI/UI/TUITranslationLanguageController.h new file mode 100644 index 00000000000..50821605892 --- /dev/null +++ b/iOS/TUIKit/TUITranslation/UI/UI/TUITranslationLanguageController.h @@ -0,0 +1,18 @@ +// +// TUITranslationLanguageController.h +// TUITranslation +// +// Created by xia on 2023/4/7. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface TUITranslationLanguageController : UIViewController + +@property (nonatomic, copy) void (^onSelectedLanguage)(NSString *languageName); + +@end + +NS_ASSUME_NONNULL_END diff --git a/iOS/TUIKit/TUITranslation/UI/UI/TUITranslationLanguageController.m b/iOS/TUIKit/TUITranslation/UI/UI/TUITranslationLanguageController.m new file mode 100644 index 00000000000..b5220e31c5e --- /dev/null +++ b/iOS/TUIKit/TUITranslation/UI/UI/TUITranslationLanguageController.m @@ -0,0 +1,111 @@ +// +// TUITranslationLanguageController.m +// TUITranslation +// +// Created by xia on 2023/4/7. +// + +#import "TUITranslationLanguageController.h" +#import +#import +#import "TUITranslationConfig.h" + +@interface TUITranslationLanguageController () + +@property (nonatomic, copy) NSArray *languageCodeList; +@property (nonatomic, copy) NSArray *languageNameList; +@property (nonatomic, strong) UITableView *tableView; +@property (nonatomic, strong) NSIndexPath *currentIndex; + +@end + +@implementation TUITranslationLanguageController + +- (void)viewDidLoad { + [super viewDidLoad]; + + self.title = TIMCommonLocalizableString(TranslateMessage); + [self.view addSubview:self.tableView]; +} + +#pragma mark - UITableView DataSource & Delegate +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { + return 1; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { + return self.languageNameList.count; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { + if (indexPath.row >= self.languageNameList.count) { + return nil; + } + NSString *language = self.languageNameList[indexPath.row]; + UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"textCell" forIndexPath:indexPath]; + cell.textLabel.text = language; + if ([language isEqualToString:[TUITranslationConfig defaultConfig].targetLanguageName]) { + cell.accessoryType = UITableViewCellAccessoryCheckmark; + self.currentIndex = indexPath; + } else { + cell.accessoryType = UITableViewCellAccessoryNone; + } + return cell; +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { + if (indexPath.row >= self.languageNameList.count || indexPath.row >= self.languageCodeList.count) { + return; + } + if (indexPath.row == self.currentIndex.row) { + return; + } + UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; + cell.accessoryType = UITableViewCellAccessoryCheckmark; + UITableViewCell *lastCell = [tableView cellForRowAtIndexPath:self.currentIndex]; + lastCell.accessoryType = UITableViewCellAccessoryNone; + self.currentIndex = indexPath; + + [TUITranslationConfig defaultConfig].targetLanguageCode = self.languageCodeList[indexPath.row]; + if (self.onSelectedLanguage) { + self.onSelectedLanguage(self.languageNameList[indexPath.row]); + } +} + +#pragma mark - Getter +- (UITableView *)tableView { + if (!_tableView) { + _tableView = [[UITableView alloc] initWithFrame:self.view.bounds]; + _tableView.delaysContentTouches = NO; + _tableView.tableFooterView = [[UIView alloc] init]; + _tableView.backgroundColor = TIMCommonDynamicColor(@"controller_bg_color", @"#F2F3F5"); + _tableView.delegate = self; + _tableView.dataSource = self; + _tableView.separatorStyle = UITableViewCellSeparatorStyleSingleLine; + _tableView.rowHeight = 55; + [_tableView registerClass:[TUICommonTextCell class] forCellReuseIdentifier:@"textCell"]; + if (@available(iOS 15.0, *)) { + _tableView.sectionHeaderTopPadding = 0; + } + } + return _tableView; +} + +/** + Simplified Chinese, Traditional Chinese, English, Japanese, Korean, French, Spanish, Italian, German, + Turkish, Russian, Portuguese, Vietnamese, Indonesian, Thai, Malaysian, + Hindi language + */ +- (NSArray *)languageNameList { + return @[@"简体中文", @"繁體中文", @"English", @"日本語", @"한국어", @"Français", @"Español", @"Italiano", @"Deutsch", + @"Türkçe", @"Русский", @"Português", @"Tiếng Việt", @"Bahasa Indonesia", @"ภาษาไทย", @"Bahasa Melayu", + @"हिन्दी"]; +} + +- (NSArray *)languageCodeList { + return @[@"zh", @"zh-TW", @"en", @"ja", @"ko", @"fr", @"es", @"it", @"de", + @"tr", @"ru", @"pt", @"vi", @"id", @"th", @"ms", + @"hi"]; +} + +@end diff --git a/iOS/TUIKit/TUITranslation/UI/UI/TUITranslationView.h b/iOS/TUIKit/TUITranslation/UI/UI/TUITranslationView.h new file mode 100644 index 00000000000..03ff7e1fd2d --- /dev/null +++ b/iOS/TUIKit/TUITranslation/UI/UI/TUITranslationView.h @@ -0,0 +1,21 @@ +/** + * 本文件声明了 TUITranslationView 类,负责实现消息文本翻译视图。 + * 文本类消息支持长按后翻译,翻译后视图位于消息气泡下方,展示翻译后文本。 + * + * When you long press the text messages, you can choose to translate it. + * Translation view will be displayed below the message bubble showing the translated text. + */ + +#import +#import + +NS_ASSUME_NONNULL_BEGIN +@class TUIMessageCellData; + +@interface TUITranslationView : UIView + +- (instancetype)initWithData:(TUIMessageCellData *)data; + +@end + +NS_ASSUME_NONNULL_END diff --git a/iOS/TUIKit/TUITranslation/UI/UI/TUITranslationView.m b/iOS/TUIKit/TUITranslation/UI/UI/TUITranslationView.m new file mode 100644 index 00000000000..c7d8651e1b4 --- /dev/null +++ b/iOS/TUIKit/TUITranslation/UI/UI/TUITranslationView.m @@ -0,0 +1,319 @@ +// +// TUITranslationView.m +// TUITranslation +// + +#import "TUITranslationView.h" +#import +#import +#import +#import +#import +#import +#import +#import "TUITranslationDataProvider.h" + +@interface TUITranslationView() + +@property (nonatomic, copy) NSString *text; +@property (nonatomic, copy) NSString *tips; +@property (nonatomic, strong) UIColor *bgColor; + +@property (nonatomic, strong) UIImageView *tipsIcon; +@property (nonatomic, strong) UILabel *tipsLabel; +@property (nonatomic, strong) UIImageView *loadingView; +@property (nonatomic, strong) TUITextView *textView; + +@property (nonatomic, strong) TUIMessageCellData *cellData; + +@end + +@implementation TUITranslationView + +- (instancetype)initWithBackgroundColor:(UIColor *)color { + self.bgColor = color; + return [self initWithFrame:CGRectZero]; +} + +- (instancetype)initWithData:(TUIMessageCellData *)data { + self = [super init]; + if (self) { + self.cellData = data; + + BOOL shouldShow = [TUITranslationDataProvider shouldShowTranslation:data.innerMessage]; + if (shouldShow) { + [self setupViews]; + [self setupGesture]; + [self refreshWithData:data]; + } else { + if (!CGSizeEqualToSize(self.cellData.bottomContainerSize, CGSizeZero)) { + [self notifyTranslationChanged]; + } + self.hidden = YES; + [self stopLoading]; + self.cellData.bottomContainerSize = CGSizeZero; + } + } + return self; +} + +- (instancetype)initWithFrame:(CGRect)frame { + self = [super initWithFrame:frame]; + if (self) { + [self setupViews]; + [self setupGesture]; + } + return self; +} + +- (void)refreshWithData:(TUIMessageCellData *)cellData { + self.text = [TUITranslationDataProvider getTranslationText:cellData.innerMessage]; + TUITranslationViewStatus status = [TUITranslationDataProvider getTranslationStatus:cellData.innerMessage]; + + CGSize size = [self calcSizeOfStatus:status]; + if (!CGSizeEqualToSize(self.cellData.bottomContainerSize, size)) { + [self notifyTranslationChanged]; + } + self.cellData.bottomContainerSize = size; + self.mm_top(0).mm_left(0).mm_width(size.width).mm_height(size.height); + if (status == TUITranslationViewStatusLoading) { + [self startLoading]; + } else if (status == TUITranslationViewStatusShown) { + [self stopLoading]; + [self updateTransaltionViewByText:self.text]; + } +} + +- (CGSize)calcSizeOfStatus:(TUITranslationViewStatus)status { + CGFloat minTextWidth = 164; + CGFloat maxTextWidth = Screen_Width * 0.68; + CGFloat actualTextWidth = 80 - 20; // 80 is the fixed container width. + CGFloat tipsHeight = 20; + CGFloat tipsBottomMargin = 10; + CGFloat oneLineTextHeight = 22; + CGFloat commonMargins = 10 * 2; + + // Translation is processing, return the size of an empty cell including loading animation. + if (status == TUITranslationViewStatusLoading) { + return CGSizeMake(80, oneLineTextHeight + commonMargins); + } + + NSAttributedString *attrStr = [self.text getAdvancedFormatEmojiStringWithFont:[UIFont systemFontOfSize:16] + textColor:[UIColor grayColor] + emojiLocations:nil]; + NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init]; + [paragraphStyle setLineBreakMode:NSLineBreakByWordWrapping]; + [paragraphStyle setAlignment:NSTextAlignmentLeft]; + + // Translation is finished. + // Calc the size according to the actual text width. + CGRect textRect = [attrStr boundingRectWithSize:CGSizeMake(actualTextWidth, MAXFLOAT) + options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading + context:nil]; + if (textRect.size.height < 30) { + // Result is only one line text. + return CGSizeMake(MAX(textRect.size.width, minTextWidth) + commonMargins, + MAX(textRect.size.height, oneLineTextHeight) + commonMargins + tipsHeight + tipsBottomMargin); + } + + // Result is more than one line, so recalc size using maxTextWidth. + textRect = [attrStr boundingRectWithSize:CGSizeMake(maxTextWidth, MAXFLOAT) + options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading + context:nil]; + return CGSizeMake(MAX(textRect.size.width, minTextWidth) + commonMargins, + MAX(textRect.size.height, oneLineTextHeight) + commonMargins + tipsHeight + tipsBottomMargin); +} + +#pragma mark - UI +- (void)setupViews { + self.backgroundColor = self.bgColor ? : TUITranslationDynamicColor(@"translation_view_bg_color", @"#F2F7FF"); + self.layer.cornerRadius = 10.0; + + self.loadingView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 15, 15)]; + [self.loadingView setImage:TUITranslationBundleThemeImage(@"translation_view_icon_loading_img", @"translation_loading")]; + self.loadingView.hidden = YES; + [self addSubview:self.loadingView]; + + self.textView = [[TUITextView alloc] init]; + self.textView.backgroundColor = [UIColor clearColor]; + self.textView.textContainerInset = UIEdgeInsetsMake(0, 0, 0, 0); + self.textView.textContainer.lineFragmentPadding = 0; + self.textView.scrollEnabled = NO; + self.textView.editable = NO; + [self addSubview:self.textView]; + self.textView.hidden = YES; + self.textView.userInteractionEnabled = NO; + + self.tipsIcon = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 13, 13)]; + [self.tipsIcon setImage:TUITranslationBundleThemeImage(@"translation_view_icon_tips_img", @"translation_tips")]; + self.tipsIcon.alpha = 0.4; + [self addSubview:self.tipsIcon]; + self.tipsIcon.hidden = YES; + + self.tipsLabel = [[UILabel alloc] init]; + self.tipsLabel.font = [UIFont systemFontOfSize:12]; + self.tipsLabel.text = TIMCommonLocalizableString(TUIKitTranslateDefaultTips); + self.tipsLabel.textColor = TUITranslationDynamicColor(@"translation_view_tips_color", @"#000000"); + self.tipsLabel.alpha = 0.4; + [self addSubview:self.tipsLabel]; + self.tipsLabel.hidden = YES; +} + +- (void)setupGesture { + UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] init]; + [longPress addTarget:self action:@selector(onLongPressed:)]; + [self addGestureRecognizer:longPress]; +} + +- (void)layoutSubviews { + if (self.text.length == 0) { + self.loadingView + .mm_height(15) + .mm_width(15) + .mm_left(10) + .mm__centerY(self.mm_h / 2.0); + } else { + self.textView + .mm_top(10) + .mm_left(10) + .mm_height(self.mm_h - 10 - 40 + 2) + .mm_width(self.mm_w - 2 * 10); + self.tipsIcon + .mm_top(self.textView.mm_maxY + 14) + .mm_left(10) + .mm_height(13) + .mm_width(13); + self.tipsLabel + .mm_height(20) + .mm_sizeToFit() + .mm__centerY(self.tipsIcon.mm_centerY) + .mm_left(self.tipsIcon.mm_maxX + 4); + } +} + +- (void)updateTransaltionViewByText:(NSString *)text { + BOOL isTranslated = text.length > 0; + if (isTranslated) { + self.textView.attributedText = [text getAdvancedFormatEmojiStringWithFont:[UIFont systemFontOfSize:16] + textColor:TUITranslationDynamicColor(@"translation_view_text_color", @"#000000") emojiLocations:nil]; + } + self.textView.hidden = !isTranslated; + self.tipsIcon.hidden = !isTranslated; + self.tipsLabel.hidden = !isTranslated; +} + +#pragma mark - Public +- (void)startLoading { + if (!self.loadingView.hidden) { + return; + } + + self.loadingView.hidden = NO; + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + CABasicAnimation *rotate = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"]; + rotate.toValue = @(M_PI * 2.0); + rotate.duration = 1; + rotate.repeatCount = HUGE_VALF; + [self.loadingView.layer addAnimation:rotate forKey:@"rotationAnimation"]; + }); +} + +- (void)stopLoading { + if (self.loadingView.hidden) { + return; + } + self.loadingView.hidden = YES; + [self.loadingView.layer removeAllAnimations]; +} + +#pragma mark - Event response +- (void)onLongPressed:(UILongPressGestureRecognizer *)recognizer { + if (![recognizer isKindOfClass:[UILongPressGestureRecognizer class]] || + recognizer.state != UIGestureRecognizerStateBegan){ + return; + } + + TUIChatPopMenu *popMenu = [[TUIChatPopMenu alloc] init]; + + @weakify(self); + TUIChatPopMenuAction *copy = [[TUIChatPopMenuAction alloc] initWithTitle:TIMCommonLocalizableString(Copy) + image:TUITranslationBundleThemeImage(@"translation_view_pop_menu_copy_img", @"icon_copy") + weight:1 + callback:^{ + @strongify(self); + [self onCopy:self.text]; + }]; + [popMenu addAction:copy]; + + TUIChatPopMenuAction *forward = [[TUIChatPopMenuAction alloc] initWithTitle:TIMCommonLocalizableString(Forward) + image:TUITranslationBundleThemeImage(@"translation_view_pop_menu_forward_img", @"icon_forward") + weight:2 + callback:^{ + @strongify(self); + [self onForward:self.text]; + }]; + [popMenu addAction:forward]; + + TUIChatPopMenuAction *hide = [[TUIChatPopMenuAction alloc] initWithTitle:TIMCommonLocalizableString(Hide) + image:TUITranslationBundleThemeImage(@"translation_view_pop_menu_hide_img", @"icon_hide") + weight:3 + callback:^{ + @strongify(self); + [self onHide:self]; + }]; + [popMenu addAction:hide]; + + CGRect frame = [UIApplication.sharedApplication.keyWindow convertRect:self.frame fromView:self.superview]; + [popMenu setArrawPosition:CGPointMake(frame.origin.x + frame.size.width * 0.5, frame.origin.y + 66) + adjustHeight:0]; + [popMenu showInView:UIApplication.sharedApplication.keyWindow]; +} + +- (void)onCopy:(NSString *)text { + if (text.length == 0) { + return; + } + UIPasteboard *pasteboard = [UIPasteboard generalPasteboard]; + pasteboard.string = text; + [TUITool makeToast:TIMCommonLocalizableString(Copied)]; +} + +- (void)onForward:(NSString *)text { + [self notifyTranslationForward:text]; +} + +- (void)onHide:(id)sender { + self.cellData.bottomContainerSize = CGSizeZero; + [TUITranslationDataProvider saveTranslationResult:self.cellData.innerMessage text:@"" status:TUITranslationViewStatusHidden]; + [self removeFromSuperview]; + [self notifyTranslationViewHidden]; +} + +#pragma mark -- Notify +- (void)notifyTranslationViewShown { + [self notifyTranslationChanged]; +} + +- (void)notifyTranslationViewHidden { + [self notifyTranslationChanged]; +} + +- (void)notifyTranslationForward:(NSString *)text { + NSDictionary *param = @{TUICore_TUITranslationNotify_WillForwardTranslationSubKey_Text:text}; + [TUICore notifyEvent:TUICore_TUITranslationNotify + subKey:TUICore_TUITranslationNotify_WillForwardTranslationSubKey + object:nil + param:param]; +} + +- (void)notifyTranslationChanged { + NSDictionary *param = @{TUICore_TUITranslationNotify_DidChangeTranslationSubKey_Data: self.cellData, + TUICore_TUITranslationNotify_DidChangeTranslationSubKey_VC: self + }; + [TUICore notifyEvent:TUICore_TUITranslationNotify + subKey:TUICore_TUITranslationNotify_DidChangeTranslationSubKey + object:nil + param:param]; +} + +@end