Replace static NAS status label with live sync status indicator

Swap dot + "NAS Connected/Offline" for an icon + text that reflects
the actual engine/coordinator state:

  Running   → ↻ arrow.triangle.2.circlepath  (orange)
  Checking  → 🔍 magnifyingglass              (gray)
  Paused    → ⏸ pause.fill                   (orange)
  Offline   → wifi.slash                      (red)
  Stopped   → ■ stop.fill                     (gray)

Animates crossfade between states. Nothing else changed.

Co-Authored-By: Kutesir <kutesir@provoc.ug>
Co-Authored-By: Sentry <sentry@provoc.ug>
This commit is contained in:
Robin Kutesa
2026-05-19 10:05:47 +03:00
parent 0bcb8f849c
commit b9b91bbb35

View File

@@ -528,27 +528,41 @@ struct BackupView: View {
}
.frame(height: 16)
if statusService.snapshot.connectionState != .unknown {
HStack(spacing: 4) {
Circle()
.fill(nasConnectionStatusColor)
.frame(width: 5, height: 5)
Text(nasConnectionStatusLabel)
.font(.system(size: 9, weight: .regular))
.foregroundStyle(nasConnectionStatusColor)
}
Image(systemName: syncStatusIcon)
.font(.system(size: 9, weight: .medium))
.foregroundStyle(syncStatusColor)
Text(syncStatusLabel)
.font(.system(size: 9, weight: .medium))
.foregroundStyle(syncStatusColor)
}
.animation(.easeInOut(duration: 0.2), value: syncStatusLabel)
}
}
private var nasConnectionStatusColor: Color {
statusService.snapshot.connectionState == .offline
? AppTheme.destructive
: Color(red: 1.0, green: 0.58, blue: 0.0)
private var syncStatusIcon: String {
if engine.job.status == .preparing { return "magnifyingglass" }
if engine.job.status.isActive { return "arrow.triangle.2.circlepath" }
if engine.job.status == .paused { return "pause.fill" }
if statusService.isRefreshing || coordinator.phase == .checking { return "magnifyingglass" }
if statusService.snapshot.connectionState == .offline { return "wifi.slash" }
return "stop.fill"
}
private var nasConnectionStatusLabel: String {
statusService.snapshot.connectionState == .offline ? "NAS Offline" : "NAS Connected"
private var syncStatusColor: Color {
if engine.job.status.isActive { return Color(red: 1.0, green: 0.58, blue: 0.0) }
if engine.job.status == .paused { return Color(red: 1.0, green: 0.58, blue: 0.0) }
if statusService.snapshot.connectionState == .offline { return AppTheme.destructive }
return AppTheme.inkQuaternary
}
private var syncStatusLabel: String {
if engine.job.status == .preparing { return "Checking" }
if engine.job.status.isActive { return "Running" }
if engine.job.status == .paused { return "Paused" }
if statusService.isRefreshing || coordinator.phase == .checking { return "Checking" }
if statusService.snapshot.connectionState == .offline { return "Offline" }
return "Stopped"
}
private func compactStat(_ value: String, label: String, color: Color) -> some View {