diff --git a/Easydict.xcodeproj/project.pbxproj b/Easydict.xcodeproj/project.pbxproj index def065d20..4a4ec6d69 100644 --- a/Easydict.xcodeproj/project.pbxproj +++ b/Easydict.xcodeproj/project.pbxproj @@ -958,6 +958,20 @@ path = AppleScript; sourceTree = ""; }; + 03071E1B2BC03ADE0042CD38 /* TabView */ = { + isa = PBXGroup; + children = ( + 278540332B3DE04F004E9488 /* GeneralTab.swift */, + 0A057D6C2B499A000025C51D /* ServiceTab.swift */, + 0A8685C72B552A590022534F /* DisabledAppTab.swift */, + 276742042B3DC230002A2C75 /* PrivacyTab.swift */, + 276742052B3DC230002A2C75 /* AboutTab.swift */, + 96099AE12B5D40330055C4DD /* ShortcutTab.swift */, + 03832F532B5F6BE200D0DC64 /* AdvancedTab.swift */, + ); + path = TabView; + sourceTree = ""; + }; 0309E1EA292B437C00AFB76A /* TextView */ = { isa = PBXGroup; children = ( @@ -2229,15 +2243,9 @@ 27FE980C2B3DD749000AD654 /* Tabs */ = { isa = PBXGroup; children = ( + 03071E1B2BC03ADE0042CD38 /* TabView */, 9627F9332B59956800B1E999 /* View */, - EAED41EA2B54A4900005FE0A /* ServiceConfiguration */, - 278540332B3DE04F004E9488 /* GeneralTab.swift */, - 0A057D6C2B499A000025C51D /* ServiceTab.swift */, - 0A8685C72B552A590022534F /* DisabledAppTab.swift */, - 276742042B3DC230002A2C75 /* PrivacyTab.swift */, - 276742052B3DC230002A2C75 /* AboutTab.swift */, - 96099AE12B5D40330055C4DD /* ShortcutTab.swift */, - 03832F532B5F6BE200D0DC64 /* AdvancedTab.swift */, + EAED41EA2B54A4900005FE0A /* ServiceConfigurationView */, ); path = Tabs; sourceTree = ""; @@ -2471,7 +2479,6 @@ 038F1F8D2BAD835500CD2F65 /* AppKit */, EA1013412B5DBDA5005E43F9 /* Defaults */, 038A723E2B62C07B004995E3 /* String */, - EAED41F02B54B1A60005FE0A /* QueryService+ConfigurableService */, EA9943E72B534D8900EE7B97 /* LanguageDetectOptimizeExtensions.swift */, EA9943ED2B5353AB00EE7B97 /* WindowTypeExtensions.swift */, EA9943EF2B5354C400EE7B97 /* ShowWindowPositionExtensions.swift */, @@ -2480,15 +2487,16 @@ path = Extensions; sourceTree = ""; }; - EAED41EA2B54A4900005FE0A /* ServiceConfiguration */ = { + EAED41EA2B54A4900005FE0A /* ServiceConfigurationView */ = { isa = PBXGroup; children = ( + EAED41F02B54B1A60005FE0A /* QueryService+ConfigurableService */, 0AC8A83C2B6685EE006DA5CC /* SecureTextField.swift */, EAED41EB2B54AA920005FE0A /* ServiceConfigurationSection.swift */, 0AC8A8462B6A4E3F006DA5CC /* ServiceConfigurationSecretSectionView.swift */, 0AC8A8442B6A4D97006DA5CC /* ServiceConfigurationCells.swift */, ); - path = ServiceConfiguration; + path = ServiceConfigurationView; sourceTree = ""; }; EAED41ED2B54B1390005FE0A /* Protocol */ = { @@ -2504,6 +2512,7 @@ isa = PBXGroup; children = ( EAED41F12B54B39D0005FE0A /* OpenAIService+ConfigurableService.swift */, + 0A318F3A2B8CCCCD0005EF77 /* CustomOpenAIService+ConfigurableService.swift */, 0AC8A8402B695480006DA5CC /* DeepLTranslate+ConfigurableService.swift */, 0AC8A8342B6641A7006DA5CC /* TencentService+ConfigurableService.swift */, 0AC8A8362B6659A8006DA5CC /* NiuTransTranslate+ConfigurableService.swift */, @@ -2511,7 +2520,6 @@ 0AC8A83A2B6682D4006DA5CC /* AliService+ConfigurableService.swift */, 0AC8A8422B6957B0006DA5CC /* BingService+ConfigurableService.swift */, 0AC8A84A2B6A629D006DA5CC /* GeminiService+ConfigurableService.swift */, - 0A318F3A2B8CCCCD0005EF77 /* CustomOpenAIService+ConfigurableService.swift */, ); path = "QueryService+ConfigurableService"; sourceTree = ""; diff --git a/Easydict/App/Localizable.xcstrings b/Easydict/App/Localizable.xcstrings index 6c70d0d17..350902d1f 100644 --- a/Easydict/App/Localizable.xcstrings +++ b/Easydict/App/Localizable.xcstrings @@ -3000,13 +3000,13 @@ "en" : { "stringUnit" : { "state" : "translated", - "value" : "Model" + "value" : "Use Model" } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "模型" + "value" : "使用模型" } } } diff --git a/Easydict/Swift/Feature/Configuration/Configuration+Defaults.swift b/Easydict/Swift/Feature/Configuration/Configuration+Defaults.swift index f1fd3a349..301251c8f 100644 --- a/Easydict/Swift/Feature/Configuration/Configuration+Defaults.swift +++ b/Easydict/Swift/Feature/Configuration/Configuration+Defaults.swift @@ -201,7 +201,15 @@ extension Defaults.Keys { default: OpenAIUsageStats.default ) static let openAIEndPoint = Key(EZOpenAIEndPointKey) - static let openAIModel = Key(EZOpenAIModelKey, default: .gpt3_5_turbo_0125) + static let openAIModel = Key(EZOpenAIModelKey, default: OpenAIModel.gpt3_5_turbo.rawValue) + static let openAIAvailableModels = Key( + EZOpenAIAvailableModelsKey, + default: OpenAIModel.allCases.map { $0.rawValue }.joined(separator: ",") + ) + static let openAIVaildModels = Key( + EZOpenAIValidModelsKey, + default: OpenAIModel.allCases.map { $0.rawValue } + ) // Custom OpenAI static let customOpenAINameKey = Key( @@ -218,9 +226,10 @@ extension Defaults.Keys { ) static let customOpenAIEndPoint = Key(EZCustomOpenAIEndPointKey, default: "") static let customOpenAIModel = Key(EZCustomOpenAIModelKey, default: "") - static let customOpenAIModelsAvailable = Key( - EZCustomOpenAIModelssAvailableKey, - default: "" + static let customOpenAIAvailableModels = Key(EZCustomOpenAIAvailableModelsKey, default: "") + static let customOpenAIVaildModels = Key( + EZCustomOpenAIValidModelsKey, + default: [""] ) // DeepL diff --git a/Easydict/Swift/Service/CustomOpenAI/CustomOpenAIService.swift b/Easydict/Swift/Service/CustomOpenAI/CustomOpenAIService.swift index abafaa320..eea956b6f 100644 --- a/Easydict/Swift/Service/CustomOpenAI/CustomOpenAIService.swift +++ b/Easydict/Swift/Service/CustomOpenAI/CustomOpenAIService.swift @@ -50,9 +50,7 @@ class CustomOpenAIService: BaseOpenAIService { } override var availableModels: [String] { - let models = Defaults[.customOpenAIModelsAvailable] - guard let models, !models.isEmpty else { return [] } - return models.components(separatedBy: ",").filter { !$0.isEmpty } + Defaults[.customOpenAIVaildModels] } override func serviceType() -> ServiceType { diff --git a/Easydict/Swift/Service/OpenAI/BaseOpenAIService.swift b/Easydict/Swift/Service/OpenAI/BaseOpenAIService.swift index 8eb0e6f47..9659e784b 100644 --- a/Easydict/Swift/Service/OpenAI/BaseOpenAIService.swift +++ b/Easydict/Swift/Service/OpenAI/BaseOpenAIService.swift @@ -123,20 +123,19 @@ public class BaseOpenAIService: QueryService { // MARK: Internal + var availableModels: [String] { + Defaults[.openAIVaildModels] + } + var model: String { get { - var model = Defaults[.openAIModel].rawValue - if model.isEmpty { - model = availableModels.first ?? OpenAIModel.gpt3_5_turbo_0125.rawValue - } - return model + Defaults[.openAIModel] } set { // easydict://writeKeyValue?EZOpenAIModelKey=gpt-3.5-turbo - let mode = OpenAIModel(rawValue: newValue) ?? .gpt3_5_turbo_0125 - Defaults[.openAIModel] = mode + Defaults[.openAIModel] = newValue } } @@ -166,10 +165,6 @@ public class BaseOpenAIService: QueryService { return endPoint } - var availableModels: [String] { - OpenAIModel.allCases.map { $0.rawValue } - } - // MARK: Private private func queryTextType(text: String, from: Language, to _: Language) -> EZQueryTextType { diff --git a/Easydict/Swift/Utility/Extensions/QueryService+ConfigurableService/AliService+ConfigurableService.swift b/Easydict/Swift/View/SettingView/Tabs/ServiceConfigurationView/QueryService+ConfigurableService/AliService+ConfigurableService.swift similarity index 100% rename from Easydict/Swift/Utility/Extensions/QueryService+ConfigurableService/AliService+ConfigurableService.swift rename to Easydict/Swift/View/SettingView/Tabs/ServiceConfigurationView/QueryService+ConfigurableService/AliService+ConfigurableService.swift diff --git a/Easydict/Swift/Utility/Extensions/QueryService+ConfigurableService/BingService+ConfigurableService.swift b/Easydict/Swift/View/SettingView/Tabs/ServiceConfigurationView/QueryService+ConfigurableService/BingService+ConfigurableService.swift similarity index 100% rename from Easydict/Swift/Utility/Extensions/QueryService+ConfigurableService/BingService+ConfigurableService.swift rename to Easydict/Swift/View/SettingView/Tabs/ServiceConfigurationView/QueryService+ConfigurableService/BingService+ConfigurableService.swift diff --git a/Easydict/Swift/Utility/Extensions/QueryService+ConfigurableService/CaiyunService+ConfigurableService.swift b/Easydict/Swift/View/SettingView/Tabs/ServiceConfigurationView/QueryService+ConfigurableService/CaiyunService+ConfigurableService.swift similarity index 100% rename from Easydict/Swift/Utility/Extensions/QueryService+ConfigurableService/CaiyunService+ConfigurableService.swift rename to Easydict/Swift/View/SettingView/Tabs/ServiceConfigurationView/QueryService+ConfigurableService/CaiyunService+ConfigurableService.swift diff --git a/Easydict/Swift/Utility/Extensions/QueryService+ConfigurableService/CustomOpenAIService+ConfigurableService.swift b/Easydict/Swift/View/SettingView/Tabs/ServiceConfigurationView/QueryService+ConfigurableService/CustomOpenAIService+ConfigurableService.swift similarity index 83% rename from Easydict/Swift/Utility/Extensions/QueryService+ConfigurableService/CustomOpenAIService+ConfigurableService.swift rename to Easydict/Swift/View/SettingView/Tabs/ServiceConfigurationView/QueryService+ConfigurableService/CustomOpenAIService+ConfigurableService.swift index 6803e95c6..40517282b 100644 --- a/Easydict/Swift/Utility/Extensions/QueryService+ConfigurableService/CustomOpenAIService+ConfigurableService.swift +++ b/Easydict/Swift/View/SettingView/Tabs/ServiceConfigurationView/QueryService+ConfigurableService/CustomOpenAIService+ConfigurableService.swift @@ -38,7 +38,7 @@ private struct CustomOpenAIServiceConfigurationView: View { var body: some View { ServiceConfigurationSecretSectionView( service: service, - observeKeys: [.customOpenAIAPIKey, .customOpenAIEndPoint, .customOpenAIModelsAvailable] + observeKeys: [.customOpenAIAPIKey, .customOpenAIEndPoint, .customOpenAIAvailableModels] ) { // title ServiceConfigurationInputCell( @@ -57,7 +57,8 @@ private struct CustomOpenAIServiceConfigurationView: View { key: .customOpenAIEndPoint, placeholder: "service.configuration.openai.endpoint.placeholder" ) - // model + + // supported models TextField( "service.configuration.custom_openai.supported_models.title", text: viewModel.$availableModels ?? "", @@ -113,7 +114,7 @@ private class CustomOpenAIViewModel: ObservableObject { Defaults.publisher(.customOpenAIModel, options: []) .removeDuplicates() .sink { _ in - self.serviceConfigChanged() + self.modelChanged() } ) cancellables.append( @@ -124,7 +125,7 @@ private class CustomOpenAIViewModel: ObservableObject { } ) cancellables.append( - Defaults.publisher(.customOpenAIModelsAvailable) + Defaults.publisher(.customOpenAIAvailableModels) .removeDuplicates() .sink { _ in self.modelsTextChanged() @@ -137,7 +138,7 @@ private class CustomOpenAIViewModel: ObservableObject { let service: CustomOpenAIService @Default(.customOpenAIModel) var model - @Default(.customOpenAIModelsAvailable) var availableModels + @Default(.customOpenAIAvailableModels) var availableModels @Published var validModels: [String] = [] @@ -150,23 +151,42 @@ private class CustomOpenAIViewModel: ObservableObject { private var cancellables: [AnyCancellable] = [] + private func modelChanged() { + if !validModels.contains(model) { + if model.isEmpty { + availableModels = "" + } else { + if availableModels?.isEmpty == true { + availableModels = model + } else { + availableModels = "\(model), " + (availableModels ?? "") + } + } + } + + serviceConfigChanged() + } + private func modelsTextChanged() { guard let availableModels else { return } - if availableModels.isEmpty { + + validModels = availableModels.components(separatedBy: ",") + .map { $0.trimmingCharacters(in: .whitespacesAndNewlines) }.filter { !$0.isEmpty } + + if validModels.isEmpty { model = "" - validModels = [] - return - } - validModels = availableModels.components(separatedBy: ",").filter { !$0.isEmpty } - if validModels.count == 1 || !validModels.contains(model) { + } else if !validModels.contains(model) { model = validModels[0] } + + Defaults[.customOpenAIVaildModels] = validModels } private func serviceConfigChanged() { - // looks like Defaults changed but View not update in this case objectWillChange.send() + let userInfo: [String: Any] = [ + EZWindowTypeKey: service.windowType.rawValue, EZServiceTypeKey: service.serviceType().rawValue, ] let notification = Notification(name: .serviceHasUpdated, object: nil, userInfo: userInfo) diff --git a/Easydict/Swift/Utility/Extensions/QueryService+ConfigurableService/DeepLTranslate+ConfigurableService.swift b/Easydict/Swift/View/SettingView/Tabs/ServiceConfigurationView/QueryService+ConfigurableService/DeepLTranslate+ConfigurableService.swift similarity index 100% rename from Easydict/Swift/Utility/Extensions/QueryService+ConfigurableService/DeepLTranslate+ConfigurableService.swift rename to Easydict/Swift/View/SettingView/Tabs/ServiceConfigurationView/QueryService+ConfigurableService/DeepLTranslate+ConfigurableService.swift diff --git a/Easydict/Swift/Utility/Extensions/QueryService+ConfigurableService/GeminiService+ConfigurableService.swift b/Easydict/Swift/View/SettingView/Tabs/ServiceConfigurationView/QueryService+ConfigurableService/GeminiService+ConfigurableService.swift similarity index 100% rename from Easydict/Swift/Utility/Extensions/QueryService+ConfigurableService/GeminiService+ConfigurableService.swift rename to Easydict/Swift/View/SettingView/Tabs/ServiceConfigurationView/QueryService+ConfigurableService/GeminiService+ConfigurableService.swift diff --git a/Easydict/Swift/Utility/Extensions/QueryService+ConfigurableService/NiuTransTranslate+ConfigurableService.swift b/Easydict/Swift/View/SettingView/Tabs/ServiceConfigurationView/QueryService+ConfigurableService/NiuTransTranslate+ConfigurableService.swift similarity index 100% rename from Easydict/Swift/Utility/Extensions/QueryService+ConfigurableService/NiuTransTranslate+ConfigurableService.swift rename to Easydict/Swift/View/SettingView/Tabs/ServiceConfigurationView/QueryService+ConfigurableService/NiuTransTranslate+ConfigurableService.swift diff --git a/Easydict/Swift/Utility/Extensions/QueryService+ConfigurableService/OpenAIService+ConfigurableService.swift b/Easydict/Swift/View/SettingView/Tabs/ServiceConfigurationView/QueryService+ConfigurableService/OpenAIService+ConfigurableService.swift similarity index 66% rename from Easydict/Swift/Utility/Extensions/QueryService+ConfigurableService/OpenAIService+ConfigurableService.swift rename to Easydict/Swift/View/SettingView/Tabs/ServiceConfigurationView/QueryService+ConfigurableService/OpenAIService+ConfigurableService.swift index 7060645a8..6160e2245 100644 --- a/Easydict/Swift/Utility/Extensions/QueryService+ConfigurableService/OpenAIService+ConfigurableService.swift +++ b/Easydict/Swift/View/SettingView/Tabs/ServiceConfigurationView/QueryService+ConfigurableService/OpenAIService+ConfigurableService.swift @@ -37,7 +37,7 @@ private struct OpenAIServiceConfigurationView: View { var body: some View { ServiceConfigurationSecretSectionView( - service: service, observeKeys: [.openAIAPIKey] + service: service, observeKeys: [.openAIAPIKey, .openAIEndPoint, .openAIAvailableModels] ) { ServiceConfigurationSecureInputCell( textFieldTitleKey: "service.configuration.openai.api_key.title", @@ -50,12 +50,24 @@ private struct OpenAIServiceConfigurationView: View { key: .openAIEndPoint, placeholder: "service.configuration.openai.endpoint.placeholder" ) + // model - ServiceConfigurationPickerCell( - titleKey: "service.configuration.openai.model.title", - key: .openAIModel, - values: OpenAIModel.allCases + TextField( + "service.configuration.custom_openai.supported_models.title", + text: viewModel.$availableModels ?? "", + prompt: Text("service.configuration.custom_openai.model.placeholder") ) + .padding(10.0) + Picker( + "service.configuration.openai.model.title", + selection: viewModel.$model + ) { + ForEach(viewModel.validModels, id: \.self) { value in + Text(value) + } + } + .padding(10.0) + ServiceConfigurationToggleCell( titleKey: "service.configuration.openai.translation.title", key: .openAITranslation @@ -95,7 +107,14 @@ private class OpenAIServiceViewModel: ObservableObject { Defaults.publisher(.openAIModel, options: []) .removeDuplicates() .sink { _ in - self.serviceConfigChanged() + self.modelChanged() + } + ) + cancellables.append( + Defaults.publisher(.openAIAvailableModels) + .removeDuplicates() + .sink { _ in + self.modelsTextChanged() } ) } @@ -105,6 +124,9 @@ private class OpenAIServiceViewModel: ObservableObject { let service: OpenAIService @Default(.openAIModel) var model + @Default(.openAIAvailableModels) var availableModels + + @Published var validModels: [String] = [] func invalidate() { cancellables.forEach { $0.cancel() } @@ -115,7 +137,43 @@ private class OpenAIServiceViewModel: ObservableObject { private var cancellables: [AnyCancellable] = [] + private func modelChanged() { + // Currently, user of low os versions can change OpenAI model using URL scheme, like easydict://writeKeyValue?EZOpenAIModelKey=gpt-4 + // In this case, model may not be included in validModels, we need to handle it. + + if !validModels.contains(model) { + if model.isEmpty { + availableModels = "" + } else { + if availableModels?.isEmpty == true { + availableModels = model + } else { + availableModels = "\(model), " + (availableModels ?? "") + } + } + } + + serviceConfigChanged() + } + + private func modelsTextChanged() { + guard let availableModels else { return } + + validModels = availableModels.components(separatedBy: ",") + .map { $0.trimmingCharacters(in: .whitespacesAndNewlines) }.filter { !$0.isEmpty } + + if validModels.isEmpty { + model = "" + } else if !validModels.contains(model) { + model = validModels[0] + } + + Defaults[.openAIVaildModels] = validModels + } + private func serviceConfigChanged() { + objectWillChange.send() + let userInfo: [String: Any] = [ EZWindowTypeKey: service.windowType.rawValue, EZServiceTypeKey: service.serviceType().rawValue, @@ -135,8 +193,10 @@ protocol EnumLocalizedStringConvertible { // swiftlint:disable identifier_name enum OpenAIModel: String, CaseIterable { - case gpt3_5_turbo_0125 = "gpt-3.5-turbo-0125" - case gpt4_0125_preview = "gpt-4-0125-preview" + // Docs: https://platform.openai.com/docs/models/gpt-3-5-turbo + + case gpt3_5_turbo = "gpt-3.5-turbo" // Currently points to gpt-3.5-turbo-0125. + case gpt4_turbo_preview = "gpt-4-turbo-preview" // Currently points to gpt-4-0125-preview. } // MARK: EnumLocalizedStringConvertible diff --git a/Easydict/Swift/Utility/Extensions/QueryService+ConfigurableService/TencentService+ConfigurableService.swift b/Easydict/Swift/View/SettingView/Tabs/ServiceConfigurationView/QueryService+ConfigurableService/TencentService+ConfigurableService.swift similarity index 100% rename from Easydict/Swift/Utility/Extensions/QueryService+ConfigurableService/TencentService+ConfigurableService.swift rename to Easydict/Swift/View/SettingView/Tabs/ServiceConfigurationView/QueryService+ConfigurableService/TencentService+ConfigurableService.swift diff --git a/Easydict/Swift/View/SettingView/Tabs/ServiceConfiguration/SecureTextField.swift b/Easydict/Swift/View/SettingView/Tabs/ServiceConfigurationView/SecureTextField.swift similarity index 100% rename from Easydict/Swift/View/SettingView/Tabs/ServiceConfiguration/SecureTextField.swift rename to Easydict/Swift/View/SettingView/Tabs/ServiceConfigurationView/SecureTextField.swift diff --git a/Easydict/Swift/View/SettingView/Tabs/ServiceConfiguration/ServiceConfigurationCells.swift b/Easydict/Swift/View/SettingView/Tabs/ServiceConfigurationView/ServiceConfigurationCells.swift similarity index 95% rename from Easydict/Swift/View/SettingView/Tabs/ServiceConfiguration/ServiceConfigurationCells.swift rename to Easydict/Swift/View/SettingView/Tabs/ServiceConfigurationView/ServiceConfigurationCells.swift index ed31c5fd4..efdc6545d 100644 --- a/Easydict/Swift/View/SettingView/Tabs/ServiceConfiguration/ServiceConfigurationCells.swift +++ b/Easydict/Swift/View/SettingView/Tabs/ServiceConfigurationView/ServiceConfigurationCells.swift @@ -137,11 +137,10 @@ struct ServiceConfigurationToggleCell: View { placeholder: "service.configuration.openai.endpoint.placeholder" ) - // model ServiceConfigurationPickerCell( - titleKey: "service.configuration.openai.model.title", - key: .openAIModel, - values: OpenAIModel.allCases + titleKey: "service.configuration.openai.usage_status.title", + key: .openAIServiceUsageStatus, + values: OpenAIUsageStats.allCases ) ServiceConfigurationToggleCell( diff --git a/Easydict/Swift/View/SettingView/Tabs/ServiceConfiguration/ServiceConfigurationSecretSectionView.swift b/Easydict/Swift/View/SettingView/Tabs/ServiceConfigurationView/ServiceConfigurationSecretSectionView.swift similarity index 100% rename from Easydict/Swift/View/SettingView/Tabs/ServiceConfiguration/ServiceConfigurationSecretSectionView.swift rename to Easydict/Swift/View/SettingView/Tabs/ServiceConfigurationView/ServiceConfigurationSecretSectionView.swift diff --git a/Easydict/Swift/View/SettingView/Tabs/ServiceConfiguration/ServiceConfigurationSection.swift b/Easydict/Swift/View/SettingView/Tabs/ServiceConfigurationView/ServiceConfigurationSection.swift similarity index 100% rename from Easydict/Swift/View/SettingView/Tabs/ServiceConfiguration/ServiceConfigurationSection.swift rename to Easydict/Swift/View/SettingView/Tabs/ServiceConfigurationView/ServiceConfigurationSection.swift diff --git a/Easydict/Swift/View/SettingView/Tabs/AboutTab.swift b/Easydict/Swift/View/SettingView/Tabs/TabView/AboutTab.swift similarity index 100% rename from Easydict/Swift/View/SettingView/Tabs/AboutTab.swift rename to Easydict/Swift/View/SettingView/Tabs/TabView/AboutTab.swift diff --git a/Easydict/Swift/View/SettingView/Tabs/AdvancedTab.swift b/Easydict/Swift/View/SettingView/Tabs/TabView/AdvancedTab.swift similarity index 100% rename from Easydict/Swift/View/SettingView/Tabs/AdvancedTab.swift rename to Easydict/Swift/View/SettingView/Tabs/TabView/AdvancedTab.swift diff --git a/Easydict/Swift/View/SettingView/Tabs/DisabledAppTab.swift b/Easydict/Swift/View/SettingView/Tabs/TabView/DisabledAppTab.swift similarity index 100% rename from Easydict/Swift/View/SettingView/Tabs/DisabledAppTab.swift rename to Easydict/Swift/View/SettingView/Tabs/TabView/DisabledAppTab.swift diff --git a/Easydict/Swift/View/SettingView/Tabs/GeneralTab.swift b/Easydict/Swift/View/SettingView/Tabs/TabView/GeneralTab.swift similarity index 100% rename from Easydict/Swift/View/SettingView/Tabs/GeneralTab.swift rename to Easydict/Swift/View/SettingView/Tabs/TabView/GeneralTab.swift diff --git a/Easydict/Swift/View/SettingView/Tabs/PrivacyTab.swift b/Easydict/Swift/View/SettingView/Tabs/TabView/PrivacyTab.swift similarity index 100% rename from Easydict/Swift/View/SettingView/Tabs/PrivacyTab.swift rename to Easydict/Swift/View/SettingView/Tabs/TabView/PrivacyTab.swift diff --git a/Easydict/Swift/View/SettingView/Tabs/ServiceTab.swift b/Easydict/Swift/View/SettingView/Tabs/TabView/ServiceTab.swift similarity index 100% rename from Easydict/Swift/View/SettingView/Tabs/ServiceTab.swift rename to Easydict/Swift/View/SettingView/Tabs/TabView/ServiceTab.swift diff --git a/Easydict/Swift/View/SettingView/Tabs/ShortcutTab.swift b/Easydict/Swift/View/SettingView/Tabs/TabView/ShortcutTab.swift similarity index 100% rename from Easydict/Swift/View/SettingView/Tabs/ShortcutTab.swift rename to Easydict/Swift/View/SettingView/Tabs/TabView/ShortcutTab.swift diff --git a/Easydict/objc/Service/Model/EZConstKey.h b/Easydict/objc/Service/Model/EZConstKey.h index 31e7fca84..9da1f3d74 100644 --- a/Easydict/objc/Service/Model/EZConstKey.h +++ b/Easydict/objc/Service/Model/EZConstKey.h @@ -15,27 +15,29 @@ static NSString *const EZBetaFeatureKey = @"EZBetaFeatureKey"; static NSString *const EZDictionaryKey = @"Dictionary"; +// OpenAI static NSString *const EZOpenAIAPIKey = @"EZOpenAIAPIKey"; static NSString *const EZOpenAIEndPointKey = @"EZOpenAIEndPointKey"; static NSString *const EZOpenAITranslationKey = @"EZOpenAITranslationKey"; static NSString *const EZOpenAIDictionaryKey = @"EZOpenAIDictionaryKey"; static NSString *const EZOpenAISentenceKey = @"EZOpenAISentenceKey"; - static NSString *const EZOpenAIServiceUsageStatusKey = @"EZOpenAIServiceUsageStatusKey"; - static NSString *const EZOpenAIModelKey = @"EZOpenAIModelKey"; +static NSString *const EZOpenAIAvailableModelsKey = @"EZOpenAIAvailableModelsKey"; +static NSString *const EZOpenAIValidModelsKey = @"EZOpenAIValidModelsKey"; +// Custom OpenAI static NSString *const EZCustomOpenAINameKey = @"EZCustomOpenAINameKey"; static NSString *const EZCustomOpenAIEndPointKey = @"EZCustomOpenAIEndPointKey"; static NSString *const EZCustomOpenAIAPIKey = @"EZCustomOpenAIAPIKey"; - -static NSString *const EZCustomOpenAIModelssAvailableKey = @"EZCustomOpenAIModelssAvailableKey"; -static NSString *const EZCustomOpenAIModelKey = @"EZCustomOpenAIModelKey"; - static NSString *const EZCustomOpenAITranslationKey = @"EZCustomOpenAITranslationKey"; static NSString *const EZCustomOpenAIDictionaryKey = @"EZCustomOpenAIDictionaryKey"; static NSString *const EZCustomOpenAISentenceKey = @"EZCustomOpenAISentenceKey"; static NSString *const EZCustomOpenAIServiceUsageStatusKey = @"EZCustomOpenAIServiceUsageStatusKey"; +static NSString *const EZCustomOpenAIAvailableModelsKey = @"EZCustomOpenAIAvailableModelsKey"; +static NSString *const EZCustomOpenAIModelKey = @"EZCustomOpenAIModelKey"; +static NSString *const EZCustomOpenAIValidModelsKey = @"EZCustomOpenAIValidModelsKey"; + static NSString *const EZDeepLAuthKey = @"EZDeepLAuthKey"; static NSString *const EZDeepLTranslateEndPointKey = @"EZDeepLTranslateEndPointKey"; diff --git a/Easydict/objc/Utility/EZLinkParser/EZSchemeParser.m b/Easydict/objc/Utility/EZLinkParser/EZSchemeParser.m index a29ef482b..b3a4b3c8e 100644 --- a/Easydict/objc/Utility/EZLinkParser/EZSchemeParser.m +++ b/Easydict/objc/Utility/EZLinkParser/EZSchemeParser.m @@ -199,11 +199,12 @@ - (NSArray *)allowedReadWriteKeys { EZOpenAISentenceKey, EZOpenAIServiceUsageStatusKey, EZOpenAIModelKey, + EZOpenAIAvailableModelsKey, EZCustomOpenAINameKey, EZCustomOpenAIEndPointKey, EZCustomOpenAIAPIKey, - EZCustomOpenAIModelssAvailableKey, + EZCustomOpenAIAvailableModelsKey, EZCustomOpenAIModelKey, EZCustomOpenAITranslationKey, EZCustomOpenAIDictionaryKey, diff --git a/Easydict/objc/ViewController/View/ResultView/EZResultView.m b/Easydict/objc/ViewController/View/ResultView/EZResultView.m index 812e5d81f..14219ab0f 100644 --- a/Easydict/objc/ViewController/View/ResultView/EZResultView.m +++ b/Easydict/objc/ViewController/View/ResultView/EZResultView.m @@ -271,7 +271,7 @@ - (void)setResult:(EZQueryResult *)result { EZBaseOpenAIService *service = (EZBaseOpenAIService *)result.service; self.serviceModelButton.title = service.model; mm_weakify(self); - [self.serviceModelButton setMouseUpBlock:^(EZButton *_Nonnull button) { + [self.serviceModelButton setClickBlock:^(EZButton *_Nonnull button) { mm_strongify(self); [self showModelSelectionMenu:button]; }]; @@ -415,7 +415,7 @@ - (void)updateServiceModelLabel { } - (void)showModelSelectionMenu:(EZButton *)sender { - EZBaseOpenAIService *service = (EZBaseOpenAIService *)self.result.service; + EZBaseOpenAIService *service = (EZBaseOpenAIService *)self.result.service; NSMenu *menu = [[NSMenu alloc] initWithTitle:@"Menu"]; for (NSString *model in service.availableModels) { NSMenuItem *item = [[NSMenuItem alloc] initWithTitle:model action:@selector(modelDidSelected:) keyEquivalent:@""]; diff --git a/Easydict/objc/ViewController/Window/BaseQueryWindow/EZBaseQueryViewController.m b/Easydict/objc/ViewController/Window/BaseQueryWindow/EZBaseQueryViewController.m index 09ee61680..3a414e75c 100644 --- a/Easydict/objc/ViewController/Window/BaseQueryWindow/EZBaseQueryViewController.m +++ b/Easydict/objc/ViewController/Window/BaseQueryWindow/EZBaseQueryViewController.m @@ -243,6 +243,8 @@ - (void)handleServiceUpdate:(NSNotification *)notification { NSDictionary *userInfo = notification.userInfo; EZWindowType type = [userInfo[EZWindowTypeKey] integerValue]; NSString *serviceType = [notification.userInfo objectForKey:EZServiceTypeKey]; + NSLog(@"update service: %@", serviceType); + if ([serviceType length] != 0) { [self reloadSingleService:serviceType]; return;