diff options
| author | Christian Cleberg <[email protected]> | 2026-04-20 16:24:20 -0500 |
|---|---|---|
| committer | Christian Cleberg <[email protected]> | 2026-04-20 16:24:20 -0500 |
| commit | 9999f876feb9a2d419a79ad601f78053c44d44f8 (patch) | |
| tree | b920aacd1192646dcca71ddae17879355ed4f040 /DomainDig/HistoryView.swift | |
| parent | 397c7c420c22fc1c235893bd85b2029da9145730 (diff) | |
| download | domain-dig-9999f876feb9a2d419a79ad601f78053c44d44f8.tar.gz domain-dig-9999f876feb9a2d419a79ad601f78053c44d44f8.tar.bz2 domain-dig-9999f876feb9a2d419a79ad601f78053c44d44f8.zip | |
feat(v2.0.0): introduce tracked domains, diffing, and monitoring foundationsv2.0.0
- replace basic watchlist with structured TrackedDomain model
- add manual refresh flow for tracked domains
- implement snapshot diffing (DNS, IP, TLS, HTTP, redirect, email, availability)
- add change summaries (changed/unchanged + affected sections)
- link tracked domains to history snapshots
- enhance HistoryEntry with normalized summary fields
- persist availability + suggestions in history and export
- add WatchlistView with pinning, notes, and status display
- introduce premium capability scaffolding (no StoreKit)
- enforce free-tier tracked domain limit (local only)
- refactor view model to support tracking, diffing, and refresh flows
notes:
- no background monitoring, notifications, or paid APIs yet
- all features remain local-first and manual
Diffstat (limited to 'DomainDig/HistoryView.swift')
| -rw-r--r-- | DomainDig/HistoryView.swift | 55 |
1 files changed, 50 insertions, 5 deletions
diff --git a/DomainDig/HistoryView.swift b/DomainDig/HistoryView.swift index 5bbbb91..bb9d255 100644 --- a/DomainDig/HistoryView.swift +++ b/DomainDig/HistoryView.swift @@ -2,6 +2,8 @@ import SwiftUI struct HistoryView: View { @Bindable var viewModel: DomainViewModel + @Environment(\.dismiss) private var dismiss + @State private var showClearAllConfirmation = false private let dateFormatter: DateFormatter = { let formatter = DateFormatter() @@ -50,8 +52,29 @@ struct HistoryView: View { .navigationTitle("History") .toolbar { if !viewModel.history.isEmpty { - EditButton() + ToolbarItemGroup(placement: .topBarTrailing) { + Menu { + Button("Clear All", role: .destructive) { + showClearAllConfirmation = true + } + } label: { + Image(systemName: "ellipsis.circle") + } + + EditButton() + } + } + } + .alert("Clear history?", isPresented: $showClearAllConfirmation) { + Button("Clear All", role: .destructive) { + viewModel.clearHistory() } + Button("Cancel", role: .cancel) {} + } message: { + Text("This will delete all saved history entries. This cannot be undone.") + } + .onChange(of: viewModel.rerunNavigationToken) { _, _ in + dismiss() } .preferredColorScheme(.dark) } @@ -60,6 +83,7 @@ struct HistoryView: View { struct HistoryDetailView: View { @Bindable var viewModel: DomainViewModel let entry: HistoryEntry + @Environment(\.dismiss) private var dismiss private let dateFormatter: DateFormatter = { let formatter = DateFormatter() @@ -84,12 +108,30 @@ struct HistoryDetailView: View { showSuggestions: entry.availabilityResult?.status == .registered && !entry.suggestions.isEmpty, availabilityLoading: false, suggestionsLoading: false, - isWatched: viewModel.watchedDomains.contains(where: { $0.domain.lowercased() == entry.domain.lowercased() }), - onToggleWatch: { - viewModel.toggleWatchedDomain(domain: entry.domain, availabilityStatus: entry.availabilityResult?.status) - } + trackedDomain: viewModel.trackedDomains.first(where: { $0.domain.lowercased() == entry.domain.lowercased() }), + trackingLimitMessage: nil, + onTrack: { + _ = viewModel.trackDomain(domain: entry.domain, availabilityStatus: entry.availabilityResult?.status) + }, + onTogglePinned: { + guard let trackedDomain = viewModel.trackedDomains.first(where: { $0.domain.lowercased() == entry.domain.lowercased() }) else { return } + viewModel.togglePinned(for: trackedDomain) + }, + onEditNote: nil ) .padding(.top, 16) + if let comparisonSnapshot = viewModel.comparisonSnapshot(for: entry) { + if let changeSummary = entry.changeSummary { + DomainChangeSummaryView(summary: changeSummary) + .padding(.top, 16) + } + DomainDiffView( + title: "Compared With Previous Snapshot", + sections: DomainDiffService.diff(from: comparisonSnapshot, to: snapshot), + showsUnchanged: false + ) + .padding(.top, 16) + } DNSSectionView( dnssecLabel: DomainViewModel.dnssecLabel(from: snapshot), sections: DomainViewModel.dnsRows(from: snapshot), @@ -150,6 +192,9 @@ struct HistoryDetailView: View { viewModel.rerunLookup(from: entry) } } + .onChange(of: viewModel.rerunNavigationToken) { _, _ in + dismiss() + } .preferredColorScheme(.dark) } |
