Skip to main content

Blink/Views/FocusedImage/LoadingIndicatorOverlay.swift

1import SwiftUI
2import Photos
4/// Renders a progress indicator if we're waiting for the image to load.
5///
6/// This is for when Photos is taking a while to load the high-quality version
7/// of a photo; see the comment on `PHAssetImage`.
8struct LoadingIndicatorOverlay: ViewModifier {
9 let isLoading: Bool
11 func body(content: Content) -> some View {
12 if (isLoading) {
13 content.overlay(alignment: Alignment(horizontal: .trailing, vertical: .bottom)) {
15 // `ProgressView` does have a `tint` modifier, but that doesn't seem to
16 // work on macOS 13 -- this uses some code from a Stack Overflow answer
17 // by aheze: https://stackoverflow.com/a/66568704/1558022
18 ProgressView()
19 .colorInvert()
20 .brightness(1)
21 .padding()
22 .deferredRendering(
23 // Note: even if the image is already cached locally, the
24 // image caching manager typically sends two images: a low-res
25 // version comes immediately, then a higher-res version within
26 // a second or two. This causes the progress indicator to
27 // "flash" -- it appears then almost instantly disappears.
28 //
29 // Deferring the rendering slightly avoids this "flash".
30 for: .milliseconds(100)
31 )
32 }
33 } else {
34 content
35 }
36 }
39extension View {
40 func loadingIndicator(isLoading: Bool) -> some View {
41 modifier(LoadingIndicatorOverlay(isLoading: isLoading))
42 }