Fix issues on new systems

This commit is contained in:
世界
2025-09-23 21:45:01 +08:00
parent a696864985
commit 286f6fd794
8 changed files with 64 additions and 7 deletions
@@ -37,7 +37,7 @@ public func FormTextItem(_ name: LocalizedStringKey, _ systemImage: String, @Vie
} }
public func FormItem(_ title: String, @ViewBuilder content: () -> some View) -> some View { public func FormItem(_ title: String, @ViewBuilder content: () -> some View) -> some View {
#if os(iOS) || os(tvOS) #if os(iOS)
HStack { HStack {
Text(title) Text(title)
.lineLimit(1) .lineLimit(1)
@@ -46,6 +46,19 @@ public func FormItem(_ title: String, @ViewBuilder content: () -> some View) ->
Spacer() Spacer()
content() 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) #elseif os(macOS)
content() content()
#endif #endif
@@ -115,6 +128,7 @@ public func FormNavigationLink(@ViewBuilder destination: () -> some View, @ViewB
.toolbar { .toolbar {
ToolbarItemGroup(placement: .topBarLeading) { ToolbarItemGroup(placement: .topBarLeading) {
BackButton() BackButton()
.tint(.accentColor)
} }
} }
}, label: label) }, label: label)
@@ -33,6 +33,7 @@ public struct ConnectionListView: View {
} }
} }
} }
#if !os(tvOS)
.toolbar { .toolbar {
ToolbarItem { ToolbarItem {
Menu { Menu {
@@ -60,6 +61,7 @@ public struct ConnectionListView: View {
} }
} }
} }
#endif
#if os(macOS) #if os(macOS)
.searchable(text: $searchText) .searchable(text: $searchText)
#endif #endif
@@ -1,6 +1,9 @@
import Libbox import Libbox
import Library import Library
import SwiftUI import SwiftUI
#if canImport(UIKit)
import UIKit
#endif
public struct ExtensionStatusView: View { public struct ExtensionStatusView: View {
@Environment(\.scenePhase) private var scenePhase @Environment(\.scenePhase) private var scenePhase
@@ -115,6 +118,8 @@ public struct ExtensionStatusView: View {
} }
private struct StatusItem<T>: View where T: View { private struct StatusItem<T>: View where T: View {
@Environment(\.colorScheme) private var colorScheme
private let title: String private let title: String
@ViewBuilder private let content: () -> T @ViewBuilder private let content: () -> T
@@ -148,7 +153,14 @@ public struct ExtensionStatusView: View {
#elseif os(macOS) #elseif os(macOS)
return Color(nsColor: .textBackgroundColor) return Color(nsColor: .textBackgroundColor)
#elseif os(tvOS) #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 #endif
} }
} }
@@ -108,6 +108,9 @@ public struct OverviewView: View {
try LibboxNewStandaloneCommandClient()!.setSystemProxyEnabled(isEnabled) try LibboxNewStandaloneCommandClient()!.setSystemProxyEnabled(isEnabled)
} else { } else {
// Apple BUG: HTTP Proxy cannot be disabled via setTunnelNetworkSettings, so we can only restart the Network Extension // 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() try await profile.stop()
var waitSeconds = 0 var waitSeconds = 0
while await profile.status != .disconnected { while await profile.status != .disconnected {
@@ -118,6 +121,9 @@ public struct OverviewView: View {
} }
} }
try await profile.start() try await profile.start()
await MainActor.run {
reasserting = false
}
} }
} catch { } catch {
await MainActor.run { await MainActor.run {
@@ -34,17 +34,23 @@ public struct EditProfileView: View {
FormItem(String(localized: "Path")) { FormItem(String(localized: "Path")) {
TextField("Path", text: $profile.path, prompt: Text("Required")) TextField("Path", text: $profile.path, prompt: Text("Required"))
.multilineTextAlignment(.trailing) .multilineTextAlignment(.trailing)
#if !os(macOS)
.keyboardType(.asciiCapableNumberPad)
#endif
} }
} else if profile.type == .remote { } else if profile.type == .remote {
FormItem(String(localized: "URL")) { FormItem(String(localized: "URL")) {
TextField("URL", text: $profile.remoteURL.unwrapped(""), prompt: Text("Required")) TextField("URL", text: $profile.remoteURL.unwrapped(""), prompt: Text("Required"))
.multilineTextAlignment(.trailing) .multilineTextAlignment(.trailing)
#if !os(macOS)
.keyboardType(.URL)
#endif
} }
Toggle("Auto Update", isOn: $profile.autoUpdate) Toggle("Auto Update", isOn: $profile.autoUpdate)
FormItem(String(localized: "Auto Update Interval")) { FormItem(String(localized: "Auto Update Interval")) {
TextField("Auto Update Interval", text: $profile.autoUpdateInterval.stringBinding(defaultValue: 60), prompt: Text("In Minutes")) TextField("Auto Update Interval", text: $profile.autoUpdateInterval.stringBinding(defaultValue: 60), prompt: Text("In Minutes"))
.multilineTextAlignment(.trailing) .multilineTextAlignment(.trailing)
#if os(iOS) #if !os(macOS)
.keyboardType(.numberPad) .keyboardType(.numberPad)
#endif #endif
} }
@@ -10,7 +10,11 @@ public struct NewProfileView: View {
@State private var isSaving = false @State private var isSaving = false
@State private var profileName = "" @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 fileImport = false
@State private var fileURL: URL! @State private var fileURL: URL!
@State private var remotePath = "" @State private var remotePath = ""
@@ -79,17 +83,23 @@ public struct NewProfileView: View {
FormItem(String(localized: "Path")) { FormItem(String(localized: "Path")) {
TextField("Path", text: $remotePath, prompt: Text("Required")) TextField("Path", text: $remotePath, prompt: Text("Required"))
.multilineTextAlignment(.trailing) .multilineTextAlignment(.trailing)
#if !os(macOS)
.keyboardType(.asciiCapableNumberPad)
#endif
} }
} else if profileType == .remote { } else if profileType == .remote {
FormItem(String(localized: "URL")) { FormItem(String(localized: "URL")) {
TextField("URL", text: $remotePath, prompt: Text("Required")) TextField("URL", text: $remotePath, prompt: Text("Required"))
.multilineTextAlignment(.trailing) .multilineTextAlignment(.trailing)
#if !os(macOS)
.keyboardType(.URL)
#endif
} }
Toggle("Auto Update", isOn: $autoUpdate) Toggle("Auto Update", isOn: $autoUpdate)
FormItem(String(localized: "Auto Update Interval")) { FormItem(String(localized: "Auto Update Interval")) {
TextField("Auto Update Interval", text: $autoUpdateInterval.stringBinding(defaultValue: 60), prompt: Text("In Minutes")) TextField("Auto Update Interval", text: $autoUpdateInterval.stringBinding(defaultValue: 60), prompt: Text("In Minutes"))
.multilineTextAlignment(.trailing) .multilineTextAlignment(.trailing)
#if os(iOS) #if !os(macOS)
.keyboardType(.numberPad) .keyboardType(.numberPad)
#endif #endif
} }
@@ -137,14 +137,20 @@ public struct ProfileView: View {
.toolbar { .toolbar {
ToolbarItem(placement: .navigationBarTrailing) { ToolbarItem(placement: .navigationBarTrailing) {
if editMode == .inactive { if editMode == .inactive {
Button("Edit") { Button(action: {
editMode = .active editMode = .active
}) {
Image(systemName: "square.and.pencil")
} }
.tint(.accentColor)
.disabled(profileList.isEmpty) .disabled(profileList.isEmpty)
} else { } else {
Button("Done") { Button(action: {
editMode = .inactive editMode = .inactive
}) {
Image(systemName: "checkmark.square.fill")
} }
.tint(.accentColor)
} }
} }
} }
@@ -53,6 +53,7 @@ public struct ServiceLogView: View {
Label("Delete", systemImage: "trash.fill") Label("Delete", systemImage: "trash.fill")
#else #else
Image(systemName: "trash.fill") Image(systemName: "trash.fill")
.tint(.red)
#endif #endif
} }
} }