172 lines
6.3 KiB
Swift
172 lines
6.3 KiB
Swift
import Foundation
|
|
import Libbox
|
|
import Library
|
|
import SwiftUI
|
|
|
|
public struct ActiveDashboardView: View {
|
|
public static let NotificationUpdateSelectedProfile = Notification.Name("update-selected-profile")
|
|
|
|
@Environment(\.scenePhase) var scenePhase
|
|
@Environment(\.selection) private var selection
|
|
|
|
@EnvironmentObject private var profile: ExtensionProfile
|
|
|
|
@State private var isLoading = true
|
|
@State private var profileList: [Profile] = []
|
|
@State private var selectedProfileID: Int64!
|
|
@State private var reasserting = false
|
|
@State private var observer: Any?
|
|
@State private var alert: Alert?
|
|
|
|
public init() {}
|
|
|
|
public var body: some View {
|
|
viewBuilder {
|
|
if isLoading {
|
|
ProgressView().onAppear {
|
|
Task.detached {
|
|
await doReload()
|
|
}
|
|
}
|
|
} else {
|
|
if profileList.isEmpty {
|
|
Text("Empty profiles")
|
|
} else {
|
|
VStack {
|
|
#if os(iOS) || os(tvOS)
|
|
if ApplicationLibrary.inPreview || profile.status.isConnected {
|
|
ExtensionStatusView()
|
|
.listStyle(.automatic)
|
|
#if os(iOS)
|
|
.navigationBarTitleDisplayMode(.inline)
|
|
#endif
|
|
}
|
|
FormView {
|
|
StartStopButton()
|
|
Section("Profile") {
|
|
Picker(selection: $selectedProfileID) {
|
|
ForEach(profileList, id: \.id) { profile in
|
|
Text(profile.name).tag(profile.id)
|
|
}
|
|
} label: {}
|
|
.pickerStyle(.inline)
|
|
}
|
|
}
|
|
#elseif os(macOS)
|
|
if ApplicationLibrary.inPreview || profile.status.isConnected {
|
|
ExtensionStatusView()
|
|
}
|
|
FormView {
|
|
Section("Profile") {
|
|
ForEach(profileList, id: \.id) { profile in
|
|
Picker(profile.name, selection: $selectedProfileID) {
|
|
Text("").tag(profile.id)
|
|
}
|
|
}
|
|
.pickerStyle(.radioGroup)
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
.onChange(of: selectedProfileID) { _ in
|
|
reasserting = true
|
|
Task.detached {
|
|
await switchProfile(selectedProfileID!)
|
|
}
|
|
}
|
|
.disabled(!ApplicationLibrary.inPreview && (!profile.status.isSwitchable || reasserting))
|
|
}
|
|
}
|
|
}
|
|
.alertBinding($alert)
|
|
.onChange(of: profile.status, perform: { newValue in
|
|
if newValue == .disconnecting || newValue == .connected {
|
|
Task.detached {
|
|
if let serviceError = try? String(contentsOf: ExtensionProvider.errorFile) {
|
|
DispatchQueue.main.async {
|
|
alert = Alert(errorMessage: serviceError)
|
|
}
|
|
try? FileManager.default.removeItem(at: ExtensionProvider.errorFile)
|
|
}
|
|
}
|
|
}
|
|
})
|
|
#if os(iOS) || os(tvOS)
|
|
.onChange(of: scenePhase, perform: { newValue in
|
|
if newValue == .active {
|
|
Task.detached {
|
|
await doReload()
|
|
}
|
|
}
|
|
})
|
|
.onChange(of: selection.wrappedValue, perform: { newValue in
|
|
if newValue == .dashboard {
|
|
Task.detached {
|
|
await doReload()
|
|
}
|
|
}
|
|
})
|
|
#elseif os(macOS)
|
|
.onAppear {
|
|
if observer == nil {
|
|
observer = NotificationCenter.default.addObserver(forName: ActiveDashboardView.NotificationUpdateSelectedProfile, object: nil, queue: nil, using: { _ in
|
|
Task.detached {
|
|
await doReload()
|
|
}
|
|
})
|
|
}
|
|
}
|
|
.onDisappear {
|
|
if let observer {
|
|
NotificationCenter.default.removeObserver(observer)
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
|
|
private func doReload() {
|
|
defer {
|
|
isLoading = false
|
|
}
|
|
if ApplicationLibrary.inPreview {
|
|
profileList = [
|
|
Profile(id: 0, name: "profile local", type: .local, path: ""),
|
|
Profile(id: 1, name: "profile remote", type: .remote, path: "", lastUpdated: Date(timeIntervalSince1970: 0)),
|
|
]
|
|
selectedProfileID = 0
|
|
} else {
|
|
do {
|
|
profileList = try ProfileManager.list()
|
|
} catch {
|
|
alert = Alert(error)
|
|
return
|
|
}
|
|
if profileList.isEmpty {
|
|
return
|
|
}
|
|
|
|
selectedProfileID = SharedPreferences.selectedProfileID
|
|
if profileList.filter({ profile in
|
|
profile.id == selectedProfileID
|
|
})
|
|
.isEmpty {
|
|
selectedProfileID = profileList[0].id!
|
|
SharedPreferences.selectedProfileID = selectedProfileID
|
|
}
|
|
}
|
|
}
|
|
|
|
private func switchProfile(_ newProfileID: Int64) {
|
|
SharedPreferences.selectedProfileID = newProfileID
|
|
NotificationCenter.default.post(name: ActiveDashboardView.NotificationUpdateSelectedProfile, object: nil)
|
|
if profile.status.isConnected {
|
|
do {
|
|
try LibboxNewStandaloneCommandClient()!.serviceReload()
|
|
} catch {
|
|
alert = Alert(error)
|
|
}
|
|
}
|
|
reasserting = false
|
|
}
|
|
}
|