Minor fixes for tvOS
This commit is contained in:
@@ -73,7 +73,9 @@ public struct DashboardView: View {
|
|||||||
DashboardView1().environmentObject(profile)
|
DashboardView1().environmentObject(profile)
|
||||||
} else {
|
} else {
|
||||||
FormView {
|
FormView {
|
||||||
InstallProfileButton()
|
InstallProfileButton {
|
||||||
|
await environments.reload()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,10 @@ import SwiftUI
|
|||||||
public struct InstallProfileButton: View {
|
public struct InstallProfileButton: View {
|
||||||
@State private var alert: Alert?
|
@State private var alert: Alert?
|
||||||
|
|
||||||
public init() {}
|
private let callback: () async -> Void
|
||||||
|
public init(_ callback: @escaping (() async -> Void)) {
|
||||||
|
self.callback = callback
|
||||||
|
}
|
||||||
|
|
||||||
public var body: some View {
|
public var body: some View {
|
||||||
Button("Install NetworkExtension") {
|
Button("Install NetworkExtension") {
|
||||||
@@ -19,6 +22,7 @@ public struct InstallProfileButton: View {
|
|||||||
private func installProfile() async {
|
private func installProfile() async {
|
||||||
do {
|
do {
|
||||||
try await ExtensionProfile.install()
|
try await ExtensionProfile.install()
|
||||||
|
await callback()
|
||||||
} catch {
|
} catch {
|
||||||
alert = Alert(error)
|
alert = Alert(error)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
@State private var alert: Alert?
|
@State private var alert: Alert?
|
||||||
@State private var connection: NWSocket?
|
@State private var connection: NWSocket?
|
||||||
@State private var profiles: [LibboxProfilePreview]?
|
@State private var profiles: [LibboxProfilePreview]?
|
||||||
|
@State private var isImporting = false
|
||||||
private let callback: () async -> Void
|
private let callback: () async -> Void
|
||||||
|
|
||||||
public init(callback: @escaping () async -> Void) {
|
public init(callback: @escaping () async -> Void) {
|
||||||
@@ -47,7 +48,7 @@
|
|||||||
selectProfile(profileID: profile.profileID)
|
selectProfile(profileID: profile.profileID)
|
||||||
isLoading = false
|
isLoading = false
|
||||||
}
|
}
|
||||||
}.disabled(isLoading)
|
}.disabled(isLoading || isImporting)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -76,12 +77,17 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private func loopMessages() async throws {
|
private nonisolated func loopMessages() async throws {
|
||||||
guard let connection else {
|
guard let connection = await connection else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
var message: Data
|
||||||
while true {
|
while true {
|
||||||
let message = try connection.read()
|
do {
|
||||||
|
message = try connection.read()
|
||||||
|
} catch {
|
||||||
|
throw NSError(domain: "read from connection: \(error.localizedDescription)", code: 0)
|
||||||
|
}
|
||||||
var error: NSError?
|
var error: NSError?
|
||||||
switch Int64(message[0]) {
|
switch Int64(message[0]) {
|
||||||
case LibboxMessageTypeError:
|
case LibboxMessageTypeError:
|
||||||
@@ -105,7 +111,10 @@
|
|||||||
}
|
}
|
||||||
profiles.append(profile)
|
profiles.append(profile)
|
||||||
}
|
}
|
||||||
self.profiles = profiles
|
await MainActor.run { [self, profiles] in
|
||||||
|
self.profiles = profiles
|
||||||
|
isImporting = false
|
||||||
|
}
|
||||||
case LibboxMessageTypeProfileContent:
|
case LibboxMessageTypeProfileContent:
|
||||||
let content = LibboxDecodeProfileContent(message, &error)
|
let content = LibboxDecodeProfileContent(message, &error)
|
||||||
if let error {
|
if let error {
|
||||||
@@ -126,6 +135,7 @@
|
|||||||
request.profileID = profileID
|
request.profileID = profileID
|
||||||
do {
|
do {
|
||||||
try connection.write(request.encode())
|
try connection.write(request.encode())
|
||||||
|
isImporting = true
|
||||||
} catch {
|
} catch {
|
||||||
alert = Alert(error)
|
alert = Alert(error)
|
||||||
reset()
|
reset()
|
||||||
|
|||||||
@@ -166,12 +166,30 @@ public struct ProfileView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#elseif os(iOS)
|
#endif
|
||||||
|
#if os(iOS)
|
||||||
.toolbar {
|
.toolbar {
|
||||||
ToolbarItem(placement: .navigationBarTrailing) {
|
ToolbarItem(placement: .navigationBarTrailing) {
|
||||||
EditButton().disabled(profileList.isEmpty)
|
EditButton().disabled(profileList.isEmpty)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#elseif os(tvOS)
|
||||||
|
.toolbar {
|
||||||
|
ToolbarItem(placement: .navigationBarTrailing) {
|
||||||
|
if editMode == .inactive {
|
||||||
|
Button("Edit") {
|
||||||
|
editMode = .active
|
||||||
|
}
|
||||||
|
.disabled(profileList.isEmpty)
|
||||||
|
} else {
|
||||||
|
Button("Done") {
|
||||||
|
editMode = .inactive
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if os(iOS) || os(tvOS)
|
||||||
.environment(\.editMode, $editMode)
|
.environment(\.editMode, $editMode)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,20 +17,16 @@ public class ExtensionEnvironments: ObservableObject {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public nonisolated func reload() async {
|
public func reload() async {
|
||||||
if let newProfile = try? await ExtensionProfile.load() {
|
if let newProfile = try? await ExtensionProfile.load() {
|
||||||
if extensionProfile == nil || extensionProfile?.status == .invalid {
|
if extensionProfile == nil || extensionProfile?.status == .invalid {
|
||||||
newProfile.register()
|
newProfile.register()
|
||||||
await MainActor.run {
|
extensionProfile = newProfile
|
||||||
extensionProfile = newProfile
|
|
||||||
extensionProfileLoading = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
await MainActor.run {
|
|
||||||
extensionProfile = nil
|
|
||||||
extensionProfileLoading = false
|
extensionProfileLoading = false
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
extensionProfile = nil
|
||||||
|
extensionProfileLoading = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user