From d6d04b19d9906fb90b1cd0b71cec6f6cdd496dd1 Mon Sep 17 00:00:00 2001 From: tisfeng Date: Sat, 4 May 2024 21:16:57 +0800 Subject: [PATCH 01/23] docs: update README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5ef54e342..2e62f526a 100644 --- a/README.md +++ b/README.md @@ -584,7 +584,7 @@ Easydict 可以根据查询文本的内容,自动启用相应的查询服务 具体来说,在智能查询模式下,当查询单词时,则只会调用支持【单词查询】的服务;当翻译文本时,则只会调用支持【文本翻译】的服务。 -对于单词,支持查询单词的服务效果明显比翻译更好,而翻译文本时,启用单词查询服务 +对于单词查询,支持查询单词服务的效果明显比简单翻译更好,例如苹果词典和有道词典;而进行长文本翻译时,启用单词查询服务没有意义,例如使用苹果词典来翻译。 默认情况下,所有的翻译服务都支持单词查询(单词也属于文本的一种),用户可以手动调整,如设置 Google 智能模式只翻译文本,只需要使用下面命令修改为 `translation | sentence` 即可。 From 30dd06d07cfbb81b07a7a4a9dfa392ebbcfa093b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 18 May 2024 22:06:22 +0800 Subject: [PATCH 02/23] chore(deps): bump rexml in the bundler group across 1 directory (#558) Bumps the bundler group with 1 update in the / directory: [rexml](https://github.com/ruby/rexml). Updates `rexml` from 3.2.6 to 3.2.8 - [Release notes](https://github.com/ruby/rexml/releases) - [Changelog](https://github.com/ruby/rexml/blob/master/NEWS.md) - [Commits](https://github.com/ruby/rexml/compare/v3.2.6...v3.2.8) --- updated-dependencies: - dependency-name: rexml dependency-type: indirect dependency-group: bundler ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- Gemfile.lock | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index a018860a2..58cd565d7 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -82,9 +82,11 @@ GEM nap (1.1.0) netrc (0.11.0) public_suffix (4.0.7) - rexml (3.2.6) + rexml (3.2.8) + strscan (>= 3.0.9) ruby-macho (2.5.1) ruby2_keywords (0.0.5) + strscan (3.1.0) typhoeus (1.4.1) ethon (>= 0.9.0) tzinfo (2.0.6) @@ -99,9 +101,10 @@ GEM PLATFORMS arm64-darwin-22 + x86_64-linux DEPENDENCIES - cocoapods (= 1.14.2)! + cocoapods (= 1.14.2) BUNDLED WITH 2.2.3 From 381033d4d27cf95a398ee1c608e33137a9003090 Mon Sep 17 00:00:00 2001 From: tisfeng Date: Fri, 31 May 2024 22:11:31 +0800 Subject: [PATCH 03/23] chore: update star-fork-notification trigger condition --- .github/workflows/star_fork_notification.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/star_fork_notification.yml b/.github/workflows/star_fork_notification.yml index c7e3d3913..14a23b0df 100644 --- a/.github/workflows/star_fork_notification.yml +++ b/.github/workflows/star_fork_notification.yml @@ -55,8 +55,8 @@ jobs: echo "commit_count=$commit_count" >> $GITHUB_ENV echo "follower_count=$follower_count" >> $GITHUB_ENV - if [[ $commit_count -ge 0 ]]; then - echo "user_conditions_met=true" >> $GITHUB_ENV + if [[ $earn_star_count -ge 10 || $commit_count -gt 1000 ]]; then + echo "user_conditions_met=true" >> $GITHUB_ENV else echo "user_conditions_met=false" >> $GITHUB_ENV fi From 566ab7b40a4f732f377c0b404c3706d49dbd7f8a Mon Sep 17 00:00:00 2001 From: choykarl <253440030@qq.com> Date: Sun, 14 Jul 2024 19:06:37 +0800 Subject: [PATCH 04/23] feat: baidu api translate --- Easydict/App/Easydict-Bridging-Header.h | 1 + Easydict/App/Localizable.xcstrings | 34 ++++++ .../Configuration+Defaults.swift | 4 + .../BaiduTranslate+ConfigurableService.swift | 30 +++++ .../objc/Service/Baidu/BaiduApiResponse.swift | 68 +++++++++++ .../Service/Baidu/BaiduApiTranslate.swift | 115 ++++++++++++++++++ .../objc/Service/Baidu/EZBaiduTranslate.m | 13 ++ Easydict/objc/Service/Model/EZConstKey.h | 3 + 8 files changed, 268 insertions(+) create mode 100644 Easydict/Swift/View/SettingView/Tabs/ServiceConfigurationView/QueryService+ConfigurableService/BaiduTranslate+ConfigurableService.swift create mode 100644 Easydict/objc/Service/Baidu/BaiduApiResponse.swift create mode 100644 Easydict/objc/Service/Baidu/BaiduApiTranslate.swift diff --git a/Easydict/App/Easydict-Bridging-Header.h b/Easydict/App/Easydict-Bridging-Header.h index 874566c16..20280c5e3 100644 --- a/Easydict/App/Easydict-Bridging-Header.h +++ b/Easydict/App/Easydict-Bridging-Header.h @@ -35,4 +35,5 @@ #import "EZDeepLTranslate.h" #import "EZBingService.h" #import "NSString+EZUtils.h" +#import "EZBaiduTranslate.h" diff --git a/Easydict/App/Localizable.xcstrings b/Easydict/App/Localizable.xcstrings index 89ccb4914..7f74d86d1 100644 --- a/Easydict/App/Localizable.xcstrings +++ b/Easydict/App/Localizable.xcstrings @@ -2739,6 +2739,40 @@ } } }, + "service.configuration.baidu.app_id.title" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "App Id" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "App Id" + } + } + } + }, + "service.configuration.baidu.secret_key.title" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Secret Key" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "Secret Key" + } + } + } + }, "service.configuration.bing.cookie.title" : { "localizations" : { "en" : { diff --git a/Easydict/Swift/Feature/Configuration/Configuration+Defaults.swift b/Easydict/Swift/Feature/Configuration/Configuration+Defaults.swift index 0044070b1..0572a7909 100644 --- a/Easydict/Swift/Feature/Configuration/Configuration+Defaults.swift +++ b/Easydict/Swift/Feature/Configuration/Configuration+Defaults.swift @@ -318,6 +318,10 @@ extension Defaults.Keys { // Gemni static let geminiAPIKey = Key(EZGeminiAPIKey) + + // baidu + static let baiduAppId = Key(EZBaiduAppId) + static let baiduSecretKey = Key(EZBaiduSecretKey) } /// shortcut diff --git a/Easydict/Swift/View/SettingView/Tabs/ServiceConfigurationView/QueryService+ConfigurableService/BaiduTranslate+ConfigurableService.swift b/Easydict/Swift/View/SettingView/Tabs/ServiceConfigurationView/QueryService+ConfigurableService/BaiduTranslate+ConfigurableService.swift new file mode 100644 index 000000000..70fea792c --- /dev/null +++ b/Easydict/Swift/View/SettingView/Tabs/ServiceConfigurationView/QueryService+ConfigurableService/BaiduTranslate+ConfigurableService.swift @@ -0,0 +1,30 @@ +// +// BaiduService+ConfigurableService.swift +// Easydict +// +// Created by karl on 2024/7/13. +// Copyright © 2024 izual. All rights reserved. +// + +import Foundation +import SwiftUI + +@available(macOS 13.0, *) +extension EZBaiduTranslate: ConfigurableService { + func configurationListItems() -> some View { + ServiceConfigurationSecretSectionView( + service: self, + observeKeys: [.baiduAppId, .baiduSecretKey] + ) { + ServiceConfigurationSecureInputCell( + textFieldTitleKey: "service.configuration.baidu.app_id.title", + key: .baiduAppId + ) + + ServiceConfigurationSecureInputCell( + textFieldTitleKey: "service.configuration.baidu.secret_key.title", + key: .baiduSecretKey + ) + } + } +} diff --git a/Easydict/objc/Service/Baidu/BaiduApiResponse.swift b/Easydict/objc/Service/Baidu/BaiduApiResponse.swift new file mode 100644 index 000000000..ba0d3a23b --- /dev/null +++ b/Easydict/objc/Service/Baidu/BaiduApiResponse.swift @@ -0,0 +1,68 @@ +// +// BaiduApiResponse.swift +// Easydict +// +// Created by karl on 2024/7/13. +// Copyright © 2024 izual. All rights reserved. +// + +import Foundation + +// MARK: - BaiduApiResponse + +/* + { + "from": "en", + "to": "zh", + "trans_result": [ + { + "src": "apple", + "dst": "苹果" + } + ] + } + + */ + +struct BaiduApiResponse: Codable { + // MARK: Internal + + struct TransResult: Codable { + var src: String + var dst: String + } + + var from: String + var to: String + var transResult: [TransResult] + + // MARK: Private + + private enum CodingKeys: String, CodingKey { + case transResult = "trans_result" + case from + case to + } +} + +// MARK: - BaiduApiErrorResponse + +/* + { + "error_code": "54001", + "error_msg": "Invalid Sign" + } + */ +struct BaiduApiErrorResponse: Codable { + // MARK: Internal + + var errorCode: String + var errorMsg: String + + // MARK: Private + + private enum CodingKeys: String, CodingKey { + case errorCode = "error_code" + case errorMsg = "error_msg" + } +} diff --git a/Easydict/objc/Service/Baidu/BaiduApiTranslate.swift b/Easydict/objc/Service/Baidu/BaiduApiTranslate.swift new file mode 100644 index 000000000..026fb6628 --- /dev/null +++ b/Easydict/objc/Service/Baidu/BaiduApiTranslate.swift @@ -0,0 +1,115 @@ +// +// EZBaiduApiTranslate.swift +// Easydict +// +// Created by karl on 2024/7/13. +// Copyright © 2024 izual. All rights reserved. +// + +import Alamofire +import Defaults +import Foundation + +@objc(EZBaiduApiTranslate) +@objcMembers +class BaiduApiTranslate: NSObject { + // MARK: Lifecycle + + required public init(queryModel: EZQueryModel) { + self.queryModel = queryModel + super.init() + } + + // MARK: Internal + + var result: EZQueryResult? + + var isEnable: Bool { + appId != nil && secretKey != nil + } + + func translate(_ text: String, from: Language, to: Language, completion: @escaping (EZQueryResult?, Error?) -> ()) { + guard let appId = appId, let secretKey = secretKey else { + assert(false, "API key is not available") + completion(result, EZError(type: EZErrorType.API, description: "API key is not available")) + return + } + + guard let utf8Data = text.data(using: .utf8), + let q = String(data: utf8Data, encoding: .utf8) else { + logError("Failed to convert text to UTF8") + completion(result, EZError(type: EZErrorType.API, description: "Failed to convert text to UTF8")) + return + } + let salt = UUID().uuidString + let sign = appId + q + salt + secretKey + let signMd5 = sign.md5() + + let param: [String: Any] = [ + "q": q, + "from": from.rawValue, + "to": to.rawValue, + "appid": appId, + "salt": salt, + "sign": signMd5, + ] + + let request = AF.request( + "https://fanyi-api.baidu.com/api/trans/vip/translate", + method: .post, + parameters: param, + headers: [ + "Content-Type": "application/x-www-form-urlencoded", + ] + ) + .validate() + .responseDecodable(of: BaiduApiResponse.self) { [weak self] response in + guard let self else { return } + let result = result ?? EZQueryResult() + result.from = from + result.to = to + result.queryText = text + + switch response.result { + case let .success(value): + result.translatedResults = value.transResult.map { $0.dst } + completion(result, nil) + case let .failure(error): + logError("Tencent lookup error \(error)") + let ezError = EZError(nsError: error) + if let data = response.data { + do { + let errorResponse = try JSONDecoder().decode(BaiduApiErrorResponse.self, from: data) + ezError?.errorDataMessage = "code:\(errorResponse.errorCode), msg:\(errorResponse.errorMsg)" + } catch { + logError("Failed to decode error response: \(error)") + } + } + completion(result, ezError) + } + } + queryModel.setStop({ + request.cancel() + }, serviceType: ServiceType.baidu.rawValue) + } + + // MARK: Private + + private let queryModel: EZQueryModel + + private var appId: String? { + let appId = Defaults[.baiduAppId] + if let appId, !appId.isEmpty { + return appId + } + return nil + } + + private var secretKey: String? { + let secretKey = Defaults[.baiduSecretKey] + if let secretKey, !secretKey.isEmpty { + return secretKey + } + return nil + } +} diff --git a/Easydict/objc/Service/Baidu/EZBaiduTranslate.m b/Easydict/objc/Service/Baidu/EZBaiduTranslate.m index ff159901e..89e150a72 100644 --- a/Easydict/objc/Service/Baidu/EZBaiduTranslate.m +++ b/Easydict/objc/Service/Baidu/EZBaiduTranslate.m @@ -22,6 +22,7 @@ @interface EZBaiduTranslate () @property (nonatomic, strong) JSValue *jsFunction; @property (nonatomic, strong) AFHTTPSessionManager *htmlSession; @property (nonatomic, strong) AFHTTPSessionManager *jsonSession; +@property (nonatomic, strong) EZBaiduApiTranslate *apiTranslate; @property (nonatomic, copy) NSString *token; @property (nonatomic, copy) NSString *gtk; @@ -45,6 +46,8 @@ - (instancetype)init { FIX https://github.com/tisfeng/Easydict/issues/466 */ + + self.apiTranslate = [[EZBaiduApiTranslate alloc] initWithQueryModel:self.queryModel]; } return self; } @@ -122,6 +125,11 @@ - (NSString *)cookie { #pragma mark - 重写父类方法 +- (void)setResult:(EZQueryResult *)result { + [super setResult:result]; + self.apiTranslate.result = result; +} + - (EZServiceType)serviceType { return EZServiceTypeBaidu; } @@ -223,6 +231,11 @@ - (void)translate:(NSString *)text from:(EZLanguage)from to:(EZLanguage)to compl text = [text trimToMaxLength:5000]; + if (self.apiTranslate.isEnable) { + [self.apiTranslate translate:text from:[self languageCodeForLanguage:from] to:[self languageCodeForLanguage:to] completion:completion]; + return; + } + void (^request)(void) = ^(void) { void (^translateBlock)(EZLanguage) = ^(EZLanguage from) { [self sendTranslateRequest:text from:from to:to completion:completion]; diff --git a/Easydict/objc/Service/Model/EZConstKey.h b/Easydict/objc/Service/Model/EZConstKey.h index 988b90de1..6a124d6fc 100644 --- a/Easydict/objc/Service/Model/EZConstKey.h +++ b/Easydict/objc/Service/Model/EZConstKey.h @@ -58,6 +58,9 @@ static NSString *const EZGeminiAPIKey = @"EZGeminiAPIKey"; static NSString *const EZAliAccessKeyId = @"EZAliAccessKeyId"; static NSString *const EZAliAccessKeySecret = @"EZAliAccessKeySecret"; +static NSString *const EZBaiduAppId = @"EZBaiduAppId"; +static NSString *const EZBaiduSecretKey = @"EZBaiduSecretKey"; + @interface EZConstKey : NSObject + (NSString *)constkey:(NSString *)key windowType:(EZWindowType)windowType; From 19b613ae05764c77a8cef3a549d1f30700d8193a Mon Sep 17 00:00:00 2001 From: choykarl <253440030@qq.com> Date: Sun, 14 Jul 2024 19:08:47 +0800 Subject: [PATCH 05/23] feat: add file --- Easydict.xcodeproj/project.pbxproj | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Easydict.xcodeproj/project.pbxproj b/Easydict.xcodeproj/project.pbxproj index 6b00dc19f..d63169d18 100644 --- a/Easydict.xcodeproj/project.pbxproj +++ b/Easydict.xcodeproj/project.pbxproj @@ -312,6 +312,9 @@ C4DD01ED2B12BE9B0025EE8E /* TencentTranslateType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4DD01EC2B12BE9B0025EE8E /* TencentTranslateType.swift */; }; C4DE3D6D2AC00EB500C2B85D /* Localizable.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = C4DE3D6C2AC00EB500C2B85D /* Localizable.xcstrings */; }; C98CAE75239F4619005F7DCA /* EasydictHelper.app in CopyFiles */ = {isa = PBXBuildFile; fileRef = C90BE309239F38EB00ADE88B /* EasydictHelper.app */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; + CB46AD812C43E8E5002472B4 /* BaiduApiTranslate.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB46AD7F2C43E8E4002472B4 /* BaiduApiTranslate.swift */; }; + CB46AD822C43E8E5002472B4 /* BaiduApiResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB46AD802C43E8E4002472B4 /* BaiduApiResponse.swift */; }; + CB46AD842C43E925002472B4 /* BaiduTranslate+ConfigurableService.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB46AD832C43E925002472B4 /* BaiduTranslate+ConfigurableService.swift */; }; DC3C643F2B187119008EEDD8 /* ChangeFontSizeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC3C643E2B187119008EEDD8 /* ChangeFontSizeView.swift */; }; DC46DF802B4417B900DEAE3E /* Configuration.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC46DF7F2B4417B900DEAE3E /* Configuration.swift */; }; DC6D9C872B352EBC0055EFFC /* FontSizeHintView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC6D9C862B352EBC0055EFFC /* FontSizeHintView.swift */; }; @@ -850,6 +853,9 @@ C4DE3D6E2AC00EB500C2B85D /* mul */ = {isa = PBXFileReference; lastKnownFileType = text.json.xcstrings; name = mul; path = mul.lproj/Main.xcstrings; sourceTree = ""; }; C90BE309239F38EB00ADE88B /* EasydictHelper.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = EasydictHelper.app; sourceTree = BUILT_PRODUCTS_DIR; }; C99EEB182385796700FEE666 /* Easydict-debug.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Easydict-debug.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + CB46AD7F2C43E8E4002472B4 /* BaiduApiTranslate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BaiduApiTranslate.swift; sourceTree = ""; }; + CB46AD802C43E8E4002472B4 /* BaiduApiResponse.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BaiduApiResponse.swift; sourceTree = ""; }; + CB46AD832C43E925002472B4 /* BaiduTranslate+ConfigurableService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "BaiduTranslate+ConfigurableService.swift"; sourceTree = ""; }; DC3C643E2B187119008EEDD8 /* ChangeFontSizeView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChangeFontSizeView.swift; sourceTree = ""; }; DC46DF7F2B4417B900DEAE3E /* Configuration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Configuration.swift; sourceTree = ""; }; DC6D9C862B352EBC0055EFFC /* FontSizeHintView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FontSizeHintView.swift; sourceTree = ""; }; @@ -1509,6 +1515,8 @@ 03B0222C29231FA6001C7E63 /* Baidu */ = { isa = PBXGroup; children = ( + CB46AD802C43E8E4002472B4 /* BaiduApiResponse.swift */, + CB46AD7F2C43E8E4002472B4 /* BaiduApiTranslate.swift */, 03542A412937B45E00C34C33 /* EZBaiduTranslate.h */, 03542A422937B45E00C34C33 /* EZBaiduTranslate.m */, 03542A442937B4C300C34C33 /* EZBaiduTranslateResponse.h */, @@ -2549,6 +2557,7 @@ 0AC8A83A2B6682D4006DA5CC /* AliService+ConfigurableService.swift */, 0AC8A8422B6957B0006DA5CC /* BingService+ConfigurableService.swift */, 0AC8A84A2B6A629D006DA5CC /* GeminiService+ConfigurableService.swift */, + CB46AD832C43E925002472B4 /* BaiduTranslate+ConfigurableService.swift */, ); path = "QueryService+ConfigurableService"; sourceTree = ""; @@ -3005,6 +3014,7 @@ 27FE95272B3DC55F000AD654 /* EasydictApp.swift in Sources */, 03882F9129D95044005B5A52 /* CTCommon.m in Sources */, 276742082B3DC230002A2C75 /* PrivacyTab.swift in Sources */, + CB46AD822C43E8E5002472B4 /* BaiduApiResponse.swift in Sources */, 0AC11B242B4E46B300F07198 /* TapHandlerView.swift in Sources */, 03882F8F29D95044005B5A52 /* CTScreen.m in Sources */, 0AC8A8392B666F07006DA5CC /* CaiyunService+ConfigurableService.swift in Sources */, @@ -3078,6 +3088,7 @@ 039CC90D292F664E0037B91E /* NSObject+EZWindowType.m in Sources */, 03B0232229231FA6001C7E63 /* NSImage+MM.m in Sources */, 03BB2DEF29F59C8A00447EDD /* EZSymbolImageButton.m in Sources */, + CB46AD812C43E8E5002472B4 /* BaiduApiTranslate.swift in Sources */, 0A2BA9642B4A3CCD002872A4 /* Notification+Name.swift in Sources */, C415C0AD2B450D4800A9D231 /* GeminiService.swift in Sources */, 9643D9402B6FC426000FBEA6 /* MainMenuShortcutCommand.swift in Sources */, @@ -3144,6 +3155,7 @@ 03B022E929231FA6001C7E63 /* AppDelegate.m in Sources */, 62E2BF4B2B4082BA00E42D38 /* AliResponse.swift in Sources */, 03B0232729231FA6001C7E63 /* NSColor+MM.m in Sources */, + CB46AD842C43E925002472B4 /* BaiduTranslate+ConfigurableService.swift in Sources */, 03B0233529231FA6001C7E63 /* MMFileLogFormatter.m in Sources */, 03DC38C1292CC97900922CB2 /* EZServiceInfo.m in Sources */, 0A318F3B2B8CCCCD0005EF77 /* CustomOpenAIService+ConfigurableService.swift in Sources */, From 01a793df0c22d5086abcd538c3d3c8b0031b097e Mon Sep 17 00:00:00 2001 From: choykarl <253440030@qq.com> Date: Sun, 14 Jul 2024 22:54:00 +0800 Subject: [PATCH 06/23] feat: baidu key config view --- .../ConfigurationView/BaiduTranslate+ConfigurableService.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Easydict/Swift/View/SettingView/Tabs/ServiceConfigurationView/ConfigurationView/BaiduTranslate+ConfigurableService.swift b/Easydict/Swift/View/SettingView/Tabs/ServiceConfigurationView/ConfigurationView/BaiduTranslate+ConfigurableService.swift index 723c2c718..61314a14a 100644 --- a/Easydict/Swift/View/SettingView/Tabs/ServiceConfigurationView/ConfigurationView/BaiduTranslate+ConfigurableService.swift +++ b/Easydict/Swift/View/SettingView/Tabs/ServiceConfigurationView/ConfigurationView/BaiduTranslate+ConfigurableService.swift @@ -10,7 +10,7 @@ import Foundation import SwiftUI extension EZBaiduTranslate { - func configurationListItems() -> some View { + open override func configurationListItems() -> Any { ServiceConfigurationSecretSectionView( service: self, observeKeys: [.baiduAppId, .baiduSecretKey] From f347776d61b2ef2e1984df2a0e2490446ce81da9 Mon Sep 17 00:00:00 2001 From: choykarl <253440030@qq.com> Date: Sun, 14 Jul 2024 23:04:42 +0800 Subject: [PATCH 07/23] pref: rename param --- Easydict/objc/Service/Baidu/BaiduApiTranslate.swift | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Easydict/objc/Service/Baidu/BaiduApiTranslate.swift b/Easydict/objc/Service/Baidu/BaiduApiTranslate.swift index 0b567f5c1..cf8c309a8 100644 --- a/Easydict/objc/Service/Baidu/BaiduApiTranslate.swift +++ b/Easydict/objc/Service/Baidu/BaiduApiTranslate.swift @@ -36,17 +36,17 @@ class BaiduApiTranslate: NSObject { } guard let utf8Data = text.data(using: .utf8), - let q = String(data: utf8Data, encoding: .utf8) else { + let utf8String = String(data: utf8Data, encoding: .utf8) else { logError("Failed to convert text to UTF8") completion(result, EZError(type: EZErrorType.API, description: "Failed to convert text to UTF8")) return } let salt = UUID().uuidString - let sign = appId + q + salt + secretKey + let sign = appId + utf8String + salt + secretKey let signMd5 = sign.md5() let param: [String: Any] = [ - "q": q, + "q": utf8String, "from": from.rawValue, "to": to.rawValue, "appid": appId, From ac831e6e314bb67454f24ef2080f8bfab6982ede Mon Sep 17 00:00:00 2001 From: choykarl <253440030@qq.com> Date: Mon, 15 Jul 2024 22:24:34 +0800 Subject: [PATCH 08/23] Update Easydict/objc/Service/Baidu/BaiduApiTranslate.swift Co-authored-by: tisfeng --- Easydict/objc/Service/Baidu/BaiduApiTranslate.swift | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Easydict/objc/Service/Baidu/BaiduApiTranslate.swift b/Easydict/objc/Service/Baidu/BaiduApiTranslate.swift index cf8c309a8..f06ea6cd7 100644 --- a/Easydict/objc/Service/Baidu/BaiduApiTranslate.swift +++ b/Easydict/objc/Service/Baidu/BaiduApiTranslate.swift @@ -98,9 +98,7 @@ class BaiduApiTranslate: NSObject { private let queryModel: EZQueryModel private var appId: String { - let appId = Defaults[.baiduAppId] - - return appId + Defaults[.baiduAppId] } private var secretKey: String { From 037df732afae184238150ec9608a6b0f08d1130a Mon Sep 17 00:00:00 2001 From: choykarl <253440030@qq.com> Date: Mon, 15 Jul 2024 22:24:39 +0800 Subject: [PATCH 09/23] Update Easydict/objc/Service/Baidu/BaiduApiTranslate.swift Co-authored-by: tisfeng --- Easydict/objc/Service/Baidu/BaiduApiTranslate.swift | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Easydict/objc/Service/Baidu/BaiduApiTranslate.swift b/Easydict/objc/Service/Baidu/BaiduApiTranslate.swift index f06ea6cd7..463ba75dd 100644 --- a/Easydict/objc/Service/Baidu/BaiduApiTranslate.swift +++ b/Easydict/objc/Service/Baidu/BaiduApiTranslate.swift @@ -102,7 +102,6 @@ class BaiduApiTranslate: NSObject { } private var secretKey: String { - let secretKey = Defaults[.baiduSecretKey] - return secretKey + Defaults[.baiduSecretKey] } } From 684cf1ccfeda10489c72c6ea67458bf71bf2cb55 Mon Sep 17 00:00:00 2001 From: choykarl <253440030@qq.com> Date: Mon, 15 Jul 2024 22:24:48 +0800 Subject: [PATCH 10/23] Update Easydict/objc/Service/Baidu/BaiduApiTranslate.swift Co-authored-by: tisfeng --- Easydict/objc/Service/Baidu/BaiduApiTranslate.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Easydict/objc/Service/Baidu/BaiduApiTranslate.swift b/Easydict/objc/Service/Baidu/BaiduApiTranslate.swift index 463ba75dd..5331b0d7f 100644 --- a/Easydict/objc/Service/Baidu/BaiduApiTranslate.swift +++ b/Easydict/objc/Service/Baidu/BaiduApiTranslate.swift @@ -75,7 +75,7 @@ class BaiduApiTranslate: NSObject { result.translatedResults = value.transResult.map { $0.dst } completion(result, nil) case let .failure(error): - logError("Tencent lookup error \(error)") + logError("Baidu official API error \(error)") let ezError = EZError(nsError: error) if let data = response.data { do { From 6dd36546ea990c08d21f113b6f65ca62216ac59e Mon Sep 17 00:00:00 2001 From: choykarl <253440030@qq.com> Date: Mon, 15 Jul 2024 22:24:55 +0800 Subject: [PATCH 11/23] Update Easydict/App/Localizable.xcstrings Co-authored-by: tisfeng --- Easydict/App/Localizable.xcstrings | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Easydict/App/Localizable.xcstrings b/Easydict/App/Localizable.xcstrings index 9767a900b..189ebc487 100644 --- a/Easydict/App/Localizable.xcstrings +++ b/Easydict/App/Localizable.xcstrings @@ -2316,7 +2316,7 @@ "en" : { "stringUnit" : { "state" : "translated", - "value" : "App Id" + "value" : "App ID" } }, "zh-Hans" : { From 29fc9c6ce699ad7ed377aebe04c20924b9e72245 Mon Sep 17 00:00:00 2001 From: choykarl <253440030@qq.com> Date: Mon, 15 Jul 2024 22:25:08 +0800 Subject: [PATCH 12/23] Update Easydict/App/Localizable.xcstrings Co-authored-by: tisfeng --- Easydict/App/Localizable.xcstrings | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Easydict/App/Localizable.xcstrings b/Easydict/App/Localizable.xcstrings index 189ebc487..14c68ebc0 100644 --- a/Easydict/App/Localizable.xcstrings +++ b/Easydict/App/Localizable.xcstrings @@ -2322,7 +2322,7 @@ "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "App Id" + "value" : "App ID" } } } From bb7283f52059e9b5e760a971a6fcd0ba1b66ac32 Mon Sep 17 00:00:00 2001 From: choykarl <253440030@qq.com> Date: Mon, 15 Jul 2024 23:12:27 +0800 Subject: [PATCH 13/23] revert version value --- Easydict.xcworkspace/xcshareddata/swiftpm/Package.resolved | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Easydict.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Easydict.xcworkspace/xcshareddata/swiftpm/Package.resolved index 07e0b3b99..fa9f74761 100644 --- a/Easydict.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Easydict.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -335,5 +335,5 @@ } } ], - "version" : 3 + "version" : 2 } From 4af4edfa2baa21bc95bf3e3b88bc0a850b6512d5 Mon Sep 17 00:00:00 2001 From: choykarl <253440030@qq.com> Date: Thu, 18 Jul 2024 22:41:43 +0800 Subject: [PATCH 14/23] feat: baidu service api picker --- Easydict/App/Localizable.xcstrings | 34 +++++++ .../Configuration+Defaults.swift | 1 + .../BaiduTranslate+ConfigurableService.swift | 92 +++++++++++++++++++ Easydict/objc/Service/Model/EZConstKey.h | 1 + 4 files changed, 128 insertions(+) diff --git a/Easydict/App/Localizable.xcstrings b/Easydict/App/Localizable.xcstrings index 14c68ebc0..ca5d91d55 100644 --- a/Easydict/App/Localizable.xcstrings +++ b/Easydict/App/Localizable.xcstrings @@ -2310,6 +2310,40 @@ } } }, + "service.configuration.baidu.api_disable.title" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "This option is not available, please check if the App ID and Secret Key are set." + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "该选项不可用,请检查App ID和Secret Key是否已设置。" + } + } + } + }, + "service.configuration.baidu.api_picker.title" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "API Type" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "API 类型" + } + } + } + }, "service.configuration.baidu.app_id.title" : { "extractionState" : "manual", "localizations" : { diff --git a/Easydict/Swift/Feature/Configuration/Configuration+Defaults.swift b/Easydict/Swift/Feature/Configuration/Configuration+Defaults.swift index f7346f8a7..1b37e40a0 100644 --- a/Easydict/Swift/Feature/Configuration/Configuration+Defaults.swift +++ b/Easydict/Swift/Feature/Configuration/Configuration+Defaults.swift @@ -250,6 +250,7 @@ extension Defaults.Keys { // baidu static let baiduAppId = Key(EZBaiduAppId, default: "") static let baiduSecretKey = Key(EZBaiduSecretKey, default: "") + static let baiduServiceApiTypeKey = Key(EZBaiduServiceApiTypeKey) } /// shortcut diff --git a/Easydict/Swift/View/SettingView/Tabs/ServiceConfigurationView/ConfigurationView/BaiduTranslate+ConfigurableService.swift b/Easydict/Swift/View/SettingView/Tabs/ServiceConfigurationView/ConfigurationView/BaiduTranslate+ConfigurableService.swift index 61314a14a..bbf3496a3 100644 --- a/Easydict/Swift/View/SettingView/Tabs/ServiceConfigurationView/ConfigurationView/BaiduTranslate+ConfigurableService.swift +++ b/Easydict/Swift/View/SettingView/Tabs/ServiceConfigurationView/ConfigurationView/BaiduTranslate+ConfigurableService.swift @@ -6,6 +6,7 @@ // Copyright © 2024 izual. All rights reserved. // +import Defaults import Foundation import SwiftUI @@ -15,6 +16,8 @@ extension EZBaiduTranslate { service: self, observeKeys: [.baiduAppId, .baiduSecretKey] ) { + BaiduServiceApiTypePicker() + ServiceConfigurationSecureInputCell( textFieldTitleKey: "service.configuration.baidu.app_id.title", key: .baiduAppId @@ -27,3 +30,92 @@ extension EZBaiduTranslate { } } } + +// MARK: - BaiduServiceApiTypePicker + +struct BaiduServiceApiTypePicker: View { + // MARK: Lifecycle + + init() { + let selected = Defaults[.baiduServiceApiTypeKey] + + if selected == nil, !Self.appid.isEmpty, !Self.secretKey.isEmpty { + self.selection = .secretKey + } else { + self.selection = selected ?? .web + } + } + + // MARK: Internal + + // MARK: - BaiduServiceConfigurationPickerSelection + + enum ApiType: String, CaseIterable, Identifiable, Defaults.Serializable { + case web + case secretKey + + // MARK: Internal + + var id: Self { self } + + var title: String { + switch self { + case .web: + "Web API" + case .secretKey: + "Secret Key API" + } + } + } + + static var appid: String { + Defaults[.baiduAppId] + } + + static var secretKey: String { + Defaults[.baiduSecretKey] + } + + var body: some View { + Picker("service.configuration.baidu.api_picker.title", selection: $selection) { + ForEach(ApiType.allCases, id: \.self) { selection in + Text(selection.title).tag(selection) + } + } + .padding(10) + .onChange(of: selection) { newValue in + validateSelection(newValue) + } + .alert(isPresented: $showAlert, error: PickerSelectionError(), actions: { + Button("ok") {} + }) + } + + // MARK: Private + + private struct PickerSelectionError: LocalizedError { + var errorDescription: String? { + NSLocalizedString("service.configuration.baidu.api_disable.title", comment: "") + } + } + + @State private var showAlert = false + + @State private var selection: ApiType { + didSet { + if oldValue == selection { + return + } + Defaults[.baiduServiceApiTypeKey] = selection + } + } + + private func validateSelection(_ newValue: ApiType) { + if newValue == .secretKey, Self.appid.isEmpty || Self.secretKey.isEmpty { + selection = .web + showAlert = true + } else { + selection = newValue + } + } +} diff --git a/Easydict/objc/Service/Model/EZConstKey.h b/Easydict/objc/Service/Model/EZConstKey.h index 2a4aaa997..e00ec2ded 100644 --- a/Easydict/objc/Service/Model/EZConstKey.h +++ b/Easydict/objc/Service/Model/EZConstKey.h @@ -28,6 +28,7 @@ static NSString *const EZAliAccessKeySecret = @"EZAliAccessKeySecret"; static NSString *const EZBaiduAppId = @"EZBaiduAppId"; static NSString *const EZBaiduSecretKey = @"EZBaiduSecretKey"; +static NSString *const EZBaiduServiceApiTypeKey = @"EZBaiduServiceApiTypeKey"; @interface EZConstKey : NSObject From a8e826b16e1c8543793164cd8bf0329759250ec9 Mon Sep 17 00:00:00 2001 From: choykarl <253440030@qq.com> Date: Thu, 18 Jul 2024 23:56:41 +0800 Subject: [PATCH 15/23] feat: listen appid and secretkey --- .../Configuration+Defaults.swift | 2 +- .../BaiduTranslate+ConfigurableService.swift | 112 ++++++++++++------ .../Service/Baidu/BaiduApiTranslate.swift | 4 +- 3 files changed, 78 insertions(+), 40 deletions(-) diff --git a/Easydict/Swift/Feature/Configuration/Configuration+Defaults.swift b/Easydict/Swift/Feature/Configuration/Configuration+Defaults.swift index 1b37e40a0..9d9013d60 100644 --- a/Easydict/Swift/Feature/Configuration/Configuration+Defaults.swift +++ b/Easydict/Swift/Feature/Configuration/Configuration+Defaults.swift @@ -250,7 +250,7 @@ extension Defaults.Keys { // baidu static let baiduAppId = Key(EZBaiduAppId, default: "") static let baiduSecretKey = Key(EZBaiduSecretKey, default: "") - static let baiduServiceApiTypeKey = Key(EZBaiduServiceApiTypeKey) + static let baiduServiceApiTypeKey = Key(EZBaiduServiceApiTypeKey) } /// shortcut diff --git a/Easydict/Swift/View/SettingView/Tabs/ServiceConfigurationView/ConfigurationView/BaiduTranslate+ConfigurableService.swift b/Easydict/Swift/View/SettingView/Tabs/ServiceConfigurationView/ConfigurationView/BaiduTranslate+ConfigurableService.swift index bbf3496a3..8ba4f8337 100644 --- a/Easydict/Swift/View/SettingView/Tabs/ServiceConfigurationView/ConfigurationView/BaiduTranslate+ConfigurableService.swift +++ b/Easydict/Swift/View/SettingView/Tabs/ServiceConfigurationView/ConfigurationView/BaiduTranslate+ConfigurableService.swift @@ -6,17 +6,23 @@ // Copyright © 2024 izual. All rights reserved. // +import Combine import Defaults import Foundation import SwiftUI +// lazy init global var. , avoid duplicate creation +private let pickerObserver: BaiduServiceApiTypePickerObserver = { + BaiduServiceApiTypePickerObserver() +}() + extension EZBaiduTranslate { open override func configurationListItems() -> Any { ServiceConfigurationSecretSectionView( service: self, observeKeys: [.baiduAppId, .baiduSecretKey] ) { - BaiduServiceApiTypePicker() + BaiduServiceApiTypePicker(observer: pickerObserver) ServiceConfigurationSecureInputCell( textFieldTitleKey: "service.configuration.baidu.app_id.title", @@ -34,21 +40,57 @@ extension EZBaiduTranslate { // MARK: - BaiduServiceApiTypePicker struct BaiduServiceApiTypePicker: View { + // MARK: Internal + + @ObservedObject var observer: BaiduServiceApiTypePickerObserver + + var body: some View { + Picker("service.configuration.baidu.api_picker.title", selection: $observer.selectedApiType) { + ForEach(BaiduServiceApiTypePickerObserver.ApiType.allCases, id: \.self) { selection in + Text(selection.title).tag(selection) + } + } + .padding(10) + .onChange(of: observer.selectedApiType) { newValue in + observer.validateSelection(newValue) + } + .alert(isPresented: $observer.showAlert, error: PickerSelectionError(), actions: { + Button("ok") {} + }) + } + + // MARK: Private + + private struct PickerSelectionError: LocalizedError { + var errorDescription: String? { + NSLocalizedString("service.configuration.baidu.api_disable.title", comment: "") + } + } +} + +// MARK: - BaiduServiceApiTypePickerObserver + +final class BaiduServiceApiTypePickerObserver: ObservableObject { // MARK: Lifecycle init() { - let selected = Defaults[.baiduServiceApiTypeKey] + let selectedApiType = Defaults[.baiduServiceApiTypeKey] - if selected == nil, !Self.appid.isEmpty, !Self.secretKey.isEmpty { - self.selection = .secretKey + if selectedApiType == nil, !Self.appid.isEmpty, !Self.secretKey.isEmpty { + self.selectedApiType = .secretKey } else { - self.selection = selected ?? .web + self.selectedApiType = selectedApiType ?? .web } + + appIdAndSecretKeyListener() } - // MARK: Internal + deinit { + cancellables.forEach { $0.cancel() } + cancellables.removeAll() + } - // MARK: - BaiduServiceConfigurationPickerSelection + // MARK: Internal enum ApiType: String, CaseIterable, Identifiable, Defaults.Serializable { case web @@ -76,46 +118,40 @@ struct BaiduServiceApiTypePicker: View { Defaults[.baiduSecretKey] } - var body: some View { - Picker("service.configuration.baidu.api_picker.title", selection: $selection) { - ForEach(ApiType.allCases, id: \.self) { selection in - Text(selection.title).tag(selection) - } - } - .padding(10) - .onChange(of: selection) { newValue in - validateSelection(newValue) - } - .alert(isPresented: $showAlert, error: PickerSelectionError(), actions: { - Button("ok") {} - }) - } + // MARK: Fileprivate - // MARK: Private + @Published fileprivate var showAlert = false - private struct PickerSelectionError: LocalizedError { - var errorDescription: String? { - NSLocalizedString("service.configuration.baidu.api_disable.title", comment: "") - } - } - - @State private var showAlert = false - - @State private var selection: ApiType { + @Published fileprivate var selectedApiType: ApiType { didSet { - if oldValue == selection { - return - } - Defaults[.baiduServiceApiTypeKey] = selection + Defaults[.baiduServiceApiTypeKey] = selectedApiType } } - private func validateSelection(_ newValue: ApiType) { + fileprivate func validateSelection(_ newValue: ApiType) { if newValue == .secretKey, Self.appid.isEmpty || Self.secretKey.isEmpty { - selection = .web + selectedApiType = .web showAlert = true } else { - selection = newValue + selectedApiType = newValue } } + + // MARK: Private + + private var cancellables: Set = [] + + private func appIdAndSecretKeyListener() { + let keys: [Defaults.Key] = [.baiduAppId, .baiduSecretKey] + Defaults.publisher(keys: keys) + .throttle(for: 0.5, scheduler: DispatchQueue.main, latest: true) + .receive(on: DispatchQueue.main) + .sink { [weak self] in + guard let self else { return } + let hasEmptyInput = keys.contains(where: { Defaults[$0].isEmpty }) + if hasEmptyInput, selectedApiType == .secretKey { + selectedApiType = .web + } + }.store(in: &cancellables) + } } diff --git a/Easydict/objc/Service/Baidu/BaiduApiTranslate.swift b/Easydict/objc/Service/Baidu/BaiduApiTranslate.swift index 5331b0d7f..211ffef16 100644 --- a/Easydict/objc/Service/Baidu/BaiduApiTranslate.swift +++ b/Easydict/objc/Service/Baidu/BaiduApiTranslate.swift @@ -25,7 +25,9 @@ class BaiduApiTranslate: NSObject { var result: EZQueryResult? var isEnable: Bool { - !appId.isEmpty && !secretKey.isEmpty + Defaults[.baiduServiceApiTypeKey] == BaiduServiceApiTypePickerObserver.ApiType.secretKey && !appId + .isEmpty && !secretKey + .isEmpty } func translate(_ text: String, from: Language, to: Language, completion: @escaping (EZQueryResult?, Error?) -> ()) { From ce6178aff4bac7187f9ddc160ca7d25337aeb0f0 Mon Sep 17 00:00:00 2001 From: choykarl <253440030@qq.com> Date: Sat, 20 Jul 2024 15:20:14 +0800 Subject: [PATCH 16/23] feat: baidu api type picker --- Easydict/App/Localizable.xcstrings | 57 +++++++- .../Configuration+Defaults.swift | 2 +- .../BaiduTranslate+ConfigurableService.swift | 134 +++--------------- .../Service/Baidu/BaiduApiTranslate.swift | 15 +- Easydict/objc/Service/Model/EZError.h | 1 + Easydict/objc/Service/Model/EZError.m | 4 +- 6 files changed, 85 insertions(+), 128 deletions(-) diff --git a/Easydict/App/Localizable.xcstrings b/Easydict/App/Localizable.xcstrings index ed46548bc..637991b8d 100644 --- a/Easydict/App/Localizable.xcstrings +++ b/Easydict/App/Localizable.xcstrings @@ -908,6 +908,23 @@ } } }, + "error_missing_api_key" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Missing API Key" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "缺少 API Key" + } + } + } + }, "error_network" : { "localizations" : { "en" : { @@ -2326,19 +2343,19 @@ } } }, - "service.configuration.baidu.api_disable.title" : { + "service.configuration.baidu.api_missing.tips" : { "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { "state" : "translated", - "value" : "This option is not available, please check if the App ID and Secret Key are set." + "value" : "The Secret Key API is currently in use, but either the App ID or Secret Key is empty. Please go to Settings > Service > Baidu Translate, fill in the required configuration information, or switch API types." } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "该选项不可用,请检查App ID和Secret Key是否已设置。" + "value" : "当前正使用 Secret Key API,但是 App ID 或者 Secret Key 为空,请前往设置-服务-百度翻译,填写相关配置信息,或切换 API 类型" } } } @@ -2377,6 +2394,23 @@ } } }, + "service.configuration.baidu.secret_key_api_type.title" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Secret Key API" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "Secret Key API" + } + } + } + }, "service.configuration.baidu.secret_key.title" : { "extractionState" : "manual", "localizations" : { @@ -2394,6 +2428,23 @@ } } }, + "service.configuration.baidu.web_api_type.title" : { + "extractionState" : "manual", + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Web API" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "Web API" + } + } + } + }, "service.configuration.bing.cookie.title" : { "localizations" : { "en" : { diff --git a/Easydict/Swift/Feature/Configuration/Configuration+Defaults.swift b/Easydict/Swift/Feature/Configuration/Configuration+Defaults.swift index 9d9013d60..017cf6634 100644 --- a/Easydict/Swift/Feature/Configuration/Configuration+Defaults.swift +++ b/Easydict/Swift/Feature/Configuration/Configuration+Defaults.swift @@ -250,7 +250,7 @@ extension Defaults.Keys { // baidu static let baiduAppId = Key(EZBaiduAppId, default: "") static let baiduSecretKey = Key(EZBaiduSecretKey, default: "") - static let baiduServiceApiTypeKey = Key(EZBaiduServiceApiTypeKey) + static let baiduServiceApiTypeKey = Key(EZBaiduServiceApiTypeKey, default: .secretKey) } /// shortcut diff --git a/Easydict/Swift/View/SettingView/Tabs/ServiceConfigurationView/ConfigurationView/BaiduTranslate+ConfigurableService.swift b/Easydict/Swift/View/SettingView/Tabs/ServiceConfigurationView/ConfigurationView/BaiduTranslate+ConfigurableService.swift index 8ba4f8337..1d9a90513 100644 --- a/Easydict/Swift/View/SettingView/Tabs/ServiceConfigurationView/ConfigurationView/BaiduTranslate+ConfigurableService.swift +++ b/Easydict/Swift/View/SettingView/Tabs/ServiceConfigurationView/ConfigurationView/BaiduTranslate+ConfigurableService.swift @@ -11,18 +11,17 @@ import Defaults import Foundation import SwiftUI -// lazy init global var. , avoid duplicate creation -private let pickerObserver: BaiduServiceApiTypePickerObserver = { - BaiduServiceApiTypePickerObserver() -}() - extension EZBaiduTranslate { open override func configurationListItems() -> Any { ServiceConfigurationSecretSectionView( service: self, observeKeys: [.baiduAppId, .baiduSecretKey] ) { - BaiduServiceApiTypePicker(observer: pickerObserver) + ServiceConfigurationPickerCell( + titleKey: "service.configuration.baidu.api_picker.title", + key: .baiduServiceApiTypeKey, + values: BaiduServiceApiType.allCases + ) ServiceConfigurationSecureInputCell( textFieldTitleKey: "service.configuration.baidu.app_id.title", @@ -37,121 +36,22 @@ extension EZBaiduTranslate { } } -// MARK: - BaiduServiceApiTypePicker - -struct BaiduServiceApiTypePicker: View { - // MARK: Internal - - @ObservedObject var observer: BaiduServiceApiTypePickerObserver - - var body: some View { - Picker("service.configuration.baidu.api_picker.title", selection: $observer.selectedApiType) { - ForEach(BaiduServiceApiTypePickerObserver.ApiType.allCases, id: \.self) { selection in - Text(selection.title).tag(selection) - } - } - .padding(10) - .onChange(of: observer.selectedApiType) { newValue in - observer.validateSelection(newValue) - } - .alert(isPresented: $observer.showAlert, error: PickerSelectionError(), actions: { - Button("ok") {} - }) - } +// MARK: - BaiduServiceApiType - // MARK: Private - - private struct PickerSelectionError: LocalizedError { - var errorDescription: String? { - NSLocalizedString("service.configuration.baidu.api_disable.title", comment: "") - } - } +enum BaiduServiceApiType: String, CaseIterable, Defaults.Serializable { + case web = "0" + case secretKey = "1" } -// MARK: - BaiduServiceApiTypePickerObserver - -final class BaiduServiceApiTypePickerObserver: ObservableObject { - // MARK: Lifecycle - - init() { - let selectedApiType = Defaults[.baiduServiceApiTypeKey] +// MARK: EnumLocalizedStringConvertible - if selectedApiType == nil, !Self.appid.isEmpty, !Self.secretKey.isEmpty { - self.selectedApiType = .secretKey - } else { - self.selectedApiType = selectedApiType ?? .web +extension BaiduServiceApiType: EnumLocalizedStringConvertible { + var title: LocalizedStringKey { + switch self { + case .web: + "service.configuration.baidu.web_api_type.title" + case .secretKey: + "service.configuration.baidu.secret_key_api_type.title" } - - appIdAndSecretKeyListener() - } - - deinit { - cancellables.forEach { $0.cancel() } - cancellables.removeAll() - } - - // MARK: Internal - - enum ApiType: String, CaseIterable, Identifiable, Defaults.Serializable { - case web - case secretKey - - // MARK: Internal - - var id: Self { self } - - var title: String { - switch self { - case .web: - "Web API" - case .secretKey: - "Secret Key API" - } - } - } - - static var appid: String { - Defaults[.baiduAppId] - } - - static var secretKey: String { - Defaults[.baiduSecretKey] - } - - // MARK: Fileprivate - - @Published fileprivate var showAlert = false - - @Published fileprivate var selectedApiType: ApiType { - didSet { - Defaults[.baiduServiceApiTypeKey] = selectedApiType - } - } - - fileprivate func validateSelection(_ newValue: ApiType) { - if newValue == .secretKey, Self.appid.isEmpty || Self.secretKey.isEmpty { - selectedApiType = .web - showAlert = true - } else { - selectedApiType = newValue - } - } - - // MARK: Private - - private var cancellables: Set = [] - - private func appIdAndSecretKeyListener() { - let keys: [Defaults.Key] = [.baiduAppId, .baiduSecretKey] - Defaults.publisher(keys: keys) - .throttle(for: 0.5, scheduler: DispatchQueue.main, latest: true) - .receive(on: DispatchQueue.main) - .sink { [weak self] in - guard let self else { return } - let hasEmptyInput = keys.contains(where: { Defaults[$0].isEmpty }) - if hasEmptyInput, selectedApiType == .secretKey { - selectedApiType = .web - } - }.store(in: &cancellables) } } diff --git a/Easydict/objc/Service/Baidu/BaiduApiTranslate.swift b/Easydict/objc/Service/Baidu/BaiduApiTranslate.swift index 211ffef16..72a5f423c 100644 --- a/Easydict/objc/Service/Baidu/BaiduApiTranslate.swift +++ b/Easydict/objc/Service/Baidu/BaiduApiTranslate.swift @@ -25,15 +25,18 @@ class BaiduApiTranslate: NSObject { var result: EZQueryResult? var isEnable: Bool { - Defaults[.baiduServiceApiTypeKey] == BaiduServiceApiTypePickerObserver.ApiType.secretKey && !appId - .isEmpty && !secretKey - .isEmpty + Defaults[.baiduServiceApiTypeKey] == BaiduServiceApiType.secretKey } func translate(_ text: String, from: Language, to: Language, completion: @escaping (EZQueryResult?, Error?) -> ()) { - if !isEnable { - assert(false, "API key is not enable") - completion(result, EZError(type: EZErrorType.API, description: "API key is not enable")) + if appId.isEmpty || secretKey.isEmpty { + completion( + result, + EZError( + type: EZErrorType.missingAPIKey, + description: "\n" + NSLocalizedString("service.configuration.baidu.api_missing.tips", comment: "") + ) + ) return } diff --git a/Easydict/objc/Service/Model/EZError.h b/Easydict/objc/Service/Model/EZError.h index 2ca7238f2..153242710 100644 --- a/Easydict/objc/Service/Model/EZError.h +++ b/Easydict/objc/Service/Model/EZError.h @@ -30,6 +30,7 @@ typedef NS_ENUM(NSUInteger, EZErrorType) { EZErrorTypeNoResultsFound, // 未查询到结果 EZErrorTypeInsufficientQuota, // 内置 API key 额度不足 EZErrorTypeWarppedNSError, // Warp NSError + EZErrorTypeMissingAPIKey, // 没有设置API Key }; /// 错误,不支持的语言 diff --git a/Easydict/objc/Service/Model/EZError.m b/Easydict/objc/Service/Model/EZError.m index da7318ad8..6678d439b 100644 --- a/Easydict/objc/Service/Model/EZError.m +++ b/Easydict/objc/Service/Model/EZError.m @@ -78,7 +78,9 @@ + (instancetype)errorWithType:(EZErrorType)type case EZErrorTypeInsufficientQuota: errorString = NSLocalizedString(@"error_insufficient_quota", nil); break; - + case EZErrorTypeMissingAPIKey: + errorString = NSLocalizedString(@"error_missing_api_key", nil); + break; default: errorString = NSLocalizedString(@"error_unknown", nil); break; From ae1f0c790ee2743b16e60f4ae77aad1a489a37a9 Mon Sep 17 00:00:00 2001 From: tisfeng Date: Sat, 20 Jul 2024 23:36:28 +0800 Subject: [PATCH 17/23] refactor: refactor localization and API handling for consistency - Updated localization keys and values for Baidu API configuration - Refactored `BaiduServiceApiType` enum to `ServiceAPIType` for consistency Signed-off-by: tisfeng --- Easydict/App/Localizable.xcstrings | 34 ------------------- .../Configuration+Defaults.swift | 2 +- .../BaiduTranslate+ConfigurableService.swift | 21 ++++-------- .../Service/Baidu/BaiduApiTranslate.swift | 4 +-- 4 files changed, 10 insertions(+), 51 deletions(-) diff --git a/Easydict/App/Localizable.xcstrings b/Easydict/App/Localizable.xcstrings index 637991b8d..f08330bc9 100644 --- a/Easydict/App/Localizable.xcstrings +++ b/Easydict/App/Localizable.xcstrings @@ -2394,23 +2394,6 @@ } } }, - "service.configuration.baidu.secret_key_api_type.title" : { - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Secret Key API" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "Secret Key API" - } - } - } - }, "service.configuration.baidu.secret_key.title" : { "extractionState" : "manual", "localizations" : { @@ -2428,23 +2411,6 @@ } } }, - "service.configuration.baidu.web_api_type.title" : { - "extractionState" : "manual", - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Web API" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "Web API" - } - } - } - }, "service.configuration.bing.cookie.title" : { "localizations" : { "en" : { diff --git a/Easydict/Swift/Feature/Configuration/Configuration+Defaults.swift b/Easydict/Swift/Feature/Configuration/Configuration+Defaults.swift index 017cf6634..0a9ff669f 100644 --- a/Easydict/Swift/Feature/Configuration/Configuration+Defaults.swift +++ b/Easydict/Swift/Feature/Configuration/Configuration+Defaults.swift @@ -250,7 +250,7 @@ extension Defaults.Keys { // baidu static let baiduAppId = Key(EZBaiduAppId, default: "") static let baiduSecretKey = Key(EZBaiduSecretKey, default: "") - static let baiduServiceApiTypeKey = Key(EZBaiduServiceApiTypeKey, default: .secretKey) + static let baiduServiceApiTypeKey = Key(EZBaiduServiceApiTypeKey, default: .secretKey) } /// shortcut diff --git a/Easydict/Swift/View/SettingView/Tabs/ServiceConfigurationView/ConfigurationView/BaiduTranslate+ConfigurableService.swift b/Easydict/Swift/View/SettingView/Tabs/ServiceConfigurationView/ConfigurationView/BaiduTranslate+ConfigurableService.swift index 1d9a90513..83b324c9e 100644 --- a/Easydict/Swift/View/SettingView/Tabs/ServiceConfigurationView/ConfigurationView/BaiduTranslate+ConfigurableService.swift +++ b/Easydict/Swift/View/SettingView/Tabs/ServiceConfigurationView/ConfigurationView/BaiduTranslate+ConfigurableService.swift @@ -20,7 +20,7 @@ extension EZBaiduTranslate { ServiceConfigurationPickerCell( titleKey: "service.configuration.baidu.api_picker.title", key: .baiduServiceApiTypeKey, - values: BaiduServiceApiType.allCases + values: ServiceAPIType.allCases ) ServiceConfigurationSecureInputCell( @@ -36,22 +36,15 @@ extension EZBaiduTranslate { } } -// MARK: - BaiduServiceApiType +// MARK: - ServiceAPIType -enum BaiduServiceApiType: String, CaseIterable, Defaults.Serializable { - case web = "0" - case secretKey = "1" -} +enum ServiceAPIType: String, CaseIterable, Defaults.Serializable, EnumLocalizedStringConvertible { + case web = "Web API" + case secretKey = "Secret Key API" -// MARK: EnumLocalizedStringConvertible + // MARK: Internal -extension BaiduServiceApiType: EnumLocalizedStringConvertible { var title: LocalizedStringKey { - switch self { - case .web: - "service.configuration.baidu.web_api_type.title" - case .secretKey: - "service.configuration.baidu.secret_key_api_type.title" - } + LocalizedStringKey(rawValue) } } diff --git a/Easydict/objc/Service/Baidu/BaiduApiTranslate.swift b/Easydict/objc/Service/Baidu/BaiduApiTranslate.swift index 72a5f423c..54afff917 100644 --- a/Easydict/objc/Service/Baidu/BaiduApiTranslate.swift +++ b/Easydict/objc/Service/Baidu/BaiduApiTranslate.swift @@ -25,7 +25,7 @@ class BaiduApiTranslate: NSObject { var result: EZQueryResult? var isEnable: Bool { - Defaults[.baiduServiceApiTypeKey] == BaiduServiceApiType.secretKey + Defaults[.baiduServiceApiTypeKey] == ServiceAPIType.secretKey } func translate(_ text: String, from: Language, to: Language, completion: @escaping (EZQueryResult?, Error?) -> ()) { @@ -34,7 +34,7 @@ class BaiduApiTranslate: NSObject { result, EZError( type: EZErrorType.missingAPIKey, - description: "\n" + NSLocalizedString("service.configuration.baidu.api_missing.tips", comment: "") + description: NSLocalizedString("service.configuration.baidu.api_missing.tips", comment: "") ) ) return From 3fe1bb207c25d15fdc7f852b54a298102980f4b2 Mon Sep 17 00:00:00 2001 From: choykarl <253440030@qq.com> Date: Thu, 25 Jul 2024 20:48:31 +0800 Subject: [PATCH 18/23] feat: modify localized --- Easydict/App/Localizable.xcstrings | 7 +++--- .../BaiduTranslate+ConfigurableService.swift | 14 ------------ .../ServiceAPIType.swift | 22 +++++++++++++++++++ .../Service/Baidu/BaiduApiTranslate.swift | 5 ++++- 4 files changed, 30 insertions(+), 18 deletions(-) create mode 100644 Easydict/Swift/View/SettingView/Tabs/ServiceConfigurationView/ServiceAPIType.swift diff --git a/Easydict/App/Localizable.xcstrings b/Easydict/App/Localizable.xcstrings index f08330bc9..cf9e1e7d1 100644 --- a/Easydict/App/Localizable.xcstrings +++ b/Easydict/App/Localizable.xcstrings @@ -427,6 +427,7 @@ } }, "baidu_translate" : { + "comment" : "Baidu Translate", "localizations" : { "en" : { "stringUnit" : { @@ -2343,19 +2344,19 @@ } } }, - "service.configuration.baidu.api_missing.tips" : { + "service.configuration.api_missing.tips %@" : { "extractionState" : "manual", "localizations" : { "en" : { "stringUnit" : { "state" : "translated", - "value" : "The Secret Key API is currently in use, but either the App ID or Secret Key is empty. Please go to Settings > Service > Baidu Translate, fill in the required configuration information, or switch API types." + "value" : "The Secret Key API is currently in use, but either the App ID or Secret Key is empty. Please go to Settings > Service > %@, fill in the required configuration information, or switch API types." } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "当前正使用 Secret Key API,但是 App ID 或者 Secret Key 为空,请前往设置-服务-百度翻译,填写相关配置信息,或切换 API 类型" + "value" : "当前正使用 Secret Key API,但是 App ID 或者 Secret Key 为空,请前往设置-服务-%@,填写相关配置信息,或切换 API 类型" } } } diff --git a/Easydict/Swift/View/SettingView/Tabs/ServiceConfigurationView/ConfigurationView/BaiduTranslate+ConfigurableService.swift b/Easydict/Swift/View/SettingView/Tabs/ServiceConfigurationView/ConfigurationView/BaiduTranslate+ConfigurableService.swift index 83b324c9e..cb74e201a 100644 --- a/Easydict/Swift/View/SettingView/Tabs/ServiceConfigurationView/ConfigurationView/BaiduTranslate+ConfigurableService.swift +++ b/Easydict/Swift/View/SettingView/Tabs/ServiceConfigurationView/ConfigurationView/BaiduTranslate+ConfigurableService.swift @@ -7,7 +7,6 @@ // import Combine -import Defaults import Foundation import SwiftUI @@ -35,16 +34,3 @@ extension EZBaiduTranslate { } } } - -// MARK: - ServiceAPIType - -enum ServiceAPIType: String, CaseIterable, Defaults.Serializable, EnumLocalizedStringConvertible { - case web = "Web API" - case secretKey = "Secret Key API" - - // MARK: Internal - - var title: LocalizedStringKey { - LocalizedStringKey(rawValue) - } -} diff --git a/Easydict/Swift/View/SettingView/Tabs/ServiceConfigurationView/ServiceAPIType.swift b/Easydict/Swift/View/SettingView/Tabs/ServiceConfigurationView/ServiceAPIType.swift new file mode 100644 index 000000000..b77141268 --- /dev/null +++ b/Easydict/Swift/View/SettingView/Tabs/ServiceConfigurationView/ServiceAPIType.swift @@ -0,0 +1,22 @@ +// +// ServiceAPIType.swift +// Easydict +// +// Created by karl on 2024/7/25. +// Copyright © 2024 izual. All rights reserved. +// + +import Defaults +import Foundation +import SwiftUI + +enum ServiceAPIType: String, CaseIterable, Defaults.Serializable, EnumLocalizedStringConvertible { + case web = "Web API" + case secretKey = "Secret Key API" + + // MARK: Internal + + var title: LocalizedStringKey { + LocalizedStringKey(rawValue) + } +} diff --git a/Easydict/objc/Service/Baidu/BaiduApiTranslate.swift b/Easydict/objc/Service/Baidu/BaiduApiTranslate.swift index 54afff917..dfcd28375 100644 --- a/Easydict/objc/Service/Baidu/BaiduApiTranslate.swift +++ b/Easydict/objc/Service/Baidu/BaiduApiTranslate.swift @@ -34,7 +34,10 @@ class BaiduApiTranslate: NSObject { result, EZError( type: EZErrorType.missingAPIKey, - description: NSLocalizedString("service.configuration.baidu.api_missing.tips", comment: "") + description: String.localizedStringWithFormat( + NSLocalizedString("service.configuration.api_missing.tips %@", comment: "API key missing"), + NSLocalizedString("baidu_translate", comment: "Baidu Translate") + ) ) ) return From 32023ba0ddcb7deccbbbd84a72107eb3539c214d Mon Sep 17 00:00:00 2001 From: choykarl <253440030@qq.com> Date: Thu, 25 Jul 2024 21:40:19 +0800 Subject: [PATCH 19/23] feat: ali service type picker --- Easydict/App/Localizable.xcstrings | 2 +- .../Configuration+Defaults.swift | 1 + Easydict/Swift/Service/Ali/AliService.swift | 26 +++++++++++-------- .../AliService+ConfigurableService.swift | 5 ++++ .../BaiduTranslate+ConfigurableService.swift | 2 +- Easydict/objc/Service/Model/EZConstKey.h | 1 + 6 files changed, 24 insertions(+), 13 deletions(-) diff --git a/Easydict/App/Localizable.xcstrings b/Easydict/App/Localizable.xcstrings index cf9e1e7d1..44c8cff81 100644 --- a/Easydict/App/Localizable.xcstrings +++ b/Easydict/App/Localizable.xcstrings @@ -2361,7 +2361,7 @@ } } }, - "service.configuration.baidu.api_picker.title" : { + "service.configuration.api_picker.title" : { "extractionState" : "manual", "localizations" : { "en" : { diff --git a/Easydict/Swift/Feature/Configuration/Configuration+Defaults.swift b/Easydict/Swift/Feature/Configuration/Configuration+Defaults.swift index 0a9ff669f..5ba90ba7e 100644 --- a/Easydict/Swift/Feature/Configuration/Configuration+Defaults.swift +++ b/Easydict/Swift/Feature/Configuration/Configuration+Defaults.swift @@ -246,6 +246,7 @@ extension Defaults.Keys { // Ali static let aliAccessKeyId = Key(EZAliAccessKeyId, default: "") static let aliAccessKeySecret = Key(EZAliAccessKeySecret, default: "") + static let aliServiceApiTypeKey = Key(EZAliServiceApiTypeKey, default: .secretKey) // baidu static let baiduAppId = Key(EZBaiduAppId, default: "") diff --git a/Easydict/Swift/Service/Ali/AliService.swift b/Easydict/Swift/Service/Ali/AliService.swift index 63e214742..366e7ee16 100644 --- a/Easydict/Swift/Service/Ali/AliService.swift +++ b/Easydict/Swift/Service/Ali/AliService.swift @@ -56,10 +56,6 @@ class AliService: QueryService { .ali } - override func hasPrivateAPIKey() -> Bool { - !aliAccessKeyId.isEmpty && !aliAccessKeySecret.isEmpty - } - override func translate( _ text: String, from: Language, @@ -78,13 +74,7 @@ class AliService: QueryService { return } - /** - use user's access key id and secret - easydict://writeKeyValue?EZAliAccessKeyId= - easydict://writeKeyValue?EZAliAccessKeySecret= - */ - if !aliAccessKeyId.isEmpty, - !aliAccessKeySecret.isEmpty { + if Defaults[.aliServiceApiTypeKey] == .secretKey { requestByAPI( id: aliAccessKeyId, secret: aliAccessKeySecret, @@ -152,6 +142,20 @@ class AliService: QueryService { to: Language, completion: @escaping (EZQueryResult, Error?) -> () ) { + if id.isEmpty || secret.isEmpty { + completion( + result, + EZError( + type: EZErrorType.missingAPIKey, + description: String.localizedStringWithFormat( + NSLocalizedString("service.configuration.api_missing.tips %@", comment: "API key missing"), + NSLocalizedString("ali_translate", comment: "Ali Translate") + ) + ) + ) + return + } + func hmacSha1(key: String, params: String) -> String? { guard let secret = key.data(using: .utf8), let what = params.data(using: .utf8) diff --git a/Easydict/Swift/View/SettingView/Tabs/ServiceConfigurationView/ConfigurationView/AliService+ConfigurableService.swift b/Easydict/Swift/View/SettingView/Tabs/ServiceConfigurationView/ConfigurationView/AliService+ConfigurableService.swift index ee711645b..c9be8593e 100644 --- a/Easydict/Swift/View/SettingView/Tabs/ServiceConfigurationView/ConfigurationView/AliService+ConfigurableService.swift +++ b/Easydict/Swift/View/SettingView/Tabs/ServiceConfigurationView/ConfigurationView/AliService+ConfigurableService.swift @@ -11,6 +11,11 @@ import SwiftUI extension AliService { override func configurationListItems() -> Any? { ServiceConfigurationSecretSectionView(service: self, observeKeys: [.aliAccessKeyId, .aliAccessKeySecret]) { + ServiceConfigurationPickerCell( + titleKey: "service.configuration.api_picker.title", + key: .aliServiceApiTypeKey, + values: ServiceAPIType.allCases + ) ServiceConfigurationSecureInputCell( textFieldTitleKey: "service.configuration.ali.access_key_id.title", key: .aliAccessKeyId diff --git a/Easydict/Swift/View/SettingView/Tabs/ServiceConfigurationView/ConfigurationView/BaiduTranslate+ConfigurableService.swift b/Easydict/Swift/View/SettingView/Tabs/ServiceConfigurationView/ConfigurationView/BaiduTranslate+ConfigurableService.swift index cb74e201a..4c2f4cdab 100644 --- a/Easydict/Swift/View/SettingView/Tabs/ServiceConfigurationView/ConfigurationView/BaiduTranslate+ConfigurableService.swift +++ b/Easydict/Swift/View/SettingView/Tabs/ServiceConfigurationView/ConfigurationView/BaiduTranslate+ConfigurableService.swift @@ -17,7 +17,7 @@ extension EZBaiduTranslate { observeKeys: [.baiduAppId, .baiduSecretKey] ) { ServiceConfigurationPickerCell( - titleKey: "service.configuration.baidu.api_picker.title", + titleKey: "service.configuration.api_picker.title", key: .baiduServiceApiTypeKey, values: ServiceAPIType.allCases ) diff --git a/Easydict/objc/Service/Model/EZConstKey.h b/Easydict/objc/Service/Model/EZConstKey.h index e00ec2ded..4884933cc 100644 --- a/Easydict/objc/Service/Model/EZConstKey.h +++ b/Easydict/objc/Service/Model/EZConstKey.h @@ -25,6 +25,7 @@ static NSString *const EZGeminiAPIKey = @"EZGeminiAPIKey"; static NSString *const EZIntelligentQueryModeKey = @"IntelligentQueryMode"; static NSString *const EZAliAccessKeyId = @"EZAliAccessKeyId"; static NSString *const EZAliAccessKeySecret = @"EZAliAccessKeySecret"; +static NSString *const EZAliServiceApiTypeKey = @"EZAliServiceApiTypeKey"; static NSString *const EZBaiduAppId = @"EZBaiduAppId"; static NSString *const EZBaiduSecretKey = @"EZBaiduSecretKey"; From f0516bf2bda539e7c6325ba039abf2c8d176e2ab Mon Sep 17 00:00:00 2001 From: tisfeng Date: Thu, 25 Jul 2024 22:35:55 +0800 Subject: [PATCH 20/23] fix: missing file ServiceAPIType --- Easydict.xcodeproj/project.pbxproj | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Easydict.xcodeproj/project.pbxproj b/Easydict.xcodeproj/project.pbxproj index 35b29c482..8c59bd983 100644 --- a/Easydict.xcodeproj/project.pbxproj +++ b/Easydict.xcodeproj/project.pbxproj @@ -57,6 +57,7 @@ 03542A5E2938F05B00C34C33 /* EZLanguageModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 03542A5D2938F05B00C34C33 /* EZLanguageModel.m */; }; 0357B95A2C04387D00A48CB0 /* TextEditorCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0357B9592C04387D00A48CB0 /* TextEditorCell.swift */; }; 035E37E72A0953120061DFAF /* EZToast.m in Sources */ = {isa = PBXBuildFile; fileRef = 035E37E62A0953120061DFAF /* EZToast.m */; }; + 035F9CCF2C529A04005D1C9A /* ServiceAPIType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 035F9CCE2C529A04005D1C9A /* ServiceAPIType.swift */; }; 0361965529FFECFC00806370 /* youdao-sign.js in Resources */ = {isa = PBXBuildFile; fileRef = 0361965429FFECFC00806370 /* youdao-sign.js */; }; 036196752A000F5900806370 /* FWEncryptorAES.m in Sources */ = {isa = PBXBuildFile; fileRef = 036196702A000F5800806370 /* FWEncryptorAES.m */; }; 036196762A000F5900806370 /* NSData+Base64.m in Sources */ = {isa = PBXBuildFile; fileRef = 036196722A000F5900806370 /* NSData+Base64.m */; }; @@ -435,6 +436,7 @@ 0357B9592C04387D00A48CB0 /* TextEditorCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextEditorCell.swift; sourceTree = ""; }; 035E37E52A0953120061DFAF /* EZToast.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EZToast.h; sourceTree = ""; }; 035E37E62A0953120061DFAF /* EZToast.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EZToast.m; sourceTree = ""; }; + 035F9CCE2C529A04005D1C9A /* ServiceAPIType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ServiceAPIType.swift; path = Easydict/Swift/View/SettingView/Tabs/ServiceConfigurationView/ServiceAPIType.swift; sourceTree = SOURCE_ROOT; }; 0361965429FFECFC00806370 /* youdao-sign.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = "youdao-sign.js"; sourceTree = ""; }; 0361966F2A000F5800806370 /* NSData+Base64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSData+Base64.h"; sourceTree = ""; }; 036196702A000F5800806370 /* FWEncryptorAES.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FWEncryptorAES.m; sourceTree = ""; }; @@ -2422,6 +2424,7 @@ 0AC8A8462B6A4E3F006DA5CC /* ServiceConfigurationSecretSectionView.swift */, 0AC8A8442B6A4D97006DA5CC /* ServiceConfigurationCells.swift */, 0357B9592C04387D00A48CB0 /* TextEditorCell.swift */, + 035F9CCE2C529A04005D1C9A /* ServiceAPIType.swift */, ); path = ServiceConfigurationView; sourceTree = ""; @@ -2898,6 +2901,7 @@ 03B3B8B52925DD3D00168E8D /* EZPopButtonViewController.m in Sources */, 03542A5B2938DA2B00C34C33 /* EZDetectLanguageButton.m in Sources */, 03B0232929231FA6001C7E63 /* NSDictionary+MM.m in Sources */, + 035F9CCF2C529A04005D1C9A /* ServiceAPIType.swift in Sources */, 03280B812C23FE4A00E75A24 /* StreamConfigurationView.swift in Sources */, 0333FDA32A035BEC00891515 /* NSArray+EZChineseText.m in Sources */, 03B0233229231FA6001C7E63 /* MMLog.swift in Sources */, From 3ec60e93396587bc9952c424c5f7877fc02069ad Mon Sep 17 00:00:00 2001 From: choykarl <253440030@qq.com> Date: Thu, 25 Jul 2024 22:36:29 +0800 Subject: [PATCH 21/23] feat: add ServiceAPIType file --- Easydict.xcodeproj/project.pbxproj | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Easydict.xcodeproj/project.pbxproj b/Easydict.xcodeproj/project.pbxproj index 8c59bd983..572bded28 100644 --- a/Easydict.xcodeproj/project.pbxproj +++ b/Easydict.xcodeproj/project.pbxproj @@ -57,7 +57,6 @@ 03542A5E2938F05B00C34C33 /* EZLanguageModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 03542A5D2938F05B00C34C33 /* EZLanguageModel.m */; }; 0357B95A2C04387D00A48CB0 /* TextEditorCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0357B9592C04387D00A48CB0 /* TextEditorCell.swift */; }; 035E37E72A0953120061DFAF /* EZToast.m in Sources */ = {isa = PBXBuildFile; fileRef = 035E37E62A0953120061DFAF /* EZToast.m */; }; - 035F9CCF2C529A04005D1C9A /* ServiceAPIType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 035F9CCE2C529A04005D1C9A /* ServiceAPIType.swift */; }; 0361965529FFECFC00806370 /* youdao-sign.js in Resources */ = {isa = PBXBuildFile; fileRef = 0361965429FFECFC00806370 /* youdao-sign.js */; }; 036196752A000F5900806370 /* FWEncryptorAES.m in Sources */ = {isa = PBXBuildFile; fileRef = 036196702A000F5800806370 /* FWEncryptorAES.m */; }; 036196762A000F5900806370 /* NSData+Base64.m in Sources */ = {isa = PBXBuildFile; fileRef = 036196722A000F5900806370 /* NSData+Base64.m */; }; @@ -305,6 +304,7 @@ CB8C42FC2C441B5B004EC86F /* BaiduTranslate+ConfigurableService.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB8C42FB2C441B5A004EC86F /* BaiduTranslate+ConfigurableService.swift */; }; CB8C42FF2C441B74004EC86F /* BaiduApiTranslate.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB8C42FD2C441B74004EC86F /* BaiduApiTranslate.swift */; }; CB8C43002C441B74004EC86F /* BaiduApiResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB8C42FE2C441B74004EC86F /* BaiduApiResponse.swift */; }; + CBFECEA42C527AB90061202C /* ServiceAPIType.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBFECEA32C527AB90061202C /* ServiceAPIType.swift */; }; DC46DF802B4417B900DEAE3E /* Configuration.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC46DF7F2B4417B900DEAE3E /* Configuration.swift */; }; DC6D9C892B3969510055EFFC /* Appearance.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC6D9C882B3969510055EFFC /* Appearance.swift */; }; DCF176F22B57CED700CA6026 /* Configuration+UserData.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCF176F12B57CED700CA6026 /* Configuration+UserData.swift */; }; @@ -436,7 +436,6 @@ 0357B9592C04387D00A48CB0 /* TextEditorCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextEditorCell.swift; sourceTree = ""; }; 035E37E52A0953120061DFAF /* EZToast.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EZToast.h; sourceTree = ""; }; 035E37E62A0953120061DFAF /* EZToast.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EZToast.m; sourceTree = ""; }; - 035F9CCE2C529A04005D1C9A /* ServiceAPIType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ServiceAPIType.swift; path = Easydict/Swift/View/SettingView/Tabs/ServiceConfigurationView/ServiceAPIType.swift; sourceTree = SOURCE_ROOT; }; 0361965429FFECFC00806370 /* youdao-sign.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = "youdao-sign.js"; sourceTree = ""; }; 0361966F2A000F5800806370 /* NSData+Base64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSData+Base64.h"; sourceTree = ""; }; 036196702A000F5800806370 /* FWEncryptorAES.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FWEncryptorAES.m; sourceTree = ""; }; @@ -811,6 +810,7 @@ CB8C42FB2C441B5A004EC86F /* BaiduTranslate+ConfigurableService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "BaiduTranslate+ConfigurableService.swift"; sourceTree = ""; }; CB8C42FD2C441B74004EC86F /* BaiduApiTranslate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BaiduApiTranslate.swift; sourceTree = ""; }; CB8C42FE2C441B74004EC86F /* BaiduApiResponse.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BaiduApiResponse.swift; sourceTree = ""; }; + CBFECEA32C527AB90061202C /* ServiceAPIType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServiceAPIType.swift; sourceTree = ""; }; DC46DF7F2B4417B900DEAE3E /* Configuration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Configuration.swift; sourceTree = ""; }; DC6D9C882B3969510055EFFC /* Appearance.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Appearance.swift; sourceTree = ""; }; DCF176F12B57CED700CA6026 /* Configuration+UserData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Configuration+UserData.swift"; sourceTree = ""; }; @@ -2424,7 +2424,7 @@ 0AC8A8462B6A4E3F006DA5CC /* ServiceConfigurationSecretSectionView.swift */, 0AC8A8442B6A4D97006DA5CC /* ServiceConfigurationCells.swift */, 0357B9592C04387D00A48CB0 /* TextEditorCell.swift */, - 035F9CCE2C529A04005D1C9A /* ServiceAPIType.swift */, + CBFECEA32C527AB90061202C /* ServiceAPIType.swift */, ); path = ServiceConfigurationView; sourceTree = ""; @@ -2901,7 +2901,7 @@ 03B3B8B52925DD3D00168E8D /* EZPopButtonViewController.m in Sources */, 03542A5B2938DA2B00C34C33 /* EZDetectLanguageButton.m in Sources */, 03B0232929231FA6001C7E63 /* NSDictionary+MM.m in Sources */, - 035F9CCF2C529A04005D1C9A /* ServiceAPIType.swift in Sources */, + CBFECEA42C527AB90061202C /* ServiceAPIType.swift in Sources */, 03280B812C23FE4A00E75A24 /* StreamConfigurationView.swift in Sources */, 0333FDA32A035BEC00891515 /* NSArray+EZChineseText.m in Sources */, 03B0233229231FA6001C7E63 /* MMLog.swift in Sources */, From 1d3fea062d90d8f73cd2a35a1582dd2a8f044279 Mon Sep 17 00:00:00 2001 From: tisfeng Date: Thu, 25 Jul 2024 22:45:05 +0800 Subject: [PATCH 22/23] Revert "feat: add ServiceAPIType file" This reverts commit 3ec60e93396587bc9952c424c5f7877fc02069ad. --- Easydict.xcodeproj/project.pbxproj | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Easydict.xcodeproj/project.pbxproj b/Easydict.xcodeproj/project.pbxproj index 572bded28..8c59bd983 100644 --- a/Easydict.xcodeproj/project.pbxproj +++ b/Easydict.xcodeproj/project.pbxproj @@ -57,6 +57,7 @@ 03542A5E2938F05B00C34C33 /* EZLanguageModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 03542A5D2938F05B00C34C33 /* EZLanguageModel.m */; }; 0357B95A2C04387D00A48CB0 /* TextEditorCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0357B9592C04387D00A48CB0 /* TextEditorCell.swift */; }; 035E37E72A0953120061DFAF /* EZToast.m in Sources */ = {isa = PBXBuildFile; fileRef = 035E37E62A0953120061DFAF /* EZToast.m */; }; + 035F9CCF2C529A04005D1C9A /* ServiceAPIType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 035F9CCE2C529A04005D1C9A /* ServiceAPIType.swift */; }; 0361965529FFECFC00806370 /* youdao-sign.js in Resources */ = {isa = PBXBuildFile; fileRef = 0361965429FFECFC00806370 /* youdao-sign.js */; }; 036196752A000F5900806370 /* FWEncryptorAES.m in Sources */ = {isa = PBXBuildFile; fileRef = 036196702A000F5800806370 /* FWEncryptorAES.m */; }; 036196762A000F5900806370 /* NSData+Base64.m in Sources */ = {isa = PBXBuildFile; fileRef = 036196722A000F5900806370 /* NSData+Base64.m */; }; @@ -304,7 +305,6 @@ CB8C42FC2C441B5B004EC86F /* BaiduTranslate+ConfigurableService.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB8C42FB2C441B5A004EC86F /* BaiduTranslate+ConfigurableService.swift */; }; CB8C42FF2C441B74004EC86F /* BaiduApiTranslate.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB8C42FD2C441B74004EC86F /* BaiduApiTranslate.swift */; }; CB8C43002C441B74004EC86F /* BaiduApiResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB8C42FE2C441B74004EC86F /* BaiduApiResponse.swift */; }; - CBFECEA42C527AB90061202C /* ServiceAPIType.swift in Sources */ = {isa = PBXBuildFile; fileRef = CBFECEA32C527AB90061202C /* ServiceAPIType.swift */; }; DC46DF802B4417B900DEAE3E /* Configuration.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC46DF7F2B4417B900DEAE3E /* Configuration.swift */; }; DC6D9C892B3969510055EFFC /* Appearance.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC6D9C882B3969510055EFFC /* Appearance.swift */; }; DCF176F22B57CED700CA6026 /* Configuration+UserData.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCF176F12B57CED700CA6026 /* Configuration+UserData.swift */; }; @@ -436,6 +436,7 @@ 0357B9592C04387D00A48CB0 /* TextEditorCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextEditorCell.swift; sourceTree = ""; }; 035E37E52A0953120061DFAF /* EZToast.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EZToast.h; sourceTree = ""; }; 035E37E62A0953120061DFAF /* EZToast.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EZToast.m; sourceTree = ""; }; + 035F9CCE2C529A04005D1C9A /* ServiceAPIType.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ServiceAPIType.swift; path = Easydict/Swift/View/SettingView/Tabs/ServiceConfigurationView/ServiceAPIType.swift; sourceTree = SOURCE_ROOT; }; 0361965429FFECFC00806370 /* youdao-sign.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = "youdao-sign.js"; sourceTree = ""; }; 0361966F2A000F5800806370 /* NSData+Base64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSData+Base64.h"; sourceTree = ""; }; 036196702A000F5800806370 /* FWEncryptorAES.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FWEncryptorAES.m; sourceTree = ""; }; @@ -810,7 +811,6 @@ CB8C42FB2C441B5A004EC86F /* BaiduTranslate+ConfigurableService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "BaiduTranslate+ConfigurableService.swift"; sourceTree = ""; }; CB8C42FD2C441B74004EC86F /* BaiduApiTranslate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BaiduApiTranslate.swift; sourceTree = ""; }; CB8C42FE2C441B74004EC86F /* BaiduApiResponse.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BaiduApiResponse.swift; sourceTree = ""; }; - CBFECEA32C527AB90061202C /* ServiceAPIType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServiceAPIType.swift; sourceTree = ""; }; DC46DF7F2B4417B900DEAE3E /* Configuration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Configuration.swift; sourceTree = ""; }; DC6D9C882B3969510055EFFC /* Appearance.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Appearance.swift; sourceTree = ""; }; DCF176F12B57CED700CA6026 /* Configuration+UserData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Configuration+UserData.swift"; sourceTree = ""; }; @@ -2424,7 +2424,7 @@ 0AC8A8462B6A4E3F006DA5CC /* ServiceConfigurationSecretSectionView.swift */, 0AC8A8442B6A4D97006DA5CC /* ServiceConfigurationCells.swift */, 0357B9592C04387D00A48CB0 /* TextEditorCell.swift */, - CBFECEA32C527AB90061202C /* ServiceAPIType.swift */, + 035F9CCE2C529A04005D1C9A /* ServiceAPIType.swift */, ); path = ServiceConfigurationView; sourceTree = ""; @@ -2901,7 +2901,7 @@ 03B3B8B52925DD3D00168E8D /* EZPopButtonViewController.m in Sources */, 03542A5B2938DA2B00C34C33 /* EZDetectLanguageButton.m in Sources */, 03B0232929231FA6001C7E63 /* NSDictionary+MM.m in Sources */, - CBFECEA42C527AB90061202C /* ServiceAPIType.swift in Sources */, + 035F9CCF2C529A04005D1C9A /* ServiceAPIType.swift in Sources */, 03280B812C23FE4A00E75A24 /* StreamConfigurationView.swift in Sources */, 0333FDA32A035BEC00891515 /* NSArray+EZChineseText.m in Sources */, 03B0233229231FA6001C7E63 /* MMLog.swift in Sources */, From 42257bd692b7d1aa1b9e7828b301bb11b283f889 Mon Sep 17 00:00:00 2001 From: tisfeng Date: Thu, 25 Jul 2024 22:56:34 +0800 Subject: [PATCH 23/23] fix: improve api key missing tips --- Easydict/App/Localizable.xcstrings | 6 +++--- Easydict/Swift/Service/Ali/AliService.swift | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Easydict/App/Localizable.xcstrings b/Easydict/App/Localizable.xcstrings index 44c8cff81..108aca71f 100644 --- a/Easydict/App/Localizable.xcstrings +++ b/Easydict/App/Localizable.xcstrings @@ -2350,13 +2350,13 @@ "en" : { "stringUnit" : { "state" : "translated", - "value" : "The Secret Key API is currently in use, but either the App ID or Secret Key is empty. Please go to Settings > Service > %@, fill in the required configuration information, or switch API types." + "value" : "Currently using the Secret Key API type, but a certain API Key is empty. Please go to Settings > Service > %@, fill in the required configuration information, or switch API types." } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "当前正使用 Secret Key API,但是 App ID 或者 Secret Key 为空,请前往设置-服务-%@,填写相关配置信息,或切换 API 类型" + "value" : "当前正使用 Secret Key API 类型,但是某个 API Key 为空,请前往设置-服务-%@,填写相关配置信息,或切换 API 类型" } } } @@ -4311,4 +4311,4 @@ } }, "version" : "1.0" -} \ No newline at end of file +} diff --git a/Easydict/Swift/Service/Ali/AliService.swift b/Easydict/Swift/Service/Ali/AliService.swift index 366e7ee16..3e25f40a3 100644 --- a/Easydict/Swift/Service/Ali/AliService.swift +++ b/Easydict/Swift/Service/Ali/AliService.swift @@ -149,7 +149,7 @@ class AliService: QueryService { type: EZErrorType.missingAPIKey, description: String.localizedStringWithFormat( NSLocalizedString("service.configuration.api_missing.tips %@", comment: "API key missing"), - NSLocalizedString("ali_translate", comment: "Ali Translate") + name() ) ) )