krz/domain-dig

an ios app for DNS & SSL analysis

clone: git clone https://gitbay.org/krz/domain-dig.git

v4.8.1: 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(.secondary)
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(.systemGray6).opacity(0.5))
67            }
68        }
69        .scrollContentBackground(.hidden)
70        .background(Color.black)
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}