From 1a2f079f42e43787dc2ba0c99cb65fb9d4cd1a2b Mon Sep 17 00:00:00 2001 From: Jerry Zhang Date: Tue, 7 May 2024 21:07:17 +0800 Subject: [PATCH] perf(UI): redesign settings advanced tab (#540) * format: setting tabs xcode file order * perf(UI): remove header for advanced tab * perf(UI): add AdvancedTabToggle view * perf: relocate AdvancedTabToggle file * perf: rename AdvancedTabStyle * perf(UI): implement new advanced tab design * perf: clean stale xcstring * perf(UI): adjust corner radius of rectangle * docs: update documentation for AdvancedTabStyle * perf(UI): add optional subtitle to AdvancedTabStyle * perf(UI): adjust en localization * perf: rename AdvancedTabItemView Co-Authored-By: Phillip Song <103433299+phlpsong@users.noreply.github.com> * format: simplify subtitle optional Co-Authored-By: Phillip Song <103433299+phlpsong@users.noreply.github.com> * format: color codes in advanced view Co-Authored-By: Phillip Song <103433299+phlpsong@users.noreply.github.com> * perf(UI): adjust en localization for SwiftUI App mode --------- Co-authored-by: Tisfeng Co-authored-by: Phillip Song <103433299+phlpsong@users.noreply.github.com> --- Easydict.xcodeproj/project.pbxproj | 8 +++- Easydict/App/Localizable.xcstrings | 36 ++++++++--------- Easydict/Swift/View/AdvancedTabItemView.swift | 39 +++++++++++++++++++ .../Tabs/TabView/AdvancedTab.swift | 31 ++++++++++++--- 4 files changed, 88 insertions(+), 26 deletions(-) create mode 100644 Easydict/Swift/View/AdvancedTabItemView.swift diff --git a/Easydict.xcodeproj/project.pbxproj b/Easydict.xcodeproj/project.pbxproj index 6e55d3b6f..c9f1362df 100644 --- a/Easydict.xcodeproj/project.pbxproj +++ b/Easydict.xcodeproj/project.pbxproj @@ -305,6 +305,7 @@ A0B65CA0F31AC8ECFB8347CC /* Pods_EasydictTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 378E73A7EA8FC8FB9C975A63 /* Pods_EasydictTests.framework */; }; B87AC7E36367075BA5D13234 /* Pods_Easydict.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6372B33DFF803C7096A82250 /* Pods_Easydict.framework */; }; C415C0AD2B450D4800A9D231 /* GeminiService.swift in Sources */ = {isa = PBXBuildFile; fileRef = C415C0AC2B450D4800A9D231 /* GeminiService.swift */; }; + C490BF722BE910B70021E40A /* AdvancedTabItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C490BF712BE910B70021E40A /* AdvancedTabItemView.swift */; }; C4DD01E92B12B3C80025EE8E /* TencentService.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4DD01E82B12B3C80025EE8E /* TencentService.swift */; }; C4DD01EB2B12BA250025EE8E /* TencentResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4DD01EA2B12BA250025EE8E /* TencentResponse.swift */; }; C4DD01ED2B12BE9B0025EE8E /* TencentTranslateType.swift in Sources */ = {isa = PBXBuildFile; fileRef = C4DD01EC2B12BE9B0025EE8E /* TencentTranslateType.swift */; }; @@ -839,6 +840,7 @@ 967712ED2B5B943400105E0F /* Shortcut.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Shortcut.swift; sourceTree = ""; }; A230E9A2358C7FBC7FB26189 /* Pods-EasydictTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-EasydictTests.debug.xcconfig"; path = "Target Support Files/Pods-EasydictTests/Pods-EasydictTests.debug.xcconfig"; sourceTree = ""; }; C415C0AC2B450D4800A9D231 /* GeminiService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GeminiService.swift; sourceTree = ""; }; + C490BF712BE910B70021E40A /* AdvancedTabItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = AdvancedTabItemView.swift; path = Easydict/Swift/View/AdvancedTabItemView.swift; sourceTree = SOURCE_ROOT; }; C4DD01E82B12B3C80025EE8E /* TencentService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TencentService.swift; sourceTree = ""; }; C4DD01EA2B12BA250025EE8E /* TencentResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TencentResponse.swift; sourceTree = ""; }; C4DD01EC2B12BE9B0025EE8E /* TencentTranslateType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TencentTranslateType.swift; sourceTree = ""; }; @@ -974,10 +976,10 @@ 278540332B3DE04F004E9488 /* GeneralTab.swift */, 0A057D6C2B499A000025C51D /* ServiceTab.swift */, 0A8685C72B552A590022534F /* DisabledAppTab.swift */, - 276742042B3DC230002A2C75 /* PrivacyTab.swift */, - 276742052B3DC230002A2C75 /* AboutTab.swift */, 96099AE12B5D40330055C4DD /* ShortcutTab.swift */, 03832F532B5F6BE200D0DC64 /* AdvancedTab.swift */, + 276742042B3DC230002A2C75 /* PrivacyTab.swift */, + 276742052B3DC230002A2C75 /* AboutTab.swift */, ); path = TabView; sourceTree = ""; @@ -2254,6 +2256,7 @@ 27FE980A2B3DD5D1000AD654 /* MenuItemView.swift */, 0AC11B212B4D16A500F07198 /* WindowAccessor.swift */, 0AC11B232B4E46B300F07198 /* TapHandlerView.swift */, + C490BF712BE910B70021E40A /* AdvancedTabItemView.swift */, 27FE98072B3DD52B000AD654 /* SettingView */, ); path = View; @@ -3076,6 +3079,7 @@ 9643D9402B6FC426000FBEA6 /* MainMenuShortcutCommand.swift in Sources */, 62A2D03F2A82967F007EEB01 /* EZBingRequest.m in Sources */, 03BDA7BE2A26DA280079D04F /* XPMCountedArgument.m in Sources */, + C490BF722BE910B70021E40A /* AdvancedTabItemView.swift in Sources */, 038A72402B62C0B9004995E3 /* String+Regex.swift in Sources */, 03D35DAA2AA6C49B00B023FE /* NSString+EZRegex.m in Sources */, 03B022FE29231FA6001C7E63 /* EZBaseQueryViewController.m in Sources */, diff --git a/Easydict/App/Localizable.xcstrings b/Easydict/App/Localizable.xcstrings index ae032dd72..89ccb4914 100644 --- a/Easydict/App/Localizable.xcstrings +++ b/Easydict/App/Localizable.xcstrings @@ -1060,13 +1060,29 @@ "en" : { "stringUnit" : { "state" : "translated", - "value" : "Launching in SwiftUI App mode, changes take effect upon restarting the app." + "value" : "Launch in SwiftUI App mode" } }, "zh-Hans" : { "stringUnit" : { "state" : "translated", - "value" : "以 SwiftUI App模式启动,重启App生效" + "value" : "以 SwiftUI App 模式启动" + } + } + } + }, + "enable_beta_new_app_info" : { + "localizations" : { + "en" : { + "stringUnit" : { + "state" : "translated", + "value" : "Changes will take effect upon restarting the app" + } + }, + "zh-Hans" : { + "stringUnit" : { + "state" : "translated", + "value" : "重启 App 以生效" } } } @@ -3316,22 +3332,6 @@ } } }, - "setting.general.advance.header" : { - "localizations" : { - "en" : { - "stringUnit" : { - "state" : "translated", - "value" : "Advance" - } - }, - "zh-Hans" : { - "stringUnit" : { - "state" : "translated", - "value" : "高级" - } - } - } - }, "setting.general.app_setting.header" : { "localizations" : { "en" : { diff --git a/Easydict/Swift/View/AdvancedTabItemView.swift b/Easydict/Swift/View/AdvancedTabItemView.swift new file mode 100644 index 000000000..1f4c20bbd --- /dev/null +++ b/Easydict/Swift/View/AdvancedTabItemView.swift @@ -0,0 +1,39 @@ +// +// AdvancedTabItemView.swift +// Easydict +// +// Created by Jerry on 2024-05-06. +// Copyright © 2024 izual. All rights reserved. +// + +import SwiftUI + +/// Takes in a Color, a systemImage, a text label, and an optional subtitle to quickly create a toggle or picker style for Advanced Tab in Settings. +struct AdvancedTabItemView: View { + var color: Color + var systemImage: String + var labelText: LocalizedStringKey + var subtitleText: LocalizedStringKey? + + var body: some View { + HStack(spacing: 8) { + Rectangle() + .fill(color) + .frame(width: 20, height: 20, alignment: .center) + .clipShape(RoundedRectangle(cornerRadius: 4)) + .overlay( + Image(systemName: systemImage) + .font(.system(size: 12)) + .foregroundColor(.white) + ) + VStack(alignment: .leading) { + Text(labelText) + if let subtitleText { + Text(subtitleText) + .font(.subheadline) + .foregroundColor(.secondary) + } + } + } + } +} diff --git a/Easydict/Swift/View/SettingView/Tabs/TabView/AdvancedTab.swift b/Easydict/Swift/View/SettingView/Tabs/TabView/AdvancedTab.swift index c53648b10..acfe0f381 100644 --- a/Easydict/Swift/View/SettingView/Tabs/TabView/AdvancedTab.swift +++ b/Easydict/Swift/View/SettingView/Tabs/TabView/AdvancedTab.swift @@ -16,19 +16,36 @@ struct AdvancedTab: View { var body: some View { Form { Section { - Picker("setting.general.advance.default_tts_service", selection: $defaultTTSServiceType) { + Picker( + selection: $defaultTTSServiceType, + label: AdvancedTabItemView( + color: .orange, + systemImage: "ellipsis.bubble.fill", + labelText: "setting.general.advance.default_tts_service" + ) + ) { ForEach(TTSServiceType.allCases, id: \.rawValue) { option in Text(option.localizedStringResource) .tag(option) } } - Toggle("setting.general.advance.enable_beta_feature", isOn: $enableBetaFeature) + } + Section { + Toggle(isOn: $enableBetaFeature) { + AdvancedTabItemView( + color: .blue, + systemImage: "hammer.fill", + labelText: "setting.general.advance.enable_beta_feature" + ) + } Toggle(isOn: $enableBetaNewApp) { - Text("enable_beta_new_app") + AdvancedTabItemView( + color: swiftColor, + systemImage: "swift", + labelText: "enable_beta_new_app", + subtitleText: "enable_beta_new_app_info" + ) } - - } header: { - Text("setting.general.advance.header") } } .formStyle(.grouped) @@ -36,6 +53,8 @@ struct AdvancedTab: View { // MARK: Private + private let swiftColor = Color(red: 240 / 255, green: 81 / 255, blue: 56 / 255) + @Default(.defaultTTSServiceType) private var defaultTTSServiceType @Default(.enableBetaFeature) private var enableBetaFeature @Default(.enableBetaNewApp) private var enableBetaNewApp