summaryrefslogtreecommitdiff
path: root/DomainDig/DomainViewModel.swift
diff options
context:
space:
mode:
authorChristian Cleberg <[email protected]>2026-07-25 00:10:46 -0500
committerChristian Cleberg <[email protected]>2026-07-25 00:11:47 -0500
commit321a10f85435fdcbfb54f109ee53df895a550a42 (patch)
treee8931efbad04ca639329d19c3417c82ccdc49cad /DomainDig/DomainViewModel.swift
parent9092ab60f82152cc4ae38677c3af4a76013f4e54 (diff)
downloaddomain-dig-321a10f85435fdcbfb54f109ee53df895a550a42.tar.gz
domain-dig-321a10f85435fdcbfb54f109ee53df895a550a42.tar.bz2
domain-dig-321a10f85435fdcbfb54f109ee53df895a550a42.zip
refactor: extract history query surface into DomainViewModel+History (v5 step 4, 5/n)
Fifth slice of the DomainViewModel decomposition. - Moves the history query/compare surface into DomainViewModel+History.swift: per-domain snapshot reads (historyEntries/historyEntry/previousHistoryEntry), timeline grouping (timelineEntries/timelineSections), the two-snapshot selection model (toggle/clear/selectedSnapshots), diff generation and navigation (generateDiff*/moveTo*DiffChange/currentDiffTargetSectionID), and the resolver-mismatch notes. Pure move. - The inspection *pipeline* that produces history — performLookup, applySnapshot, saveHistoryEntry, persistHistory, snapshot-metadata bookkeeping — stays on the main type with the inspection code. This slice needs zero visibility changes: every dependency (the history array, diff state, latestSnapshot) was already internal. The main-file diff is pure deletion. DomainViewModel.swift: 4306 -> 4171 lines (4864 at the start of step 4; -693 total). App builds clean; unit suite 58/58. No project.pbxproj change.
Diffstat (limited to 'DomainDig/DomainViewModel.swift')
-rw-r--r--DomainDig/DomainViewModel.swift136
1 files changed, 0 insertions, 136 deletions
diff --git a/DomainDig/DomainViewModel.swift b/DomainDig/DomainViewModel.swift
index e0f649b..7246112 100644
--- a/DomainDig/DomainViewModel.swift
+++ b/DomainDig/DomainViewModel.swift
@@ -3047,142 +3047,6 @@ final class DomainViewModel {
}
}
- func resolverMismatchNote(for entry: HistoryEntry) -> String? {
- guard entry.resolverURLString != resolverURLString else { return nil }
- return "Current resolver differs from this snapshot. Re-running may produce different evidence."
- }
-
- func resolverMismatchNote(for trackedDomain: TrackedDomain) -> String? {
- guard let snapshot = latestSnapshot(for: trackedDomain), snapshot.resolverURLString != resolverURLString else {
- return nil
- }
- return "Current resolver differs from the latest snapshot for this tracked domain."
- }
-
- func comparisonSnapshot(for entry: HistoryEntry) -> LookupSnapshot? {
- previousHistoryEntry(for: entry)?.snapshot
- }
-
- func timelineEntries(for domain: String) -> [SnapshotSummary] {
- historyEntries(for: domain).map(\.snapshotSummary)
- }
-
- func timelineSections(for domain: String, grouping: TimelineGroupingOption? = nil) -> [TimelineSection] {
- let entries = timelineEntries(for: domain)
- let grouping = grouping ?? timelineGrouping
-
- guard grouping == .relativeDay else {
- return entries.isEmpty ? [] : [TimelineSection(id: "all", title: "All Snapshots", entries: entries)]
- }
-
- let calendar = Calendar.current
- let today = Date()
- let yesterday = calendar.date(byAdding: .day, value: -1, to: today) ?? today
- let grouped = Dictionary(grouping: entries) { entry -> String in
- if calendar.isDate(entry.timestamp, inSameDayAs: today) {
- return "Today"
- }
- if calendar.isDate(entry.timestamp, inSameDayAs: yesterday) {
- return "Yesterday"
- }
- return "Older"
- }
-
- return ["Today", "Yesterday", "Older"].compactMap { title in
- guard let items = grouped[title], !items.isEmpty else { return nil }
- return TimelineSection(id: title.lowercased(), title: title, entries: items)
- }
- }
-
- func historyEntries(for domain: String) -> [HistoryEntry] {
- history
- .filter { $0.domain.caseInsensitiveCompare(domain) == .orderedSame }
- .sorted { $0.timestamp > $1.timestamp }
- }
-
- func historyEntry(withID id: UUID) -> HistoryEntry? {
- history.first(where: { $0.id == id })
- }
-
- func previousHistoryEntry(for entry: HistoryEntry) -> HistoryEntry? {
- let siblings = historyEntries(for: entry.domain)
- guard let index = siblings.firstIndex(where: { $0.id == entry.id }) else { return nil }
- let nextIndex = index + 1
- guard siblings.indices.contains(nextIndex) else { return nil }
- return siblings[nextIndex]
- }
-
- func toggleSnapshotSelection(_ entry: HistoryEntry) {
- if selectedSnapshotIDs.contains(entry.id) {
- selectedSnapshotIDs.remove(entry.id)
- } else if selectedSnapshotIDs.count < 2 {
- selectedSnapshotIDs.insert(entry.id)
- } else if let oldest = selectedSnapshotIDs.first {
- selectedSnapshotIDs.remove(oldest)
- selectedSnapshotIDs.insert(entry.id)
- }
- }
-
- func clearSnapshotSelection() {
- selectedSnapshotIDs.removeAll()
- }
-
- var selectedSnapshots: [HistoryEntry] {
- selectedSnapshotIDs.compactMap(historyEntry(withID:)).sorted { $0.timestamp < $1.timestamp }
- }
-
- @discardableResult
- func generateDiffForSelectedSnapshots(focusSectionID: String? = nil) -> DomainDiff? {
- guard selectedSnapshots.count == 2 else {
- activeDomainDiff = nil
- activeDiffChangeIndex = 0
- return nil
- }
-
- let diff = DiffService.compare(from: selectedSnapshots[0].snapshot, to: selectedSnapshots[1].snapshot)
- activeDomainDiff = diff
- if let focusSectionID, let index = diff.changedSectionIDs.firstIndex(of: focusSectionID) {
- activeDiffChangeIndex = index
- } else {
- activeDiffChangeIndex = 0
- }
- return diff
- }
-
- func generateDiff(from olderEntry: HistoryEntry, to newerEntry: HistoryEntry, focusSectionID: String? = nil) -> DomainDiff {
- selectedSnapshotIDs = [olderEntry.id, newerEntry.id]
- let diff = DiffService.compare(from: olderEntry.snapshot, to: newerEntry.snapshot)
- activeDomainDiff = diff
- if let focusSectionID, let index = diff.changedSectionIDs.firstIndex(of: focusSectionID) {
- activeDiffChangeIndex = index
- } else {
- activeDiffChangeIndex = 0
- }
- return diff
- }
-
- func historyEntry(for batchResult: BatchLookupResult) -> HistoryEntry? {
- guard let historyEntryID = batchResult.historyEntryID else { return nil }
- return history.first(where: { $0.id == historyEntryID })
- }
-
- var currentDiffTargetSectionID: String? {
- guard let activeDomainDiff, activeDomainDiff.changedSectionIDs.indices.contains(activeDiffChangeIndex) else {
- return nil
- }
- return activeDomainDiff.changedSectionIDs[activeDiffChangeIndex]
- }
-
- func moveToNextDiffChange() {
- guard let activeDomainDiff, !activeDomainDiff.changedSectionIDs.isEmpty else { return }
- activeDiffChangeIndex = min(activeDiffChangeIndex + 1, activeDomainDiff.changedSectionIDs.count - 1)
- }
-
- func moveToPreviousDiffChange() {
- guard activeDomainDiff != nil else { return }
- activeDiffChangeIndex = max(activeDiffChangeIndex - 1, 0)
- }
-
private func exportSnapshots(for domains: [TrackedDomain]) -> [LookupSnapshot] {
let latestEntries = latestSnapshots(for: domains)