diff options
| author | Christian Cleberg <[email protected]> | 2026-07-25 00:10:46 -0500 |
|---|---|---|
| committer | Christian Cleberg <[email protected]> | 2026-07-25 00:11:47 -0500 |
| commit | 321a10f85435fdcbfb54f109ee53df895a550a42 (patch) | |
| tree | e8931efbad04ca639329d19c3417c82ccdc49cad /DomainDig/DomainViewModel.swift | |
| parent | 9092ab60f82152cc4ae38677c3af4a76013f4e54 (diff) | |
| download | domain-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.swift | 136 |
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) |
