176 lines
5.8 KiB
Swift
176 lines
5.8 KiB
Swift
import Foundation
|
|
import Libbox
|
|
import Library
|
|
import SwiftUI
|
|
|
|
@MainActor
|
|
public struct ActiveDashboardView: View {
|
|
@Environment(\.scenePhase) private var scenePhase
|
|
@EnvironmentObject private var environments: ExtensionEnvironments
|
|
@EnvironmentObject private var profile: ExtensionProfile
|
|
@StateObject private var coordinator = DashboardCoordinator()
|
|
@State private var cardConfigurationVersion = 0
|
|
#if os(iOS) || os(tvOS)
|
|
@State private var showCardManagement = false
|
|
#endif
|
|
|
|
private let externalCardConfigurationVersion: Int?
|
|
|
|
public init(externalCardConfigurationVersion: Int? = nil) {
|
|
self.externalCardConfigurationVersion = externalCardConfigurationVersion
|
|
}
|
|
|
|
public var body: some View {
|
|
if coordinator.isLoading {
|
|
ProgressView()
|
|
.onAppear {
|
|
coordinator.onEmptyProfilesChange = { environments.emptyProfiles = $0 }
|
|
Task { await coordinator.reload() }
|
|
}
|
|
} else {
|
|
content
|
|
.onAppear {
|
|
guard !ApplicationLibrary.inPreview else { return }
|
|
Task { await coordinator.reloadSystemProxy() }
|
|
}
|
|
.onChangeCompat(of: profile.status) { status in
|
|
guard !ApplicationLibrary.inPreview, status == .connected else { return }
|
|
Task { await coordinator.reloadSystemProxy() }
|
|
}
|
|
}
|
|
}
|
|
|
|
@ViewBuilder
|
|
private var content: some View {
|
|
VStack {
|
|
#if os(iOS) || os(tvOS)
|
|
if ApplicationLibrary.inPreview || profile.status.isConnectedStrict {
|
|
pageSelector
|
|
pageContent
|
|
} else {
|
|
overviewPage
|
|
}
|
|
#else
|
|
overviewPage
|
|
#endif
|
|
}
|
|
#if os(iOS) || os(tvOS)
|
|
.toolbar { toolbar }
|
|
#endif
|
|
.onAppear {
|
|
if ApplicationLibrary.inPreview {
|
|
environments.commandClient.connect()
|
|
} else {
|
|
environments.connect()
|
|
}
|
|
}
|
|
.onChangeCompat(of: scenePhase) { phase in
|
|
guard phase == .active else { return }
|
|
environments.connect()
|
|
}
|
|
.onChangeCompat(of: profile.status) { status in
|
|
guard status.isConnected else { return }
|
|
environments.connect()
|
|
}
|
|
.onReceive(environments.profileUpdate) { _ in
|
|
Task { await coordinator.reload() }
|
|
}
|
|
.onReceive(environments.selectedProfileUpdate) { _ in
|
|
Task {
|
|
await coordinator.updateSelectedProfile()
|
|
if profile.status.isConnected {
|
|
await coordinator.reloadSystemProxy()
|
|
}
|
|
}
|
|
}
|
|
.alertBinding($coordinator.alert)
|
|
}
|
|
|
|
#if os(iOS) || os(tvOS)
|
|
@ViewBuilder
|
|
private var pageSelector: some View {
|
|
Picker("Page", selection: $coordinator.selection) {
|
|
ForEach(DashboardPage.enabledCases()) { page in
|
|
page.label
|
|
}
|
|
}
|
|
.pickerStyle(.segmented)
|
|
#if os(iOS)
|
|
.padding([.leading, .trailing])
|
|
.navigationBarTitleDisplayMode(.inline)
|
|
#endif
|
|
}
|
|
|
|
@ViewBuilder
|
|
private var pageContent: some View {
|
|
TabView(selection: $coordinator.selection) {
|
|
ForEach(DashboardPage.enabledCases()) { page in
|
|
page.contentView(
|
|
$coordinator.profileList,
|
|
$coordinator.selectedProfileID,
|
|
$coordinator.systemProxyAvailable,
|
|
$coordinator.systemProxyEnabled,
|
|
externalCardConfigurationVersion ?? cardConfigurationVersion
|
|
)
|
|
.tag(page)
|
|
}
|
|
}
|
|
#if os(iOS)
|
|
.navigationBarTitleDisplayMode(.inline)
|
|
#endif
|
|
.tabViewStyle(.page(indexDisplayMode: .never))
|
|
}
|
|
#endif
|
|
|
|
@ViewBuilder
|
|
private var overviewPage: some View {
|
|
OverviewView(
|
|
$coordinator.profileList,
|
|
$coordinator.selectedProfileID,
|
|
$coordinator.systemProxyAvailable,
|
|
$coordinator.systemProxyEnabled,
|
|
cardConfigurationVersion: externalCardConfigurationVersion ?? cardConfigurationVersion
|
|
)
|
|
}
|
|
|
|
#if os(iOS) || os(tvOS)
|
|
@ToolbarContentBuilder
|
|
private var toolbar: some ToolbarContent {
|
|
ToolbarItem(placement: .topBarTrailing) {
|
|
if coordinator.selection == .overview {
|
|
if #available(iOS 16.0, tvOS 17.0, *) {
|
|
cardManagementButton
|
|
}
|
|
}
|
|
}
|
|
ToolbarItem(placement: .topBarTrailing) {
|
|
if #available(iOS 26.0, *), !Variant.debugNoIOS26 {
|
|
EmptyView()
|
|
} else {
|
|
StartStopButton()
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
#if os(iOS) || os(tvOS)
|
|
@available(iOS 16.0, tvOS 17.0, *)
|
|
@ViewBuilder
|
|
private var cardManagementButton: some View {
|
|
Menu {
|
|
Button {
|
|
showCardManagement = true
|
|
} label: {
|
|
Label("Dashboard Items", systemImage: "square.grid.2x2")
|
|
}
|
|
} label: {
|
|
Label("Others", systemImage: "ellipsis.circle")
|
|
}
|
|
.sheet(isPresented: $showCardManagement) {
|
|
CardManagementSheet(configurationVersion: $cardConfigurationVersion)
|
|
.presentationDetents([.medium, .large])
|
|
}
|
|
}
|
|
#endif
|
|
}
|