737201e0d65b
auto-retry failed thumbnail loads with backoff instead of manual Retry button
- time
- 2026-07-15 22:27 UTC · 3 months ago
- machine
- koh2
- agent
- claude-opus-4
- session
- haven cleanup
- parent
- 7b7a808a210c
↓ haven-737201e0.tar.gzatlas at this save
files changed1 file
Sources/Haven/UI/Views/Components/WallpaperItem.swift+23 −15Sources/Haven/UI/Views/Components/WallpaperItem.swift+23 −15
@@ -5,8 +5,13 @@55 let action: () -> Void66 @ObservedObject var favoritesManager = FavoritesManager.shared77 @State private var retryID = UUID()8+ @State private var attempt = 089 @State private var isHovering = false9- 10+11+ // Transient thumbnail failures (flaky network) are common; retry a few12+ // times with growing backoff before giving up quietly.13+ private let maxAttempts = 414+1015 var body: some View {1116 Button(action: action) {1217 AsyncImage(url: URL(string: wallpaper.thumbs.small)) { phase in@@ -20,20 +25,23 @@2025 .resizable()2126 .aspectRatio(contentMode: .fill)2227 case .failure:23- Button {24- retryID = UUID()25- } label: {26- Rectangle()27- .fill(Color.red.opacity(0.1))28- .overlay(29- VStack {30- Image(systemName: "exclamationmark.triangle")31- Text("Retry")32- .font(.caption)33- }34- )35- }36- .buttonStyle(.plain)28+ Rectangle()29+ .fill(Color.gray.opacity(0.2))30+ .overlay(31+ attempt < maxAttempts32+ ? AnyView(ProgressView())33+ : AnyView(Image(systemName: "photo")34+ .foregroundColor(.gray.opacity(0.6)))35+ )36+ .task {37+ guard attempt < maxAttempts else { return }38+ // 0.8s, 1.6s, 2.4s, 3.2s39+ let delay = UInt64(attempt + 1) * 800_000_00040+ try? await Task.sleep(nanoseconds: delay)41+ guard !Task.isCancelled else { return }42+ attempt += 143+ retryID = UUID()44+ }3745 @unknown default:3846 EmptyView()3947 }