diff --git a/Features/Backup/BackupView.swift b/Features/Backup/BackupView.swift index 74461e4..8cde1e6 100644 --- a/Features/Backup/BackupView.swift +++ b/Features/Backup/BackupView.swift @@ -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(