fix(backup): live Pending/Safe counters now count down during active backup

Previous logic capped alreadySafe at phoneTotal immediately when the last
reconcile showed everything safe, freezing both counters at 0 pending /
max safe even while uploads were running.

Now during an active session both counters are driven by engine.job:
  Pending = totalFiles - (uploaded + skipped + failed)  → counts down
  Safe    = phoneTotal - Pending                        → counts up
Ensures Safe + Pending == phoneTotal at all times and the numbers visibly
move as uploads complete, regardless of the snapshot state.

Co-Authored-By: Kutesir <kutesir@provoc.ug>
Co-Authored-By: Sentry <sentry@provoc.ug>
This commit is contained in:
Robin Kutesa
2026-05-30 22:49:35 +03:00
parent 8fb425344d
commit b3961257f6

View File

@@ -346,28 +346,29 @@ struct BackupView: View {
return base
}
private var alreadySafeDisplayCount: Int {
let total = statusService.snapshot.phoneTotal
guard total > 0 else { return 0 }
let base = statusService.snapshot.alreadySafe
if engine.job.status.isActive {
// Uploaded = newly confirmed on NAS this session.
// Skipped = fileExists returned true already on NAS but wasn't in manifest.
// Both are now confirmed safe; count them both optimistically.
return min(base + engine.job.uploadedFiles + engine.job.skippedFiles, total)
}
return min(base, total)
}
private var notBackedUpDisplayCount: Int {
let total = statusService.snapshot.phoneTotal
guard total > 0 else { return 0 }
if engine.job.status.isActive {
return max(0, total - alreadySafeDisplayCount)
// During an active session derive from the job so the counter
// counts down even when the snapshot was already "all safe"
// (e.g. re-uploading files deleted from NAS after last reconcile).
if engine.job.status.isActive, engine.job.totalFiles > 0 {
let done = engine.job.uploadedFiles + engine.job.skippedFiles + engine.job.failedFiles
return max(0, engine.job.totalFiles - done)
}
return statusService.snapshot.needBackup
}
private var alreadySafeDisplayCount: Int {
let total = statusService.snapshot.phoneTotal
guard total > 0 else { return 0 }
// Mirror of notBackedUpDisplayCount so Safe + Pending == phoneTotal always.
if engine.job.status.isActive, engine.job.totalFiles > 0 {
return max(0, total - notBackedUpDisplayCount)
}
return min(statusService.snapshot.alreadySafe, total)
}
private var statsStrip: some View {
HStack(spacing: 0) {
compactStat(