From d0d45837ed3f1f4d906ac199a4fb2c8b3c63e418 Mon Sep 17 00:00:00 2001 From: Kyle Date: Tue, 7 Nov 2023 01:02:27 +0800 Subject: [PATCH 01/15] Fix header issue --- Easydict.xcodeproj/project.pbxproj | 12 ++++++++++++ Easydict/App/Easydict-Bridging-Header.h | 2 ++ .../PerferenceWindow/EZSettingViewController.m | 1 + .../Feature/Service/Caiyun/CaiyunService.swift | 14 ++++++++++++++ .../Feature/Service/Language/EZLanguageManager.h | 1 + .../Feature/Service/Language/EZLanguageModel.h | 1 + Easydict/Feature/Service/Model/EZEnumTypes.h | 2 ++ Easydict/Feature/Service/Model/EZEnumTypes.m | 1 + Easydict/Feature/Service/Model/EZQueryService.h | 2 ++ Easydict/Feature/Service/Model/EZServiceTypes.m | 2 ++ 10 files changed, 38 insertions(+) create mode 100644 Easydict/Feature/Service/Caiyun/CaiyunService.swift diff --git a/Easydict.xcodeproj/project.pbxproj b/Easydict.xcodeproj/project.pbxproj index 0ef126f70..9c2c9fb56 100644 --- a/Easydict.xcodeproj/project.pbxproj +++ b/Easydict.xcodeproj/project.pbxproj @@ -209,6 +209,7 @@ 03F639952AA6CFBB009B9914 /* EZBingConfig.m in Sources */ = {isa = PBXBuildFile; fileRef = 03F639942AA6CFBB009B9914 /* EZBingConfig.m */; }; 17BCAEF72B0DFF9000A7D372 /* EZNiuTransTranslateResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = 17BCAEF52B0DFF9000A7D372 /* EZNiuTransTranslateResponse.m */; }; 17BCAEF82B0DFF9000A7D372 /* EZNiuTransTranslate.m in Sources */ = {isa = PBXBuildFile; fileRef = 17BCAEF62B0DFF9000A7D372 /* EZNiuTransTranslate.m */; }; + 2746AEC12AF95138005FE0A1 /* CaiyunService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2746AEC02AF95138005FE0A1 /* CaiyunService.swift */; }; 27B7919E2AEC36A1006E07C6 /* Easydict.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 27B7919C2AEC36A1006E07C6 /* Easydict.xcconfig */; }; 27B7919F2AEC36A1006E07C6 /* Easydict-debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 27B7919D2AEC36A1006E07C6 /* Easydict-debug.xcconfig */; }; 6220AD5B2A82812300BBFB52 /* EZBingService.m in Sources */ = {isa = PBXBuildFile; fileRef = 6220AD5A2A82812300BBFB52 /* EZBingService.m */; }; @@ -635,6 +636,7 @@ 17BCAEF42B0DFF9000A7D372 /* EZNiuTransTranslate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZNiuTransTranslate.h; sourceTree = ""; }; 17BCAEF52B0DFF9000A7D372 /* EZNiuTransTranslateResponse.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZNiuTransTranslateResponse.m; sourceTree = ""; }; 17BCAEF62B0DFF9000A7D372 /* EZNiuTransTranslate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZNiuTransTranslate.m; sourceTree = ""; }; + 2746AEC02AF95138005FE0A1 /* CaiyunService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CaiyunService.swift; sourceTree = ""; }; 27B7919C2AEC36A1006E07C6 /* Easydict.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Easydict.xcconfig; sourceTree = ""; }; 27B7919D2AEC36A1006E07C6 /* Easydict-debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = "Easydict-debug.xcconfig"; sourceTree = ""; }; 27B791A02AEC3A5C006E07C6 /* Easydict-debug.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = "Easydict-debug.entitlements"; sourceTree = ""; }; @@ -1151,6 +1153,7 @@ isa = PBXGroup; children = ( 17BCAEF22B0DFF9000A7D372 /* Niutrans */, + 2746AEBF2AF95040005FE0A1 /* Caiyun */, 6220AD582A8280E800BBFB52 /* Bing */, 0399C6A929A8608000B4AFCC /* OpenAI */, 03F14A382956011400CB7379 /* Volcano */, @@ -1828,6 +1831,14 @@ path = Niutrans; sourceTree = ""; }; + 2746AEBF2AF95040005FE0A1 /* Caiyun */ = { + isa = PBXGroup; + children = ( + 2746AEC02AF95138005FE0A1 /* CaiyunService.swift */, + ); + path = Caiyun; + sourceTree = ""; + }; 6220AD582A8280E800BBFB52 /* Bing */ = { isa = PBXGroup; children = ( @@ -2318,6 +2329,7 @@ 03F0DB382953428300EBF9C1 /* EZLog.m in Sources */, 03B0231429231FA6001C7E63 /* DarkModeManager.m in Sources */, 03BDA7C02A26DA280079D04F /* XPMArgumentPackage.m in Sources */, + 2746AEC12AF95138005FE0A1 /* CaiyunService.swift in Sources */, 037852B02957FEB200D0E2CF /* EZServiceViewController.m in Sources */, 6220AD5B2A82812300BBFB52 /* EZBingService.m in Sources */, 039F5508294B6E29004AB940 /* EZAboutViewController.m in Sources */, diff --git a/Easydict/App/Easydict-Bridging-Header.h b/Easydict/App/Easydict-Bridging-Header.h index 724abb748..071ae9577 100644 --- a/Easydict/App/Easydict-Bridging-Header.h +++ b/Easydict/App/Easydict-Bridging-Header.h @@ -3,3 +3,5 @@ // #import "MMLog.h" + +#import "EZQueryService.h" diff --git a/Easydict/Feature/PerferenceWindow/EZSettingViewController.m b/Easydict/Feature/PerferenceWindow/EZSettingViewController.m index 87c499b5c..b171378b2 100644 --- a/Easydict/Feature/PerferenceWindow/EZSettingViewController.m +++ b/Easydict/Feature/PerferenceWindow/EZSettingViewController.m @@ -130,6 +130,7 @@ @implementation EZSettingViewController _enabledTTSServiceTypes = @[ EZServiceTypeYoudao, EZServiceTypeBing, + EZServiceTypeCaiyun, EZServiceTypeGoogle, EZServiceTypeBaidu, EZServiceTypeApple, diff --git a/Easydict/Feature/Service/Caiyun/CaiyunService.swift b/Easydict/Feature/Service/Caiyun/CaiyunService.swift new file mode 100644 index 000000000..6a44e2c5a --- /dev/null +++ b/Easydict/Feature/Service/Caiyun/CaiyunService.swift @@ -0,0 +1,14 @@ +// +// CaiyunService.swift +// Easydict +// +// Created by Kyle on 2023/11/7. +// Copyright © 2023 izual. All rights reserved. +// + +import Foundation + +@objc(EZCaiyunService) +public final class CaiyunService: QueryService { + +} diff --git a/Easydict/Feature/Service/Language/EZLanguageManager.h b/Easydict/Feature/Service/Language/EZLanguageManager.h index 16f9ad9b7..5c28f9a53 100644 --- a/Easydict/Feature/Service/Language/EZLanguageManager.h +++ b/Easydict/Feature/Service/Language/EZLanguageManager.h @@ -8,6 +8,7 @@ #import #import "EZLanguageModel.h" +#import "MMOrderedDictionary.h" NS_ASSUME_NONNULL_BEGIN diff --git a/Easydict/Feature/Service/Language/EZLanguageModel.h b/Easydict/Feature/Service/Language/EZLanguageModel.h index 6f2100962..e16d446a5 100644 --- a/Easydict/Feature/Service/Language/EZLanguageModel.h +++ b/Easydict/Feature/Service/Language/EZLanguageModel.h @@ -7,6 +7,7 @@ // #import +#import "MMOrderedDictionary.h" NS_ASSUME_NONNULL_BEGIN diff --git a/Easydict/Feature/Service/Model/EZEnumTypes.h b/Easydict/Feature/Service/Model/EZEnumTypes.h index 8c6dd62b0..a91eb1375 100644 --- a/Easydict/Feature/Service/Model/EZEnumTypes.h +++ b/Easydict/Feature/Service/Model/EZEnumTypes.h @@ -7,6 +7,7 @@ // #import +#import "MMOrderedDictionary.h" NS_ASSUME_NONNULL_BEGIN @@ -39,6 +40,7 @@ FOUNDATION_EXPORT EZServiceType const EZServiceTypeOpenAI; FOUNDATION_EXPORT EZServiceType const EZServiceTypeAppleDictionary; FOUNDATION_EXPORT EZServiceType const EZServiceTypeBing; FOUNDATION_EXPORT EZServiceType const EZServiceTypeNiuTrans; +FOUNDATION_EXPORT EZServiceType const EZServiceTypeCaiyun; FOUNDATION_EXPORT NSString *const EZQueryTextTypeKey; FOUNDATION_EXPORT NSString *const EZIntelligentQueryTextTypeKey; diff --git a/Easydict/Feature/Service/Model/EZEnumTypes.m b/Easydict/Feature/Service/Model/EZEnumTypes.m index 2a4ec85e1..22133cb5e 100644 --- a/Easydict/Feature/Service/Model/EZEnumTypes.m +++ b/Easydict/Feature/Service/Model/EZEnumTypes.m @@ -19,6 +19,7 @@ NSString *const EZServiceTypeOpenAI = @"OpenAI"; NSString *const EZServiceTypeBing = @"Bing"; NSString *const EZServiceTypeNiuTrans = @"NiuTrans"; +NSString *const EZServiceTypeCaiyun = @"Caiyun"; NSString *const EZServiceTypeAppleDictionary = @"AppleDictionary"; diff --git a/Easydict/Feature/Service/Model/EZQueryService.h b/Easydict/Feature/Service/Model/EZQueryService.h index 60bfd60ca..469be465c 100644 --- a/Easydict/Feature/Service/Model/EZQueryService.h +++ b/Easydict/Feature/Service/Model/EZQueryService.h @@ -14,11 +14,13 @@ #import "EZLayoutManager.h" #import "EZAudioPlayer.h" #import "EZError.h" +#import "MMOrderedDictionary.h" NS_ASSUME_NONNULL_BEGIN //@class EZAudioPlayer; +NS_SWIFT_NAME(QueryService) @interface EZQueryService : NSObject @property (nonatomic, strong) EZQueryModel *queryModel; diff --git a/Easydict/Feature/Service/Model/EZServiceTypes.m b/Easydict/Feature/Service/Model/EZServiceTypes.m index e0f6d1515..9deb9c25b 100644 --- a/Easydict/Feature/Service/Model/EZServiceTypes.m +++ b/Easydict/Feature/Service/Model/EZServiceTypes.m @@ -18,6 +18,7 @@ #import "EZConfiguration.h" #import "EZAppleDictionary.h" #import "EZNiuTransTranslate.h" +#import "Easydict-Swift.h" @interface EZServiceTypes () @@ -59,6 +60,7 @@ + (instancetype)allocWithZone:(struct _NSZone *)zone { EZServiceTypeBing, [EZBingService class], EZServiceTypeVolcano, [EZVolcanoTranslate class], EZServiceTypeNiuTrans, [EZNiuTransTranslate class], + EZServiceTypeCaiyun, [EZCaiyunService class], nil]; return allServiceDict; } From 4762aec7c16af7923476bc243bee2ffc33799be5 Mon Sep 17 00:00:00 2001 From: Kyle Date: Tue, 7 Nov 2023 01:31:23 +0800 Subject: [PATCH 02/15] Add basic support for CaiyunService Add basic implementation for Caiyun Service Fix CR suggestion Add caiyun service transtype support perf: split caiyun test token to more parts perf: improve caiyun supported langauges dict Update Easydict/Feature/Service/Caiyun/CaiyunService.swift Co-authored-by: Kyle --- Easydict.xcodeproj/project.pbxproj | 35 +++++++ Easydict/App/Easydict-Bridging-Header.h | 2 + Easydict/App/Localizable.xcstrings | 11 +++ .../Service/Caiyun/CaiyunResponse.swift | 15 +++ .../Service/Caiyun/CaiyunService.swift | 99 +++++++++++++++++++ .../Service/Caiyun/CaiyunTranslateType.swift | 73 ++++++++++++++ .../Service/Language/EZLanguageModel.h | 2 +- Easydict/Feature/Service/Model/EZConstKey.h | 1 + Easydict/Feature/Service/Model/EZEnumTypes.h | 2 +- .../Utility/EZLinkParser/EZSchemeParser.m | 3 +- 10 files changed, 240 insertions(+), 3 deletions(-) create mode 100644 Easydict/Feature/Service/Caiyun/CaiyunResponse.swift create mode 100644 Easydict/Feature/Service/Caiyun/CaiyunTranslateType.swift diff --git a/Easydict.xcodeproj/project.pbxproj b/Easydict.xcodeproj/project.pbxproj index 9c2c9fb56..1abe9b581 100644 --- a/Easydict.xcodeproj/project.pbxproj +++ b/Easydict.xcodeproj/project.pbxproj @@ -209,7 +209,10 @@ 03F639952AA6CFBB009B9914 /* EZBingConfig.m in Sources */ = {isa = PBXBuildFile; fileRef = 03F639942AA6CFBB009B9914 /* EZBingConfig.m */; }; 17BCAEF72B0DFF9000A7D372 /* EZNiuTransTranslateResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = 17BCAEF52B0DFF9000A7D372 /* EZNiuTransTranslateResponse.m */; }; 17BCAEF82B0DFF9000A7D372 /* EZNiuTransTranslate.m in Sources */ = {isa = PBXBuildFile; fileRef = 17BCAEF62B0DFF9000A7D372 /* EZNiuTransTranslate.m */; }; + 2721E4D02AFE920700A059AC /* Alamofire in Frameworks */ = {isa = PBXBuildFile; productRef = 2721E4CF2AFE920700A059AC /* Alamofire */; }; 2746AEC12AF95138005FE0A1 /* CaiyunService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2746AEC02AF95138005FE0A1 /* CaiyunService.swift */; }; + 278322602B0FB0EA0026644C /* CaiyunResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2783225F2B0FB0EA0026644C /* CaiyunResponse.swift */; }; + 278322622B0FB8EF0026644C /* CaiyunTranslateType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 278322612B0FB8EF0026644C /* CaiyunTranslateType.swift */; }; 27B7919E2AEC36A1006E07C6 /* Easydict.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 27B7919C2AEC36A1006E07C6 /* Easydict.xcconfig */; }; 27B7919F2AEC36A1006E07C6 /* Easydict-debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 27B7919D2AEC36A1006E07C6 /* Easydict-debug.xcconfig */; }; 6220AD5B2A82812300BBFB52 /* EZBingService.m in Sources */ = {isa = PBXBuildFile; fileRef = 6220AD5A2A82812300BBFB52 /* EZBingService.m */; }; @@ -637,6 +640,8 @@ 17BCAEF52B0DFF9000A7D372 /* EZNiuTransTranslateResponse.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZNiuTransTranslateResponse.m; sourceTree = ""; }; 17BCAEF62B0DFF9000A7D372 /* EZNiuTransTranslate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZNiuTransTranslate.m; sourceTree = ""; }; 2746AEC02AF95138005FE0A1 /* CaiyunService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CaiyunService.swift; sourceTree = ""; }; + 2783225F2B0FB0EA0026644C /* CaiyunResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CaiyunResponse.swift; sourceTree = ""; }; + 278322612B0FB8EF0026644C /* CaiyunTranslateType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CaiyunTranslateType.swift; sourceTree = ""; }; 27B7919C2AEC36A1006E07C6 /* Easydict.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Easydict.xcconfig; sourceTree = ""; }; 27B7919D2AEC36A1006E07C6 /* Easydict-debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = "Easydict-debug.xcconfig"; sourceTree = ""; }; 27B791A02AEC3A5C006E07C6 /* Easydict-debug.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = "Easydict-debug.entitlements"; sourceTree = ""; }; @@ -679,6 +684,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 2721E4D02AFE920700A059AC /* Alamofire in Frameworks */, B87AC7E36367075BA5D13234 /* Pods_Easydict.framework in Frameworks */, 03B63ABF2A86967800E155ED /* CoreServices.framework in Frameworks */, ); @@ -1835,6 +1841,8 @@ isa = PBXGroup; children = ( 2746AEC02AF95138005FE0A1 /* CaiyunService.swift */, + 2783225F2B0FB0EA0026644C /* CaiyunResponse.swift */, + 278322612B0FB8EF0026644C /* CaiyunTranslateType.swift */, ); path = Caiyun; sourceTree = ""; @@ -1968,6 +1976,9 @@ dependencies = ( ); name = Easydict; + packageProductDependencies = ( + 2721E4CF2AFE920700A059AC /* Alamofire */, + ); productName = Bob; productReference = C99EEB182385796700FEE666 /* Easydict-Debug.app */; productType = "com.apple.product-type.application"; @@ -2006,6 +2017,9 @@ "zh-Hans", ); mainGroup = C99EEB0F2385796700FEE666; + packageReferences = ( + 2721E4CE2AFE920700A059AC /* XCRemoteSwiftPackageReference "Alamofire" */, + ); productRefGroup = C99EEB192385796700FEE666 /* Products */; projectDirPath = ""; projectRoot = ""; @@ -2252,6 +2266,7 @@ 03B0232329231FA6001C7E63 /* NSString+MM.m in Sources */, 036196772A000F5900806370 /* NSData+CommonCrypto.m in Sources */, 03882F8D29D95044005B5A52 /* CTView.m in Sources */, + 278322602B0FB0EA0026644C /* CaiyunResponse.swift in Sources */, 03B3B8B52925DD3D00168E8D /* EZPopButtonViewController.m in Sources */, 03542A5B2938DA2B00C34C33 /* EZDetectLanguageButton.m in Sources */, 03B0232929231FA6001C7E63 /* NSDictionary+MM.m in Sources */, @@ -2324,6 +2339,7 @@ 17BCAEF72B0DFF9000A7D372 /* EZNiuTransTranslateResponse.m in Sources */, 03BDA7B82A26DA280079D04F /* XPMValuedArgument.m in Sources */, 036196762A000F5900806370 /* NSData+Base64.m in Sources */, + 278322622B0FB8EF0026644C /* CaiyunTranslateType.swift in Sources */, 03BDA7BA2A26DA280079D04F /* XPMMutableAttributedArray.m in Sources */, 037852B629588EDE00D0E2CF /* EZCustomTableRowView.m in Sources */, 03F0DB382953428300EBF9C1 /* EZLog.m in Sources */, @@ -2730,6 +2746,25 @@ defaultConfigurationName = Release; }; /* End XCConfigurationList section */ + +/* Begin XCRemoteSwiftPackageReference section */ + 2721E4CE2AFE920700A059AC /* XCRemoteSwiftPackageReference "Alamofire" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/Alamofire/Alamofire.git"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 5.8.1; + }; + }; +/* End XCRemoteSwiftPackageReference section */ + +/* Begin XCSwiftPackageProductDependency section */ + 2721E4CF2AFE920700A059AC /* Alamofire */ = { + isa = XCSwiftPackageProductDependency; + package = 2721E4CE2AFE920700A059AC /* XCRemoteSwiftPackageReference "Alamofire" */; + productName = Alamofire; + }; +/* End XCSwiftPackageProductDependency section */ }; rootObject = C99EEB102385796700FEE666 /* Project object */; } diff --git a/Easydict/App/Easydict-Bridging-Header.h b/Easydict/App/Easydict-Bridging-Header.h index 071ae9577..9f9a9f0f2 100644 --- a/Easydict/App/Easydict-Bridging-Header.h +++ b/Easydict/App/Easydict-Bridging-Header.h @@ -5,3 +5,5 @@ #import "MMLog.h" #import "EZQueryService.h" +#import "EZConstKey.h" +#import "FWEncryptorAES.h" diff --git a/Easydict/App/Localizable.xcstrings b/Easydict/App/Localizable.xcstrings index 893731daf..8d05857b2 100644 --- a/Easydict/App/Localizable.xcstrings +++ b/Easydict/App/Localizable.xcstrings @@ -414,6 +414,17 @@ } } }, + "caiyun_translate" : { + "comment" : "The name of Caiyun Translate", + "localizations" : { + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "彩云小译" + } + } + } + }, "cancel" : { "localizations" : { "en" : { diff --git a/Easydict/Feature/Service/Caiyun/CaiyunResponse.swift b/Easydict/Feature/Service/Caiyun/CaiyunResponse.swift new file mode 100644 index 000000000..9225955b4 --- /dev/null +++ b/Easydict/Feature/Service/Caiyun/CaiyunResponse.swift @@ -0,0 +1,15 @@ +// +// CaiyunResponse.swift +// Easydict +// +// Created by Kyle on 2023/11/24. +// Copyright © 2023 izual. All rights reserved. +// + +import Foundation + +struct CaiyunResponse: Codable { + var confidence: Double + var rc: Int + var target: [String] +} diff --git a/Easydict/Feature/Service/Caiyun/CaiyunService.swift b/Easydict/Feature/Service/Caiyun/CaiyunService.swift index 6a44e2c5a..d7f51266b 100644 --- a/Easydict/Feature/Service/Caiyun/CaiyunService.swift +++ b/Easydict/Feature/Service/Caiyun/CaiyunService.swift @@ -6,9 +6,108 @@ // Copyright © 2023 izual. All rights reserved. // +import Alamofire import Foundation @objc(EZCaiyunService) public final class CaiyunService: QueryService { + override public func serviceType() -> ServiceType { + .caiyun + } + override public func link() -> String? { + "https://fanyi.caiyunapp.com" + } + + override public func name() -> String { + NSLocalizedString("caiyun_translate", comment: "The name of Caiyun Translate") + } + + override public func supportLanguagesDictionary() -> MMOrderedDictionary { + // TODO: Replace MMOrderedDictionary in the API + let orderedDict = MMOrderedDictionary() + let dic: [Language: String] = [ + .auto: "auto", + .simplifiedChinese: "zh", + .english: "en", + .japanese: "ja", + ] + dic.forEach { key, value in + orderedDict.setObject(value as NSString, forKey: key.rawValue as NSString) + } + return orderedDict + } + + override public func ocr(_: EZQueryModel) async throws -> EZOCRResult { + NSLog("Caiyun Translate does not support OCR") + throw QueryServiceError.notSupported + } + + private var apiEndPoint = "https://api.interpreter.caiyunai.com/v1/translator" + + /// Official Test Token for Caiyun + private static let defaultTestToken = FWEncryptorAES.decryptText("hlvDXvvfjeFTjMjhkB5HMlyPWEXQhn3U1r+qIqn/YAk=", key: "Easydict") + + private var token: String { + let token = UserDefaults.standard.string(forKey: EZCaiyunAPIKey) + if let token, !token.isEmpty { + return token + } else { + return CaiyunService.defaultTestToken + } + } + + public override func translate(_ text: String, from: Language, to: Language, completion: @escaping (EZQueryResult, Error?) -> Void) { + if prehandleQueryTextLanguage(text, autoConvertChineseText: false, from: from, to: to, completion: completion) { + return + } + let transType = CaiyunTranslateType.type(from: from, to: to) + guard transType != .unsupported else { + result.errorType = .unsupportedLanguage + result.errorMessage = "不支持的翻译类型: \(from.rawValue) --> \(to.rawValue)" + completion(result, nil) + return + } + + let parameters: [String: Any] = [ + "source": text.split(separator: "\n"), + "trans_type": transType.rawValue, + "media": "text", + "request_id": "Easydict", + "detect": true, + ] + let headers: HTTPHeaders = [ + "content-type": "application/json", + "x-authorization": "token " + token, + ] + + let request = AF.request(apiEndPoint, + method: .post, + parameters: parameters, + encoding: JSONEncoding.default, + headers: headers) + .validate() + .responseDecodable(of: CaiyunResponse.self) { [weak self] response in + guard let self else { return } + let result = self.result + switch response.result { + case let .success(value): + result.from = from + result.to = to + result.queryText = text + result.translatedResults = value.target + completion(result, nil) + case let .failure(error): + NSLog("Caiyun lookup error \(error)") + completion(result, error) + } + } + queryModel.setStop({ + request.cancel() + }, serviceType: serviceType().rawValue) + } +} + +enum QueryServiceError: Error { + case notSupported } diff --git a/Easydict/Feature/Service/Caiyun/CaiyunTranslateType.swift b/Easydict/Feature/Service/Caiyun/CaiyunTranslateType.swift new file mode 100644 index 000000000..b7cd96989 --- /dev/null +++ b/Easydict/Feature/Service/Caiyun/CaiyunTranslateType.swift @@ -0,0 +1,73 @@ +// +// CaiyunTranslateType.swift +// Easydict +// +// Created by Kyle on 2023/11/24. +// Copyright © 2023 izual. All rights reserved. +// + +import Foundation + +struct CaiyunTranslateType: RawRepresentable { + var rawValue: String + + static let unsupported = CaiyunTranslateType(rawValue: "unsupported") + + // Align with the web interface + static func type(from: Language, to: Language) -> CaiyunTranslateType { + if from.isChinese { + guard [Language.english, .japanese, .korean, .spanish, .french, .russian].contains(to) else { + return .unsupported + } + } else if from == .english { + guard [Language.simplifiedChinese, .spanish, .french, .russian].contains(to) else { + return .unsupported + } + } else if from == .japanese { + guard [Language.simplifiedChinese].contains(to) else { + return .unsupported + } + } else if from == .korean { + guard [Language.simplifiedChinese].contains(to) else { + return .unsupported + } + } else if from == .spanish { + guard [Language.simplifiedChinese, .english, .french, .russian].contains(to) else { + return .unsupported + } + } else if from == .french { + guard [Language.simplifiedChinese, .english, .spanish, .russian].contains(to) else { + return .unsupported + } + } else if from == .french { + guard [Language.simplifiedChinese, .english, .spanish, .french].contains(to) else { + return .unsupported + } + } else if from == .auto { + guard [Language.simplifiedChinese, .english, .japanese, .korean, .spanish, .french, .russian].contains(to) else { + return .unsupported + } + } + return CaiyunTranslateType(rawValue: "\(from.caiyunValue)2\(to.caiyunValue)") + } +} + +extension Language { + var isChinese: Bool { + [Language.classicalChinese, .simplifiedChinese, .traditionalChinese].contains(self) + } + + var caiyunValue: String { + switch self { + case .classicalChinese, .simplifiedChinese, .traditionalChinese: return "zh" + case .english: return "en" + case .japanese: return "ja" + case .korean: return "ko" + case .spanish: return "es" + case .french: return "fr" + case .russian: return "ru" + case .auto: return "auto" + default: return "" + } + } +} diff --git a/Easydict/Feature/Service/Language/EZLanguageModel.h b/Easydict/Feature/Service/Language/EZLanguageModel.h index e16d446a5..7152182a4 100644 --- a/Easydict/Feature/Service/Language/EZLanguageModel.h +++ b/Easydict/Feature/Service/Language/EZLanguageModel.h @@ -12,7 +12,7 @@ NS_ASSUME_NONNULL_BEGIN // Refer Apple NLLanguage. -typedef NSString *EZLanguage NS_STRING_ENUM; +typedef NSString *EZLanguage NS_STRING_ENUM NS_SWIFT_NAME(Language); // 目前总计支持 49 种语言:简体中文,繁体中文,文言文,英语,日语,韩语,法语,西班牙语,葡萄牙语,意大利语,德语,俄语,阿拉伯语,瑞典语,罗马尼亚语,泰语,斯洛伐克语,荷兰语,匈牙利语,希腊语,丹麦语,芬兰语,波兰语,捷克语,土耳其语,立陶宛语,拉脱维亚语,乌克兰语,保加利亚语,印尼语,马来语,斯洛文尼亚语,爱沙尼亚语,越南语,波斯语,印地语,泰卢固语,泰米尔语,乌尔都语,菲律宾语,高棉语,老挝语,孟加拉语,缅甸语,挪威语,塞尔维亚语,克罗地亚语,蒙古语,希伯来语。 diff --git a/Easydict/Feature/Service/Model/EZConstKey.h b/Easydict/Feature/Service/Model/EZConstKey.h index be5472b7b..94b23b20b 100644 --- a/Easydict/Feature/Service/Model/EZConstKey.h +++ b/Easydict/Feature/Service/Model/EZConstKey.h @@ -31,6 +31,7 @@ static NSString *const EZDeepLAuthKey = @"EZDeepLAuthKey"; static NSString *const EZBingCookieKey = @"EZBingCookieKey"; static NSString *const EZNiuTransAPIKey = @"EZNiuTransAPIKey"; +static NSString *const EZCaiyunAPIKey = @"EZCaiyunAPIKey"; @interface EZConstKey : NSObject diff --git a/Easydict/Feature/Service/Model/EZEnumTypes.h b/Easydict/Feature/Service/Model/EZEnumTypes.h index a91eb1375..db285ade9 100644 --- a/Easydict/Feature/Service/Model/EZEnumTypes.h +++ b/Easydict/Feature/Service/Model/EZEnumTypes.h @@ -29,7 +29,7 @@ typedef NS_ENUM(NSUInteger, EZShowWindowPosition) { FOUNDATION_EXPORT NSString *const EZServiceTypeKey; -typedef NSString *EZServiceType NS_STRING_ENUM; +typedef NSString *EZServiceType NS_STRING_ENUM NS_SWIFT_NAME(ServiceType); FOUNDATION_EXPORT EZServiceType const EZServiceTypeGoogle; FOUNDATION_EXPORT EZServiceType const EZServiceTypeBaidu; FOUNDATION_EXPORT EZServiceType const EZServiceTypeYoudao; diff --git a/Easydict/Feature/Utility/EZLinkParser/EZSchemeParser.m b/Easydict/Feature/Utility/EZLinkParser/EZSchemeParser.m index 3983ef0e5..4a4ccbf36 100644 --- a/Easydict/Feature/Utility/EZLinkParser/EZSchemeParser.m +++ b/Easydict/Feature/Utility/EZLinkParser/EZSchemeParser.m @@ -204,7 +204,8 @@ - (NSArray *)allowedReadWriteKeys { EZDeepLAuthKey, EZDeepLTranslationAPIKey, EZNiuTransAPIKey, - +// EZCaiyunAPIKey, + EZIntelligentQueryModeKey, EZBingCookieKey, From c56125e54f18efdb35343aeac1e98b37a0b59479 Mon Sep 17 00:00:00 2001 From: tisfeng Date: Sun, 26 Nov 2023 20:40:02 +0800 Subject: [PATCH 03/15] perf: improve multiple texts translation --- Easydict/Feature/Service/Caiyun/CaiyunService.swift | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Easydict/Feature/Service/Caiyun/CaiyunService.swift b/Easydict/Feature/Service/Caiyun/CaiyunService.swift index d7f51266b..d9602ecff 100644 --- a/Easydict/Feature/Service/Caiyun/CaiyunService.swift +++ b/Easydict/Feature/Service/Caiyun/CaiyunService.swift @@ -69,8 +69,9 @@ public final class CaiyunService: QueryService { return } + // Docs: https://docs.caiyunapp.com/blog/ let parameters: [String: Any] = [ - "source": text.split(separator: "\n"), + "source": text.split(separator: "\n", omittingEmptySubsequences: false), "trans_type": transType.rawValue, "media": "text", "request_id": "Easydict", From 374b869faafb658a21109e3aac4a2a96de668ac1 Mon Sep 17 00:00:00 2001 From: tisfeng Date: Sun, 26 Nov 2023 20:46:29 +0800 Subject: [PATCH 04/15] chore: add swiftpm/Package.resolved --- .../xcshareddata/swiftpm/Package.resolved | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 Easydict.xcworkspace/xcshareddata/swiftpm/Package.resolved diff --git a/Easydict.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Easydict.xcworkspace/xcshareddata/swiftpm/Package.resolved new file mode 100644 index 000000000..bc7ce257b --- /dev/null +++ b/Easydict.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -0,0 +1,14 @@ +{ + "pins" : [ + { + "identity" : "alamofire", + "kind" : "remoteSourceControl", + "location" : "https://github.com/Alamofire/Alamofire.git", + "state" : { + "revision" : "3dc6a42c7727c49bf26508e29b0a0b35f9c7e1ad", + "version" : "5.8.1" + } + } + ], + "version" : 2 +} From b7324717f7fb854859bf79028e02f4b74af27662 Mon Sep 17 00:00:00 2001 From: tisfeng Date: Sun, 26 Nov 2023 21:05:07 +0800 Subject: [PATCH 05/15] perf: add more supported languages --- Easydict/Feature/Service/Caiyun/CaiyunService.swift | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Easydict/Feature/Service/Caiyun/CaiyunService.swift b/Easydict/Feature/Service/Caiyun/CaiyunService.swift index d9602ecff..3c2a00322 100644 --- a/Easydict/Feature/Service/Caiyun/CaiyunService.swift +++ b/Easydict/Feature/Service/Caiyun/CaiyunService.swift @@ -31,6 +31,10 @@ public final class CaiyunService: QueryService { .simplifiedChinese: "zh", .english: "en", .japanese: "ja", + .korean: "ko", + .french: "fr", + .spanish: "es", + .russian: "ru", ] dic.forEach { key, value in orderedDict.setObject(value as NSString, forKey: key.rawValue as NSString) From c3e4f822c3d649a024daa89ab3afec1744e65e6c Mon Sep 17 00:00:00 2001 From: tisfeng Date: Sun, 26 Nov 2023 21:05:32 +0800 Subject: [PATCH 06/15] perf: rename EZCaiyunAPIKey to EZCaiyunToken --- Easydict/Feature/Service/Caiyun/CaiyunService.swift | 4 ++-- Easydict/Feature/Service/Model/EZConstKey.h | 2 +- Easydict/Feature/Utility/EZLinkParser/EZSchemeParser.m | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Easydict/Feature/Service/Caiyun/CaiyunService.swift b/Easydict/Feature/Service/Caiyun/CaiyunService.swift index 3c2a00322..f784154cc 100644 --- a/Easydict/Feature/Service/Caiyun/CaiyunService.swift +++ b/Easydict/Feature/Service/Caiyun/CaiyunService.swift @@ -53,7 +53,7 @@ public final class CaiyunService: QueryService { private static let defaultTestToken = FWEncryptorAES.decryptText("hlvDXvvfjeFTjMjhkB5HMlyPWEXQhn3U1r+qIqn/YAk=", key: "Easydict") private var token: String { - let token = UserDefaults.standard.string(forKey: EZCaiyunAPIKey) + let token = UserDefaults.standard.string(forKey: EZCaiyunToken) if let token, !token.isEmpty { return token } else { @@ -68,7 +68,7 @@ public final class CaiyunService: QueryService { let transType = CaiyunTranslateType.type(from: from, to: to) guard transType != .unsupported else { result.errorType = .unsupportedLanguage - result.errorMessage = "不支持的翻译类型: \(from.rawValue) --> \(to.rawValue)" + result.errorMessage = "不支持的翻译类型:\(from.rawValue) --> \(to.rawValue)" completion(result, nil) return } diff --git a/Easydict/Feature/Service/Model/EZConstKey.h b/Easydict/Feature/Service/Model/EZConstKey.h index 94b23b20b..d698c17d4 100644 --- a/Easydict/Feature/Service/Model/EZConstKey.h +++ b/Easydict/Feature/Service/Model/EZConstKey.h @@ -31,7 +31,7 @@ static NSString *const EZDeepLAuthKey = @"EZDeepLAuthKey"; static NSString *const EZBingCookieKey = @"EZBingCookieKey"; static NSString *const EZNiuTransAPIKey = @"EZNiuTransAPIKey"; -static NSString *const EZCaiyunAPIKey = @"EZCaiyunAPIKey"; +static NSString *const EZCaiyunToken = @"EZCaiyunToken"; @interface EZConstKey : NSObject diff --git a/Easydict/Feature/Utility/EZLinkParser/EZSchemeParser.m b/Easydict/Feature/Utility/EZLinkParser/EZSchemeParser.m index 4a4ccbf36..1574be544 100644 --- a/Easydict/Feature/Utility/EZLinkParser/EZSchemeParser.m +++ b/Easydict/Feature/Utility/EZLinkParser/EZSchemeParser.m @@ -204,7 +204,7 @@ - (NSArray *)allowedReadWriteKeys { EZDeepLAuthKey, EZDeepLTranslationAPIKey, EZNiuTransAPIKey, -// EZCaiyunAPIKey, + EZCaiyunToken, EZIntelligentQueryModeKey, From 9ca4c05b2cf507b8fe0f1f6187b0b4d8bec28be8 Mon Sep 17 00:00:00 2001 From: tisfeng Date: Sun, 26 Nov 2023 21:06:52 +0800 Subject: [PATCH 07/15] perf: set auto convert Chinese text to true --- Easydict/Feature/Service/Caiyun/CaiyunService.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Easydict/Feature/Service/Caiyun/CaiyunService.swift b/Easydict/Feature/Service/Caiyun/CaiyunService.swift index f784154cc..12a8411fd 100644 --- a/Easydict/Feature/Service/Caiyun/CaiyunService.swift +++ b/Easydict/Feature/Service/Caiyun/CaiyunService.swift @@ -62,7 +62,7 @@ public final class CaiyunService: QueryService { } public override func translate(_ text: String, from: Language, to: Language, completion: @escaping (EZQueryResult, Error?) -> Void) { - if prehandleQueryTextLanguage(text, autoConvertChineseText: false, from: from, to: to, completion: completion) { + if prehandleQueryTextLanguage(text, autoConvertChineseText: true, from: from, to: to, completion: completion) { return } let transType = CaiyunTranslateType.type(from: from, to: to) From 35d4e4d6ceda6d1cd431e8a1f227c5cbbe961355 Mon Sep 17 00:00:00 2001 From: tisfeng Date: Sun, 26 Nov 2023 23:52:25 +0800 Subject: [PATCH 08/15] perf: support traditional Chinese as target language --- Easydict.xcodeproj/project.pbxproj | 20 +++++++++++++++++++ Easydict/App/Easydict-Bridging-Header.h | 1 + .../Service/Caiyun/CaiyunService.swift | 12 +++++++++++ .../Service/Caiyun/CaiyunTranslateType.swift | 9 +++++++++ .../Feature/Service/Model/EZQueryService.h | 4 ++-- .../Array/Array+ChineseTextConversion.swift | 18 +++++++++++++++++ 6 files changed, 62 insertions(+), 2 deletions(-) create mode 100644 Easydict/Feature/Utility/Swift/Array/Array+ChineseTextConversion.swift diff --git a/Easydict.xcodeproj/project.pbxproj b/Easydict.xcodeproj/project.pbxproj index 1abe9b581..7046e9917 100644 --- a/Easydict.xcodeproj/project.pbxproj +++ b/Easydict.xcodeproj/project.pbxproj @@ -180,6 +180,7 @@ 03BFFC6E295FE59C004E033E /* EZQueryResult+EZYoudaoDictModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 03BFFC6D295FE59C004E033E /* EZQueryResult+EZYoudaoDictModel.m */; }; 03BFFC7129612E10004E033E /* NSString+EZConvenience.m in Sources */ = {isa = PBXBuildFile; fileRef = 03BFFC7029612E10004E033E /* NSString+EZConvenience.m */; }; 03CAB9552ADBF0FF00DA94A3 /* EZSystemUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = 03CAB9542ADBF0FF00DA94A3 /* EZSystemUtility.m */; }; + 03CF88632B137F650030C199 /* Array+ChineseTextConversion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03CF88622B137F650030C199 /* Array+ChineseTextConversion.swift */; }; 03D0434E292886D200E7559E /* EZMiniQueryWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = 03D0434D292886D200E7559E /* EZMiniQueryWindow.m */; }; 03D043522928935300E7559E /* EZMainQueryWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = 03D043512928935300E7559E /* EZMainQueryWindow.m */; }; 03D043562928940500E7559E /* EZBaseQueryWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = 03D043552928940500E7559E /* EZBaseQueryWindow.m */; }; @@ -584,6 +585,7 @@ 03BFFC7029612E10004E033E /* NSString+EZConvenience.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSString+EZConvenience.m"; sourceTree = ""; }; 03CAB9532ADBF0FF00DA94A3 /* EZSystemUtility.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EZSystemUtility.h; sourceTree = ""; }; 03CAB9542ADBF0FF00DA94A3 /* EZSystemUtility.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EZSystemUtility.m; sourceTree = ""; }; + 03CF88622B137F650030C199 /* Array+ChineseTextConversion.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Array+ChineseTextConversion.swift"; sourceTree = ""; }; 03D0434C292886D200E7559E /* EZMiniQueryWindow.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EZMiniQueryWindow.h; sourceTree = ""; }; 03D0434D292886D200E7559E /* EZMiniQueryWindow.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EZMiniQueryWindow.m; sourceTree = ""; }; 03D043502928935300E7559E /* EZMainQueryWindow.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EZMainQueryWindow.h; sourceTree = ""; }; @@ -1021,6 +1023,7 @@ 038954372A25A94E00EFFDC3 /* Utility */ = { isa = PBXGroup; children = ( + 03CF88602B137ECB0030C199 /* Swift */, 03CAB9522ADBEF5000DA94A3 /* SystemUtility */, 030570DF2ADB916E00C9905E /* AppleScript */, 03D8B26A292DBC8800D5A811 /* EZCategory */, @@ -1670,6 +1673,22 @@ path = SystemUtility; sourceTree = ""; }; + 03CF88602B137ECB0030C199 /* Swift */ = { + isa = PBXGroup; + children = ( + 03CF88612B137ED60030C199 /* Array */, + ); + path = Swift; + sourceTree = ""; + }; + 03CF88612B137ED60030C199 /* Array */ = { + isa = PBXGroup; + children = ( + 03CF88622B137F650030C199 /* Array+ChineseTextConversion.swift */, + ); + path = Array; + sourceTree = ""; + }; 03D0434A292884B900E7559E /* MiniQueryWindow */ = { isa = PBXGroup; children = ( @@ -2247,6 +2266,7 @@ 03B0230629231FA6001C7E63 /* EZLabel.m in Sources */, 03F25CB329327BC200E66A12 /* EZShortcut.m in Sources */, 033B7134293CE2430096E2DF /* EZWebViewTranslator.m in Sources */, + 03CF88632B137F650030C199 /* Array+ChineseTextConversion.swift in Sources */, 03B0231229231FA6001C7E63 /* NSObject+DarkMode.m in Sources */, 03B0233829231FA6001C7E63 /* MMOrderedDictionary.m in Sources */, 03BDA7BC2A26DA280079D04F /* XPMArgumentSignature.m in Sources */, diff --git a/Easydict/App/Easydict-Bridging-Header.h b/Easydict/App/Easydict-Bridging-Header.h index 9f9a9f0f2..edf8fcb2d 100644 --- a/Easydict/App/Easydict-Bridging-Header.h +++ b/Easydict/App/Easydict-Bridging-Header.h @@ -7,3 +7,4 @@ #import "EZQueryService.h" #import "EZConstKey.h" #import "FWEncryptorAES.h" +#import "NSString+EZChineseText.h" diff --git a/Easydict/Feature/Service/Caiyun/CaiyunService.swift b/Easydict/Feature/Service/Caiyun/CaiyunService.swift index 12a8411fd..b84fef5e9 100644 --- a/Easydict/Feature/Service/Caiyun/CaiyunService.swift +++ b/Easydict/Feature/Service/Caiyun/CaiyunService.swift @@ -29,6 +29,7 @@ public final class CaiyunService: QueryService { let dic: [Language: String] = [ .auto: "auto", .simplifiedChinese: "zh", + .traditionalChinese: "zh", .english: "en", .japanese: "ja", .korean: "ko", @@ -72,6 +73,16 @@ public final class CaiyunService: QueryService { completion(result, nil) return } + + self.didFinishBlock = ({ [weak self] (result: EZQueryResult, error: Error?) in + guard let self = self else { return } + guard var texts = result.translatedResults else { return } + + if self.queryModel.queryTargetLanguage == Language.traditionalChinese { + texts = texts.toTraditionalChineseTexts() + } + result.translatedResults = texts + }) // Docs: https://docs.caiyunapp.com/blog/ let parameters: [String: Any] = [ @@ -101,6 +112,7 @@ public final class CaiyunService: QueryService { result.to = to result.queryText = text result.translatedResults = value.target + self.didFinishBlock!(result, nil) completion(result, nil) case let .failure(error): NSLog("Caiyun lookup error \(error)") diff --git a/Easydict/Feature/Service/Caiyun/CaiyunTranslateType.swift b/Easydict/Feature/Service/Caiyun/CaiyunTranslateType.swift index b7cd96989..34c74a0e3 100644 --- a/Easydict/Feature/Service/Caiyun/CaiyunTranslateType.swift +++ b/Easydict/Feature/Service/Caiyun/CaiyunTranslateType.swift @@ -15,6 +15,11 @@ struct CaiyunTranslateType: RawRepresentable { // Align with the web interface static func type(from: Language, to: Language) -> CaiyunTranslateType { + // Auto convert Tradional Chinese + if to == .traditionalChinese { + return transType(from: from, to: to) + } + if from.isChinese { guard [Language.english, .japanese, .korean, .spanish, .french, .russian].contains(to) else { return .unsupported @@ -48,6 +53,10 @@ struct CaiyunTranslateType: RawRepresentable { return .unsupported } } + return transType(from: from, to: to) + } + + static func transType(from: Language, to: Language) -> CaiyunTranslateType { return CaiyunTranslateType(rawValue: "\(from.caiyunValue)2\(to.caiyunValue)") } } diff --git a/Easydict/Feature/Service/Model/EZQueryService.h b/Easydict/Feature/Service/Model/EZQueryService.h index 469be465c..d3231cacf 100644 --- a/Easydict/Feature/Service/Model/EZQueryService.h +++ b/Easydict/Feature/Service/Model/EZQueryService.h @@ -39,8 +39,8 @@ NS_SWIFT_NAME(QueryService) @property (nonatomic, strong) EZAudioPlayer *audioPlayer; -@property (nonatomic, copy, nullable) void (^didFinishBlock)(EZQueryResult *result, NSError *error); -@property (nonatomic, copy, nullable) void (^autoCopyTranslatedTextBlock)(EZQueryResult *result, NSError *error); +@property (nonatomic, copy, nullable) void (^didFinishBlock)(EZQueryResult *result, NSError * _Nullable error); +@property (nonatomic, copy, nullable) void (^autoCopyTranslatedTextBlock)(EZQueryResult *result, NSError *_Nullable error); /// 支持的语言 diff --git a/Easydict/Feature/Utility/Swift/Array/Array+ChineseTextConversion.swift b/Easydict/Feature/Utility/Swift/Array/Array+ChineseTextConversion.swift new file mode 100644 index 000000000..7531b6268 --- /dev/null +++ b/Easydict/Feature/Utility/Swift/Array/Array+ChineseTextConversion.swift @@ -0,0 +1,18 @@ +// +// Array+ChineseTextConversion.swift +// Easydict +// +// Created by tisfeng on 2023/11/26. +// Copyright © 2023 izual. All rights reserved. +// + +import Foundation + +extension Array where Element == String { + func toTraditionalChineseTexts() -> [String] { + return self.map { text in + let nsStringText = text as NSString + return nsStringText.toTraditionalChineseText() + } + } +} From e04fc307802465fd9a6f5dd368015e1cc601774d Mon Sep 17 00:00:00 2001 From: tisfeng Date: Mon, 27 Nov 2023 00:35:29 +0800 Subject: [PATCH 09/15] refactor: auto convert to traditional Chinese texts if need --- .../Service/Caiyun/CaiyunService.swift | 11 +--------- .../Feature/Service/DeepL/EZDeepLTranslate.m | 20 +++---------------- .../Service/Google/EZGoogleTranslate.m | 1 - .../Feature/Service/Model/EZQueryResult.h | 2 ++ .../Feature/Service/Model/EZQueryResult.m | 5 +++++ .../Feature/Service/Model/EZQueryService.h | 2 ++ .../Feature/Service/Model/EZQueryService.m | 1 - .../Service/Niutrans/EZNiuTransTranslate.m | 1 - .../Service/Youdao/EZYoudaoTranslate.m | 13 +----------- .../EZBaseQueryViewController.m | 4 ++++ 10 files changed, 18 insertions(+), 42 deletions(-) diff --git a/Easydict/Feature/Service/Caiyun/CaiyunService.swift b/Easydict/Feature/Service/Caiyun/CaiyunService.swift index b84fef5e9..8c13346cb 100644 --- a/Easydict/Feature/Service/Caiyun/CaiyunService.swift +++ b/Easydict/Feature/Service/Caiyun/CaiyunService.swift @@ -74,15 +74,7 @@ public final class CaiyunService: QueryService { return } - self.didFinishBlock = ({ [weak self] (result: EZQueryResult, error: Error?) in - guard let self = self else { return } - guard var texts = result.translatedResults else { return } - - if self.queryModel.queryTargetLanguage == Language.traditionalChinese { - texts = texts.toTraditionalChineseTexts() - } - result.translatedResults = texts - }) + self.autoConvertToTraditionalChineseResult = true // Docs: https://docs.caiyunapp.com/blog/ let parameters: [String: Any] = [ @@ -112,7 +104,6 @@ public final class CaiyunService: QueryService { result.to = to result.queryText = text result.translatedResults = value.target - self.didFinishBlock!(result, nil) completion(result, nil) case let .failure(error): NSLog("Caiyun lookup error \(error)") diff --git a/Easydict/Feature/Service/DeepL/EZDeepLTranslate.m b/Easydict/Feature/Service/DeepL/EZDeepLTranslate.m index 6ab27406c..6d2bed607 100644 --- a/Easydict/Feature/Service/DeepL/EZDeepLTranslate.m +++ b/Easydict/Feature/Service/DeepL/EZDeepLTranslate.m @@ -10,7 +10,6 @@ #import "EZWebViewTranslator.h" #import "EZTranslateError.h" #import "EZQueryResult+EZDeepLTranslateResponse.h" -#import "NSArray+EZChineseText.h" static NSString *kDeepLTranslateURL = @"https://www.deepl.com/translator"; @@ -134,25 +133,12 @@ - (void)translate:(NSString *)text from:(EZLanguage)from to:(EZLanguage)to compl return; } - mm_weakify(self); - [self setDidFinishBlock:^(EZQueryResult *result, NSError *error) { - mm_strongify(self); - NSArray *texts = result.translatedResults; - if ([self.queryModel.queryTargetLanguage isEqualToString:EZLanguageTraditionalChinese]) { - texts = [texts toTraditionalChineseTexts]; - } - result.translatedResults = texts; - }]; + self.autoConvertToTraditionalChineseResult = YES; - void (^callback)(EZQueryResult *result, NSError *error) = ^(EZQueryResult *result, NSError *error) { - self.didFinishBlock(result, error); - completion(result, error); - }; - if (self.apiType == EZDeepLTranslationAPIWebFirst) { - [self deepLWebTranslate:text from:from to:to completion:callback]; + [self deepLWebTranslate:text from:from to:to completion:completion]; } else { - [self deepLTranslate:text from:from to:to completion:callback]; + [self deepLTranslate:text from:from to:to completion:completion]; } } diff --git a/Easydict/Feature/Service/Google/EZGoogleTranslate.m b/Easydict/Feature/Service/Google/EZGoogleTranslate.m index bb3d13575..48d53f292 100644 --- a/Easydict/Feature/Service/Google/EZGoogleTranslate.m +++ b/Easydict/Feature/Service/Google/EZGoogleTranslate.m @@ -10,7 +10,6 @@ #import "EZYoudaoTranslate.h" #import #import "NSString+EZUtils.h" -#import "NSArray+EZChineseText.h" #import "EZConfiguration.h" static NSString *const kGoogleTranslateURL = @"https://translate.google.com"; diff --git a/Easydict/Feature/Service/Model/EZQueryResult.h b/Easydict/Feature/Service/Model/EZQueryResult.h index 64d27d733..041d7c330 100644 --- a/Easydict/Feature/Service/Model/EZQueryResult.h +++ b/Easydict/Feature/Service/Model/EZQueryResult.h @@ -177,6 +177,8 @@ NS_ASSUME_NONNULL_BEGIN - (void)reset; +- (void)convertToTraditionalChineseResult; + @end NS_ASSUME_NONNULL_END diff --git a/Easydict/Feature/Service/Model/EZQueryResult.m b/Easydict/Feature/Service/Model/EZQueryResult.m index bd1ac3eed..24b5cec02 100644 --- a/Easydict/Feature/Service/Model/EZQueryResult.m +++ b/Easydict/Feature/Service/Model/EZQueryResult.m @@ -8,6 +8,7 @@ #import "EZQueryResult.h" #import "EZLocalStorage.h" +#import "NSArray+EZChineseText.h" /// Convert part /** @@ -181,4 +182,8 @@ - (void)reset { self.showReplaceButton = NO; } +- (void)convertToTraditionalChineseResult { + self.translatedResults = [self.translatedResults toTraditionalChineseTexts]; +} + @end diff --git a/Easydict/Feature/Service/Model/EZQueryService.h b/Easydict/Feature/Service/Model/EZQueryService.h index d3231cacf..648c54e2a 100644 --- a/Easydict/Feature/Service/Model/EZQueryService.h +++ b/Easydict/Feature/Service/Model/EZQueryService.h @@ -42,6 +42,8 @@ NS_SWIFT_NAME(QueryService) @property (nonatomic, copy, nullable) void (^didFinishBlock)(EZQueryResult *result, NSError * _Nullable error); @property (nonatomic, copy, nullable) void (^autoCopyTranslatedTextBlock)(EZQueryResult *result, NSError *_Nullable error); +@property (nonatomic, assign) BOOL autoConvertToTraditionalChineseResult; + /// 支持的语言 - (NSArray *)languages; diff --git a/Easydict/Feature/Service/Model/EZQueryService.m b/Easydict/Feature/Service/Model/EZQueryService.m index 61029a946..1063602c7 100644 --- a/Easydict/Feature/Service/Model/EZQueryService.m +++ b/Easydict/Feature/Service/Model/EZQueryService.m @@ -132,7 +132,6 @@ - (void)ocr:(EZQueryModel *)queryModel completion:(void (^)(EZOCRResult *_Nullab [self ocr:queryModel.OCRImage from:queryModel.queryFromLanguage to:queryModel.queryTargetLanguage completion:completion]; } - #pragma mark - 子类重写 - (EZServiceType)serviceType { diff --git a/Easydict/Feature/Service/Niutrans/EZNiuTransTranslate.m b/Easydict/Feature/Service/Niutrans/EZNiuTransTranslate.m index da6cd25e3..5dd269387 100644 --- a/Easydict/Feature/Service/Niutrans/EZNiuTransTranslate.m +++ b/Easydict/Feature/Service/Niutrans/EZNiuTransTranslate.m @@ -7,7 +7,6 @@ // #import "EZNiuTransTranslate.h" -#import "NSArray+EZChineseText.h" #import "EZNiuTransTranslateResponse.h" #import "FWEncryptorAES.h" diff --git a/Easydict/Feature/Service/Youdao/EZYoudaoTranslate.m b/Easydict/Feature/Service/Youdao/EZYoudaoTranslate.m index bab2efe4c..c44f7844e 100644 --- a/Easydict/Feature/Service/Youdao/EZYoudaoTranslate.m +++ b/Easydict/Feature/Service/Youdao/EZYoudaoTranslate.m @@ -20,7 +20,6 @@ #import #import "NSData+EZMD5.h" #import "EZNetworkManager.h" -#import "NSArray+EZChineseText.h" #import "EZConfiguration.h" static NSString *const kYoudaoTranslatetURL = @"https://fanyi.youdao.com"; @@ -293,17 +292,7 @@ - (void)translate:(NSString *)text from:(EZLanguage)from to:(EZLanguage)to compl return; } - [self setDidFinishBlock:^(EZQueryResult *result, NSError *error) { - NSArray *texts = result.translatedResults; - result.translatedResults = texts; - }]; - - void (^callback)(EZQueryResult *result, NSError *error) = ^(EZQueryResult *result, NSError *error) { - self.didFinishBlock(result, error); - completion(result, error); - }; - - [self queryYoudaoDictAndTranslation:text from:from to:to completion:callback]; + [self queryYoudaoDictAndTranslation:text from:from to:to completion:completion]; } - (void)detectText:(NSString *)text completion:(void (^)(EZLanguage, NSError *_Nullable))completion { diff --git a/Easydict/Feature/ViewController/Window/BaseQueryWindow/EZBaseQueryViewController.m b/Easydict/Feature/ViewController/Window/BaseQueryWindow/EZBaseQueryViewController.m index 8648a6c33..132d667c4 100644 --- a/Easydict/Feature/ViewController/Window/BaseQueryWindow/EZBaseQueryViewController.m +++ b/Easydict/Feature/ViewController/Window/BaseQueryWindow/EZBaseQueryViewController.m @@ -685,6 +685,10 @@ - (void)queryWithModel:(EZQueryModel *)queryModel } result.error = error; + if (service.autoConvertToTraditionalChineseResult) { + [service.result convertToTraditionalChineseResult]; + } + BOOL hideResult = !result.manulShow && !result.hasTranslatedResult && result.isWarningErrorType; if (hideResult) { result.isShowing = NO; From 43bcbfe27c48eeb766dc3e14db6a2a0ee4ca179f Mon Sep 17 00:00:00 2001 From: tisfeng Date: Mon, 27 Nov 2023 09:30:24 +0800 Subject: [PATCH 10/15] perf: localize LingoCloud as English name --- Easydict/App/Localizable.xcstrings | 38 +++++++++++++++++------------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/Easydict/App/Localizable.xcstrings b/Easydict/App/Localizable.xcstrings index 8d05857b2..27b4f58a3 100644 --- a/Easydict/App/Localizable.xcstrings +++ b/Easydict/App/Localizable.xcstrings @@ -417,6 +417,12 @@ "caiyun_translate" : { "comment" : "The name of Caiyun Translate", "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "LingoCloud" + } + }, "zh-Hans" : { "stringUnit" : { "state" : "translated", @@ -1390,6 +1396,22 @@ } } }, + "niuTrans_translate" : { + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "NiuTrans" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "小牛翻译" + } + } + } + }, "no_results_found" : { "localizations" : { "en" : { @@ -2204,22 +2226,6 @@ } } }, - "niuTrans_translate" : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "NiuTrans" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "小牛翻译" - } - } - } - }, "Youdao" : { "extractionState" : "manual", "localizations" : { From 71959a0d9e05cb328a3532ff6f1466eedb3c5d1c Mon Sep 17 00:00:00 2001 From: tisfeng Date: Mon, 27 Nov 2023 09:32:48 +0800 Subject: [PATCH 11/15] perf: update Localizable.xcstrings --- Easydict/App/Localizable.xcstrings | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/Easydict/App/Localizable.xcstrings b/Easydict/App/Localizable.xcstrings index 27b4f58a3..6cb871832 100644 --- a/Easydict/App/Localizable.xcstrings +++ b/Easydict/App/Localizable.xcstrings @@ -408,7 +408,7 @@ "localizations" : { "zh-Hans" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "" } } @@ -612,7 +612,7 @@ "localizations" : { "zh-Hans" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "" } } @@ -882,7 +882,7 @@ "localizations" : { "zh-Hans" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "" } } @@ -1053,7 +1053,7 @@ "localizations" : { "zh-Hans" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "" } } @@ -1154,7 +1154,7 @@ "localizations" : { "zh-Hans" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "" } } @@ -1165,7 +1165,7 @@ "localizations" : { "zh-Hans" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "" } } @@ -1176,7 +1176,7 @@ "localizations" : { "zh-Hans" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "" } } @@ -1203,7 +1203,7 @@ "localizations" : { "zh-Hans" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "" } } @@ -1342,7 +1342,7 @@ "localizations" : { "zh-Hans" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "" } } @@ -1545,7 +1545,7 @@ "localizations" : { "zh-Hans" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "" } } @@ -1802,7 +1802,7 @@ }, "zh-Hans" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "使用译文替换" } } @@ -2086,7 +2086,7 @@ "localizations" : { "zh-Hans" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "" } } @@ -2161,7 +2161,7 @@ "localizations" : { "zh-Hans" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "" } } @@ -2172,7 +2172,7 @@ "localizations" : { "zh-Hans" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "" } } From 15da6e02cba9ef3bf512451d59a56fd8408fb0a7 Mon Sep 17 00:00:00 2001 From: tisfeng Date: Mon, 27 Nov 2023 09:44:12 +0800 Subject: [PATCH 12/15] perf: localize unsupported_translation_type --- Easydict/App/Localizable.xcstrings | 16 ++++++++++++++++ .../Feature/Service/Caiyun/CaiyunService.swift | 3 ++- 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/Easydict/App/Localizable.xcstrings b/Easydict/App/Localizable.xcstrings index 6cb871832..d5359222d 100644 --- a/Easydict/App/Localizable.xcstrings +++ b/Easydict/App/Localizable.xcstrings @@ -2194,6 +2194,22 @@ } } }, + "unsupported_translation_type" : { + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Unsupported translation type" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "不支持的翻译类型" + } + } + } + }, "us_phonetic" : { "localizations" : { "en" : { diff --git a/Easydict/Feature/Service/Caiyun/CaiyunService.swift b/Easydict/Feature/Service/Caiyun/CaiyunService.swift index 8c13346cb..7cd86364e 100644 --- a/Easydict/Feature/Service/Caiyun/CaiyunService.swift +++ b/Easydict/Feature/Service/Caiyun/CaiyunService.swift @@ -69,7 +69,8 @@ public final class CaiyunService: QueryService { let transType = CaiyunTranslateType.type(from: from, to: to) guard transType != .unsupported else { result.errorType = .unsupportedLanguage - result.errorMessage = "不支持的翻译类型:\(from.rawValue) --> \(to.rawValue)" + let unsupportedType = NSLocalizedString("unsupported_translation_type", comment: "") + result.errorMessage = "\(unsupportedType): \(from.rawValue) --> \(to.rawValue)" completion(result, nil) return } From 8c8e4065291f2f9f0598912b1c24bd8cbe9c5801 Mon Sep 17 00:00:00 2001 From: tisfeng Date: Mon, 27 Nov 2023 10:40:05 +0800 Subject: [PATCH 13/15] perf: improve transType() --- .../Service/Caiyun/CaiyunService.swift | 2 +- .../Service/Caiyun/CaiyunTranslateType.swift | 64 ++++++------------- 2 files changed, 20 insertions(+), 46 deletions(-) diff --git a/Easydict/Feature/Service/Caiyun/CaiyunService.swift b/Easydict/Feature/Service/Caiyun/CaiyunService.swift index 7cd86364e..210e0e995 100644 --- a/Easydict/Feature/Service/Caiyun/CaiyunService.swift +++ b/Easydict/Feature/Service/Caiyun/CaiyunService.swift @@ -66,7 +66,7 @@ public final class CaiyunService: QueryService { if prehandleQueryTextLanguage(text, autoConvertChineseText: true, from: from, to: to, completion: completion) { return } - let transType = CaiyunTranslateType.type(from: from, to: to) + let transType = CaiyunTranslateType.transType(from: from, to: to) guard transType != .unsupported else { result.errorType = .unsupportedLanguage let unsupportedType = NSLocalizedString("unsupported_translation_type", comment: "") diff --git a/Easydict/Feature/Service/Caiyun/CaiyunTranslateType.swift b/Easydict/Feature/Service/Caiyun/CaiyunTranslateType.swift index 34c74a0e3..51c308a9f 100644 --- a/Easydict/Feature/Service/Caiyun/CaiyunTranslateType.swift +++ b/Easydict/Feature/Service/Caiyun/CaiyunTranslateType.swift @@ -10,54 +10,28 @@ import Foundation struct CaiyunTranslateType: RawRepresentable { var rawValue: String - + static let unsupported = CaiyunTranslateType(rawValue: "unsupported") - - // Align with the web interface - static func type(from: Language, to: Language) -> CaiyunTranslateType { - // Auto convert Tradional Chinese - if to == .traditionalChinese { - return transType(from: from, to: to) - } - - if from.isChinese { - guard [Language.english, .japanese, .korean, .spanish, .french, .russian].contains(to) else { - return .unsupported - } - } else if from == .english { - guard [Language.simplifiedChinese, .spanish, .french, .russian].contains(to) else { - return .unsupported - } - } else if from == .japanese { - guard [Language.simplifiedChinese].contains(to) else { - return .unsupported - } - } else if from == .korean { - guard [Language.simplifiedChinese].contains(to) else { - return .unsupported - } - } else if from == .spanish { - guard [Language.simplifiedChinese, .english, .french, .russian].contains(to) else { - return .unsupported - } - } else if from == .french { - guard [Language.simplifiedChinese, .english, .spanish, .russian].contains(to) else { - return .unsupported - } - } else if from == .french { - guard [Language.simplifiedChinese, .english, .spanish, .french].contains(to) else { - return .unsupported - } - } else if from == .auto { - guard [Language.simplifiedChinese, .english, .japanese, .korean, .spanish, .french, .russian].contains(to) else { - return .unsupported - } - } - return transType(from: from, to: to) - } + + // Align with the web interface, https://fanyi.caiyunapp.com/#/ + static let supportedTypes: [Language: [Language]] = [ + .simplifiedChinese: [.english, .japanese, .korean, .spanish, .french, .russian], + .english: [.simplifiedChinese, .spanish, .french, .russian], + .japanese: [.simplifiedChinese], + .korean: [.simplifiedChinese], + .spanish: [.simplifiedChinese, .english, .french, .russian], + .french: [.simplifiedChinese, .english, .spanish, .russian], + .russian: [.simplifiedChinese, .english, .spanish, .french], + ] static func transType(from: Language, to: Language) -> CaiyunTranslateType { - return CaiyunTranslateType(rawValue: "\(from.caiyunValue)2\(to.caiyunValue)") + // We can auto convert to Traditional Chinese. + if (supportedTypes[from] != nil && to == .traditionalChinese) || + (supportedTypes[from]?.contains(to) == true) { + return CaiyunTranslateType(rawValue: "\(from.caiyunValue)2\(to.caiyunValue)") + } else { + return .unsupported + } } } From 49b18ac2e1f4f8f0a38ce2143029527791df4738 Mon Sep 17 00:00:00 2001 From: tisfeng Date: Mon, 27 Nov 2023 11:32:08 +0800 Subject: [PATCH 14/15] fix: only auto convert to traditional Chinese when matching query target language --- Easydict/Feature/Service/Caiyun/CaiyunService.swift | 8 +++++--- Easydict/Feature/Service/DeepL/EZDeepLTranslate.m | 6 ++++-- Easydict/Feature/Service/Model/EZQueryService.h | 13 +++++++------ Easydict/Feature/Service/Model/EZQueryService.m | 4 ++++ .../BaseQueryWindow/EZBaseQueryViewController.m | 3 ++- 5 files changed, 22 insertions(+), 12 deletions(-) diff --git a/Easydict/Feature/Service/Caiyun/CaiyunService.swift b/Easydict/Feature/Service/Caiyun/CaiyunService.swift index 210e0e995..f02e6ea48 100644 --- a/Easydict/Feature/Service/Caiyun/CaiyunService.swift +++ b/Easydict/Feature/Service/Caiyun/CaiyunService.swift @@ -61,8 +61,12 @@ public final class CaiyunService: QueryService { return CaiyunService.defaultTestToken } } + + override public func autoConvertToTraditionalChineseResult() -> Bool { + return true + } - public override func translate(_ text: String, from: Language, to: Language, completion: @escaping (EZQueryResult, Error?) -> Void) { + public override func translate(_ text: String, from: Language, to: Language, completion: @escaping (EZQueryResult, Error?) -> Void) { if prehandleQueryTextLanguage(text, autoConvertChineseText: true, from: from, to: to, completion: completion) { return } @@ -74,8 +78,6 @@ public final class CaiyunService: QueryService { completion(result, nil) return } - - self.autoConvertToTraditionalChineseResult = true // Docs: https://docs.caiyunapp.com/blog/ let parameters: [String: Any] = [ diff --git a/Easydict/Feature/Service/DeepL/EZDeepLTranslate.m b/Easydict/Feature/Service/DeepL/EZDeepLTranslate.m index 6d2bed607..2b4cc0edb 100644 --- a/Easydict/Feature/Service/DeepL/EZDeepLTranslate.m +++ b/Easydict/Feature/Service/DeepL/EZDeepLTranslate.m @@ -133,8 +133,6 @@ - (void)translate:(NSString *)text from:(EZLanguage)from to:(EZLanguage)to compl return; } - self.autoConvertToTraditionalChineseResult = YES; - if (self.apiType == EZDeepLTranslationAPIWebFirst) { [self deepLWebTranslate:text from:from to:to completion:completion]; } else { @@ -146,6 +144,10 @@ - (void)ocr:(EZQueryModel *)queryModel completion:(void (^)(EZOCRResult *_Nullab NSLog(@"deepL not support ocr"); } +- (BOOL)autoConvertToTraditionalChineseResult { + return YES; +} + #pragma mark - WebView Translate - (void)webViewTranslate:(nonnull void (^)(EZQueryResult *, NSError *_Nullable))completion { diff --git a/Easydict/Feature/Service/Model/EZQueryService.h b/Easydict/Feature/Service/Model/EZQueryService.h index 648c54e2a..e169fc232 100644 --- a/Easydict/Feature/Service/Model/EZQueryService.h +++ b/Easydict/Feature/Service/Model/EZQueryService.h @@ -39,12 +39,8 @@ NS_SWIFT_NAME(QueryService) @property (nonatomic, strong) EZAudioPlayer *audioPlayer; -@property (nonatomic, copy, nullable) void (^didFinishBlock)(EZQueryResult *result, NSError * _Nullable error); @property (nonatomic, copy, nullable) void (^autoCopyTranslatedTextBlock)(EZQueryResult *result, NSError *_Nullable error); -@property (nonatomic, assign) BOOL autoConvertToTraditionalChineseResult; - - /// 支持的语言 - (NSArray *)languages; @@ -54,11 +50,9 @@ NS_SWIFT_NAME(QueryService) /// 语言字符串转枚举,不支持则返回Auto - (EZLanguage)languageEnumFromCode:(NSString *)langString; - /// 语言在支持的语言数组中的位置,不包含则返回0 - (NSInteger)indexForLanguage:(EZLanguage)lang; - /// 是否提前处理查询,如不支持的语言 /// - Parameters: /// - isAutoConvert: 是否使用本地中文简繁体转换,如 API 服务支持繁简体,则最好交给 API。 @@ -69,6 +63,13 @@ NS_SWIFT_NAME(QueryService) @end +/// 子类方法,可选重写 +@interface EZQueryService () + +/// 如果服务不支持繁体中文,可重写返回 YES 来支持。 +- (BOOL)autoConvertToTraditionalChineseResult; + +@end /// 以下方法供子类重写,且必须重写 @interface EZQueryService () diff --git a/Easydict/Feature/Service/Model/EZQueryService.m b/Easydict/Feature/Service/Model/EZQueryService.m index 1063602c7..29b8b2d38 100644 --- a/Easydict/Feature/Service/Model/EZQueryService.m +++ b/Easydict/Feature/Service/Model/EZQueryService.m @@ -165,6 +165,10 @@ - (nullable NSString *)wordLink:(EZQueryModel *)queryModel { return nil; } +- (BOOL)autoConvertToTraditionalChineseResult { + return NO; +} + - (MMOrderedDictionary *)supportLanguagesDictionary { MethodNotImplemented(); diff --git a/Easydict/Feature/ViewController/Window/BaseQueryWindow/EZBaseQueryViewController.m b/Easydict/Feature/ViewController/Window/BaseQueryWindow/EZBaseQueryViewController.m index 132d667c4..18c98608c 100644 --- a/Easydict/Feature/ViewController/Window/BaseQueryWindow/EZBaseQueryViewController.m +++ b/Easydict/Feature/ViewController/Window/BaseQueryWindow/EZBaseQueryViewController.m @@ -685,7 +685,8 @@ - (void)queryWithModel:(EZQueryModel *)queryModel } result.error = error; - if (service.autoConvertToTraditionalChineseResult) { + if (service.autoConvertToTraditionalChineseResult && + [self.queryModel.queryTargetLanguage isEqualToString:EZLanguageTraditionalChinese]) { [service.result convertToTraditionalChineseResult]; } From 71e5b755e36ce3cfb2fbe37757b16edd282673b2 Mon Sep 17 00:00:00 2001 From: tisfeng Date: Mon, 27 Nov 2023 17:16:08 +0800 Subject: [PATCH 15/15] perf: improve supportLanguagesDictionary() --- .../Service/Caiyun/CaiyunService.swift | 15 +------ .../Service/Caiyun/CaiyunTranslateType.swift | 40 +++++++++---------- 2 files changed, 20 insertions(+), 35 deletions(-) diff --git a/Easydict/Feature/Service/Caiyun/CaiyunService.swift b/Easydict/Feature/Service/Caiyun/CaiyunService.swift index f02e6ea48..2a8c44e9d 100644 --- a/Easydict/Feature/Service/Caiyun/CaiyunService.swift +++ b/Easydict/Feature/Service/Caiyun/CaiyunService.swift @@ -24,20 +24,9 @@ public final class CaiyunService: QueryService { } override public func supportLanguagesDictionary() -> MMOrderedDictionary { - // TODO: Replace MMOrderedDictionary in the API + // TODO: Replace MMOrderedDictionary. let orderedDict = MMOrderedDictionary() - let dic: [Language: String] = [ - .auto: "auto", - .simplifiedChinese: "zh", - .traditionalChinese: "zh", - .english: "en", - .japanese: "ja", - .korean: "ko", - .french: "fr", - .spanish: "es", - .russian: "ru", - ] - dic.forEach { key, value in + CaiyunTranslateType.supportLanguagesDictionary.forEach { key, value in orderedDict.setObject(value as NSString, forKey: key.rawValue as NSString) } return orderedDict diff --git a/Easydict/Feature/Service/Caiyun/CaiyunTranslateType.swift b/Easydict/Feature/Service/Caiyun/CaiyunTranslateType.swift index 51c308a9f..22c19dbb5 100644 --- a/Easydict/Feature/Service/Caiyun/CaiyunTranslateType.swift +++ b/Easydict/Feature/Service/Caiyun/CaiyunTranslateType.swift @@ -13,7 +13,7 @@ struct CaiyunTranslateType: RawRepresentable { static let unsupported = CaiyunTranslateType(rawValue: "unsupported") - // Align with the web interface, https://fanyi.caiyunapp.com/#/ + // Align with the web interface https://fanyi.caiyunapp.com/#/ static let supportedTypes: [Language: [Language]] = [ .simplifiedChinese: [.english, .japanese, .korean, .spanish, .french, .russian], .english: [.simplifiedChinese, .spanish, .french, .russian], @@ -24,33 +24,29 @@ struct CaiyunTranslateType: RawRepresentable { .russian: [.simplifiedChinese, .english, .spanish, .french], ] + static let supportLanguagesDictionary: [Language: String] = [ + .auto: "auto", + .simplifiedChinese: "zh", + .traditionalChinese: "zh", + .english: "en", + .japanese: "ja", + .korean: "ko", + .french: "fr", + .spanish: "es", + .russian: "ru", + ] + static func transType(from: Language, to: Language) -> CaiyunTranslateType { // We can auto convert to Traditional Chinese. if (supportedTypes[from] != nil && to == .traditionalChinese) || (supportedTypes[from]?.contains(to) == true) { - return CaiyunTranslateType(rawValue: "\(from.caiyunValue)2\(to.caiyunValue)") + guard let from = supportLanguagesDictionary[from], + let to = supportLanguagesDictionary[to] else { + return .unsupported + } + return CaiyunTranslateType(rawValue: "\(from)2\(to)") } else { return .unsupported } } } - -extension Language { - var isChinese: Bool { - [Language.classicalChinese, .simplifiedChinese, .traditionalChinese].contains(self) - } - - var caiyunValue: String { - switch self { - case .classicalChinese, .simplifiedChinese, .traditionalChinese: return "zh" - case .english: return "en" - case .japanese: return "ja" - case .korean: return "ko" - case .spanish: return "es" - case .french: return "fr" - case .russian: return "ru" - case .auto: return "auto" - default: return "" - } - } -}