From 286f6fd7942e3ff574f7034b88bc2402be6314aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=96=E7=95=8C?= Date: Tue, 23 Sep 2025 21:44:33 +0800 Subject: [PATCH] Fix issues on new systems --- ApplicationLibrary/Views/Abstract/FormItem.swift | 16 +++++++++++++++- .../Views/Connections/ConnectionListView.swift | 2 ++ .../Views/Dashboard/ExtensionStatusView.swift | 14 +++++++++++++- .../Views/Dashboard/OverviewView.swift | 6 ++++++ .../Views/Profile/EditProfileView.swift | 8 +++++++- .../Views/Profile/NewProfileView.swift | 14 ++++++++++++-- .../Views/Profile/ProfileView.swift | 10 ++++++++-- .../Views/Setting/ServiceLogView.swift | 1 + 8 files changed, 64 insertions(+), 7 deletions(-) diff --git a/ApplicationLibrary/Views/Abstract/FormItem.swift b/ApplicationLibrary/Views/Abstract/FormItem.swift index ad99841..08da31f 100644 --- a/ApplicationLibrary/Views/Abstract/FormItem.swift +++ b/ApplicationLibrary/Views/Abstract/FormItem.swift @@ -37,7 +37,7 @@ public func FormTextItem(_ name: LocalizedStringKey, _ systemImage: String, @Vie } public func FormItem(_ title: String, @ViewBuilder content: () -> some View) -> some View { - #if os(iOS) || os(tvOS) + #if os(iOS) HStack { Text(title) .lineLimit(1) @@ -46,6 +46,19 @@ public func FormItem(_ title: String, @ViewBuilder content: () -> some View) -> Spacer() content() } + #elseif os(tvOS) + HStack { + Text(title) + .frame(maxWidth: .infinity, alignment: .leading) + .lineLimit(1) + .layoutPriority(1) + Spacer() + Spacer() + content() + .frame(maxWidth: .infinity, alignment: .leading) + .lineLimit(1) + .layoutPriority(1) + } #elseif os(macOS) content() #endif @@ -115,6 +128,7 @@ public func FormNavigationLink(@ViewBuilder destination: () -> some View, @ViewB .toolbar { ToolbarItemGroup(placement: .topBarLeading) { BackButton() + .tint(.accentColor) } } }, label: label) diff --git a/ApplicationLibrary/Views/Connections/ConnectionListView.swift b/ApplicationLibrary/Views/Connections/ConnectionListView.swift index 204f199..84f84a2 100644 --- a/ApplicationLibrary/Views/Connections/ConnectionListView.swift +++ b/ApplicationLibrary/Views/Connections/ConnectionListView.swift @@ -33,6 +33,7 @@ public struct ConnectionListView: View { } } } + #if !os(tvOS) .toolbar { ToolbarItem { Menu { @@ -60,6 +61,7 @@ public struct ConnectionListView: View { } } } + #endif #if os(macOS) .searchable(text: $searchText) #endif diff --git a/ApplicationLibrary/Views/Dashboard/ExtensionStatusView.swift b/ApplicationLibrary/Views/Dashboard/ExtensionStatusView.swift index 7907217..9f13fc8 100644 --- a/ApplicationLibrary/Views/Dashboard/ExtensionStatusView.swift +++ b/ApplicationLibrary/Views/Dashboard/ExtensionStatusView.swift @@ -1,6 +1,9 @@ import Libbox import Library import SwiftUI +#if canImport(UIKit) + import UIKit +#endif public struct ExtensionStatusView: View { @Environment(\.scenePhase) private var scenePhase @@ -115,6 +118,8 @@ public struct ExtensionStatusView: View { } private struct StatusItem: View where T: View { + @Environment(\.colorScheme) private var colorScheme + private let title: String @ViewBuilder private let content: () -> T @@ -148,7 +153,14 @@ public struct ExtensionStatusView: View { #elseif os(macOS) return Color(nsColor: .textBackgroundColor) #elseif os(tvOS) - return Color(uiColor: .black) + switch colorScheme { + case .dark: + return Color(uiColor: .black) + default: + return Color(uiColor: .white) + } + #else + return Color.clear #endif } } diff --git a/ApplicationLibrary/Views/Dashboard/OverviewView.swift b/ApplicationLibrary/Views/Dashboard/OverviewView.swift index 74f5e49..7511a7c 100644 --- a/ApplicationLibrary/Views/Dashboard/OverviewView.swift +++ b/ApplicationLibrary/Views/Dashboard/OverviewView.swift @@ -108,6 +108,9 @@ public struct OverviewView: View { try LibboxNewStandaloneCommandClient()!.setSystemProxyEnabled(isEnabled) } else { // Apple BUG: HTTP Proxy cannot be disabled via setTunnelNetworkSettings, so we can only restart the Network Extension + await MainActor.run { + reasserting = true + } try await profile.stop() var waitSeconds = 0 while await profile.status != .disconnected { @@ -118,6 +121,9 @@ public struct OverviewView: View { } } try await profile.start() + await MainActor.run { + reasserting = false + } } } catch { await MainActor.run { diff --git a/ApplicationLibrary/Views/Profile/EditProfileView.swift b/ApplicationLibrary/Views/Profile/EditProfileView.swift index 647e836..c0295b5 100644 --- a/ApplicationLibrary/Views/Profile/EditProfileView.swift +++ b/ApplicationLibrary/Views/Profile/EditProfileView.swift @@ -34,17 +34,23 @@ public struct EditProfileView: View { FormItem(String(localized: "Path")) { TextField("Path", text: $profile.path, prompt: Text("Required")) .multilineTextAlignment(.trailing) + #if !os(macOS) + .keyboardType(.asciiCapableNumberPad) + #endif } } else if profile.type == .remote { FormItem(String(localized: "URL")) { TextField("URL", text: $profile.remoteURL.unwrapped(""), prompt: Text("Required")) .multilineTextAlignment(.trailing) + #if !os(macOS) + .keyboardType(.URL) + #endif } Toggle("Auto Update", isOn: $profile.autoUpdate) FormItem(String(localized: "Auto Update Interval")) { TextField("Auto Update Interval", text: $profile.autoUpdateInterval.stringBinding(defaultValue: 60), prompt: Text("In Minutes")) .multilineTextAlignment(.trailing) - #if os(iOS) + #if !os(macOS) .keyboardType(.numberPad) #endif } diff --git a/ApplicationLibrary/Views/Profile/NewProfileView.swift b/ApplicationLibrary/Views/Profile/NewProfileView.swift index ecde815..bf95512 100644 --- a/ApplicationLibrary/Views/Profile/NewProfileView.swift +++ b/ApplicationLibrary/Views/Profile/NewProfileView.swift @@ -10,7 +10,11 @@ public struct NewProfileView: View { @State private var isSaving = false @State private var profileName = "" - @State private var profileType = ProfileType.local + #if !os(tvOS) + @State private var profileType = ProfileType.local + #else + @State private var profileType = ProfileType.remote + #endif @State private var fileImport = false @State private var fileURL: URL! @State private var remotePath = "" @@ -79,17 +83,23 @@ public struct NewProfileView: View { FormItem(String(localized: "Path")) { TextField("Path", text: $remotePath, prompt: Text("Required")) .multilineTextAlignment(.trailing) + #if !os(macOS) + .keyboardType(.asciiCapableNumberPad) + #endif } } else if profileType == .remote { FormItem(String(localized: "URL")) { TextField("URL", text: $remotePath, prompt: Text("Required")) .multilineTextAlignment(.trailing) + #if !os(macOS) + .keyboardType(.URL) + #endif } Toggle("Auto Update", isOn: $autoUpdate) FormItem(String(localized: "Auto Update Interval")) { TextField("Auto Update Interval", text: $autoUpdateInterval.stringBinding(defaultValue: 60), prompt: Text("In Minutes")) .multilineTextAlignment(.trailing) - #if os(iOS) + #if !os(macOS) .keyboardType(.numberPad) #endif } diff --git a/ApplicationLibrary/Views/Profile/ProfileView.swift b/ApplicationLibrary/Views/Profile/ProfileView.swift index e8e8d48..236445c 100644 --- a/ApplicationLibrary/Views/Profile/ProfileView.swift +++ b/ApplicationLibrary/Views/Profile/ProfileView.swift @@ -137,14 +137,20 @@ public struct ProfileView: View { .toolbar { ToolbarItem(placement: .navigationBarTrailing) { if editMode == .inactive { - Button("Edit") { + Button(action: { editMode = .active + }) { + Image(systemName: "square.and.pencil") } + .tint(.accentColor) .disabled(profileList.isEmpty) } else { - Button("Done") { + Button(action: { editMode = .inactive + }) { + Image(systemName: "checkmark.square.fill") } + .tint(.accentColor) } } } diff --git a/ApplicationLibrary/Views/Setting/ServiceLogView.swift b/ApplicationLibrary/Views/Setting/ServiceLogView.swift index 6522d4e..3c07ff3 100644 --- a/ApplicationLibrary/Views/Setting/ServiceLogView.swift +++ b/ApplicationLibrary/Views/Setting/ServiceLogView.swift @@ -53,6 +53,7 @@ public struct ServiceLogView: View { Label("Delete", systemImage: "trash.fill") #else Image(systemName: "trash.fill") + .tint(.red) #endif } }