summaryrefslogtreecommitdiff
path: root/DomainDig/ContentView.swift
diff options
context:
space:
mode:
authorChristian Cleberg <[email protected]>2026-07-20 16:22:28 -0500
committerChristian Cleberg <[email protected]>2026-07-20 16:27:59 -0500
commitbb18197860ffdb491f010648ec903003b6e1bb65 (patch)
treee569d7cdeb1c14c7eab889cb7fac1ea9813e6efe /DomainDig/ContentView.swift
parent083dfa723739eedd409ea8a6ae27332e48515210 (diff)
downloaddomain-dig-bb18197860ffdb491f010648ec903003b6e1bb65.tar.gz
domain-dig-bb18197860ffdb491f010648ec903003b6e1bb65.tar.bz2
domain-dig-bb18197860ffdb491f010648ec903003b6e1bb65.zip
v4.8.3: Clear SonarCloud new-code issues
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.
Diffstat (limited to 'DomainDig/ContentView.swift')
-rw-r--r--DomainDig/ContentView.swift87
1 files changed, 56 insertions, 31 deletions
diff --git a/DomainDig/ContentView.swift b/DomainDig/ContentView.swift
index 3e1015d..40c97d1 100644
--- a/DomainDig/ContentView.swift
+++ b/DomainDig/ContentView.swift
@@ -569,13 +569,13 @@ struct ContentView: View {
shareSingleResults(format: .pdf)
}
} else {
- Button("CSV Export • Available in Pro") {}
+ Button("CSV Export • Available in Pro") { /* Inert: disabled Pro upsell affordance. */ }
.disabled(true)
- Button("JSON Export • Available in Pro") {}
+ Button("JSON Export • Available in Pro") { /* Inert: disabled Pro upsell affordance. */ }
.disabled(true)
- Button("Markdown Export • Available in Pro") {}
+ Button("Markdown Export • Available in Pro") { /* Inert: disabled Pro upsell affordance. */ }
.disabled(true)
- Button("PDF Export • Available in Pro") {}
+ Button("PDF Export • Available in Pro") { /* Inert: disabled Pro upsell affordance. */ }
.disabled(true)
}
} label: {
@@ -621,13 +621,13 @@ struct ContentView: View {
shareBatchResults(format: .pdf)
}
} else {
- Button("Batch CSV • Available in Pro") {}
+ Button("Batch CSV • Available in Pro") { /* Inert: disabled Pro upsell affordance. */ }
.disabled(true)
- Button("Batch JSON • Available in Pro") {}
+ Button("Batch JSON • Available in Pro") { /* Inert: disabled Pro upsell affordance. */ }
.disabled(true)
- Button("Batch Markdown • Available in Pro") {}
+ Button("Batch Markdown • Available in Pro") { /* Inert: disabled Pro upsell affordance. */ }
.disabled(true)
- Button("Batch PDF • Available in Pro") {}
+ Button("Batch PDF • Available in Pro") { /* Inert: disabled Pro upsell affordance. */ }
.disabled(true)
}
} label: {
@@ -1040,10 +1040,10 @@ struct DomainChangeSummaryView: View {
.clipShape(Capsule())
Text(summary.impactClassification.title.uppercased())
.font(appDensity.font(.caption2))
- .foregroundStyle(impactColor(summary.impactClassification))
+ .foregroundStyle(summary.impactClassification.color)
.padding(.horizontal, 8)
.padding(.vertical, 4)
- .background(impactColor(summary.impactClassification).opacity(0.16))
+ .background(summary.impactClassification.color.opacity(0.16))
.clipShape(Capsule())
Text(summary.generatedAt, style: .time)
.font(appDensity.font(.caption2))
@@ -1107,16 +1107,6 @@ struct DomainChangeSummaryView: View {
}
}
- private func impactColor(_ impact: ChangeImpactClassification) -> Color {
- switch impact {
- case .informational:
- return .secondary
- case .warning:
- return .yellow
- case .critical:
- return .red
- }
- }
}
struct DomainDiffView: View {
@@ -2008,7 +1998,7 @@ struct WebSectionView: View {
}
SectionTrustMetadataView(provenance: tlsProvenance, confidence: nil)
if !sslLoading, let tlsSummary {
- LabeledValueRow(row: InfoRowViewData(label: "TLS Grade", value: tlsSummary.tlsGrade.rawValue, tone: tlsSummary.tlsGrade == .a ? .success : (tlsSummary.tlsGrade == .f ? .failure : .warning)))
+ LabeledValueRow(row: InfoRowViewData(label: "TLS Grade", value: tlsSummary.tlsGrade.rawValue, tone: tlsSummary.tlsGrade.tone))
ForEach(Array(tlsSummary.tlsHighlights.enumerated()), id: \.offset) { _, highlight in
MessageRowView(text: highlight, isError: isTLSHighlightError(highlight))
}
@@ -2153,7 +2143,7 @@ struct EmailSectionView: View {
.opacity(loading ? 0 : 1)
}
if let assessment, let grade = assessment.grade {
- LabeledValueRow(row: InfoRowViewData(label: "Grade", value: grade.rawValue, tone: grade == .a ? .success : (grade == .f ? .failure : .warning)))
+ LabeledValueRow(row: InfoRowViewData(label: "Grade", value: grade.rawValue, tone: grade.tone))
if !assessment.reasons.isEmpty {
Text(assessment.reasons.joined(separator: " | "))
.font(appDensity.font(.caption2))
@@ -2897,6 +2887,11 @@ private struct LocalAPISettingsView: View {
@State private var localAPIService = LocalAPIService.shared
@State private var portText = ""
+ private var statusText: String {
+ if localAPIService.isRunning { return "Running" }
+ return localAPIService.config.isEnabled ? "Stopped" : "Disabled"
+ }
+
var body: some View {
Form {
Section("Local API") {
@@ -2923,7 +2918,7 @@ private struct LocalAPISettingsView: View {
.keyboardType(.numberPad)
LabeledContent("Address", value: localAPIService.address)
- LabeledContent("Status", value: localAPIService.isRunning ? "Running" : (localAPIService.config.isEnabled ? "Stopped" : "Disabled"))
+ LabeledContent("Status", value: statusText)
LabeledContent("Token", value: localAPIService.maskedToken)
if let statusMessage = localAPIService.statusMessage {
@@ -3339,7 +3334,7 @@ private struct DataPortabilitySettingsView: View {
Button("Replace", role: .destructive) {
applyPendingImport()
}
- Button("Cancel", role: .cancel) {}
+ Button("Cancel", role: .cancel) { /* Dismiss only; SwiftUI closes the alert. */ }
} message: {
Text("Replace mode overwrites local data covered by the imported file and may remove items that are only on this device.")
}
@@ -3347,7 +3342,7 @@ private struct DataPortabilitySettingsView: View {
get: { pendingImportError != nil },
set: { if !$0 { pendingImportError = nil } }
)) {
- Button("OK", role: .cancel) {}
+ Button("OK", role: .cancel) { /* Dismiss only; SwiftUI closes the alert. */ }
} message: {
Text(pendingImportError ?? "The import could not be completed.")
}
@@ -3585,7 +3580,7 @@ private struct DataManagementSettingsView: View {
Button("Clear", role: .destructive) {
viewModel.clearHistory()
}
- Button("Cancel", role: .cancel) {}
+ Button("Cancel", role: .cancel) { /* Dismiss only; SwiftUI closes the alert. */ }
} message: {
Text("This removes saved lookup snapshots and clears monitoring run history on this device.")
}
@@ -3593,7 +3588,7 @@ private struct DataManagementSettingsView: View {
Button("Clear", role: .destructive) {
viewModel.clearLookupCache()
}
- Button("Cancel", role: .cancel) {}
+ Button("Cancel", role: .cancel) { /* Dismiss only; SwiftUI closes the alert. */ }
} message: {
Text("This clears the in-memory lookup cache and cancels any cached in-flight work.")
}
@@ -3601,7 +3596,7 @@ private struct DataManagementSettingsView: View {
Button("Clear", role: .destructive) {
viewModel.clearWorkflows()
}
- Button("Cancel", role: .cancel) {}
+ Button("Cancel", role: .cancel) { /* Dismiss only; SwiftUI closes the alert. */ }
} message: {
Text("This removes saved workflows only. History, tracked domains, and saved reports stay intact.")
}
@@ -3609,12 +3604,12 @@ private struct DataManagementSettingsView: View {
Button("Clear", role: .destructive) {
viewModel.clearTrackedDomains()
}
- Button("Cancel", role: .cancel) {}
+ Button("Cancel", role: .cancel) { /* Dismiss only; SwiftUI closes the alert. */ }
} message: {
Text("This removes the watchlist and clears monitoring run history. History and workflows stay intact.")
}
.alert("Delete All Data?", isPresented: $showDeleteAllConfirmation) {
- Button("Cancel", role: .cancel) {}
+ Button("Cancel", role: .cancel) { /* Dismiss only; SwiftUI closes the alert. */ }
Button("Delete All Data", role: .destructive) {
deleteAllData()
}
@@ -3625,7 +3620,7 @@ private struct DataManagementSettingsView: View {
get: { deleteAllErrorMessage != nil },
set: { if !$0 { deleteAllErrorMessage = nil } }
)) {
- Button("OK", role: .cancel) {}
+ Button("OK", role: .cancel) { /* Dismiss only; SwiftUI closes the alert. */ }
} message: {
Text(deleteAllErrorMessage ?? "The local data reset could not be completed.")
}
@@ -3745,6 +3740,36 @@ private struct DataImportPreviewSheet: View {
}
}
+extension ChangeImpactClassification {
+ var color: Color {
+ switch self {
+ case .informational: return .secondary
+ case .warning: return .yellow
+ case .critical: return .red
+ }
+ }
+}
+
+extension TLSGrade {
+ var tone: ResultTone {
+ switch self {
+ case .a: return .success
+ case .f: return .failure
+ default: return .warning
+ }
+ }
+}
+
+extension EmailSecurityGrade {
+ var tone: ResultTone {
+ switch self {
+ case .a: return .success
+ case .f: return .failure
+ default: return .warning
+ }
+ }
+}
+
#Preview {
ContentView(viewModel: DomainViewModel())
}