New version v2.3.6
This commit is contained in:
@@ -190,7 +190,7 @@ struct StatItem: View {
|
||||
|
||||
struct StatusPill: View {
|
||||
let icon: String
|
||||
let label: String
|
||||
let label: LocalizedStringKey
|
||||
let color: Color
|
||||
|
||||
var body: some View {
|
||||
@@ -210,9 +210,31 @@ struct StatusPill: View {
|
||||
|
||||
struct SyncStatusPill: View {
|
||||
private let gitSync = GitSyncService.shared
|
||||
|
||||
private enum SyncPillState { case notConfigured, syncing, error(String), synced(Date?) }
|
||||
@State private var syncState: SyncPillState = .notConfigured
|
||||
@State private var syncColor: Color = .secondary
|
||||
@State private var syncLabel: String = "Sync"
|
||||
@State private var tooltipText: String = ""
|
||||
|
||||
private var syncLabel: LocalizedStringKey {
|
||||
switch syncState {
|
||||
case .notConfigured: return "Sync"
|
||||
case .syncing: return "Syncing"
|
||||
case .error: return "Error"
|
||||
case .synced: return "Synced"
|
||||
}
|
||||
}
|
||||
|
||||
private var tooltipText: LocalizedStringKey {
|
||||
switch syncState {
|
||||
case .notConfigured: return "Sync not configured"
|
||||
case .syncing: return "Syncing..."
|
||||
case .error(let msg): return "Sync failed: \(msg)"
|
||||
case .synced(let date):
|
||||
guard let date else { return "Synced" }
|
||||
let rel = RelativeDateTimeFormatter().localizedString(for: date, relativeTo: .now)
|
||||
return "Last synced: \(rel)"
|
||||
}
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
HStack(spacing: 3) {
|
||||
@@ -227,58 +249,21 @@ struct SyncStatusPill: View {
|
||||
.padding(.vertical, 2)
|
||||
.background(syncColor.opacity(0.1), in: Capsule())
|
||||
.help(tooltipText)
|
||||
.onAppear {
|
||||
updateState()
|
||||
}
|
||||
.onChange(of: gitSync.syncStatus) {
|
||||
updateState()
|
||||
}
|
||||
.onChange(of: gitSync.isSyncing) {
|
||||
updateState()
|
||||
}
|
||||
.onChange(of: gitSync.lastSyncError) {
|
||||
updateState()
|
||||
}
|
||||
.onAppear { updateState() }
|
||||
.onChange(of: gitSync.syncStatus) { updateState() }
|
||||
.onChange(of: gitSync.isSyncing) { updateState() }
|
||||
.onChange(of: gitSync.lastSyncError) { updateState() }
|
||||
}
|
||||
|
||||
private func updateState() {
|
||||
// Determine sync state
|
||||
if let error = gitSync.lastSyncError {
|
||||
syncColor = .red
|
||||
syncLabel = "Error"
|
||||
tooltipText = "Sync failed: \(error)"
|
||||
syncState = .error(error); syncColor = .red
|
||||
} else if gitSync.isSyncing {
|
||||
syncColor = .orange
|
||||
syncLabel = "Syncing"
|
||||
tooltipText = "Syncing..."
|
||||
syncState = .syncing; syncColor = .orange
|
||||
} else if gitSync.syncStatus.isCloned {
|
||||
syncColor = .green
|
||||
syncLabel = "Synced"
|
||||
if let lastSync = gitSync.syncStatus.lastSyncTime {
|
||||
tooltipText = "Last synced: \(timeAgo(lastSync))"
|
||||
} else {
|
||||
tooltipText = "Synced"
|
||||
}
|
||||
syncState = .synced(gitSync.syncStatus.lastSyncTime); syncColor = .green
|
||||
} else {
|
||||
syncColor = .secondary
|
||||
syncLabel = "Sync"
|
||||
tooltipText = "Sync not configured"
|
||||
}
|
||||
}
|
||||
|
||||
private func timeAgo(_ date: Date) -> String {
|
||||
let seconds = Int(Date().timeIntervalSince(date))
|
||||
if seconds < 60 {
|
||||
return "just now"
|
||||
} else if seconds < 3600 {
|
||||
let minutes = seconds / 60
|
||||
return "\(minutes)m ago"
|
||||
} else if seconds < 86400 {
|
||||
let hours = seconds / 3600
|
||||
return "\(hours)h ago"
|
||||
} else {
|
||||
let days = seconds / 86400
|
||||
return "\(days)d ago"
|
||||
syncState = .notConfigured; syncColor = .secondary
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user