Fix update on LoadableImage (#973)

* Refactor LoadableImage

* Cleanup
This commit is contained in:
Alfonso Grillo 2023-05-29 12:53:23 +02:00 committed by GitHub
parent 909b8eed7e
commit 1c07f6f86c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 40 additions and 12 deletions

View File

@ -53,9 +53,6 @@ struct LoadableAvatarImage: View {
} placeholder: {
PlaceholderAvatarImage(name: name, contentID: contentID)
}
// Binds the lifecycle of the LoadableImage to the associated URL.
// This fixes the problem of the cache returning old values after a change in the URL.
.id(url)
} else {
PlaceholderAvatarImage(name: name, contentID: contentID)
}

View File

@ -17,17 +17,14 @@
import Kingfisher
import SwiftUI
struct LoadableImage<TransformerView: View, PlaceholderView: View>: View, ImageDataProvider {
struct LoadableImage<TransformerView: View, PlaceholderView: View>: View {
private let mediaSource: MediaSourceProxy
private let blurhash: String?
private let size: CGSize?
private let imageProvider: ImageProviderProtocol?
private var transformer: (AnyView) -> TransformerView
private let transformer: (AnyView) -> TransformerView
private let placeholder: () -> PlaceholderView
@StateObject private var contentLoader: ContentLoader
/// A SwiftUI view that automatically fetches images
/// It will try fetching the image from in-memory cache and if that's not available
/// it will fire a task to load it through the image provider
@ -46,11 +43,8 @@ struct LoadableImage<TransformerView: View, PlaceholderView: View>: View, ImageD
self.blurhash = blurhash
self.size = size
self.imageProvider = imageProvider
self.transformer = transformer
self.placeholder = placeholder
_contentLoader = StateObject(wrappedValue: ContentLoader(mediaSource: mediaSource, size: size, imageProvider: imageProvider))
}
init(url: URL,
@ -67,9 +61,46 @@ struct LoadableImage<TransformerView: View, PlaceholderView: View>: View, ImageD
placeholder: placeholder)
}
var body: some View {
LoadableImageContent(mediaSource: mediaSource,
blurhash: blurhash,
size: size,
imageProvider: imageProvider,
transformer: transformer,
placeholder: placeholder)
// Binds the lifecycle of the LoadableImage to the associated URL.
// This fixes the problem of the cache returning old values after a change in the URL.
.id(mediaSource.url)
}
}
private struct LoadableImageContent<TransformerView: View, PlaceholderView: View>: View, ImageDataProvider {
private let mediaSource: MediaSourceProxy
private let blurhash: String?
private let size: CGSize?
private let imageProvider: ImageProviderProtocol?
private let transformer: (AnyView) -> TransformerView
private let placeholder: () -> PlaceholderView
@StateObject private var contentLoader: ContentLoader
init(mediaSource: MediaSourceProxy,
blurhash: String? = nil,
size: CGSize? = nil,
imageProvider: ImageProviderProtocol?,
transformer: @escaping (AnyView) -> TransformerView,
placeholder: @escaping () -> PlaceholderView) {
self.mediaSource = mediaSource
self.blurhash = blurhash
self.size = size
self.imageProvider = imageProvider
self.transformer = transformer
self.placeholder = placeholder
_contentLoader = StateObject(wrappedValue: ContentLoader(mediaSource: mediaSource, size: size, imageProvider: imageProvider))
}
var body: some View {
let _ = Task {
// Future improvement: Does guarding against a nil image prevent the image being updated when the URL changes?
guard contentLoader.content == nil else {
return
}