Remove newFilesOnly toggle; add functional notifications; fix WiFi status

WHAT TO BACK UP section:
- Remove "New files only" / "Skip files already on NAS" toggle from Settings
- Remove BackupFilter.newFilesOnly field — duplicate protection is always active
  (fileExists pre-check + hybrid filterIndex ensure NAS files are never re-uploaded)

NOTIFICATIONS section:
- Replace static decorative rows with real ToggleRow controls backed by
  ConnectionStore (notifyOnStart=false, notifyOnComplete=true, notifyOnErrors=true)
- BackupEngine now gates notification calls behind these store flags

NETWORK section:
- WiFi row always shows ● On / ● Off indicator (was only shown when SSID known)
- Shows "Trusted" / "Unknown" when SSID is available, "On" / "Off" otherwise

Tests:
- makeAssets: add missing isScreenRecording parameter
- Rename test_backup_skipsExistingFiles_whenNewFilesOnly → _alwaysHardcoded,
  remove filter.newFilesOnly assignment
- MockNASService: add downloadData, writeData, deleteFile to satisfy protocol

Co-Authored-By: Kutesir <kutesir@provoc.ug>
Co-Authored-By: Sentry <sentry@provoc.ug>
This commit is contained in:
Robin Kutesa
2026-05-19 01:33:36 +03:00
parent 089c9dfd67
commit 47867f2ef3
6 changed files with 53 additions and 40 deletions

View File

@@ -138,10 +138,6 @@ struct SettingsView: View {
hairline
ToggleRow(icon: "rays", title: "RAW",
isOn: $store.backupFilter.includeRAW)
hairline
ToggleRow(icon: "doc.badge.clock", title: "New files only",
subtitle: "Skip files already on NAS",
isOn: $store.backupFilter.newFilesOnly)
}
.background(AppTheme.surfaceRaised)
.clipShape(RoundedRectangle(cornerRadius: AppTheme.radius, style: .continuous))
@@ -221,15 +217,19 @@ struct SettingsView: View {
.foregroundStyle(AppTheme.inkTertiary)
}
Spacer()
if lanMonitor.currentSSID != nil {
let trusted = store.trustedSSIDs.contains(lanMonitor.currentSSID ?? "")
HStack(spacing: 4) {
Circle()
.fill(trusted ? AppTheme.positive : AppTheme.inkQuaternary)
.frame(width: 5, height: 5)
HStack(spacing: 4) {
Circle()
.fill(lanMonitor.isOnNetwork ? AppTheme.positive : AppTheme.inkQuaternary)
.frame(width: 5, height: 5)
if let ssid = lanMonitor.currentSSID {
let trusted = store.trustedSSIDs.contains(ssid)
Text(trusted ? "Trusted" : "Unknown")
.font(AppTheme.micro())
.foregroundStyle(trusted ? AppTheme.positive : AppTheme.inkTertiary)
} else {
Text(lanMonitor.isOnNetwork ? "On" : "Off")
.font(AppTheme.micro())
.foregroundStyle(lanMonitor.isOnNetwork ? AppTheme.positive : AppTheme.inkTertiary)
}
}
}
@@ -490,11 +490,17 @@ struct SettingsView: View {
sectionLabel("NOTIFICATIONS")
VStack(spacing: 0) {
notifRow(icon: "bell", title: "On start", value: "Off")
ToggleRow(icon: "bell", title: "On start",
subtitle: "Notify when a backup begins",
isOn: $store.notifyOnStart)
hairline
notifRow(icon: "checkmark.circle", title: "On complete", value: "On")
ToggleRow(icon: "checkmark.circle", title: "On complete",
subtitle: "Notify when all files are safe",
isOn: $store.notifyOnComplete)
hairline
notifRow(icon: "exclamationmark.triangle", title: "On errors", value: "On")
ToggleRow(icon: "exclamationmark.triangle", title: "On errors",
subtitle: "Notify if any uploads fail",
isOn: $store.notifyOnErrors)
}
.background(AppTheme.surfaceRaised)
.clipShape(RoundedRectangle(cornerRadius: AppTheme.radius, style: .continuous))
@@ -502,24 +508,6 @@ struct SettingsView: View {
}
}
private func notifRow(icon: String, title: String, value: String) -> some View {
HStack(spacing: 12) {
Image(systemName: icon)
.font(.system(size: 14, weight: .regular))
.foregroundStyle(AppTheme.inkSecondary)
.frame(width: 20)
Text(title)
.font(AppTheme.body())
.foregroundStyle(AppTheme.ink)
Spacer()
Text(value)
.font(AppTheme.caption())
.foregroundStyle(AppTheme.inkTertiary)
}
.padding(.horizontal, AppTheme.cardPad)
.padding(.vertical, 14)
}
private var hairline: some View {
Rectangle()
.fill(AppTheme.separator)