Base fixes and test harness
This commit is contained in:
@@ -1,17 +1,21 @@
|
||||
import SwiftUI
|
||||
import CoreData
|
||||
|
||||
struct SourceListView: View {
|
||||
@EnvironmentObject var iapService: IAPService
|
||||
@EnvironmentObject var accountStore: AccountStore
|
||||
@Environment(\.managedObjectContext) private var context
|
||||
@StateObject private var viewModel: SourceListViewModel
|
||||
@AppStorage("calmModeEnabled") private var calmModeEnabled = true
|
||||
@State private var sourceToDelete: InvestmentSource?
|
||||
@State private var navigationPath = NavigationPath()
|
||||
|
||||
init(iapService: IAPService) {
|
||||
_viewModel = StateObject(wrappedValue: SourceListViewModel(iapService: iapService))
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
NavigationStack {
|
||||
NavigationStack(path: $navigationPath) {
|
||||
ZStack {
|
||||
AppBackground()
|
||||
|
||||
@@ -58,6 +62,36 @@ struct SourceListView: View {
|
||||
.onReceive(accountStore.$showAllAccounts) { showAll in
|
||||
viewModel.showAllAccounts = showAll
|
||||
}
|
||||
.navigationDestination(for: NSManagedObjectID.self) { objectID in
|
||||
if let source = try? context.existingObject(with: objectID) as? InvestmentSource,
|
||||
!source.isDeleted {
|
||||
SourceDetailView(source: source, iapService: iapService)
|
||||
} else {
|
||||
MissingSourceView()
|
||||
}
|
||||
}
|
||||
.confirmationDialog(
|
||||
"Delete Source",
|
||||
isPresented: Binding(
|
||||
get: { sourceToDelete != nil },
|
||||
set: { if !$0 { sourceToDelete = nil } }
|
||||
),
|
||||
titleVisibility: .visible
|
||||
) {
|
||||
Button("Delete", role: .destructive) {
|
||||
if let source = sourceToDelete {
|
||||
viewModel.deleteSource(source)
|
||||
sourceToDelete = nil
|
||||
}
|
||||
}
|
||||
Button("Cancel", role: .cancel) {
|
||||
sourceToDelete = nil
|
||||
}
|
||||
} message: {
|
||||
if let source = sourceToDelete {
|
||||
Text("This will permanently delete \(source.name) and all its snapshots.")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,15 +148,19 @@ struct SourceListView: View {
|
||||
|
||||
// Sources
|
||||
Section {
|
||||
ForEach(viewModel.sources) { source in
|
||||
NavigationLink {
|
||||
SourceDetailView(source: source, iapService: iapService)
|
||||
} label: {
|
||||
SourceRowView(source: source, calmModeEnabled: calmModeEnabled)
|
||||
}
|
||||
}
|
||||
.onDelete { indexSet in
|
||||
viewModel.deleteSource(at: indexSet)
|
||||
ForEach(viewModel.sources, id: \.objectID) { source in
|
||||
SourceRowView(source: source, calmModeEnabled: calmModeEnabled)
|
||||
.contentShape(Rectangle())
|
||||
.onTapGesture {
|
||||
navigationPath.append(source.objectID)
|
||||
}
|
||||
.swipeActions(edge: .trailing, allowsFullSwipe: false) {
|
||||
Button(role: .destructive) {
|
||||
sourceToDelete = source
|
||||
} label: {
|
||||
Label("Delete", systemImage: "trash")
|
||||
}
|
||||
}
|
||||
}
|
||||
} header: {
|
||||
if viewModel.isFiltered {
|
||||
@@ -263,6 +301,22 @@ struct SourceListView: View {
|
||||
}
|
||||
}
|
||||
|
||||
private struct MissingSourceView: View {
|
||||
var body: some View {
|
||||
VStack(spacing: 12) {
|
||||
Image(systemName: "exclamationmark.triangle")
|
||||
.font(.system(size: 42))
|
||||
.foregroundColor(.secondary)
|
||||
Text("Source not available")
|
||||
.font(.headline)
|
||||
Text("This source was deleted.")
|
||||
.font(.subheadline)
|
||||
.foregroundColor(.secondary)
|
||||
}
|
||||
.padding()
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Source Row View
|
||||
|
||||
struct SourceRowView: View {
|
||||
|
||||
Reference in New Issue
Block a user