Skip to content

Commit

Permalink
Add service tab in settings use SwiftUI (#311)
Browse files Browse the repository at this point in the history
* feat: add service tab screen use SwiftUI

* feat: add service list move function

* fix: Removed a file change

* fix: service list order issue and UI change

* style: format code

* fix: change service tab frame size

* feat: update the style of service list

* style: auto update Localizable.xcstrings

* perf: remove unused variables

* fix: service list index of bounds issue and tap issue

* fix: serviceTypes count is greater than services count, cause crash

* perf: adjust service rowHeight to 30

* perf: hide scrollIndicators

* fix: reset service list selection

* feat: optimize tab selection window transition

* fix: window frame not reset issue

* fix: onTap conflict with onMove in service tab

* fix: remove tap event print

---------

Co-authored-by: tisfeng <[email protected]>
  • Loading branch information
phlpsong and tisfeng authored Jan 14, 2024
1 parent 39b7730 commit baca1fd
Show file tree
Hide file tree
Showing 12 changed files with 415 additions and 4 deletions.
40 changes: 40 additions & 0 deletions Easydict.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,12 @@
03FC699A2B39D13A0035D2DA /* EZOpenAIChatResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = 03FC69992B39D13A0035D2DA /* EZOpenAIChatResponse.m */; };
03FD68BB2B1DC59600FD388E /* CryptoSwift in Frameworks */ = {isa = PBXBuildFile; productRef = 03FD68BA2B1DC59600FD388E /* CryptoSwift */; };
03FD68BE2B1E151A00FD388E /* String+EncryptAES.swift in Sources */ = {isa = PBXBuildFile; fileRef = 03FD68BD2B1E151A00FD388E /* String+EncryptAES.swift */; };
0A057D6D2B499A000025C51D /* ServiceTab.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A057D6C2B499A000025C51D /* ServiceTab.swift */; };
0A057D6F2B499A0B0025C51D /* ServiceItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A057D6E2B499A0B0025C51D /* ServiceItemView.swift */; };
0A2BA9602B49A989002872A4 /* Binding+DidSet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A2BA95F2B49A989002872A4 /* Binding+DidSet.swift */; };
0A2BA9642B4A3CCD002872A4 /* Notification+Name.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A2BA9632B4A3CCD002872A4 /* Notification+Name.swift */; };
0AC11B222B4D16A500F07198 /* WindowAccessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AC11B212B4D16A500F07198 /* WindowAccessor.swift */; };
0AC11B242B4E46B300F07198 /* TapHandlerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AC11B232B4E46B300F07198 /* TapHandlerView.swift */; };
17BCAEF72B0DFF9000A7D372 /* EZNiuTransTranslateResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = 17BCAEF52B0DFF9000A7D372 /* EZNiuTransTranslateResponse.m */; };
17BCAEF82B0DFF9000A7D372 /* EZNiuTransTranslate.m in Sources */ = {isa = PBXBuildFile; fileRef = 17BCAEF62B0DFF9000A7D372 /* EZNiuTransTranslate.m */; };
2721E4D02AFE920700A059AC /* Alamofire in Frameworks */ = {isa = PBXBuildFile; productRef = 2721E4CF2AFE920700A059AC /* Alamofire */; };
Expand Down Expand Up @@ -696,6 +702,12 @@
03FC69992B39D13A0035D2DA /* EZOpenAIChatResponse.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZOpenAIChatResponse.m; sourceTree = "<group>"; };
03FD68BD2B1E151A00FD388E /* String+EncryptAES.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "String+EncryptAES.swift"; sourceTree = "<group>"; };
06E15747A7BD34D510ADC6A8 /* Pods-Easydict.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Easydict.debug.xcconfig"; path = "Target Support Files/Pods-Easydict/Pods-Easydict.debug.xcconfig"; sourceTree = "<group>"; };
0A057D6C2B499A000025C51D /* ServiceTab.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ServiceTab.swift; sourceTree = "<group>"; };
0A057D6E2B499A0B0025C51D /* ServiceItemView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ServiceItemView.swift; sourceTree = "<group>"; };
0A2BA95F2B49A989002872A4 /* Binding+DidSet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Binding+DidSet.swift"; sourceTree = "<group>"; };
0A2BA9632B4A3CCD002872A4 /* Notification+Name.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Notification+Name.swift"; sourceTree = "<group>"; };
0AC11B212B4D16A500F07198 /* WindowAccessor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WindowAccessor.swift; sourceTree = "<group>"; };
0AC11B232B4E46B300F07198 /* TapHandlerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TapHandlerView.swift; sourceTree = "<group>"; };
17BCAEF32B0DFF9000A7D372 /* EZNiuTransTranslateResponse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZNiuTransTranslateResponse.h; sourceTree = "<group>"; };
17BCAEF42B0DFF9000A7D372 /* EZNiuTransTranslate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EZNiuTransTranslate.h; sourceTree = "<group>"; };
17BCAEF52B0DFF9000A7D372 /* EZNiuTransTranslateResponse.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EZNiuTransTranslateResponse.m; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1806,6 +1818,8 @@
03CF88602B137ECB0030C199 /* Swift */ = {
isa = PBXGroup;
children = (
0A2BA9622B4A3CBB002872A4 /* Notification */,
0A2BA95E2B49A967002872A4 /* Binding */,
03FD68BC2B1E14B500FD388E /* String */,
03CF88612B137ED60030C199 /* Array */,
);
Expand Down Expand Up @@ -1984,6 +1998,22 @@
path = String;
sourceTree = "<group>";
};
0A2BA95E2B49A967002872A4 /* Binding */ = {
isa = PBXGroup;
children = (
0A2BA95F2B49A989002872A4 /* Binding+DidSet.swift */,
);
path = Binding;
sourceTree = "<group>";
};
0A2BA9622B4A3CBB002872A4 /* Notification */ = {
isa = PBXGroup;
children = (
0A2BA9632B4A3CCD002872A4 /* Notification+Name.swift */,
);
path = Notification;
sourceTree = "<group>";
};
17BCAEF22B0DFF9000A7D372 /* Niutrans */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -2022,6 +2052,9 @@
isa = PBXGroup;
children = (
27FE980A2B3DD5D1000AD654 /* MenuItemView.swift */,
0A057D6E2B499A0B0025C51D /* ServiceItemView.swift */,
0AC11B212B4D16A500F07198 /* WindowAccessor.swift */,
0AC11B232B4E46B300F07198 /* TapHandlerView.swift */,
27FE98072B3DD52B000AD654 /* SettingView */,
);
path = View;
Expand All @@ -2040,6 +2073,7 @@
isa = PBXGroup;
children = (
278540332B3DE04F004E9488 /* GeneralTab.swift */,
0A057D6C2B499A000025C51D /* ServiceTab.swift */,
276742042B3DC230002A2C75 /* PrivacyTab.swift */,
276742052B3DC230002A2C75 /* AboutTab.swift */,
);
Expand Down Expand Up @@ -2571,6 +2605,7 @@
03991166292A8A4400E1B06D /* EZTitleBarMoveView.m in Sources */,
03542A582937CC3200C34C33 /* EZConfiguration.m in Sources */,
27FE98092B3DD536000AD654 /* SettingView.swift in Sources */,
0A057D6F2B499A0B0025C51D /* ServiceItemView.swift in Sources */,
035E37E72A0953120061DFAF /* EZToast.m in Sources */,
03542A492937B5CF00C34C33 /* EZGoogleTranslate.m in Sources */,
03D0435A2928C4C800E7559E /* EZWindowManager.m in Sources */,
Expand Down Expand Up @@ -2608,6 +2643,7 @@
27FE95272B3DC55F000AD654 /* EasydictApp.swift in Sources */,
03882F9129D95044005B5A52 /* CTCommon.m in Sources */,
276742082B3DC230002A2C75 /* PrivacyTab.swift in Sources */,
0AC11B242B4E46B300F07198 /* TapHandlerView.swift in Sources */,
03882F8F29D95044005B5A52 /* CTScreen.m in Sources */,
27FE980B2B3DD5D1000AD654 /* MenuItemView.swift in Sources */,
03DC7C6A2A3CA852000BF7C9 /* EZAppCell.m in Sources */,
Expand All @@ -2619,6 +2655,7 @@
033B7134293CE2430096E2DF /* EZWebViewTranslator.m in Sources */,
03CF88632B137F650030C199 /* Array+Convenience.swift in Sources */,
03B0231229231FA6001C7E63 /* NSObject+DarkMode.m in Sources */,
0AC11B222B4D16A500F07198 /* WindowAccessor.swift in Sources */,
03B0233829231FA6001C7E63 /* MMOrderedDictionary.m in Sources */,
278540342B3DE04F004E9488 /* GeneralTab.swift in Sources */,
03BDA7BC2A26DA280079D04F /* XPMArgumentSignature.m in Sources */,
Expand All @@ -2637,6 +2674,7 @@
03B0230529231FA6001C7E63 /* EZButton.m in Sources */,
03B0232329231FA6001C7E63 /* NSString+MM.m in Sources */,
036196772A000F5900806370 /* NSData+CommonCrypto.m in Sources */,
0A057D6D2B499A000025C51D /* ServiceTab.swift in Sources */,
03882F8D29D95044005B5A52 /* CTView.m in Sources */,
278322602B0FB0EA0026644C /* CaiyunResponse.swift in Sources */,
03B3B8B52925DD3D00168E8D /* EZPopButtonViewController.m in Sources */,
Expand All @@ -2662,6 +2700,7 @@
039CC90D292F664E0037B91E /* NSObject+EZWindowType.m in Sources */,
03B0232229231FA6001C7E63 /* NSImage+MM.m in Sources */,
03BB2DEF29F59C8A00447EDD /* EZSymbolImageButton.m in Sources */,
0A2BA9642B4A3CCD002872A4 /* Notification+Name.swift in Sources */,
62A2D03F2A82967F007EEB01 /* EZBingRequest.m in Sources */,
03BDA7BE2A26DA280079D04F /* XPMCountedArgument.m in Sources */,
03D35DAA2AA6C49B00B023FE /* NSString+EZRegex.m in Sources */,
Expand Down Expand Up @@ -2706,6 +2745,7 @@
03B0232629231FA6001C7E63 /* NSAttributedString+MM.m in Sources */,
03542A402937B3C900C34C33 /* EZOCRResult.m in Sources */,
C4DD01E92B12B3C80025EE8E /* TencentService.swift in Sources */,
0A2BA9602B49A989002872A4 /* Binding+DidSet.swift in Sources */,
EA9943E32B534C3300EE7B97 /* TTSServiceType.swift in Sources */,
036A0DBB2AD941F9006E6D4F /* EZReplaceTextButton.m in Sources */,
03DC7C662A3CA465000BF7C9 /* HWSegmentedControl.m in Sources */,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "1.000",
"green" : "0.847",
"red" : "0.706"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0.251",
"green" : "0.251",
"red" : "0.251"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
1 change: 1 addition & 0 deletions Easydict/App/Easydict-Bridging-Header.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#import "entry.h"
#import "AppDelegate.h"
#import "EZConfiguration.h"
#import "EZLocalStorage.h"

