krz/domain-dig
an ios app for DNS & SSL analysis
clone: git clone https://gitbay.org/krz/domain-dig.git
v4.9.0: DomainDig/DomainCompareView.swift · raw
1import SwiftUI
2
3/// Side-by-side comparison of two tracked domains' latest reports, reusing the
4/// same section-diff rendering (`DomainDiffView`) that time-based history diffs
5/// use, via `DiffService.compare(domainA:domainB:)`.
6struct DomainCompareView: View {
7 @Bindable var viewModel: DomainViewModel
8 @State private var domainAID: UUID?
9 @State private var domainBID: UUID?
10
11 private var states: [PortfolioDomainStatus] {
12 viewModel.portfolioDashboardData.domainStates
13 }
14
15 private var stateA: PortfolioDomainStatus? {
16 states.first { $0.trackedDomain.id == domainAID }
17 }
18
19 private var stateB: PortfolioDomainStatus? {
20 states.first { $0.trackedDomain.id == domainBID }
21 }
22
23 private var result: DomainComparisonResult? {
24 guard let stateA, let stateB, stateA.trackedDomain.id != stateB.trackedDomain.id else {
25 return nil
26 }
27 return DiffService.compare(domainA: stateA.report, domainB: stateB.report)
28 }
29
30 var body: some View {
31 List {
32 Section("Domains") {
33 domainPicker("Domain A", selection: $domainAID)
34 domainPicker("Domain B", selection: $domainBID)
35 }
36
37 if domainAID != nil, domainAID == domainBID {
38 Section {
39 Text("Choose two different domains to compare.")
40 .font(.callout)
41 .foregroundStyle(Color(.appTextSecondary))
42 }
43 }
44
45 if let result {
46 Section {
47 DomainDiffView(
48 title: "\(result.domainA) vs \(result.domainB)",
49 sections: result.sections,
50 contextNote: result.contextNote,
51 showsUnchanged: true,
52 highlightedSectionID: nil
53 )
54 }
55 .listRowBackground(Color.clear)
56 } else if domainAID == nil || domainBID == nil {
57 Section {
58 EmptyStateCardView(
59 title: "Pick Two Domains",
60 message: "Select a domain in each slot to see a side-by-side comparison across DNS, TLS, ownership, and risk.",
61 suggestion: "Both domains must already be tracked.",
62 systemImage: "arrow.left.arrow.right",
63 showsCardBackground: false
64 )
65 }
66 .listRowBackground(Color(.appSurface))
67 }
68 }
69 .scrollContentBackground(.hidden)
70 .background(Color(.appBackground))
71 .navigationTitle("Compare Domains")
72 }
73
74 private func domainPicker(_ label: String, selection: Binding<UUID?>) -> some View {
75 Picker(label, selection: selection) {
76 Text("Select a domain").tag(UUID?.none)
77 ForEach(states) { state in
78 Text(state.trackedDomain.domain).tag(Optional(state.trackedDomain.id))
79 }
80 }
81 }
82}