From 1c07f6f86c022f3cb71f1de9429f0f0db6fae53b Mon Sep 17 00:00:00 2001 From: Alfonso Grillo Date: Mon, 29 May 2023 12:53:23 +0200 Subject: [PATCH] Fix update on LoadableImage (#973) * Refactor LoadableImage * Cleanup --- .../SwiftUI/Views/LoadableAvatarImage.swift | 3 -- .../Other/SwiftUI/Views/LoadableImage.swift | 49 +++++++++++++++---- 2 files changed, 40 insertions(+), 12 deletions(-) diff --git a/ElementX/Sources/Other/SwiftUI/Views/LoadableAvatarImage.swift b/ElementX/Sources/Other/SwiftUI/Views/LoadableAvatarImage.swift index b94780f9b..f8e56c5bd 100644 --- a/ElementX/Sources/Other/SwiftUI/Views/LoadableAvatarImage.swift +++ b/ElementX/Sources/Other/SwiftUI/Views/LoadableAvatarImage.swift @@ -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) } diff --git a/ElementX/Sources/Other/SwiftUI/Views/LoadableImage.swift b/ElementX/Sources/Other/SwiftUI/Views/LoadableImage.swift index 3fdf8713b..31439cb57 100644 --- a/ElementX/Sources/Other/SwiftUI/Views/LoadableImage.swift +++ b/ElementX/Sources/Other/SwiftUI/Views/LoadableImage.swift @@ -17,17 +17,14 @@ import Kingfisher import SwiftUI -struct LoadableImage: View, ImageDataProvider { +struct LoadableImage: 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: 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: 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: 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 }