From 0db37a9a4f43439d29ed4c8e6704666b50fe707e Mon Sep 17 00:00:00 2001 From: Lava <34743145+CanglongCl@users.noreply.github.com> Date: Fri, 12 Jan 2024 22:07:20 -0800 Subject: [PATCH 01/10] import Defaults package --- Easydict.xcodeproj/project.pbxproj | 15 +++++++++++++++ .../xcshareddata/swiftpm/Package.resolved | 11 ++++++++++- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/Easydict.xcodeproj/project.pbxproj b/Easydict.xcodeproj/project.pbxproj index 56aeb6d3f..c3ad54f1c 100644 --- a/Easydict.xcodeproj/project.pbxproj +++ b/Easydict.xcodeproj/project.pbxproj @@ -2234,6 +2234,7 @@ 038030962B4106800009230C /* CocoaLumberjackSwift */, 038EA1A92B41169C008A6DD1 /* ZipArchive */, 038EA1AC2B41282F008A6DD1 /* MJExtension */, + EA3B81FB2B52555C004C0E8B /* Defaults */, ); productName = Bob; productReference = C99EEB182385796700FEE666 /* Easydict-debug.app */; @@ -2292,6 +2293,7 @@ 038030932B4106800009230C /* XCRemoteSwiftPackageReference "CocoaLumberjack" */, 038EA1A82B41169C008A6DD1 /* XCRemoteSwiftPackageReference "ZipArchive" */, 038EA1AB2B41282F008A6DD1 /* XCRemoteSwiftPackageReference "MJExtension" */, + EA3B81FA2B52555C004C0E8B /* XCRemoteSwiftPackageReference "Defaults" */, ); productRefGroup = C99EEB192385796700FEE666 /* Products */; projectDirPath = ""; @@ -3251,6 +3253,14 @@ minimumVersion = 5.8.1; }; }; + EA3B81FA2B52555C004C0E8B /* XCRemoteSwiftPackageReference "Defaults" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/sindresorhus/Defaults.git"; + requirement = { + branch = main; + kind = branch; + }; + }; /* End XCRemoteSwiftPackageReference section */ /* Begin XCSwiftPackageProductDependency section */ @@ -3329,6 +3339,11 @@ package = 2721E4CE2AFE920700A059AC /* XCRemoteSwiftPackageReference "Alamofire" */; productName = Alamofire; }; + EA3B81FB2B52555C004C0E8B /* Defaults */ = { + isa = XCSwiftPackageProductDependency; + package = EA3B81FA2B52555C004C0E8B /* XCRemoteSwiftPackageReference "Defaults" */; + productName = Defaults; + }; /* End XCSwiftPackageProductDependency section */ }; rootObject = C99EEB102385796700FEE666 /* Project object */; diff --git a/Easydict.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Easydict.xcworkspace/xcshareddata/swiftpm/Package.resolved index 4516ef259..fa4a8c59a 100644 --- a/Easydict.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Easydict.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -12,7 +12,7 @@ { "identity" : "alamofire", "kind" : "remoteSourceControl", - "location" : "https://github.com/Alamofire/Alamofire", + "location" : "https://github.com/Alamofire/Alamofire.git", "state" : { "revision" : "3dc6a42c7727c49bf26508e29b0a0b35f9c7e1ad", "version" : "5.8.1" @@ -54,6 +54,15 @@ "version" : "1.8.0" } }, + { + "identity" : "defaults", + "kind" : "remoteSourceControl", + "location" : "https://github.com/sindresorhus/Defaults.git", + "state" : { + "branch" : "main", + "revision" : "d8a9f5105607c85b544558e7f5b51d6c360ba88b" + } + }, { "identity" : "firebase-ios-sdk", "kind" : "remoteSourceControl", From 97ebeef318236796a4811ad3a6ce58d2ba402f99 Mon Sep 17 00:00:00 2001 From: Lava <34743145+CanglongCl@users.noreply.github.com> Date: Fri, 12 Jan 2024 22:08:04 -0800 Subject: [PATCH 02/10] refactor EZConfiguration using Defaults package and Implement Boolean options in SwiftUI Setting View --- Easydict.xcodeproj/project.pbxproj | 14 ++ Easydict/App/Localizable.xcstrings | 36 +++++ .../Configuration/EZConfiguration.swift | 43 ++++++ .../View/SettingView/Tabs/GeneralTab.swift | 129 ++++++++++++++---- 4 files changed, 197 insertions(+), 25 deletions(-) create mode 100644 Easydict/NewApp/Configuration/EZConfiguration.swift diff --git a/Easydict.xcodeproj/project.pbxproj b/Easydict.xcodeproj/project.pbxproj index c3ad54f1c..292d92c08 100644 --- a/Easydict.xcodeproj/project.pbxproj +++ b/Easydict.xcodeproj/project.pbxproj @@ -260,6 +260,8 @@ DC3C643F2B187119008EEDD8 /* ChangeFontSizeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC3C643E2B187119008EEDD8 /* ChangeFontSizeView.swift */; }; DC6D9C872B352EBC0055EFFC /* FontSizeHintView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC6D9C862B352EBC0055EFFC /* FontSizeHintView.swift */; }; DC6D9C892B3969510055EFFC /* Appearance.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC6D9C882B3969510055EFFC /* Appearance.swift */; }; + EA3B81F92B5254AA004C0E8B /* EZConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA3B81F82B5254AA004C0E8B /* EZConfiguration.swift */; }; + EA3B81FC2B52555C004C0E8B /* Defaults in Frameworks */ = {isa = PBXBuildFile; productRef = EA3B81FB2B52555C004C0E8B /* Defaults */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -737,6 +739,7 @@ DC3C643E2B187119008EEDD8 /* ChangeFontSizeView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChangeFontSizeView.swift; sourceTree = ""; }; DC6D9C862B352EBC0055EFFC /* FontSizeHintView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FontSizeHintView.swift; sourceTree = ""; }; DC6D9C882B3969510055EFFC /* Appearance.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Appearance.swift; sourceTree = ""; }; + EA3B81F82B5254AA004C0E8B /* EZConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EZConfiguration.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -778,6 +781,7 @@ 03A830922B4073E700112834 /* AppCenterCrashes in Frameworks */, 03022F1C2B35DEBA00B63209 /* Hue in Frameworks */, 03A830952B4076FC00112834 /* FirebaseAnalyticsSwift in Frameworks */, + EA3B81FC2B52555C004C0E8B /* Defaults in Frameworks */, 03CF27FE2B3DA7D500E19B57 /* Realm in Frameworks */, 03A830902B4073E700112834 /* AppCenterAnalytics in Frameworks */, 03B63ABF2A86967800E155ED /* CoreServices.framework in Frameworks */, @@ -1994,6 +1998,7 @@ 27FE98032B3DCA9F000AD654 /* NewApp */ = { isa = PBXGroup; children = ( + EA3B81F72B52549B004C0E8B /* Configuration */, 27FE95262B3DC55F000AD654 /* EasydictApp.swift */, 27FE98042B3DCB09000AD654 /* NewAppManager.swift */, 27FE98062B3DD525000AD654 /* View */, @@ -2143,6 +2148,14 @@ path = ChangeFontSizeView; sourceTree = ""; }; + EA3B81F72B52549B004C0E8B /* Configuration */ = { + isa = PBXGroup; + children = ( + EA3B81F82B5254AA004C0E8B /* EZConfiguration.swift */, + ); + path = Configuration; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -2593,6 +2606,7 @@ 03B0233229231FA6001C7E63 /* MMLog.swift in Sources */, 03DC7C5E2A3ABE28000BF7C9 /* EZConstKey.m in Sources */, 62E2BF4C2B4082BA00E42D38 /* AliTranslateType.swift in Sources */, + EA3B81F92B5254AA004C0E8B /* EZConfiguration.swift in Sources */, 03E3E7C22ADE318800812C84 /* EZQueryMenuTextView.m in Sources */, 03B0231829231FA6001C7E63 /* SnipWindowController.m in Sources */, 03542A342936F70F00C34C33 /* EZLanguageManager.m in Sources */, diff --git a/Easydict/App/Localizable.xcstrings b/Easydict/App/Localizable.xcstrings index 160e6409b..d6ae1931f 100644 --- a/Easydict/App/Localizable.xcstrings +++ b/Easydict/App/Localizable.xcstrings @@ -2172,6 +2172,42 @@ } } } + }, + "setting.general.advance.header" : { + + }, + "setting.general.auto_copy.header" : { + + }, + "setting.general.auto_query.header" : { + + }, + "setting.general.input.header" : { + + }, + "setting.general.language.header" : { + + }, + "setting.general.mouse_query.adjust_pop_button_origin" : { + + }, + "setting.general.mouse_query.header" : { + + }, + "setting.general.quick_link.header" : { + + }, + "setting.general.voice.auto_play_word_audio" : { + + }, + "setting.general.voice.disable_empty_copy_beep_msg" : { + + }, + "setting.general.voice.header" : { + + }, + "setting.general.windows.header" : { + }, "Settings..." : { "localizations" : { diff --git a/Easydict/NewApp/Configuration/EZConfiguration.swift b/Easydict/NewApp/Configuration/EZConfiguration.swift new file mode 100644 index 000000000..2c40efb40 --- /dev/null +++ b/Easydict/NewApp/Configuration/EZConfiguration.swift @@ -0,0 +1,43 @@ +// +// EZConfiguration.swift +// Easydict +// +// Created by 戴藏龙 on 2024/1/12. +// Copyright © 2024 izual. All rights reserved. +// + +import Defaults +import Foundation + +extension Defaults.Keys { +// static let firstLanguage = Key("EZConfiguration_kFirstLanguageKey", default: true) + + static let autoSelectText = Key("EZConfiguration_kAutoSelectTextKey", default: true) + static let forceAutoGetSelectedText = Key("EZConfiguration_kForceAutoGetSelectedText", default: false) + + static let disableEmptyCopyBeep = Key("EZConfiguration_kDisableEmptyCopyBeepKey", default: true) + static let clickQuery = Key("EZConfiguration_kClickQueryKey", default: false) + static let autoPlayAudio = Key("EZConfiguration_kAutoPlayAudioKey", default: true) + static let launchAtStartup = Key("EZConfiguration_kLaunchAtStartupKey", default: false) + static let hideMainWindow = Key("EZConfiguration_kHideMainWindowKey", default: true) + static let autoQueryOCRText = Key("EZConfiguration_kAutoQueryOCTTextKey", default: true) + static let autoQuerySelectedText = Key("EZConfiguration_kAutoQuerySelectedTextKey", default: true) + static let autoQueryPastedText = Key("EZConfiguration_kAutoQueryPastedTextKey", default: false) + static let autoCopyOCRText = Key("EZConfiguration_kAutoCopyOCRTextKey", default: false) + static let autoCopySelectedText = Key("EZConfiguration_kAutoCopySelectedTextKey", default: false) + static let autoCopyFirstTranslatedText = Key("EZConfiguration_kAutoCopyFirstTranslatedTextKey", default: false) +// static let languageDetectOptimize = Key("EZConfiguration_kLanguageDetectOptimizeTypeKey", default: EZLanguageDetectOptimize.none) +// static let defaultTTSServiceType = Key("EZConfiguration_kDefaultTTSServiceTypeKey", default: ) + static let showGoogleQuickLink = Key("EZConfiguration_kShowGoogleLinkKey", default: true) + static let showEudicQuickLink = Key("EZConfiguration_kShowEudicLinkKey", default: true) + static let showAppleDictionaryQuickLink = Key("EZConfiguration_kShowAppleDictionaryLinkKey", default: true) + static let hideMenuBarIcon = Key("EZConfiguration_kHideMenuBarIconKey", default: false) +// static let fixedWindowPosition = Key("EZConfiguration_kShowFixedWindowPositionKey", default: ) +// static let mouseSelectTranslateWindowType = Key("EZConfiguration_kMouseSelectTranslateWindowTypeKey", default: ) +// static let shortcutSelectTranslateWindowType = Key("EZConfiguration_kShortcutSelectTranslateWindowTypeKey", default: ) + static let adjustPopButtonOrigin = Key("EZConfiguration_kAdjustPopButtomOriginKey", default: false) + static let allowCrashLog = Key("EZConfiguration_kAllowCrashLogKey", default: true) + static let allowAnalytics = Key("EZConfiguration_kAllowAnalyticsKey", default: true) + static let clearInput = Key("EZConfiguration_kClearInputKey", default: true) + static let enableBetaNewApp = Key("EZConfiguration_kEnableBetaNewAppKey", default: false) +} diff --git a/Easydict/NewApp/View/SettingView/Tabs/GeneralTab.swift b/Easydict/NewApp/View/SettingView/Tabs/GeneralTab.swift index e9368eaea..14d466499 100644 --- a/Easydict/NewApp/View/SettingView/Tabs/GeneralTab.swift +++ b/Easydict/NewApp/View/SettingView/Tabs/GeneralTab.swift @@ -6,6 +6,7 @@ // Copyright © 2023 izual. All rights reserved. // +import Defaults import SwiftUI @available(macOS 13, *) @@ -13,41 +14,119 @@ struct GeneralTab: View { var body: some View { Form { Section { - HStack { - Text("show_main_window") - Toggle(isOn: $hideMainWindow) { - Text("hide_main_window") - } - } - HStack { - Text("launch") - Toggle(isOn: $launchAtStartup) { - Text("launch_at_startup") - } + Text("first_language") + Text("second_language") + Text("language_detect_optimize") + } header: { + Text("setting.general.language.header") + } + + Section { + Toggle("auto_show_query_icon", isOn: $autoSelectText) + Toggle("force_auto_get_selected_text", isOn: $forceAutoGetSelectedText) + Toggle("click_icon_query_info", isOn: $clickQuery) + Toggle("setting.general.mouse_query.adjust_pop_button_origin", isOn: $adjustPopButtonOrigin) // 调整查询图标位置: + } header: { + Text("setting.general.mouse_query.header") + } + + Section { + Toggle("setting.general.voice.disable_empty_copy_beep_msg", isOn: $disableEmptyCopyBeep) // 禁用提示音:划词内容为空时生效 + Toggle("setting.general.voice.auto_play_word_audio", isOn: $autoPlayAudio) // 查询英语单词后自动播放发音 + } header: { + Text("setting.general.voice.header") + } + + Section { + Toggle(isOn: $hideMainWindow) { + Text("hide_main_window") } - HStack { - Text("menu_bar_icon") - Toggle(isOn: $hideMenuBarIcon) { - Text("hide_menu_bar_icon") - } + Text("mouse_select_translate_window_type") + Text("shortcut_select_translate_window_type") + Text("fixed_window_position") + } header: { + Text("setting.general.windows.header") + } + + Section { + Toggle("clear_input_when_translating", isOn: $clearInput) + } header: { + Text("setting.general.input.header") + } + + Section { + Toggle("auto_query_ocr_text", isOn: $autoQueryOCRText) + Toggle("auto_query_selected_text", isOn: $autoQuerySelectedText) + Toggle("auto_query_pasted_text", isOn: $autoQueryPastedText) + } header: { + Text("setting.general.auto_query.header") + } + + Section { + Toggle("auto_copy_ocr_text", isOn: $autoCopyOCRText) + Toggle("auto_copy_selected_text", isOn: $autoCopySelectedText) + Toggle("auto_copy_first_translated_text", isOn: $autoCopyFirstTranslatedText) + } header: { + Text("setting.general.auto_copy.header") + } + + Section { + Toggle("show_google_quick_link", isOn: $showGoogleQuickLink) + Toggle("show_eudic_quick_link", isOn: $showEudicQuickLink) + Toggle("show_apple_dictionary_quick_link", isOn: $showAppleDictionaryQuickLink) + } header: { + Text("setting.general.quick_link.header") + } + + Section { + Toggle(isOn: $launchAtStartup) { + Text("launch_at_startup") } - HStack { - Text("beta_new_app") - Toggle(isOn: $enableBetaNewApp) { - Text("enable_beta_new_app") - } + Toggle(isOn: $hideMenuBarIcon) { + Text("hide_menu_bar_icon") } } header: { Text("other") } + + Section { + Text("default_tts_service") + Toggle(isOn: $enableBetaNewApp) { + Text("enable_beta_new_app") + } + } header: { + Text("setting.general.advance.header") + } } .formStyle(.grouped) } - @AppStorage(kHideMainWindowKey) private var hideMainWindow = false - @AppStorage(kLaunchAtStartupKey) private var launchAtStartup = false - @AppStorage(kHideMenuBarIconKey) private var hideMenuBarIcon = false - @AppStorage(kEnableBetaNewAppKey) private var enableBetaNewApp = false + @Default(.autoSelectText) private var autoSelectText + @Default(.forceAutoGetSelectedText) private var forceAutoGetSelectedText + @Default(.clickQuery) private var clickQuery + @Default(.adjustPopButtonOrigin) private var adjustPopButtonOrigin + + @Default(.clearInput) private var clearInput + + @Default(.disableEmptyCopyBeep) private var disableEmptyCopyBeep + @Default(.autoPlayAudio) private var autoPlayAudio + + @Default(.autoQueryOCRText) private var autoQueryOCRText + @Default(.autoQuerySelectedText) private var autoQuerySelectedText + @Default(.autoQueryPastedText) private var autoQueryPastedText + + @Default(.autoCopyOCRText) private var autoCopyOCRText + @Default(.autoCopySelectedText) private var autoCopySelectedText + @Default(.autoCopyFirstTranslatedText) private var autoCopyFirstTranslatedText + + @Default(.showGoogleQuickLink) private var showGoogleQuickLink + @Default(.showEudicQuickLink) private var showEudicQuickLink + @Default(.showAppleDictionaryQuickLink) private var showAppleDictionaryQuickLink + + @Default(.hideMainWindow) private var hideMainWindow + @Default(.launchAtStartup) private var launchAtStartup + @Default(.hideMenuBarIcon) private var hideMenuBarIcon + @Default(.enableBetaNewApp) private var enableBetaNewApp } @available(macOS 13, *) From 53cdc59ea0c32780bae129db13237354b38bf82e Mon Sep 17 00:00:00 2001 From: Lava <34743145+CanglongCl@users.noreply.github.com> Date: Sat, 13 Jan 2024 17:21:15 -0800 Subject: [PATCH 03/10] complete enum options in `GeneralTab` of `Setting` --- Easydict.xcodeproj/project.pbxproj | 44 ++ Easydict/App/Localizable.xcstrings | 456 +++++++++++++++++- .../Tencent/TencentTranslateType.swift | 14 - .../Configuration/EZConfiguration.swift | 21 +- Easydict/NewApp/Model/TTSService.swift | 80 +++ .../EZLanguageDetectOptimizeExtensions.swift | 32 ++ .../Extensions/EZLanguageExtensions.swift | 78 +++ .../EZShowWindowPositionExtensions.swift | 34 ++ .../Extensions/EZWindowTypeExtensions.swift | 34 ++ .../View/SettingView/Tabs/GeneralTab.swift | 132 ++++- 10 files changed, 882 insertions(+), 43 deletions(-) create mode 100644 Easydict/NewApp/Model/TTSService.swift create mode 100644 Easydict/NewApp/Utility/Extensions/EZLanguageDetectOptimizeExtensions.swift create mode 100644 Easydict/NewApp/Utility/Extensions/EZLanguageExtensions.swift create mode 100644 Easydict/NewApp/Utility/Extensions/EZShowWindowPositionExtensions.swift create mode 100644 Easydict/NewApp/Utility/Extensions/EZWindowTypeExtensions.swift diff --git a/Easydict.xcodeproj/project.pbxproj b/Easydict.xcodeproj/project.pbxproj index 292d92c08..117ef5042 100644 --- a/Easydict.xcodeproj/project.pbxproj +++ b/Easydict.xcodeproj/project.pbxproj @@ -262,6 +262,11 @@ DC6D9C892B3969510055EFFC /* Appearance.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC6D9C882B3969510055EFFC /* Appearance.swift */; }; EA3B81F92B5254AA004C0E8B /* EZConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA3B81F82B5254AA004C0E8B /* EZConfiguration.swift */; }; EA3B81FC2B52555C004C0E8B /* Defaults in Frameworks */ = {isa = PBXBuildFile; productRef = EA3B81FB2B52555C004C0E8B /* Defaults */; }; + EA9943E32B534C3300EE7B97 /* TTSService.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA9943E22B534C3300EE7B97 /* TTSService.swift */; }; + EA9943E82B534D8900EE7B97 /* EZLanguageDetectOptimizeExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA9943E72B534D8900EE7B97 /* EZLanguageDetectOptimizeExtensions.swift */; }; + EA9943EE2B5353AB00EE7B97 /* EZWindowTypeExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA9943ED2B5353AB00EE7B97 /* EZWindowTypeExtensions.swift */; }; + EA9943F02B5354C400EE7B97 /* EZShowWindowPositionExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA9943EF2B5354C400EE7B97 /* EZShowWindowPositionExtensions.swift */; }; + EA9943F22B5358BF00EE7B97 /* EZLanguageExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA9943F12B5358BF00EE7B97 /* EZLanguageExtensions.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -740,6 +745,11 @@ DC6D9C862B352EBC0055EFFC /* FontSizeHintView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FontSizeHintView.swift; sourceTree = ""; }; DC6D9C882B3969510055EFFC /* Appearance.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Appearance.swift; sourceTree = ""; }; EA3B81F82B5254AA004C0E8B /* EZConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EZConfiguration.swift; sourceTree = ""; }; + EA9943E22B534C3300EE7B97 /* TTSService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TTSService.swift; sourceTree = ""; }; + EA9943E72B534D8900EE7B97 /* EZLanguageDetectOptimizeExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EZLanguageDetectOptimizeExtensions.swift; sourceTree = ""; }; + EA9943ED2B5353AB00EE7B97 /* EZWindowTypeExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EZWindowTypeExtensions.swift; sourceTree = ""; }; + EA9943EF2B5354C400EE7B97 /* EZShowWindowPositionExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EZShowWindowPositionExtensions.swift; sourceTree = ""; }; + EA9943F12B5358BF00EE7B97 /* EZLanguageExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EZLanguageExtensions.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -1998,6 +2008,8 @@ 27FE98032B3DCA9F000AD654 /* NewApp */ = { isa = PBXGroup; children = ( + EA9943E12B534C2900EE7B97 /* Model */, + EA9943DD2B534BAE00EE7B97 /* Utility */, EA3B81F72B52549B004C0E8B /* Configuration */, 27FE95262B3DC55F000AD654 /* EasydictApp.swift */, 27FE98042B3DCB09000AD654 /* NewAppManager.swift */, @@ -2156,6 +2168,33 @@ path = Configuration; sourceTree = ""; }; + EA9943DD2B534BAE00EE7B97 /* Utility */ = { + isa = PBXGroup; + children = ( + EA9943E62B534D7C00EE7B97 /* Extensions */, + ); + path = Utility; + sourceTree = ""; + }; + EA9943E12B534C2900EE7B97 /* Model */ = { + isa = PBXGroup; + children = ( + EA9943E22B534C3300EE7B97 /* TTSService.swift */, + ); + path = Model; + sourceTree = ""; + }; + EA9943E62B534D7C00EE7B97 /* Extensions */ = { + isa = PBXGroup; + children = ( + EA9943E72B534D8900EE7B97 /* EZLanguageDetectOptimizeExtensions.swift */, + EA9943ED2B5353AB00EE7B97 /* EZWindowTypeExtensions.swift */, + EA9943EF2B5354C400EE7B97 /* EZShowWindowPositionExtensions.swift */, + EA9943F12B5358BF00EE7B97 /* EZLanguageExtensions.swift */, + ); + path = Extensions; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -2508,6 +2547,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + EA9943EE2B5353AB00EE7B97 /* EZWindowTypeExtensions.swift in Sources */, 030570E22ADB919900C9905E /* EZAppleScriptManager.m in Sources */, 03991158292927E000E1B06D /* EZTitlebar.m in Sources */, 03D8A65C2A433B4100D9A968 /* EZConfiguration+EZUserData.m in Sources */, @@ -2643,6 +2683,7 @@ 0333FDA62A035D5700891515 /* NSString+EZChineseText.m in Sources */, 03E02A222924E77100A10260 /* EZMenuItemManager.m in Sources */, 039D119929D5E26300C93F46 /* EZAudioUtils.m in Sources */, + EA9943F22B5358BF00EE7B97 /* EZLanguageExtensions.swift in Sources */, 03B0231729231FA6001C7E63 /* Snip.m in Sources */, 03BFFC6E295FE59C004E033E /* EZQueryResult+EZYoudaoDictModel.m in Sources */, DC3C643F2B187119008EEDD8 /* ChangeFontSizeView.swift in Sources */, @@ -2660,10 +2701,12 @@ 0320C5872B29F35700861B3D /* QueryServiceRecord.swift in Sources */, 03FC699A2B39D13A0035D2DA /* EZOpenAIChatResponse.m in Sources */, 03B022FA29231FA6001C7E63 /* EZServiceTypes.m in Sources */, + EA9943F02B5354C400EE7B97 /* EZShowWindowPositionExtensions.swift in Sources */, 03B0233129231FA6001C7E63 /* MMCrash.m in Sources */, 03B0232629231FA6001C7E63 /* NSAttributedString+MM.m in Sources */, 03542A402937B3C900C34C33 /* EZOCRResult.m in Sources */, C4DD01E92B12B3C80025EE8E /* TencentService.swift in Sources */, + EA9943E32B534C3300EE7B97 /* TTSService.swift in Sources */, 036A0DBB2AD941F9006E6D4F /* EZReplaceTextButton.m in Sources */, 03DC7C662A3CA465000BF7C9 /* HWSegmentedControl.m in Sources */, 037E006D2B3DC098006491C6 /* EZOpenAIService+EZPromptMessages.m in Sources */, @@ -2699,6 +2742,7 @@ DC6D9C872B352EBC0055EFFC /* FontSizeHintView.swift in Sources */, 03B0232429231FA6001C7E63 /* NSUserDefaults+MM.m in Sources */, 03542A5E2938F05B00C34C33 /* EZLanguageModel.m in Sources */, + EA9943E82B534D8900EE7B97 /* EZLanguageDetectOptimizeExtensions.swift in Sources */, 03F639952AA6CFBB009B9914 /* EZBingConfig.m in Sources */, 03D2A3E329F4C6F50035CED4 /* EZNetworkManager.m in Sources */, 0309E1ED292B439A00AFB76A /* EZTextView.m in Sources */, diff --git a/Easydict/App/Localizable.xcstrings b/Easydict/App/Localizable.xcstrings index d6ae1931f..97050d572 100644 --- a/Easydict/App/Localizable.xcstrings +++ b/Easydict/App/Localizable.xcstrings @@ -845,7 +845,7 @@ "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "划词内容为空时生效" + "value" : "划词内容为空时禁用复制提示音" } } } @@ -907,7 +907,7 @@ "localizations" : { "zh-Hans" : { "stringUnit" : { - "state" : "translated", + "state" : "needs_review", "value" : "以 SwiftUI App模式启动,重启App生效" } } @@ -1675,6 +1675,9 @@ } } } + }, + "none_window" : { + }, "ocr_result_is_empty" : { "localizations" : { @@ -2173,41 +2176,463 @@ } } }, + "setting.general.advance.default_tts_service" : { + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Default TTS Service" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "默认 TTS 服务" + } + } + } + }, + "setting.general.advance.enable_beta_feature" : { + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Enable Beta features" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "启用 Beta 特性" + } + } + } + }, "setting.general.advance.header" : { - + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Advance" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "高级" + } + } + } }, "setting.general.auto_copy.header" : { - + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Auto Copy" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "自动复制" + } + } + } }, "setting.general.auto_query.header" : { - + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Auto Query" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "自动查询" + } + } + } }, "setting.general.input.header" : { - + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Input Field" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "输入框" + } + } + } + }, + "setting.general.language.duplicated_alert %@%@%@" : { + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "The first language should not be the same as the second language (%1$@). The %2$@ was replaced with %3$@." + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "第一语言不能与第二语言相同(%1$@)。%2$@已被替换为%3$@。" + } + } + } + }, + "setting.general.language.duplicated_alert.field.first" : { + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "first language" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "第二语言" + } + } + } + }, + "setting.general.language.duplicated_alert.field.second" : { + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "second language" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "第一语言" + } + } + } + }, + "setting.general.language.duplicated_alert.title" : { + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Language Duplicated" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "语言重复" + } + } + } + }, + "setting.general.language.first_language" : { + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "First Language" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "第一语言" + } + } + } }, "setting.general.language.header" : { - + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Language" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "语言" + } + } + } + }, + "setting.general.language.language_detect_optimize" : { + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Language Detection" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "语种识别" + } + } + } + }, + "setting.general.language.second_language" : { + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Second Language" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "第二语言" + } + } + } }, "setting.general.mouse_query.adjust_pop_button_origin" : { - + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Adjust Query Icon Position to avoid conflict with PopClip" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "needs_review", + "value" : "调整查询图标位置(避免和 PopClip 显示冲突)" + } + } + } }, "setting.general.mouse_query.header" : { - + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Query with Mouse" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "鼠标查询" + } + } + } }, "setting.general.quick_link.header" : { - + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Quick Link" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "快捷功能" + } + } + } }, "setting.general.voice.auto_play_word_audio" : { - + "localizations" : { + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "查询英语单词后自动播放发音" + } + } + } }, "setting.general.voice.disable_empty_copy_beep_msg" : { - + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Disable 'beep' when selected text is empty" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "划词内容为空时" + } + } + } }, "setting.general.voice.header" : { - + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Sound" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "声音" + } + } + } + }, + "setting.general.window.fixed_window_position" : { + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Floating Window Position" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "侧悬浮窗口位置" + } + } + } + }, + "setting.general.window.mouse_select_translate_window_type" : { + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Mouse Window Type" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "鼠标划词窗口类型" + } + } + } + }, + "setting.general.window.shortcut_select_translate_window_type" : { + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Shortcut Window Type" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "快捷键划词窗口类型" + } + } + } }, "setting.general.windows.header" : { - + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Window" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "窗口" + } + } + } + }, + "setting.tts_service.options.apple" : { + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Apple" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "苹果" + } + } + } + }, + "setting.tts_service.options.baidu" : { + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Baidu" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "百度" + } + } + } + }, + "setting.tts_service.options.bing" : { + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Bing" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "Bing" + } + } + } + }, + "setting.tts_service.options.google" : { + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Google" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "Google" + } + } + } + }, + "setting.tts_service.options.youdao" : { + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Youdao" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "有道" + } + } + } }, "Settings..." : { "localizations" : { @@ -2552,6 +2977,9 @@ } } } + }, + "unknown_option" : { + }, "unpin" : { "localizations" : { diff --git a/Easydict/Feature/Service/Tencent/TencentTranslateType.swift b/Easydict/Feature/Service/Tencent/TencentTranslateType.swift index e82753154..84ac8b712 100644 --- a/Easydict/Feature/Service/Tencent/TencentTranslateType.swift +++ b/Easydict/Feature/Service/Tencent/TencentTranslateType.swift @@ -75,17 +75,3 @@ struct TencentTranslateType: Equatable { return TencentTranslateType(sourceLanguage: fromLanguage, targetLanguage: toLanguage) } } - -extension [Language] { - /// Contains Chinese language, - func containsChinese() -> Bool { - contains { $0.isKindOfChinese() } - } -} - -extension Language { - /// Is kind of Chinese language, means it is simplifiedChinese or traditionalChinese. - func isKindOfChinese() -> Bool { - self == .simplifiedChinese || self == .traditionalChinese - } -} diff --git a/Easydict/NewApp/Configuration/EZConfiguration.swift b/Easydict/NewApp/Configuration/EZConfiguration.swift index 2c40efb40..76d54f3d3 100644 --- a/Easydict/NewApp/Configuration/EZConfiguration.swift +++ b/Easydict/NewApp/Configuration/EZConfiguration.swift @@ -10,7 +10,13 @@ import Defaults import Foundation extension Defaults.Keys { -// static let firstLanguage = Key("EZConfiguration_kFirstLanguageKey", default: true) + // rename `from` + static let queryFromLanguage = Key("EZConfiguration_kFromKey", default: .auto) + // rename `to` + static let queryToLanguage = Key("EZConfiguration_kToKey", default: .auto) + + static let firstLanguage = Key("EZConfiguration_kFirstLanguageKey", default: EZLanguageManager.shared().systemPreferredTwoLanguages[0]) + static let secondLanguage = Key("EZConfiguration_kSecondLanguageKey", default: EZLanguageManager.shared().systemPreferredTwoLanguages[1]) static let autoSelectText = Key("EZConfiguration_kAutoSelectTextKey", default: true) static let forceAutoGetSelectedText = Key("EZConfiguration_kForceAutoGetSelectedText", default: false) @@ -26,18 +32,21 @@ extension Defaults.Keys { static let autoCopyOCRText = Key("EZConfiguration_kAutoCopyOCRTextKey", default: false) static let autoCopySelectedText = Key("EZConfiguration_kAutoCopySelectedTextKey", default: false) static let autoCopyFirstTranslatedText = Key("EZConfiguration_kAutoCopyFirstTranslatedTextKey", default: false) -// static let languageDetectOptimize = Key("EZConfiguration_kLanguageDetectOptimizeTypeKey", default: EZLanguageDetectOptimize.none) -// static let defaultTTSServiceType = Key("EZConfiguration_kDefaultTTSServiceTypeKey", default: ) + static let languageDetectOptimize = Key("EZConfiguration_kLanguageDetectOptimizeTypeKey", default: EZLanguageDetectOptimize.none) + @available(macOS 13, *) + static let defaultTTSServiceType = Key("EZConfiguration_kDefaultTTSServiceTypeKey", default: TTSService.youdao) static let showGoogleQuickLink = Key("EZConfiguration_kShowGoogleLinkKey", default: true) static let showEudicQuickLink = Key("EZConfiguration_kShowEudicLinkKey", default: true) static let showAppleDictionaryQuickLink = Key("EZConfiguration_kShowAppleDictionaryLinkKey", default: true) static let hideMenuBarIcon = Key("EZConfiguration_kHideMenuBarIconKey", default: false) -// static let fixedWindowPosition = Key("EZConfiguration_kShowFixedWindowPositionKey", default: ) -// static let mouseSelectTranslateWindowType = Key("EZConfiguration_kMouseSelectTranslateWindowTypeKey", default: ) -// static let shortcutSelectTranslateWindowType = Key("EZConfiguration_kShortcutSelectTranslateWindowTypeKey", default: ) + static let fixedWindowPosition = Key("EZConfiguration_kShowFixedWindowPositionKey", default: .right) + static let mouseSelectTranslateWindowType = Key("EZConfiguration_kMouseSelectTranslateWindowTypeKey", default: .mini) + static let shortcutSelectTranslateWindowType = Key("EZConfiguration_kShortcutSelectTranslateWindowTypeKey", default: .fixed) static let adjustPopButtonOrigin = Key("EZConfiguration_kAdjustPopButtomOriginKey", default: false) static let allowCrashLog = Key("EZConfiguration_kAllowCrashLogKey", default: true) static let allowAnalytics = Key("EZConfiguration_kAllowAnalyticsKey", default: true) static let clearInput = Key("EZConfiguration_kClearInputKey", default: true) static let enableBetaNewApp = Key("EZConfiguration_kEnableBetaNewAppKey", default: false) + + static let enableBetaFeature = Key("EZBetaFeatureKey", default: false) } diff --git a/Easydict/NewApp/Model/TTSService.swift b/Easydict/NewApp/Model/TTSService.swift new file mode 100644 index 000000000..59154e434 --- /dev/null +++ b/Easydict/NewApp/Model/TTSService.swift @@ -0,0 +1,80 @@ +// +// TTSService.swift +// Easydict +// +// Created by 戴藏龙 on 2024/1/13. +// Copyright © 2024 izual. All rights reserved. +// + +import Defaults +import Foundation + +@available(macOS 13, *) +enum TTSService: String, CaseIterable, CustomLocalizedStringResourceConvertible { + var localizedStringResource: LocalizedStringResource { + switch self { + case .youdao: + "setting.tts_service.options.youdao" + case .bing: + "setting.tts_service.options.bing" + case .google: + "setting.tts_service.options.google" + case .baidu: + "setting.tts_service.options.baidu" + case .apple: + "setting.tts_service.options.apple" + } + } + + case youdao + case bing + case google + case baidu + case apple +} + +@available(macOS 13, *) +extension TTSService: Defaults.Serializable { + // while in the future, ServiceType was deleted, then you can safely delete this struct and `bridge` + struct TTSServiceBridge: Defaults.Bridge { + func serialize(_ value: TTSService?) -> String? { + guard let value else { return nil } + switch value { + case .youdao: + return ServiceType.youdao.rawValue + case .bing: + return ServiceType.bing.rawValue + case .google: + return ServiceType.google.rawValue + case .baidu: + return ServiceType.baidu.rawValue + case .apple: + return ServiceType.apple.rawValue + } + } + + func deserialize(_ object: String?) -> TTSService? { + guard let object else { return nil } + switch object { + case "Youdao": + return .youdao + case "Bing": + return .bing + case "Google": + return .google + case "Baidu": + return .baidu + case "Apple": + return .apple + default: + return nil + } + } + + typealias Value = TTSService + + typealias Serializable = String + } + + static let bridge = TTSServiceBridge() +} diff --git a/Easydict/NewApp/Utility/Extensions/EZLanguageDetectOptimizeExtensions.swift b/Easydict/NewApp/Utility/Extensions/EZLanguageDetectOptimizeExtensions.swift new file mode 100644 index 000000000..f6021d276 --- /dev/null +++ b/Easydict/NewApp/Utility/Extensions/EZLanguageDetectOptimizeExtensions.swift @@ -0,0 +1,32 @@ +// +// EZLanguageDetectOptimizeExtensions.swift +// Easydict +// +// Created by 戴藏龙 on 2024/1/13. +// Copyright © 2024 izual. All rights reserved. +// + +import Defaults +import Foundation + +extension EZLanguageDetectOptimize: Defaults.Serializable {} + +extension EZLanguageDetectOptimize: CaseIterable { + public static let allCases: [EZLanguageDetectOptimize] = [.none, .baidu, .google] +} + +@available(macOS 13, *) +extension EZLanguageDetectOptimize: CustomLocalizedStringResourceConvertible { + public var localizedStringResource: LocalizedStringResource { + switch self { + case .none: + "language_detect_optimize_none" + case .google: + "language_detect_optimize_google" + case .baidu: + "language_detect_optimize_baidu" + @unknown default: + "unknown_option" + } + } +} diff --git a/Easydict/NewApp/Utility/Extensions/EZLanguageExtensions.swift b/Easydict/NewApp/Utility/Extensions/EZLanguageExtensions.swift new file mode 100644 index 000000000..5e18082dc --- /dev/null +++ b/Easydict/NewApp/Utility/Extensions/EZLanguageExtensions.swift @@ -0,0 +1,78 @@ +// +// EZLanguageExtensions.swift +// Easydict +// +// Created by 戴藏龙 on 2024/1/13. +// Copyright © 2024 izual. All rights reserved. +// + +import Defaults +import Foundation + +extension Language: Defaults.Serializable {} + +extension Language: CaseIterable { + public static let allCases: [Language] = EZLanguageModel.allLanguagesDict().allKeys().map { rawValue in + Language(rawValue: rawValue as String) + } + + public static let allCasesWithoutAuto: [Language] = allCases.filter { language in + language != .auto + } +} + +public extension Language { + var model: EZLanguageModel { + EZLanguageModel.allLanguagesDict().object(forKey: rawValue as NSString) + } + + var chineseName: String { + model.chineseName + } + + var englishName: String { + model.englishName.rawValue + } + + var localName: String { + model.localName + } + + var flagEmoji: String { + model.flagEmoji + } + + var voiceName: String { + model.voiceName + } + + var localeIdentifier: String { + model.localeIdentifier + } + + var localizedName: String { + if EZLanguageManager.shared().isSystemChineseFirstLanguage() { + chineseName + } else { + if self == .auto { + "Auto" + } else { + englishName + } + } + } +} + +extension [Language] { + /// Contains Chinese language, + func containsChinese() -> Bool { + contains { $0.isKindOfChinese() } + } +} + +extension Language { + /// Is kind of Chinese language, means it is simplifiedChinese or traditionalChinese. + func isKindOfChinese() -> Bool { + self == .simplifiedChinese || self == .traditionalChinese + } +} diff --git a/Easydict/NewApp/Utility/Extensions/EZShowWindowPositionExtensions.swift b/Easydict/NewApp/Utility/Extensions/EZShowWindowPositionExtensions.swift new file mode 100644 index 000000000..402ce9be7 --- /dev/null +++ b/Easydict/NewApp/Utility/Extensions/EZShowWindowPositionExtensions.swift @@ -0,0 +1,34 @@ +// +// EZShowWindowPositionExtensions.swift +// Easydict +// +// Created by 戴藏龙 on 2024/1/13. +// Copyright © 2024 izual. All rights reserved. +// + +import Defaults +import Foundation + +extension EZShowWindowPosition: Defaults.Serializable {} + +extension EZShowWindowPosition: CaseIterable { + public static let allCases: [EZShowWindowPosition] = [.right, .mouse, .former, .center] +} + +@available(macOS 13, *) +extension EZShowWindowPosition: CustomLocalizedStringResourceConvertible { + public var localizedStringResource: LocalizedStringResource { + switch self { + case .right: + "fixed_window_position_right" + case .mouse: + "fixed_window_position_mouse" + case .former: + "fixed_window_position_former" + case .center: + "fixed_window_position_center" + @unknown default: + "unknown_option" + } + } +} diff --git a/Easydict/NewApp/Utility/Extensions/EZWindowTypeExtensions.swift b/Easydict/NewApp/Utility/Extensions/EZWindowTypeExtensions.swift new file mode 100644 index 000000000..e5e8fe091 --- /dev/null +++ b/Easydict/NewApp/Utility/Extensions/EZWindowTypeExtensions.swift @@ -0,0 +1,34 @@ +// +// EZWindowTypeExtensions.swift +// Easydict +// +// Created by 戴藏龙 on 2024/1/13. +// Copyright © 2024 izual. All rights reserved. +// + +import Defaults +import Foundation + +extension EZWindowType: Defaults.Serializable {} + +public extension EZWindowType { + static let availableOptions: [EZWindowType] = [.mini, .fixed] +} + +@available(macOS 13, *) +extension EZWindowType: CustomLocalizedStringResourceConvertible { + public var localizedStringResource: LocalizedStringResource { + switch self { + case .fixed: + "fixed_window" + case .main: + "main_window" + case .mini: + "mini_window" + case .none: + "none_window" + @unknown default: + "unknown_option" + } + } +} diff --git a/Easydict/NewApp/View/SettingView/Tabs/GeneralTab.swift b/Easydict/NewApp/View/SettingView/Tabs/GeneralTab.swift index 14d466499..e3f39be7e 100644 --- a/Easydict/NewApp/View/SettingView/Tabs/GeneralTab.swift +++ b/Easydict/NewApp/View/SettingView/Tabs/GeneralTab.swift @@ -14,9 +14,13 @@ struct GeneralTab: View { var body: some View { Form { Section { - Text("first_language") - Text("second_language") - Text("language_detect_optimize") + FirstAndSecondLanguageSettingView() + Picker("setting.general.language.language_detect_optimize", selection: $languageDetectOptimize) { + ForEach(EZLanguageDetectOptimize.allCases, id: \.rawValue) { option in + Text(option.localizedStringResource) + .tag(option) + } + } } header: { Text("setting.general.language.header") } @@ -38,12 +42,24 @@ struct GeneralTab: View { } Section { - Toggle(isOn: $hideMainWindow) { - Text("hide_main_window") + Picker("setting.general.window.mouse_select_translate_window_type", selection: $mouseSelectTranslateWindowType) { + ForEach(EZWindowType.availableOptions, id: \.rawValue) { option in + Text(option.localizedStringResource) + .tag(option) + } + } + Picker("setting.general.window.shortcut_select_translate_window_type", selection: $shortcutSelectTranslateWindowType) { + ForEach(EZWindowType.availableOptions, id: \.rawValue) { option in + Text(option.localizedStringResource) + .tag(option) + } + } + Picker("setting.general.window.fixed_window_position", selection: $fixedWindowPosition) { + ForEach(EZShowWindowPosition.allCases, id: \.rawValue) { option in + Text(option.localizedStringResource) + .tag(option) + } } - Text("mouse_select_translate_window_type") - Text("shortcut_select_translate_window_type") - Text("fixed_window_position") } header: { Text("setting.general.windows.header") } @@ -82,6 +98,9 @@ struct GeneralTab: View { Toggle(isOn: $launchAtStartup) { Text("launch_at_startup") } + Toggle(isOn: $hideMainWindow) { + Text("hide_main_window") + } Toggle(isOn: $hideMenuBarIcon) { Text("hide_menu_bar_icon") } @@ -90,7 +109,13 @@ struct GeneralTab: View { } Section { - Text("default_tts_service") + Picker("setting.general.advance.default_tts_service", selection: $defaultTTSServiceType) { + ForEach(TTSService.allCases, id: \.rawValue) { option in + Text(option.localizedStringResource) + .tag(option) + } + } + Toggle("setting.general.advance.enable_beta_feature", isOn: $enableBetaFeature) Toggle(isOn: $enableBetaNewApp) { Text("enable_beta_new_app") } @@ -127,9 +152,98 @@ struct GeneralTab: View { @Default(.launchAtStartup) private var launchAtStartup @Default(.hideMenuBarIcon) private var hideMenuBarIcon @Default(.enableBetaNewApp) private var enableBetaNewApp + + @Default(.languageDetectOptimize) private var languageDetectOptimize + @Default(.defaultTTSServiceType) private var defaultTTSServiceType + + @Default(.fixedWindowPosition) private var fixedWindowPosition + @Default(.mouseSelectTranslateWindowType) private var mouseSelectTranslateWindowType + @Default(.shortcutSelectTranslateWindowType) private var shortcutSelectTranslateWindowType + @Default(.enableBetaFeature) private var enableBetaFeature } @available(macOS 13, *) #Preview { GeneralTab() } + +@available(macOS 13, *) +private struct FirstAndSecondLanguageSettingView: View { + var body: some View { + Group { + Picker("setting.general.language.first_language", selection: $firstLanguage) { + ForEach(Language.allCasesWithoutAuto, id: \.rawValue) { option in + Text(verbatim: "\(option.flagEmoji) \(option.localizedName)") + .tag(option) + } + } + Picker("setting.general.language.second_language", selection: $secondLanguage) { + ForEach(Language.allCasesWithoutAuto, id: \.rawValue) { option in + Text(verbatim: "\(option.flagEmoji) \(option.localizedName)") + .tag(option) + } + } + } + .onChange(of: firstLanguage) { [firstLanguage] newValue in + let oldValue = firstLanguage + if newValue == secondLanguage { + secondLanguage = oldValue + languageDuplicatedAlert = .init(duplicatedLanguage: newValue, setField: .second, setLanguage: oldValue) + } + } + .onChange(of: secondLanguage) { [secondLanguage] newValue in + let oldValue = secondLanguage + if newValue == firstLanguage { + firstLanguage = oldValue + languageDuplicatedAlert = .init(duplicatedLanguage: newValue, setField: .first, setLanguage: oldValue) + } + } + .alert("setting.general.language.duplicated_alert.title", isPresented: showLanguageDuplicatedAlert, presenting: languageDuplicatedAlert) { _ in + + } message: { alert in + Text(alert.description) + } + } + + @Default(.firstLanguage) private var firstLanguage + @Default(.secondLanguage) private var secondLanguage + + private struct LanguageDuplicateAlert: CustomStringConvertible { + var description: String { + // First language should not be same as second language. (\(duplicatedLanguage)) + // \(setField) is replaced with \(setLanguage). + String(localized: "setting.general.language.duplicated_alert \(duplicatedLanguage.localizedName)\(String(localized: setField.localizedStringResource))\(setLanguage.localizedName)") + } + + let duplicatedLanguage: Language + + let setField: Field + + let setLanguage: Language + + enum Field: CustomLocalizedStringResourceConvertible { + var localizedStringResource: LocalizedStringResource { + switch self { + case .first: + "setting.general.language.duplicated_alert.field.first" + case .second: + "setting.general.language.duplicated_alert.field.second" + } + } + + case first + case second + } + } + + @State private var languageDuplicatedAlert: LanguageDuplicateAlert? + private var showLanguageDuplicatedAlert: Binding { + .init { + languageDuplicatedAlert != nil + } set: { newValue in + if !newValue { + languageDuplicatedAlert = nil + } + } + } +} From d0f16fe30ea21478f608d950a821bd7a503e291b Mon Sep 17 00:00:00 2001 From: Lava <34743145+CanglongCl@users.noreply.github.com> Date: Sat, 13 Jan 2024 18:22:22 -0800 Subject: [PATCH 04/10] Font Size and Appearance setting --- Easydict/App/Localizable.xcstrings | 66 ++++++++++++++++++- .../Feature/Configuration/Appearance.swift | 3 +- .../Configuration/EZConfiguration.swift | 3 + .../View/SettingView/Tabs/GeneralTab.swift | 35 ++++++++++ 4 files changed, 105 insertions(+), 2 deletions(-) diff --git a/Easydict/App/Localizable.xcstrings b/Easydict/App/Localizable.xcstrings index 97050d572..aa35e533b 100644 --- a/Easydict/App/Localizable.xcstrings +++ b/Easydict/App/Localizable.xcstrings @@ -2202,7 +2202,7 @@ }, "zh-Hans" : { "stringUnit" : { - "state" : "needs_review", + "state" : "translated", "value" : "启用 Beta 特性" } } @@ -2224,6 +2224,38 @@ } } }, + "setting.general.appearance.header" : { + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Appearance" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "外观" + } + } + } + }, + "setting.general.appearance.light_dark_appearance" : { + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Appearance" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "外观" + } + } + } + }, "setting.general.auto_copy.header" : { "localizations" : { "en" : { @@ -2256,6 +2288,38 @@ } } }, + "setting.general.font.font_size.label" : { + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Font Size" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "字体大小" + } + } + } + }, + "setting.general.font.header" : { + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Font" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "字体" + } + } + } + }, "setting.general.input.header" : { "localizations" : { "en" : { diff --git a/Easydict/Feature/Configuration/Appearance.swift b/Easydict/Feature/Configuration/Appearance.swift index 3a59f1124..eb49593cc 100644 --- a/Easydict/Feature/Configuration/Appearance.swift +++ b/Easydict/Feature/Configuration/Appearance.swift @@ -6,9 +6,10 @@ // Copyright © 2023 izual. All rights reserved. // +import Defaults import Foundation -@objc enum AppearenceType: Int, CaseIterable { +@objc enum AppearenceType: Int, CaseIterable, Defaults.Serializable { case followSystem = 0 case light case dark diff --git a/Easydict/NewApp/Configuration/EZConfiguration.swift b/Easydict/NewApp/Configuration/EZConfiguration.swift index 76d54f3d3..79c0381a6 100644 --- a/Easydict/NewApp/Configuration/EZConfiguration.swift +++ b/Easydict/NewApp/Configuration/EZConfiguration.swift @@ -49,4 +49,7 @@ extension Defaults.Keys { static let enableBetaNewApp = Key("EZConfiguration_kEnableBetaNewAppKey", default: false) static let enableBetaFeature = Key("EZBetaFeatureKey", default: false) + + static let appearanceType = Key("EZConfiguration_kApperanceKey", default: .followSystem) + static let fontSizeOptionIndex = Key("EZConfiguration_kTranslationControllerFontKey", default: 0) } diff --git a/Easydict/NewApp/View/SettingView/Tabs/GeneralTab.swift b/Easydict/NewApp/View/SettingView/Tabs/GeneralTab.swift index e3f39be7e..d633c0f54 100644 --- a/Easydict/NewApp/View/SettingView/Tabs/GeneralTab.swift +++ b/Easydict/NewApp/View/SettingView/Tabs/GeneralTab.swift @@ -13,6 +13,16 @@ import SwiftUI struct GeneralTab: View { var body: some View { Form { + Section { + Picker("setting.general.appearance.light_dark_appearance", selection: $appearanceType) { + ForEach(AppearenceType.allCases, id: \.rawValue) { option in + Text(option.title) + .tag(option) + } + } + } header: { + Text("setting.general.appearance.header") + } Section { FirstAndSecondLanguageSettingView() Picker("setting.general.language.language_detect_optimize", selection: $languageDetectOptimize) { @@ -94,6 +104,28 @@ struct GeneralTab: View { Text("setting.general.quick_link.header") } + Section { + let bindingFontSize = Binding(get: { + Double(fontSizeOptionIndex) + }, set: { newValue in + fontSizeOptionIndex = UInt(newValue) + }) + Slider(value: bindingFontSize, in: 0.0 ... 4.0, step: 1) { + Text("setting.general.font.font_size.label") + } minimumValueLabel: { + Text("small") + .font(.system(size: 10)) + } maximumValueLabel: { + Text("large") + .font(.system(size: 14)) + } + } header: { + Text("setting.general.font.header") + } footer: { + Text("hints_keyboard_shortcuts_font_size") + .font(.footnote) + } + Section { Toggle(isOn: $launchAtStartup) { Text("launch_at_startup") @@ -160,6 +192,9 @@ struct GeneralTab: View { @Default(.mouseSelectTranslateWindowType) private var mouseSelectTranslateWindowType @Default(.shortcutSelectTranslateWindowType) private var shortcutSelectTranslateWindowType @Default(.enableBetaFeature) private var enableBetaFeature + @Default(.appearanceType) private var appearanceType + + @Default(.fontSizeOptionIndex) private var fontSizeOptionIndex } @available(macOS 13, *) From fdc79391cd50cad8a89080ce5e99b2271bda338d Mon Sep 17 00:00:00 2001 From: Lava <34743145+CanglongCl@users.noreply.github.com> Date: Sat, 13 Jan 2024 19:02:21 -0800 Subject: [PATCH 05/10] rename EZConfiguration file in swift to Configuration --- Easydict.xcodeproj/project.pbxproj | 8 ++++---- .../{EZConfiguration.swift => Configuration.swift} | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) rename Easydict/NewApp/Configuration/{EZConfiguration.swift => Configuration.swift} (99%) diff --git a/Easydict.xcodeproj/project.pbxproj b/Easydict.xcodeproj/project.pbxproj index 117ef5042..c3a2439f3 100644 --- a/Easydict.xcodeproj/project.pbxproj +++ b/Easydict.xcodeproj/project.pbxproj @@ -260,7 +260,7 @@ DC3C643F2B187119008EEDD8 /* ChangeFontSizeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC3C643E2B187119008EEDD8 /* ChangeFontSizeView.swift */; }; DC6D9C872B352EBC0055EFFC /* FontSizeHintView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC6D9C862B352EBC0055EFFC /* FontSizeHintView.swift */; }; DC6D9C892B3969510055EFFC /* Appearance.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC6D9C882B3969510055EFFC /* Appearance.swift */; }; - EA3B81F92B5254AA004C0E8B /* EZConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA3B81F82B5254AA004C0E8B /* EZConfiguration.swift */; }; + EA3B81F92B5254AA004C0E8B /* Configuration.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA3B81F82B5254AA004C0E8B /* Configuration.swift */; }; EA3B81FC2B52555C004C0E8B /* Defaults in Frameworks */ = {isa = PBXBuildFile; productRef = EA3B81FB2B52555C004C0E8B /* Defaults */; }; EA9943E32B534C3300EE7B97 /* TTSService.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA9943E22B534C3300EE7B97 /* TTSService.swift */; }; EA9943E82B534D8900EE7B97 /* EZLanguageDetectOptimizeExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA9943E72B534D8900EE7B97 /* EZLanguageDetectOptimizeExtensions.swift */; }; @@ -744,7 +744,7 @@ DC3C643E2B187119008EEDD8 /* ChangeFontSizeView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ChangeFontSizeView.swift; sourceTree = ""; }; DC6D9C862B352EBC0055EFFC /* FontSizeHintView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FontSizeHintView.swift; sourceTree = ""; }; DC6D9C882B3969510055EFFC /* Appearance.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Appearance.swift; sourceTree = ""; }; - EA3B81F82B5254AA004C0E8B /* EZConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EZConfiguration.swift; sourceTree = ""; }; + EA3B81F82B5254AA004C0E8B /* Configuration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Configuration.swift; sourceTree = ""; }; EA9943E22B534C3300EE7B97 /* TTSService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TTSService.swift; sourceTree = ""; }; EA9943E72B534D8900EE7B97 /* EZLanguageDetectOptimizeExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EZLanguageDetectOptimizeExtensions.swift; sourceTree = ""; }; EA9943ED2B5353AB00EE7B97 /* EZWindowTypeExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EZWindowTypeExtensions.swift; sourceTree = ""; }; @@ -2163,7 +2163,7 @@ EA3B81F72B52549B004C0E8B /* Configuration */ = { isa = PBXGroup; children = ( - EA3B81F82B5254AA004C0E8B /* EZConfiguration.swift */, + EA3B81F82B5254AA004C0E8B /* Configuration.swift */, ); path = Configuration; sourceTree = ""; @@ -2646,7 +2646,7 @@ 03B0233229231FA6001C7E63 /* MMLog.swift in Sources */, 03DC7C5E2A3ABE28000BF7C9 /* EZConstKey.m in Sources */, 62E2BF4C2B4082BA00E42D38 /* AliTranslateType.swift in Sources */, - EA3B81F92B5254AA004C0E8B /* EZConfiguration.swift in Sources */, + EA3B81F92B5254AA004C0E8B /* Configuration.swift in Sources */, 03E3E7C22ADE318800812C84 /* EZQueryMenuTextView.m in Sources */, 03B0231829231FA6001C7E63 /* SnipWindowController.m in Sources */, 03542A342936F70F00C34C33 /* EZLanguageManager.m in Sources */, diff --git a/Easydict/NewApp/Configuration/EZConfiguration.swift b/Easydict/NewApp/Configuration/Configuration.swift similarity index 99% rename from Easydict/NewApp/Configuration/EZConfiguration.swift rename to Easydict/NewApp/Configuration/Configuration.swift index 79c0381a6..513fc114d 100644 --- a/Easydict/NewApp/Configuration/EZConfiguration.swift +++ b/Easydict/NewApp/Configuration/Configuration.swift @@ -1,5 +1,5 @@ // -// EZConfiguration.swift +// Configuration.swift // Easydict // // Created by 戴藏龙 on 2024/1/12. From 349525dd86e1cc4d5454693a368adf531c0b4570 Mon Sep 17 00:00:00 2001 From: Lava <34743145+CanglongCl@users.noreply.github.com> Date: Sat, 13 Jan 2024 19:06:53 -0800 Subject: [PATCH 06/10] rename `TTSService` with `TTSServiceType` --- Easydict.xcodeproj/project.pbxproj | 8 ++++---- Easydict/NewApp/Configuration/Configuration.swift | 2 +- .../{TTSService.swift => TTSServiceType.swift} | 14 +++++++------- 3 files changed, 12 insertions(+), 12 deletions(-) rename Easydict/NewApp/Model/{TTSService.swift => TTSServiceType.swift} (81%) diff --git a/Easydict.xcodeproj/project.pbxproj b/Easydict.xcodeproj/project.pbxproj index c3a2439f3..d317f29e3 100644 --- a/Easydict.xcodeproj/project.pbxproj +++ b/Easydict.xcodeproj/project.pbxproj @@ -262,7 +262,7 @@ DC6D9C892B3969510055EFFC /* Appearance.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC6D9C882B3969510055EFFC /* Appearance.swift */; }; EA3B81F92B5254AA004C0E8B /* Configuration.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA3B81F82B5254AA004C0E8B /* Configuration.swift */; }; EA3B81FC2B52555C004C0E8B /* Defaults in Frameworks */ = {isa = PBXBuildFile; productRef = EA3B81FB2B52555C004C0E8B /* Defaults */; }; - EA9943E32B534C3300EE7B97 /* TTSService.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA9943E22B534C3300EE7B97 /* TTSService.swift */; }; + EA9943E32B534C3300EE7B97 /* TTSServiceType.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA9943E22B534C3300EE7B97 /* TTSServiceType.swift */; }; EA9943E82B534D8900EE7B97 /* EZLanguageDetectOptimizeExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA9943E72B534D8900EE7B97 /* EZLanguageDetectOptimizeExtensions.swift */; }; EA9943EE2B5353AB00EE7B97 /* EZWindowTypeExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA9943ED2B5353AB00EE7B97 /* EZWindowTypeExtensions.swift */; }; EA9943F02B5354C400EE7B97 /* EZShowWindowPositionExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA9943EF2B5354C400EE7B97 /* EZShowWindowPositionExtensions.swift */; }; @@ -745,7 +745,7 @@ DC6D9C862B352EBC0055EFFC /* FontSizeHintView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FontSizeHintView.swift; sourceTree = ""; }; DC6D9C882B3969510055EFFC /* Appearance.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Appearance.swift; sourceTree = ""; }; EA3B81F82B5254AA004C0E8B /* Configuration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Configuration.swift; sourceTree = ""; }; - EA9943E22B534C3300EE7B97 /* TTSService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TTSService.swift; sourceTree = ""; }; + EA9943E22B534C3300EE7B97 /* TTSServiceType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TTSServiceType.swift; sourceTree = ""; }; EA9943E72B534D8900EE7B97 /* EZLanguageDetectOptimizeExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EZLanguageDetectOptimizeExtensions.swift; sourceTree = ""; }; EA9943ED2B5353AB00EE7B97 /* EZWindowTypeExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EZWindowTypeExtensions.swift; sourceTree = ""; }; EA9943EF2B5354C400EE7B97 /* EZShowWindowPositionExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EZShowWindowPositionExtensions.swift; sourceTree = ""; }; @@ -2179,7 +2179,7 @@ EA9943E12B534C2900EE7B97 /* Model */ = { isa = PBXGroup; children = ( - EA9943E22B534C3300EE7B97 /* TTSService.swift */, + EA9943E22B534C3300EE7B97 /* TTSServiceType.swift */, ); path = Model; sourceTree = ""; @@ -2706,7 +2706,7 @@ 03B0232629231FA6001C7E63 /* NSAttributedString+MM.m in Sources */, 03542A402937B3C900C34C33 /* EZOCRResult.m in Sources */, C4DD01E92B12B3C80025EE8E /* TencentService.swift in Sources */, - EA9943E32B534C3300EE7B97 /* TTSService.swift in Sources */, + EA9943E32B534C3300EE7B97 /* TTSServiceType.swift in Sources */, 036A0DBB2AD941F9006E6D4F /* EZReplaceTextButton.m in Sources */, 03DC7C662A3CA465000BF7C9 /* HWSegmentedControl.m in Sources */, 037E006D2B3DC098006491C6 /* EZOpenAIService+EZPromptMessages.m in Sources */, diff --git a/Easydict/NewApp/Configuration/Configuration.swift b/Easydict/NewApp/Configuration/Configuration.swift index 513fc114d..9ecdff830 100644 --- a/Easydict/NewApp/Configuration/Configuration.swift +++ b/Easydict/NewApp/Configuration/Configuration.swift @@ -34,7 +34,7 @@ extension Defaults.Keys { static let autoCopyFirstTranslatedText = Key("EZConfiguration_kAutoCopyFirstTranslatedTextKey", default: false) static let languageDetectOptimize = Key("EZConfiguration_kLanguageDetectOptimizeTypeKey", default: EZLanguageDetectOptimize.none) @available(macOS 13, *) - static let defaultTTSServiceType = Key("EZConfiguration_kDefaultTTSServiceTypeKey", default: TTSService.youdao) + static let defaultTTSServiceType = Key("EZConfiguration_kDefaultTTSServiceTypeKey", default: TTSServiceType.youdao) static let showGoogleQuickLink = Key("EZConfiguration_kShowGoogleLinkKey", default: true) static let showEudicQuickLink = Key("EZConfiguration_kShowEudicLinkKey", default: true) static let showAppleDictionaryQuickLink = Key("EZConfiguration_kShowAppleDictionaryLinkKey", default: true) diff --git a/Easydict/NewApp/Model/TTSService.swift b/Easydict/NewApp/Model/TTSServiceType.swift similarity index 81% rename from Easydict/NewApp/Model/TTSService.swift rename to Easydict/NewApp/Model/TTSServiceType.swift index 59154e434..fc734cea4 100644 --- a/Easydict/NewApp/Model/TTSService.swift +++ b/Easydict/NewApp/Model/TTSServiceType.swift @@ -10,7 +10,7 @@ import Defaults import Foundation @available(macOS 13, *) -enum TTSService: String, CaseIterable, CustomLocalizedStringResourceConvertible { +enum TTSServiceType: String, CaseIterable, CustomLocalizedStringResourceConvertible { var localizedStringResource: LocalizedStringResource { switch self { case .youdao: @@ -34,10 +34,10 @@ enum TTSService: String, CaseIterable, CustomLocalizedStringResourceConvertible } @available(macOS 13, *) -extension TTSService: Defaults.Serializable { +extension TTSServiceType: Defaults.Serializable { // while in the future, ServiceType was deleted, then you can safely delete this struct and `bridge` - struct TTSServiceBridge: Defaults.Bridge { - func serialize(_ value: TTSService?) -> String? { + struct TTSServiceTypeBridge: Defaults.Bridge { + func serialize(_ value: TTSServiceType?) -> String? { guard let value else { return nil } switch value { case .youdao: @@ -53,7 +53,7 @@ extension TTSService: Defaults.Serializable { } } - func deserialize(_ object: String?) -> TTSService? { + func deserialize(_ object: String?) -> TTSServiceType? { guard let object else { return nil } switch object { case "Youdao": @@ -71,10 +71,10 @@ extension TTSService: Defaults.Serializable { } } - typealias Value = TTSService + typealias Value = TTSServiceType typealias Serializable = String } - static let bridge = TTSServiceBridge() + static let bridge = TTSServiceTypeBridge() } From 5038ee684c7a588420be8fdcb14561c24681c114 Mon Sep 17 00:00:00 2001 From: Lava <34743145+CanglongCl@users.noreply.github.com> Date: Sat, 13 Jan 2024 19:18:58 -0800 Subject: [PATCH 07/10] renaming TTSService to TTSServiceType and remove EZ prefix of some file --- Easydict.xcodeproj/project.pbxproj | 32 +++++++++---------- .../Feature/Configuration/EZConfiguration.h | 1 + Easydict/NewApp/Model/TTSServiceType.swift | 2 +- ...=> LanguageDetectOptimizeExtensions.swift} | 2 +- ...ensions.swift => LanguageExtensions.swift} | 2 +- ...ift => ShowWindowPositionExtensions.swift} | 2 +- ...sions.swift => WindowTypeExtensions.swift} | 2 +- .../View/SettingView/Tabs/GeneralTab.swift | 2 +- 8 files changed, 23 insertions(+), 22 deletions(-) rename Easydict/NewApp/Utility/Extensions/{EZLanguageDetectOptimizeExtensions.swift => LanguageDetectOptimizeExtensions.swift} (94%) rename Easydict/NewApp/Utility/Extensions/{EZLanguageExtensions.swift => LanguageExtensions.swift} (98%) rename Easydict/NewApp/Utility/Extensions/{EZShowWindowPositionExtensions.swift => ShowWindowPositionExtensions.swift} (95%) rename Easydict/NewApp/Utility/Extensions/{EZWindowTypeExtensions.swift => WindowTypeExtensions.swift} (95%) diff --git a/Easydict.xcodeproj/project.pbxproj b/Easydict.xcodeproj/project.pbxproj index d317f29e3..b3d6daeee 100644 --- a/Easydict.xcodeproj/project.pbxproj +++ b/Easydict.xcodeproj/project.pbxproj @@ -263,10 +263,10 @@ EA3B81F92B5254AA004C0E8B /* Configuration.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA3B81F82B5254AA004C0E8B /* Configuration.swift */; }; EA3B81FC2B52555C004C0E8B /* Defaults in Frameworks */ = {isa = PBXBuildFile; productRef = EA3B81FB2B52555C004C0E8B /* Defaults */; }; EA9943E32B534C3300EE7B97 /* TTSServiceType.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA9943E22B534C3300EE7B97 /* TTSServiceType.swift */; }; - EA9943E82B534D8900EE7B97 /* EZLanguageDetectOptimizeExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA9943E72B534D8900EE7B97 /* EZLanguageDetectOptimizeExtensions.swift */; }; - EA9943EE2B5353AB00EE7B97 /* EZWindowTypeExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA9943ED2B5353AB00EE7B97 /* EZWindowTypeExtensions.swift */; }; - EA9943F02B5354C400EE7B97 /* EZShowWindowPositionExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA9943EF2B5354C400EE7B97 /* EZShowWindowPositionExtensions.swift */; }; - EA9943F22B5358BF00EE7B97 /* EZLanguageExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA9943F12B5358BF00EE7B97 /* EZLanguageExtensions.swift */; }; + EA9943E82B534D8900EE7B97 /* LanguageDetectOptimizeExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA9943E72B534D8900EE7B97 /* LanguageDetectOptimizeExtensions.swift */; }; + EA9943EE2B5353AB00EE7B97 /* WindowTypeExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA9943ED2B5353AB00EE7B97 /* WindowTypeExtensions.swift */; }; + EA9943F02B5354C400EE7B97 /* ShowWindowPositionExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA9943EF2B5354C400EE7B97 /* ShowWindowPositionExtensions.swift */; }; + EA9943F22B5358BF00EE7B97 /* LanguageExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA9943F12B5358BF00EE7B97 /* LanguageExtensions.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -746,10 +746,10 @@ DC6D9C882B3969510055EFFC /* Appearance.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Appearance.swift; sourceTree = ""; }; EA3B81F82B5254AA004C0E8B /* Configuration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Configuration.swift; sourceTree = ""; }; EA9943E22B534C3300EE7B97 /* TTSServiceType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TTSServiceType.swift; sourceTree = ""; }; - EA9943E72B534D8900EE7B97 /* EZLanguageDetectOptimizeExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EZLanguageDetectOptimizeExtensions.swift; sourceTree = ""; }; - EA9943ED2B5353AB00EE7B97 /* EZWindowTypeExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EZWindowTypeExtensions.swift; sourceTree = ""; }; - EA9943EF2B5354C400EE7B97 /* EZShowWindowPositionExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EZShowWindowPositionExtensions.swift; sourceTree = ""; }; - EA9943F12B5358BF00EE7B97 /* EZLanguageExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EZLanguageExtensions.swift; sourceTree = ""; }; + EA9943E72B534D8900EE7B97 /* LanguageDetectOptimizeExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LanguageDetectOptimizeExtensions.swift; sourceTree = ""; }; + EA9943ED2B5353AB00EE7B97 /* WindowTypeExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WindowTypeExtensions.swift; sourceTree = ""; }; + EA9943EF2B5354C400EE7B97 /* ShowWindowPositionExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShowWindowPositionExtensions.swift; sourceTree = ""; }; + EA9943F12B5358BF00EE7B97 /* LanguageExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LanguageExtensions.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -2187,10 +2187,10 @@ EA9943E62B534D7C00EE7B97 /* Extensions */ = { isa = PBXGroup; children = ( - EA9943E72B534D8900EE7B97 /* EZLanguageDetectOptimizeExtensions.swift */, - EA9943ED2B5353AB00EE7B97 /* EZWindowTypeExtensions.swift */, - EA9943EF2B5354C400EE7B97 /* EZShowWindowPositionExtensions.swift */, - EA9943F12B5358BF00EE7B97 /* EZLanguageExtensions.swift */, + EA9943E72B534D8900EE7B97 /* LanguageDetectOptimizeExtensions.swift */, + EA9943ED2B5353AB00EE7B97 /* WindowTypeExtensions.swift */, + EA9943EF2B5354C400EE7B97 /* ShowWindowPositionExtensions.swift */, + EA9943F12B5358BF00EE7B97 /* LanguageExtensions.swift */, ); path = Extensions; sourceTree = ""; @@ -2547,7 +2547,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - EA9943EE2B5353AB00EE7B97 /* EZWindowTypeExtensions.swift in Sources */, + EA9943EE2B5353AB00EE7B97 /* WindowTypeExtensions.swift in Sources */, 030570E22ADB919900C9905E /* EZAppleScriptManager.m in Sources */, 03991158292927E000E1B06D /* EZTitlebar.m in Sources */, 03D8A65C2A433B4100D9A968 /* EZConfiguration+EZUserData.m in Sources */, @@ -2683,7 +2683,7 @@ 0333FDA62A035D5700891515 /* NSString+EZChineseText.m in Sources */, 03E02A222924E77100A10260 /* EZMenuItemManager.m in Sources */, 039D119929D5E26300C93F46 /* EZAudioUtils.m in Sources */, - EA9943F22B5358BF00EE7B97 /* EZLanguageExtensions.swift in Sources */, + EA9943F22B5358BF00EE7B97 /* LanguageExtensions.swift in Sources */, 03B0231729231FA6001C7E63 /* Snip.m in Sources */, 03BFFC6E295FE59C004E033E /* EZQueryResult+EZYoudaoDictModel.m in Sources */, DC3C643F2B187119008EEDD8 /* ChangeFontSizeView.swift in Sources */, @@ -2701,7 +2701,7 @@ 0320C5872B29F35700861B3D /* QueryServiceRecord.swift in Sources */, 03FC699A2B39D13A0035D2DA /* EZOpenAIChatResponse.m in Sources */, 03B022FA29231FA6001C7E63 /* EZServiceTypes.m in Sources */, - EA9943F02B5354C400EE7B97 /* EZShowWindowPositionExtensions.swift in Sources */, + EA9943F02B5354C400EE7B97 /* ShowWindowPositionExtensions.swift in Sources */, 03B0233129231FA6001C7E63 /* MMCrash.m in Sources */, 03B0232629231FA6001C7E63 /* NSAttributedString+MM.m in Sources */, 03542A402937B3C900C34C33 /* EZOCRResult.m in Sources */, @@ -2742,7 +2742,7 @@ DC6D9C872B352EBC0055EFFC /* FontSizeHintView.swift in Sources */, 03B0232429231FA6001C7E63 /* NSUserDefaults+MM.m in Sources */, 03542A5E2938F05B00C34C33 /* EZLanguageModel.m in Sources */, - EA9943E82B534D8900EE7B97 /* EZLanguageDetectOptimizeExtensions.swift in Sources */, + EA9943E82B534D8900EE7B97 /* LanguageDetectOptimizeExtensions.swift in Sources */, 03F639952AA6CFBB009B9914 /* EZBingConfig.m in Sources */, 03D2A3E329F4C6F50035CED4 /* EZNetworkManager.m in Sources */, 0309E1ED292B439A00AFB76A /* EZTextView.m in Sources */, diff --git a/Easydict/Feature/Configuration/EZConfiguration.h b/Easydict/Feature/Configuration/EZConfiguration.h index bc07911ee..310f47031 100644 --- a/Easydict/Feature/Configuration/EZConfiguration.h +++ b/Easydict/Feature/Configuration/EZConfiguration.h @@ -23,6 +23,7 @@ static NSString *const EZFontSizeUpdateNotification = @"EZFontSizeUpdateNotifica static NSString *const EZIntelligentQueryModeKey = @"IntelligentQueryMode"; + typedef NS_ENUM(NSUInteger, EZLanguageDetectOptimize) { EZLanguageDetectOptimizeNone = 0, EZLanguageDetectOptimizeBaidu = 1, diff --git a/Easydict/NewApp/Model/TTSServiceType.swift b/Easydict/NewApp/Model/TTSServiceType.swift index fc734cea4..6eda5cf16 100644 --- a/Easydict/NewApp/Model/TTSServiceType.swift +++ b/Easydict/NewApp/Model/TTSServiceType.swift @@ -1,5 +1,5 @@ // -// TTSService.swift +// TTSServiceType.swift // Easydict // // Created by 戴藏龙 on 2024/1/13. diff --git a/Easydict/NewApp/Utility/Extensions/EZLanguageDetectOptimizeExtensions.swift b/Easydict/NewApp/Utility/Extensions/LanguageDetectOptimizeExtensions.swift similarity index 94% rename from Easydict/NewApp/Utility/Extensions/EZLanguageDetectOptimizeExtensions.swift rename to Easydict/NewApp/Utility/Extensions/LanguageDetectOptimizeExtensions.swift index f6021d276..82ec281a1 100644 --- a/Easydict/NewApp/Utility/Extensions/EZLanguageDetectOptimizeExtensions.swift +++ b/Easydict/NewApp/Utility/Extensions/LanguageDetectOptimizeExtensions.swift @@ -1,5 +1,5 @@ // -// EZLanguageDetectOptimizeExtensions.swift +// LanguageDetectOptimizeExtensions.swift // Easydict // // Created by 戴藏龙 on 2024/1/13. diff --git a/Easydict/NewApp/Utility/Extensions/EZLanguageExtensions.swift b/Easydict/NewApp/Utility/Extensions/LanguageExtensions.swift similarity index 98% rename from Easydict/NewApp/Utility/Extensions/EZLanguageExtensions.swift rename to Easydict/NewApp/Utility/Extensions/LanguageExtensions.swift index 5e18082dc..7dc6f5e5c 100644 --- a/Easydict/NewApp/Utility/Extensions/EZLanguageExtensions.swift +++ b/Easydict/NewApp/Utility/Extensions/LanguageExtensions.swift @@ -1,5 +1,5 @@ // -// EZLanguageExtensions.swift +// LanguageExtensions.swift // Easydict // // Created by 戴藏龙 on 2024/1/13. diff --git a/Easydict/NewApp/Utility/Extensions/EZShowWindowPositionExtensions.swift b/Easydict/NewApp/Utility/Extensions/ShowWindowPositionExtensions.swift similarity index 95% rename from Easydict/NewApp/Utility/Extensions/EZShowWindowPositionExtensions.swift rename to Easydict/NewApp/Utility/Extensions/ShowWindowPositionExtensions.swift index 402ce9be7..e531d64c1 100644 --- a/Easydict/NewApp/Utility/Extensions/EZShowWindowPositionExtensions.swift +++ b/Easydict/NewApp/Utility/Extensions/ShowWindowPositionExtensions.swift @@ -1,5 +1,5 @@ // -// EZShowWindowPositionExtensions.swift +// ShowWindowPositionExtensions.swift // Easydict // // Created by 戴藏龙 on 2024/1/13. diff --git a/Easydict/NewApp/Utility/Extensions/EZWindowTypeExtensions.swift b/Easydict/NewApp/Utility/Extensions/WindowTypeExtensions.swift similarity index 95% rename from Easydict/NewApp/Utility/Extensions/EZWindowTypeExtensions.swift rename to Easydict/NewApp/Utility/Extensions/WindowTypeExtensions.swift index e5e8fe091..34b60c049 100644 --- a/Easydict/NewApp/Utility/Extensions/EZWindowTypeExtensions.swift +++ b/Easydict/NewApp/Utility/Extensions/WindowTypeExtensions.swift @@ -1,5 +1,5 @@ // -// EZWindowTypeExtensions.swift +// WindowTypeExtensions.swift // Easydict // // Created by 戴藏龙 on 2024/1/13. diff --git a/Easydict/NewApp/View/SettingView/Tabs/GeneralTab.swift b/Easydict/NewApp/View/SettingView/Tabs/GeneralTab.swift index d633c0f54..962bad4da 100644 --- a/Easydict/NewApp/View/SettingView/Tabs/GeneralTab.swift +++ b/Easydict/NewApp/View/SettingView/Tabs/GeneralTab.swift @@ -142,7 +142,7 @@ struct GeneralTab: View { Section { Picker("setting.general.advance.default_tts_service", selection: $defaultTTSServiceType) { - ForEach(TTSService.allCases, id: \.rawValue) { option in + ForEach(TTSServiceType.allCases, id: \.rawValue) { option in Text(option.localizedStringResource) .tag(option) } From 2c8c22c3432ecb3b64d5b20356b62d69526889f2 Mon Sep 17 00:00:00 2001 From: Lava <34743145+CanglongCl@users.noreply.github.com> Date: Sat, 13 Jan 2024 19:23:30 -0800 Subject: [PATCH 08/10] maintain the order of languages --- Easydict/NewApp/Utility/Extensions/LanguageExtensions.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Easydict/NewApp/Utility/Extensions/LanguageExtensions.swift b/Easydict/NewApp/Utility/Extensions/LanguageExtensions.swift index 7dc6f5e5c..0f9668bda 100644 --- a/Easydict/NewApp/Utility/Extensions/LanguageExtensions.swift +++ b/Easydict/NewApp/Utility/Extensions/LanguageExtensions.swift @@ -12,7 +12,7 @@ import Foundation extension Language: Defaults.Serializable {} extension Language: CaseIterable { - public static let allCases: [Language] = EZLanguageModel.allLanguagesDict().allKeys().map { rawValue in + public static let allCases: [Language] = EZLanguageModel.allLanguagesDict().sortedKeys().map { rawValue in Language(rawValue: rawValue as String) } From 0d4052a7712f7ec3d2c94c0631ee2f7410b8a676 Mon Sep 17 00:00:00 2001 From: Lava <34743145+CanglongCl@users.noreply.github.com> Date: Sat, 13 Jan 2024 19:25:20 -0800 Subject: [PATCH 09/10] filter classical Chinese in first/second language options --- Easydict/NewApp/Utility/Extensions/LanguageExtensions.swift | 4 ++-- Easydict/NewApp/View/SettingView/Tabs/GeneralTab.swift | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Easydict/NewApp/Utility/Extensions/LanguageExtensions.swift b/Easydict/NewApp/Utility/Extensions/LanguageExtensions.swift index 0f9668bda..b7cc84eae 100644 --- a/Easydict/NewApp/Utility/Extensions/LanguageExtensions.swift +++ b/Easydict/NewApp/Utility/Extensions/LanguageExtensions.swift @@ -16,8 +16,8 @@ extension Language: CaseIterable { Language(rawValue: rawValue as String) } - public static let allCasesWithoutAuto: [Language] = allCases.filter { language in - language != .auto + public static let allAvailableOptions: [Language] = allCases.filter { language in + language != .auto && language != .classicalChinese } } diff --git a/Easydict/NewApp/View/SettingView/Tabs/GeneralTab.swift b/Easydict/NewApp/View/SettingView/Tabs/GeneralTab.swift index 962bad4da..852631707 100644 --- a/Easydict/NewApp/View/SettingView/Tabs/GeneralTab.swift +++ b/Easydict/NewApp/View/SettingView/Tabs/GeneralTab.swift @@ -207,13 +207,13 @@ private struct FirstAndSecondLanguageSettingView: View { var body: some View { Group { Picker("setting.general.language.first_language", selection: $firstLanguage) { - ForEach(Language.allCasesWithoutAuto, id: \.rawValue) { option in + ForEach(Language.allAvailableOptions, id: \.rawValue) { option in Text(verbatim: "\(option.flagEmoji) \(option.localizedName)") .tag(option) } } Picker("setting.general.language.second_language", selection: $secondLanguage) { - ForEach(Language.allCasesWithoutAuto, id: \.rawValue) { option in + ForEach(Language.allAvailableOptions, id: \.rawValue) { option in Text(verbatim: "\(option.flagEmoji) \(option.localizedName)") .tag(option) } From 3e0ee479076c12a5b0f21c250bcae35f0070ce95 Mon Sep 17 00:00:00 2001 From: Lava <34743145+CanglongCl@users.noreply.github.com> Date: Sat, 13 Jan 2024 19:59:49 -0800 Subject: [PATCH 10/10] `Defaults ` package use version instead of branch --- Easydict.xcodeproj/project.pbxproj | 4 ++-- Easydict.xcworkspace/xcshareddata/swiftpm/Package.resolved | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Easydict.xcodeproj/project.pbxproj b/Easydict.xcodeproj/project.pbxproj index b3d6daeee..ec44cd1ab 100644 --- a/Easydict.xcodeproj/project.pbxproj +++ b/Easydict.xcodeproj/project.pbxproj @@ -3315,8 +3315,8 @@ isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/sindresorhus/Defaults.git"; requirement = { - branch = main; - kind = branch; + kind = upToNextMajorVersion; + minimumVersion = 7.3.1; }; }; /* End XCRemoteSwiftPackageReference section */ diff --git a/Easydict.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Easydict.xcworkspace/xcshareddata/swiftpm/Package.resolved index fa4a8c59a..9c63ea7f5 100644 --- a/Easydict.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Easydict.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -59,8 +59,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/sindresorhus/Defaults.git", "state" : { - "branch" : "main", - "revision" : "d8a9f5105607c85b544558e7f5b51d6c360ba88b" + "revision" : "3efef5a28ebdbbe922d4a2049493733ed14475a6", + "version" : "7.3.1" } }, {