#import "NSString+EZConvenience.h"
#import "EZWindowManager.h"
Expand Down
3 changes: 3 additions & 0 deletions Easydict/App/Localizable.xcstrings
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
{
"sourceLanguage" : "en",
"strings" : {
"" : {

},
"about" : {
"comment" : "about",
"localizations" : {
Expand Down
23 changes: 23 additions & 0 deletions Easydict/Feature/Utility/Swift/Binding/Binding+DidSet.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//
// Binding+DidSet.swift
// Easydict
//
// Created by phlpsong on 2024/1/6.
// Copyright © 2024 izual. All rights reserved.
//

import SwiftUI

// Ref https://stackoverflow.com/a/62871938
// Toggle onChange not trigger issue
extension Binding {
func didSet(execute: @escaping (Value) -> Void) -> Binding {
Binding(
get: { self.wrappedValue },
set: {
self.wrappedValue = $0
execute($0)
}
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
//
// Notification+Name.swift
// Easydict
//
// Created by phlpsong on 2024/1/7.
// Copyright © 2024 izual. All rights reserved.
//

import Foundation

extension Notification.Name {
static let serviceHasUpdated = Notification.Name(EZServiceHasUpdatedNotification)
}

@objc public extension NSNotification {
static let serviceHasUpdated = Notification.Name.serviceHasUpdated
}
41 changes: 41 additions & 0 deletions Easydict/NewApp/View/ServiceItemView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
//
// ServiceItemView.swift
// Easydict
//
// Created by phlpsong on 2024/1/6.
// Copyright © 2024 izual. All rights reserved.
//

import SwiftUI

@available(macOS 13.0, *)
struct ServiceItemView: View {
@Binding var service: QueryService

var toggleValueChanged: (Bool) -> Void

var body: some View {
HStack {
Image(nsImage: NSImage(named: service.serviceType().rawValue) ?? NSImage())
.resizable()
.frame(maxWidth: 18.0, maxHeight: 18.0)

Text(service.name())

Toggle(isOn: $service.enabled.didSet(execute: { value in
toggleValueChanged(value)
})) {}
.toggleStyle(.switch)
.controlSize(.small)
}
.padding(4.0)
}
}

@available(macOS 13, *)
#Preview {
let service = EZLocalStorage.shared().allServices(.mini).first ?? QueryService()
return ServiceItemView(service: .constant(service)) { val in
print("toggle value changed: \(val)")
}
}
43 changes: 39 additions & 4 deletions Easydict/NewApp/View/SettingView/SettingView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,55 @@

import SwiftUI

enum SettingTab: Int {
case general
case service
case privacy
case about
}

@available(macOS 13, *)
struct SettingView: View {
@State private var selection = SettingTab.general.rawValue
@State private var window: NSWindow?

var body: some View {
TabView {
TabView(selection: $selection.didSet(execute: { _ in
resizeWindowFrame()
})) {
GeneralTab()
.tabItem { Label("setting_general", systemImage: "gear") }
.frame(width: 500, height: 400)
.tag(SettingTab.general.rawValue)

ServiceTab()
.tabItem { Label("service", systemImage: "briefcase") }
.tag(SettingTab.service.rawValue)

PrivacyTab()
.tabItem { Label("privacy", systemImage: "hand.raised.square") }
.frame(width: 500, height: 400)
.tag(SettingTab.privacy.rawValue)

AboutTab()
.tabItem { Label("about", systemImage: "info.bubble") }
.frame(width: 500, height: 400)
.tag(SettingTab.about.rawValue)
}
.background(WindowAccessor(window: $window.didSet(execute: { _ in
// reset frame when first launch
resizeWindowFrame()
})))
}

func resizeWindowFrame() {
guard let window else { return }

let originalFrame = window.frame
let newSize = selection == SettingTab.service.rawValue
? CGSize(width: 360, height: 520) : CGSize(width: 500, height: 400)

let newY = originalFrame.origin.y + originalFrame.size.height - newSize.height
let newRect = NSRect(origin: CGPoint(x: originalFrame.origin.x, y: newY), size: newSize)

window.setFrame(newRect, display: true, animate: true)
}
}

Expand Down
2 changes: 2 additions & 0 deletions Easydict/NewApp/View/SettingView/Tabs/AboutTab.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ struct AboutTab: View {
}
.padding(.horizontal, 50)
.padding(.vertical, 30)
.frame(maxWidth: .infinity)
}
.scrollIndicators(.hidden)
.task {
let version = await EZMenuItemManager.shared().fetchRepoLatestVersion(EZGithubRepoEasydict)
await MainActor.run {
Expand Down
Loading

0 comments on commit baca1fd

Please sign in to comment.