Replace sheets with navigation destinations on tvOS

This commit is contained in:
世界
2025-12-02 13:53:07 +08:00
parent b3714ed957
commit e9d6b380bf
4 changed files with 174 additions and 3 deletions
@@ -97,6 +97,55 @@ import SwiftUI
}
}
#if os(tvOS)
@MainActor public struct CardManagementView: View {
@StateObject private var configuration = DashboardCardConfiguration()
private let onDisappear: (() -> Void)?
public init(onDisappear: (() -> Void)? = nil) {
self.onDisappear = onDisappear
}
public var body: some View {
Group {
if configuration.isLoading {
ProgressView()
} else {
List {
ForEach(configuration.cardOrder) { card in
CardRow(
card: card,
isEnabled: configuration.isEnabled(card),
onToggle: {
configuration.toggleCard(card)
}
)
}
.onMove { source, destination in
Task {
await configuration.moveCard(from: source, to: destination)
}
}
}
.applyContentMargins()
}
}
.toolbar {
ToolbarItem(placement: .topBarTrailing) {
Button("Reset", role: .destructive) {
Task {
await configuration.resetToDefault()
}
}
}
}
.onDisappear {
onDisappear?()
}
}
}
#endif
private struct CardRow: View {
let card: DashboardCard
let isEnabled: Bool
@@ -32,6 +32,44 @@ public struct ProfileCard: View {
}
}
.disabled(viewModel.isUpdating)
#if os(tvOS)
.navigationDestination(isPresented: $viewModel.showNewProfile) {
NewProfileContentView(onDisappear: {
environments.profileUpdate.send()
})
.environmentObject(environments)
.toolbar {
ToolbarItemGroup(placement: .topBarLeading) {
BackButton()
}
}
}
.navigationDestination(isPresented: $viewModel.showManageProfiles) {
ManageProfilesView()
.environmentObject(environments)
.navigationTitle("Manage profiles")
.toolbar {
ToolbarItemGroup(placement: .topBarLeading) {
BackButton()
}
}
}
.navigationDestination(item: $viewModel.profileToEdit) { profile in
EditProfileView()
.environmentObject(profile)
.environmentObject(environments)
.toolbar {
ToolbarItemGroup(placement: .topBarLeading) {
BackButton()
}
}
}
.sheet(isPresented: $viewModel.showQRCode) {
if let profile = selectedProfile, let remoteURL = profile.remoteURL {
QRCodeSheet(profileName: profile.name, remoteURL: remoteURL)
}
}
#else
.sheet(isPresented: $viewModel.showNewProfile, onDismiss: {
environments.profileUpdate.send()
}, content: {
@@ -44,13 +82,14 @@ public struct ProfileCard: View {
.sheet(item: $viewModel.profileToEdit) { profile in
editProfileSheet(for: profile)
}
#if os(iOS) || os(tvOS)
#if os(iOS)
.sheet(isPresented: $viewModel.showQRCode) {
if let profile = selectedProfile, let remoteURL = profile.remoteURL {
QRCodeSheet(profileName: profile.name, remoteURL: remoteURL)
}
}
#endif
#endif
.alert($viewModel.alert)
}
@@ -326,6 +365,41 @@ extension ProfileCard {
}
}
// MARK: - NewProfileContentView (tvOS)
#if os(tvOS)
extension ProfileCard {
@MainActor
struct NewProfileContentView: View {
@EnvironmentObject private var environments: ExtensionEnvironments
@State private var createdProfile: Profile?
private let onDisappear: (() -> Void)?
init(onDisappear: (() -> Void)? = nil) {
self.onDisappear = onDisappear
}
var body: some View {
Group {
if let profile = createdProfile {
EditProfileView()
.environmentObject(profile)
.environmentObject(environments)
} else {
NewProfileView { profile in
createdProfile = profile
}
.environmentObject(environments)
}
}
.onDisappear {
onDisappear?()
}
}
}
}
#endif
// MARK: - ManageProfilesView
extension ProfileCard {