Fix for tvOS
This commit is contained in:
@@ -128,7 +128,6 @@ public func FormNavigationLink(@ViewBuilder destination: () -> some View, @ViewB
|
|||||||
.toolbar {
|
.toolbar {
|
||||||
ToolbarItemGroup(placement: .topBarLeading) {
|
ToolbarItemGroup(placement: .topBarLeading) {
|
||||||
BackButton()
|
BackButton()
|
||||||
.tint(.accentColor)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, label: label)
|
}, label: label)
|
||||||
|
|||||||
@@ -26,35 +26,64 @@ public struct NavigationButtonsView: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public var body: some View {
|
public var body: some View {
|
||||||
HStack(spacing: 12) {
|
#if os(tvOS)
|
||||||
if showConnectionsButton {
|
tvOSBody
|
||||||
Divider()
|
#else
|
||||||
Text(verbatim: "\(connectionsCount)")
|
iOSBody
|
||||||
.font(.subheadline)
|
#endif
|
||||||
.foregroundStyle(.secondary)
|
}
|
||||||
.fixedSize()
|
|
||||||
Button {
|
#if os(tvOS)
|
||||||
onConnectionsTap()
|
private var tvOSBody: some View {
|
||||||
} label: {
|
viewBuilder {
|
||||||
Label("Connections", systemImage: "list.bullet.rectangle.portrait.fill")
|
if showConnectionsButton {
|
||||||
|
Button {
|
||||||
|
onConnectionsTap()
|
||||||
|
} label: {
|
||||||
|
Image(systemName: "list.bullet.rectangle.portrait.fill")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.labelStyle(.iconOnly)
|
if showGroupsButton {
|
||||||
.foregroundStyle(.primary)
|
Button {
|
||||||
}
|
onGroupsTap()
|
||||||
if showGroupsButton {
|
} label: {
|
||||||
Divider()
|
Image(systemName: "rectangle.3.group.fill")
|
||||||
Text(verbatim: "\(groupsCount)")
|
}
|
||||||
.font(.subheadline)
|
|
||||||
.foregroundStyle(.secondary)
|
|
||||||
.fixedSize()
|
|
||||||
Button {
|
|
||||||
onGroupsTap()
|
|
||||||
} label: {
|
|
||||||
Label("Groups", systemImage: "rectangle.3.group.fill")
|
|
||||||
}
|
}
|
||||||
.labelStyle(.iconOnly)
|
|
||||||
.foregroundStyle(.primary)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
#else
|
||||||
|
private var iOSBody: some View {
|
||||||
|
HStack(spacing: 12) {
|
||||||
|
if showConnectionsButton {
|
||||||
|
Divider()
|
||||||
|
Text(verbatim: "\(connectionsCount)")
|
||||||
|
.font(.subheadline)
|
||||||
|
.foregroundStyle(.secondary)
|
||||||
|
.fixedSize()
|
||||||
|
Button {
|
||||||
|
onConnectionsTap()
|
||||||
|
} label: {
|
||||||
|
Label("Connections", systemImage: "list.bullet.rectangle.portrait.fill")
|
||||||
|
}
|
||||||
|
.labelStyle(.iconOnly)
|
||||||
|
.foregroundStyle(.primary)
|
||||||
|
}
|
||||||
|
if showGroupsButton {
|
||||||
|
Divider()
|
||||||
|
Text(verbatim: "\(groupsCount)")
|
||||||
|
.font(.subheadline)
|
||||||
|
.foregroundStyle(.secondary)
|
||||||
|
.fixedSize()
|
||||||
|
Button {
|
||||||
|
onGroupsTap()
|
||||||
|
} label: {
|
||||||
|
Label("Groups", systemImage: "rectangle.3.group.fill")
|
||||||
|
}
|
||||||
|
.labelStyle(.iconOnly)
|
||||||
|
.foregroundStyle(.primary)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,8 +3,7 @@ import Libbox
|
|||||||
import Library
|
import Library
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
@MainActor
|
@MainActor public struct ActiveDashboardView: View {
|
||||||
public struct ActiveDashboardView: View {
|
|
||||||
@Environment(\.scenePhase) private var scenePhase
|
@Environment(\.scenePhase) private var scenePhase
|
||||||
@EnvironmentObject private var environments: ExtensionEnvironments
|
@EnvironmentObject private var environments: ExtensionEnvironments
|
||||||
@EnvironmentObject private var profile: ExtensionProfile
|
@EnvironmentObject private var profile: ExtensionProfile
|
||||||
@@ -25,35 +24,48 @@ public struct ActiveDashboardView: View {
|
|||||||
|
|
||||||
public var body: some View {
|
public var body: some View {
|
||||||
if coordinator.isLoading {
|
if coordinator.isLoading {
|
||||||
ProgressView()
|
ProgressView().onAppear {
|
||||||
.onAppear {
|
coordinator.onEmptyProfilesChange = {
|
||||||
coordinator.onEmptyProfilesChange = { environments.emptyProfiles = $0 }
|
environments.emptyProfiles = $0
|
||||||
Task { await coordinator.reload() }
|
|
||||||
}
|
}
|
||||||
|
Task {
|
||||||
|
await coordinator.reload()
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
content
|
content.onAppear {
|
||||||
.onAppear {
|
guard !ApplicationLibrary.inPreview else {
|
||||||
guard !ApplicationLibrary.inPreview else { return }
|
return
|
||||||
Task { await coordinator.reloadSystemProxy() }
|
|
||||||
}
|
}
|
||||||
.onChangeCompat(of: profile.status) { status in
|
Task {
|
||||||
guard !ApplicationLibrary.inPreview, status == .connected else { return }
|
await coordinator.reloadSystemProxy()
|
||||||
Task { await coordinator.reloadSystemProxy() }
|
|
||||||
}
|
}
|
||||||
|
}.onChangeCompat(of: profile.status) {
|
||||||
|
status in
|
||||||
|
guard !ApplicationLibrary.inPreview, status == .connected else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
Task {
|
||||||
|
await coordinator.reloadSystemProxy()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ViewBuilder
|
@ViewBuilder private var content: some View {
|
||||||
private var content: some View {
|
|
||||||
overviewPage
|
overviewPage
|
||||||
#if os(iOS) || os(tvOS)
|
#if os(iOS) || os(tvOS)
|
||||||
.toolbar { toolbar }
|
.toolbar {
|
||||||
.sheet(isPresented: $showGroups) {
|
toolbar
|
||||||
|
}.sheet(isPresented: $showGroups) {
|
||||||
groupsSheetContent
|
groupsSheetContent
|
||||||
}
|
}.sheet(isPresented: $showConnections) {
|
||||||
.sheet(isPresented: $showConnections) {
|
|
||||||
connectionsSheetContent
|
connectionsSheetContent
|
||||||
}
|
}.sheet(isPresented: $showCardManagement, onDismiss: {
|
||||||
|
cardConfigurationVersion += 1
|
||||||
|
}, content: {
|
||||||
|
CardManagementSheet().presentationDetents([.large]).presentationDragIndicator(.visible)
|
||||||
|
})
|
||||||
#endif
|
#endif
|
||||||
.onAppear {
|
.onAppear {
|
||||||
if ApplicationLibrary.inPreview {
|
if ApplicationLibrary.inPreview {
|
||||||
@@ -61,19 +73,25 @@ public struct ActiveDashboardView: View {
|
|||||||
} else {
|
} else {
|
||||||
environments.connect()
|
environments.connect()
|
||||||
}
|
}
|
||||||
}
|
}.onChangeCompat(of: scenePhase) {
|
||||||
.onChangeCompat(of: scenePhase) { phase in
|
phase in
|
||||||
guard phase == .active else { return }
|
guard phase == .active else {
|
||||||
|
return
|
||||||
|
}
|
||||||
environments.connect()
|
environments.connect()
|
||||||
}
|
}.onChangeCompat(of: profile.status) {
|
||||||
.onChangeCompat(of: profile.status) { status in
|
status in
|
||||||
guard status.isConnected else { return }
|
guard status.isConnected else {
|
||||||
|
return
|
||||||
|
}
|
||||||
environments.connect()
|
environments.connect()
|
||||||
}
|
}.onReceive(environments.profileUpdate) {
|
||||||
.onReceive(environments.profileUpdate) { _ in
|
_ in
|
||||||
Task { await coordinator.reload() }
|
Task {
|
||||||
}
|
await coordinator.reload()
|
||||||
.onReceive(environments.selectedProfileUpdate) { _ in
|
}
|
||||||
|
}.onReceive(environments.selectedProfileUpdate) {
|
||||||
|
_ in
|
||||||
Task {
|
Task {
|
||||||
await coordinator.updateSelectedProfile()
|
await coordinator.updateSelectedProfile()
|
||||||
if profile.status.isConnected {
|
if profile.status.isConnected {
|
||||||
@@ -82,24 +100,23 @@ public struct ActiveDashboardView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#if os(iOS) || os(tvOS)
|
#if os(iOS) || os(tvOS)
|
||||||
.onReceive(environments.commandClient.$groups) { _ in
|
.onReceive(environments.commandClient.$groups) {
|
||||||
|
_ in
|
||||||
updateButtonVisibility()
|
updateButtonVisibility()
|
||||||
}
|
}.onReceive(environments.commandClient.$connections) {
|
||||||
.onReceive(environments.commandClient.$connections) { _ in
|
_ in
|
||||||
updateButtonVisibility()
|
updateButtonVisibility()
|
||||||
}
|
}.onReceive(profile.$status) {
|
||||||
.onReceive(profile.$status) { _ in
|
_ in
|
||||||
updateButtonVisibility()
|
updateButtonVisibility()
|
||||||
}
|
}.onAppear {
|
||||||
.onAppear {
|
|
||||||
updateButtonVisibility()
|
updateButtonVisibility()
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
.alertBinding($coordinator.alert)
|
.alertBinding($coordinator.alert)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ViewBuilder
|
@ViewBuilder private var overviewPage: some View {
|
||||||
private var overviewPage: some View {
|
|
||||||
OverviewView(
|
OverviewView(
|
||||||
$coordinator.profileList,
|
$coordinator.profileList,
|
||||||
$coordinator.selectedProfileID,
|
$coordinator.selectedProfileID,
|
||||||
@@ -123,28 +140,21 @@ public struct ActiveDashboardView: View {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ToolbarContentBuilder
|
@ToolbarContentBuilder private var toolbar: some ToolbarContent {
|
||||||
private var toolbar: some ToolbarContent {
|
|
||||||
#if os(tvOS)
|
#if os(tvOS)
|
||||||
ToolbarItem(placement: .topBarLeading) {
|
ToolbarItem(placement: .topBarLeading) {
|
||||||
navigationButtons
|
navigationButtons
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
ToolbarItem(placement: .topBarTrailing) {
|
ToolbarItemGroup(placement: .topBarTrailing) {
|
||||||
if #available(iOS 16.0, tvOS 17.0, *) {
|
if #available(iOS 16.0, tvOS 17.0, *) {
|
||||||
cardManagementButton
|
cardManagementButton
|
||||||
}
|
}
|
||||||
}
|
#if os(tvOS)
|
||||||
ToolbarItem(placement: .topBarTrailing) {
|
StartStopButton()
|
||||||
#if os(iOS)
|
|
||||||
if #available(iOS 26.0, *), !Variant.debugNoIOS26 {
|
|
||||||
EmptyView()
|
|
||||||
} else {
|
|
||||||
StartStopButton()
|
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
HStack(spacing: 12) {
|
if #available(iOS 26.0, *), !Variant.debugNoIOS26 {
|
||||||
Divider()
|
} else {
|
||||||
StartStopButton()
|
StartStopButton()
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -158,8 +168,12 @@ public struct ActiveDashboardView: View {
|
|||||||
showConnectionsButton: buttonState.showConnectionsButton,
|
showConnectionsButton: buttonState.showConnectionsButton,
|
||||||
groupsCount: buttonState.groupsCount,
|
groupsCount: buttonState.groupsCount,
|
||||||
connectionsCount: buttonState.connectionsCount,
|
connectionsCount: buttonState.connectionsCount,
|
||||||
onGroupsTap: { showGroups = true },
|
onGroupsTap: {
|
||||||
onConnectionsTap: { showConnections = true }
|
showGroups = true
|
||||||
|
},
|
||||||
|
onConnectionsTap: {
|
||||||
|
showConnections = true
|
||||||
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -174,11 +188,9 @@ public struct ActiveDashboardView: View {
|
|||||||
ConnectionsSheetContent()
|
ConnectionsSheetContent()
|
||||||
}
|
}
|
||||||
|
|
||||||
@available(iOS 16.0, tvOS 17.0, *)
|
@available(iOS 16.0, *) @ViewBuilder private var cardManagementButton: some View {
|
||||||
@ViewBuilder
|
#if os(iOS)
|
||||||
private var cardManagementButton: some View {
|
Menu {
|
||||||
Menu {
|
|
||||||
#if os(iOS)
|
|
||||||
if !isTabViewBottomAccessoryAvailable {
|
if !isTabViewBottomAccessoryAvailable {
|
||||||
if buttonState.showGroupsButton {
|
if buttonState.showGroupsButton {
|
||||||
Button {
|
Button {
|
||||||
@@ -198,22 +210,21 @@ public struct ActiveDashboardView: View {
|
|||||||
Divider()
|
Divider()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
Button {
|
||||||
|
showCardManagement = true
|
||||||
|
} label: {
|
||||||
|
Label("Dashboard Items", systemImage: "square.grid.2x2")
|
||||||
|
}
|
||||||
|
} label: {
|
||||||
|
Label("Others", systemImage: "line.3.horizontal.circle")
|
||||||
|
}
|
||||||
|
#elseif os(tvOS)
|
||||||
Button {
|
Button {
|
||||||
showCardManagement = true
|
showCardManagement = true
|
||||||
} label: {
|
} label: {
|
||||||
Label("Dashboard Items", systemImage: "square.grid.2x2")
|
Image(systemName: "line.3.horizontal.circle")
|
||||||
}
|
}
|
||||||
} label: {
|
#endif
|
||||||
Label("Others", systemImage: "line.3.horizontal.circle")
|
|
||||||
}
|
|
||||||
.sheet(isPresented: $showCardManagement, onDismiss: {
|
|
||||||
cardConfigurationVersion += 1
|
|
||||||
}, content: {
|
|
||||||
CardManagementSheet()
|
|
||||||
.presentationDetents([.large])
|
|
||||||
.presentationDragIndicator(.visible)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,14 +12,22 @@ public struct StartStopButton: View {
|
|||||||
viewBuilder {
|
viewBuilder {
|
||||||
if ApplicationLibrary.inPreview {
|
if ApplicationLibrary.inPreview {
|
||||||
Button {} label: {
|
Button {} label: {
|
||||||
Label("Stop", systemImage: "stop.fill")
|
#if os(tvOS)
|
||||||
|
Image(systemName: "stop.fill")
|
||||||
|
#else
|
||||||
|
Label("Stop", systemImage: "stop.fill")
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
.labelStyle(.iconOnly)
|
.labelStyle(.iconOnly)
|
||||||
} else if let profile = environments.extensionProfile {
|
} else if let profile = environments.extensionProfile {
|
||||||
ToggleConnectionButton().environmentObject(profile)
|
ToggleConnectionButton().environmentObject(profile)
|
||||||
} else {
|
} else {
|
||||||
Button {} label: {
|
Button {} label: {
|
||||||
Label("Start", systemImage: "play.fill")
|
#if os(tvOS)
|
||||||
|
Image(systemName: "play.fill")
|
||||||
|
#else
|
||||||
|
Label("Start", systemImage: "play.fill")
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
.labelStyle(.iconOnly)
|
.labelStyle(.iconOnly)
|
||||||
.disabled(true)
|
.disabled(true)
|
||||||
@@ -63,6 +71,12 @@ public struct StartStopButton: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
.animation(.spring(response: 0.35, dampingFraction: 0.75), value: profile.status.isConnectedStrict)
|
.animation(.spring(response: 0.35, dampingFraction: 0.75), value: profile.status.isConnectedStrict)
|
||||||
|
#elseif os(tvOS)
|
||||||
|
if !profile.status.isConnected {
|
||||||
|
Image(systemName: "play.fill")
|
||||||
|
} else {
|
||||||
|
Image(systemName: "stop.fill")
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
HStack(spacing: 8) {
|
HStack(spacing: 8) {
|
||||||
if profile.status.isConnectedStrict, let duration = runtimeDuration {
|
if profile.status.isConnectedStrict, let duration = runtimeDuration {
|
||||||
@@ -89,8 +103,6 @@ public struct StartStopButton: View {
|
|||||||
.labelStyle(.iconOnly)
|
.labelStyle(.iconOnly)
|
||||||
#if os(iOS)
|
#if os(iOS)
|
||||||
.modifier(PrimaryTintModifier())
|
.modifier(PrimaryTintModifier())
|
||||||
#else
|
|
||||||
.tint(.primary)
|
|
||||||
#endif
|
#endif
|
||||||
.disabled(!profile.status.isEnabled)
|
.disabled(!profile.status.isEnabled)
|
||||||
.alertBinding($alert)
|
.alertBinding($alert)
|
||||||
|
|||||||
Reference in New Issue
Block a user