summaryrefslogtreecommitdiff
path: root/DomainDig/HistoryView.swift
Commit message (Collapse)AuthorAgeFilesLines
* feat(a11y): VoiceOver labels, dense-row rotor content, announcements (#21 ↵Christian Cleberg14 days1-0/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | phase 4) The audit count is unchanged at 11 dark, and that is the expected result: performAccessibilityAudit validates descriptions, traits, contrast, hit regions, and clipping, but exercises none of VoiceOver's speech, the More Content rotor, custom-content ordering, or announcements — which is the entire substance of this phase. It is verified by construction and stays green with no regressions; the manual VoiceOver pass is Phase 6. Icon-only controls (~14) get accessibilityLabel, obeying label-in-name: where a control has visible text the label keeps it, so Voice Control still works. The pin and bookmark toggles gain accessibilityValue and .isSelected; the audit and workflow checkboxes gain .isSelected and a hint. Decorative icons split out of Labels are hidden. AppStatusBadgeView now reads as one word ("Critical"), not "icon, Critical", via children: .ignore + label. SectionTitleView and CollapsibleSectionView headers get the .isHeader trait for rotor navigation; the collapsible header also exposes expanded/collapsed as a value with a hint. The header deliberately does NOT use children: .combine — its trailing() closure can hold Track/Pin controls, and combining would swallow them. Dense rows use combine-for-summary, custom-content-for-detail. BatchResultRowView (8 elements) and WatchlistRowView (up to 9) become a single element — domain as label, status as value — with risk, IP, timestamp, source, certificate, and monitoring on the More Content rotor, risk and certificate at .high importance. Reading all of it inline would make a long sweep unnavigable. The custom-content chains live in ViewModifiers because inlining six of them plus the layout broke the type-checker. The shorter 3-4 element portfolio rows are left to NavigationLink's automatic combine, per WWDC21-10121. Technical strings get a speechStyle field on InfoRowViewData: .technical applies speechAlwaysIncludesPunctuation and accessibilityTextContentType(.sourceCode), set on DNS record values and cipher suites so load-bearing punctuation is not swallowed. Completion announcements: the sweep posts from the view model; the single lookup posts from an onChange in the view, since resultsLoaded is derived from many loading flags and has no single view-model moment. Widget: each domain row was a silent 8pt status dot plus a bare "12d" countdown. Rows now read as one phrase ("example.com, critical, certificate expires in 12 days"); the count pills are labelled. Not verifiable by the suite: the dense rows and the widget never render in the audit (no tracked domains or batch results in the test simulator), same limit as the deferred Phase 3 row reflow. Documented in Docs/ACCESSIBILITY.md.
* fix(a11y): rebalance the light palette so hues surviveChristian Cleberg2026-07-201-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Reported as "colors seem muted and hard to see on light mode", and correct. The light palette optimised contrast and produced mud: #7A5600 reads olive rather than amber, #146C2E bottle-dark rather than green. Contrast passed while the UI got harder to read, because hue identity is what distinguishes warning from critical at a glance. Two causes, both fixed. Every foreground was required to clear 4.5:1 against its own 16% badge tint — the harshest surface it ever sits on — which pushed each colour about 20% darker than the common case needed. Most of what is actually on screen is plain text on a card, with far more headroom. The fill is now decoupled from the foreground: AppStatusTone carries a foreground and a surface authored independently, with matching …Surface colorsets, so a foreground no longer has to survive a wash of itself. Every status foreground is now fully saturated. And warning was yellow. Yellow cannot stay yellow at a lightness low enough to pass 4.5:1 on white — it becomes olive. That is colorimetric, not a tuning problem. Warning is now orange: #AD5100 light, #FF9F0A dark. New light values: positive #008035, warning #AD5100, critical #CC0700. Worst-case ratios 4.54–6.76 across page, card, and surface in both schemes. Audit findings are unchanged — light 21, dark 18 — so the vividness costs nothing. Also picks up a literal .blue missed in phase 1: DomainDiffItem's low-severity change colour, which the phase 1 sweep did not cover because its pattern listed only cyan/yellow/green/red/orange/pink.
* feat(a11y): unlock light mode and add appearance preference (#21 phase 2)Christian Cleberg2026-07-201-7/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Removes the 16 scattered .preferredColorScheme(.dark) calls and the one .toolbarColorScheme, and applies appearance in exactly one place — the WindowGroup in DomainDigApp. Re-applying per view is what let the lock spread across eight files unnoticed until light mode was unreachable. Adds AppAppearance (System / Light / Dark) in @AppStorage, exposed under Settings > Display next to Density. Honouring the system setting and offering an override is one key, and it keeps the deliberate dark aesthetic reachable for anyone who wants it. Also replaces .secondary with AppTextSecondary across 191 sites. iOS's own secondaryLabel is 3.29:1 on a light card — below AA — which never showed while the app was locked to dark, where the same colour reads 6.32:1. Unlocking light mode is precisely what exposed it, so it belongs here rather than in a later phase: without it, light mode would ship with body text under 4.5:1 app-wide. Dark mode reports 18 findings, unchanged from phase 1 — no regression from unlocking. Light mode reports 21. The three extra are iOS-rendered Section headers (TIER, PREFERENCES, SERVICES) using the system's grey; overriding system header styling across every section to gain ~0.3:1 on decorative labels is a poor trade and is left alone. Two long-standing Settings contrast findings are now explained. They are the last rows of a section sitting under the translucent tab bar, so the audit measures text against a blended background — confirmed by screenshot, present in dark mode since phase 0, and standard iOS scroll-under behaviour rather than a defect.
* feat(a11y): semantic colour system (#21 phase 1)Christian Cleberg2026-07-201-9/+9
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Replaces every hard-coded colour with semantic asset colours that adapt to light, dark, and Increase Contrast. Dark mode stays locked, so this is a pure refactor: the audit reports the same findings before and after. The accent is now blue rather than cyan, per the tech/DNS theme. Why custom values rather than the system palette: every system colour fails WCAG AA in light mode. Measured on white — systemYellow 1.51:1, systemOrange 2.20:1, systemGreen 2.22:1, systemCyan 2.54:1, systemRed 3.55:1. All of them pass in dark mode, which is why the dark-locked app looked fine, and why unlocking light mode was never a matter of deleting .preferredColorScheme(.dark). Every new value clears 4.5:1 as text on its page, its card, and its own 16% badge tint — the way AppStatusBadgeView actually draws it. The accent needed splitting in two. As text on a dark background it must be light; as a fill behind a white label it must be dark. #4DA3FF reads 8.00:1 as text on black but 2.63:1 behind white text, so StatusInfo / AccentColor cover the foreground role and AccentFill covers .borderedProminent. AppOnAccent is the label colour for a solid fill and flips by scheme. Colours live in Shared/Colors.xcassets rather than the app catalog: the Shared folder is already a synchronized group in all three targets, so the widget and share extension pick the palette up with no project-file surgery. AccentColor stays in the app catalog as the global tint — and is now actually defined, having been an empty colorset that silently left system controls rendering in stock blue while custom chrome used cyan. Two deliberate visual changes: orange folds into StatusWarning and pink into StatusCritical. They encoded the same severity as the colours they now share, and both sites also carry a text label. Audit findings drop 15 to 14, and one of the originals turned out to be a phantom: the Inspect contrast failure was the Run button in its disabled state, which WCAG 1.4.3 exempts. testInspectScreen now types a domain first so the audit measures an enabled control. Findings also carry the offending element now, so the remaining clipped-text items name themselves ("No Portfolio Yet", "Search domains") instead of being anonymous.
* v4.8.3: Clear SonarCloud new-code issuesChristian Cleberg2026-07-201-3/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | Fixes the 4 reported bugs and ~97 code smells flagged in the new-code period. No behavior changes. Bugs (swift:S3923) — DomainInspectionService's confidenceFor* helpers each returned `error == nil ? .low : .low`, an inert conditional. Simplified to `return .low` and dropped the now-unused `error` parameter. Smells: - Merged 14 identical `.empty`/`.error` switch branches in DomainViewModel - Consolidated duplicate implementations (clearPresentedResults/reset, String.nonEmpty/nilIfEmpty, ExportFormat.id/fileExtension) - Extracted nested ternaries into TLSGrade.tone, EmailSecurityGrade.tone, and ChangeImpactClassification.color; removed ContentView.impactColor and the duplicate mapping in BatchResultsView - Documented empty closures and singleton inits - Marked unused protocol-conformance parameters `_` - Renamed CloudSyncTrigger.`import` to `imported` (raw value preserved) and SSLSessionDelegate's _serverTrust/_tlsMetadata - Merged nested ifs in the DER parser; flattened closure nesting in PortScanService and IntegrationService - Replaced two-case switches with if/else Left open: S107 (init parameter counts), S115 (constants mirroring DoH and ipapi JSON keys), S1075 (false positives on https:// literals), and two S117 hits on SwiftUI $binding shorthand. These want a Won't Fix resolution in SonarCloud, not a code change.
* DomainDig v3.5.0: Expand the Pro+ Data+ intelligence layer with deeper local ↵Christian Cleberg2026-04-261-1/+11
| | | | | | | | | | | | | | | | | | | | | | | | historical context and inferred enrichment. - add derived intelligence fields for provider fingerprinting, classification, ownership transitions, hosting transitions, subdomain history, risk signals, and inferred timeline events - expand DNS history beyond A/NS snapshots to retain A, AAAA, MX, NS, TXT, and CNAME change state - persist enriched intelligence in snapshots and history entries so analysis is local-first and incremental - add a dedicated Data+ Intelligence panel to current and historical domain detail views - surface intelligence events in timeline rows and include Data+ changes in diff output - preserve non-blocking inspection behavior by keeping enrichment additive to the main lookup path This makes Pro+ materially deeper for investigative workflows by improving historical ownership visibility, infrastructure context, hosting change detection, subdomain intelligence, and explainable risk signals.
* DomainDig v3.8.0 — Smart MonitoringChristian Cleberg2026-04-241-1/+2
| | | | | | | | | * Stable domain intervals * Frequent changes decrease intervals * Duplicate states do not trigger alerts * Quiet hours suppress alerts * Quiet hours across midnight work correctly * Sensitivity levels alter behavior as expected
* feat(v3.7.0): add timeline and advanced diffing systemChristian Cleberg2026-04-241-47/+38
| | | | | | | | | | - introduce TimelineView for historical snapshots - allow comparison between any two snapshots - implement DiffService for structured domain diffs - improve diff visualization with clear change indicators - add navigation across changes - optimize history loading for performance - extend CLI and export to support timeline data
* feat(v3.2.0): add Data+ tier and external data integrationsChristian Cleberg2026-04-221-0/+3
| | | | | | | | | | - introduce Data+ tier for advanced data features - add ownership history and DNS history - expand subdomain discovery with external sources - add domain pricing insights - implement local usage/credit system - integrate external data service layer with rate limiting - extend export and CLI for Data+ features
* feat(v2.9.0): add risk scoring and deterministic insight engineChristian Cleberg2026-04-221-2/+18
| | | | | | | | | * introduce domain risk assessment with transparent factors * add insight engine for actionable observations * implement cross-domain insights for workflows * improve DNS, subdomain, email, and TLS interpretation * classify change impact severity * include insights and risk in export
* feat(v2.8.0): add workflows and repeatable inspection automationChristian Cleberg2026-04-221-1/+19
| | | | | | | | | | * introduce DomainWorkflow model and persistence * add WorkflowsView and execution flow * support batch inspection via workflows * add workflow-based export (TXT/CSV/JSON) * enable bulk add from history/watchlist * add quick actions for common operations * integrate workflows with tracking and history
* feat(v2.7.0): add provenance, confidence, and reproducibility metadataChristian Cleberg2026-04-221-11/+101
| | | | | | | | | | * add result provenance across major sections * introduce confidence levels for ambiguous outputs * distinguish observed facts from inferred summaries * expand snapshot metadata for reproducibility * improve error classification and partial snapshot handling * include provenance and confidence in export * add local notes for tracked domains and history
* feat(v2​.6​.0): refine ​UI, density, and usabilityChristian Cleberg2026-04-221-43/+95
| | | | | | | | | • add compact/comfortable density modes • implement collapsible sections and sticky summary header • improve visual status indicators and copy actions • refine watchlist and history UX with swipe actions • reorganize settings and improve empty states • add subtle animations and accessibility improvements
* feat(v2.3.0): add ownership intelligence and subdomain discoveryChristian Cleberg2026-04-211-0/+14
| | | | | | | | | * implement RDAP-based ownership section * add ownership diffing and change classification * add passive subdomain discovery via certificate transparency * highlight interesting subdomains * introduce Data+ scaffolding for future features * include ownership and subdomains in export and history
* feat(v2.1.0): add bulk workflows, CSV export, and filteringChristian Cleberg2026-04-201-6/+33
|
* feat(v2.0.0): introduce tracked domains, diffing, and monitoring foundationsv2.0.0Christian Cleberg2026-04-201-5/+50
| | | | | | | | | | | | | | | | | | - 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
* feat(v1.9.0): add domain availability lookup and watchlist foundationChristian Cleberg2026-04-201-1/+11
| | | | | | | | | - implement availability detection (available/registered/unknown) - integrate availability into domain results - add lightweight domain suggestions - introduce local watchlist with persistence - add WatchlistView and toolbar access - include availability in export
* feat(v1.8): improve result structure, history, and consistencyChristian Cleberg2026-04-201-469/+93
| | | | | | | | - normalize sections and add summary card - fix resolver usage in reverse DNS - include custom port scans in history/export - standardize error handling - decompose ContentView into smaller views
* Add BIMI and MTA-STS checks to email securityv1.5.0Christian Cleberg2026-04-031-1/+32
|
* fix: various bugsChristian Cleberg2026-04-031-32/+45
| | | | | | - fix Email section to left align - ensure container contents can overflow scroll but page cannot - fix map width
* realigning commitsChristian Cleberg2026-03-181-0/+496