From 63bc5b7c8ea641022c4578f53d081b7a68432db0 Mon Sep 17 00:00:00 2001 From: kean Date: Mon, 30 Dec 2024 16:01:53 -0500 Subject: [PATCH 1/2] Add ImageRequest support in AsyncImageView --- .../WordPressMedia/ImageDownloader.swift | 6 +++++ .../Utility/Media/AsyncImageView.swift | 10 ++++++--- .../Media/ImageLoadingController.swift | 22 ++++--------------- .../Media/UIImageView+ImageDownloader.swift | 13 +++++------ .../LightboxImagePageViewController.swift | 3 ++- .../Views/ReaderDetailFeaturedImageView.swift | 2 +- .../Views/WPRichText/WPRichTextImage.swift | 2 +- .../DashboardCustomAnnouncementCell.swift | 3 ++- 8 files changed, 29 insertions(+), 32 deletions(-) diff --git a/Modules/Sources/WordPressMedia/ImageDownloader.swift b/Modules/Sources/WordPressMedia/ImageDownloader.swift index 08e6b907bd43..384aac235b76 100644 --- a/Modules/Sources/WordPressMedia/ImageDownloader.swift +++ b/Modules/Sources/WordPressMedia/ImageDownloader.swift @@ -69,6 +69,12 @@ public final class ImageDownloader { // MARK: - Caching + /// Returns an image from the memory cache. + nonisolated public func cachedImage(for request: ImageRequest) -> UIImage? { + guard let imageURL = request.source.url else { return nil } + return cachedImage(for: imageURL, size: request.options.size) + } + /// Returns an image from the memory cache. /// /// - note: Use it to retrieve the image synchronously, which is no not possible diff --git a/WordPress/Classes/Utility/Media/AsyncImageView.swift b/WordPress/Classes/Utility/Media/AsyncImageView.swift index 5f071c43ae31..16b0b48df0a9 100644 --- a/WordPress/Classes/Utility/Media/AsyncImageView.swift +++ b/WordPress/Classes/Utility/Media/AsyncImageView.swift @@ -84,10 +84,14 @@ final class AsyncImageView: UIView { func setImage( with imageURL: URL, host: MediaHost? = nil, - size: CGSize? = nil, - completion: (@MainActor (Result) -> Void)? = nil + size: CGSize? = nil ) { - controller.setImage(with: imageURL, host: host, size: size, completion: completion) + let request = ImageRequest(url: imageURL, host: host, options: ImageRequestOptions(size: size)) + controller.setImage(with: request) + } + + func setImage(with request: ImageRequest, completion: (@MainActor (Result) -> Void)? = nil) { + controller.setImage(with: request, completion: completion) } private func setState(_ state: ImageLoadingController.State) { diff --git a/WordPress/Classes/Utility/Media/ImageLoadingController.swift b/WordPress/Classes/Utility/Media/ImageLoadingController.swift index a1e0a2c41933..1611a2c2aed1 100644 --- a/WordPress/Classes/Utility/Media/ImageLoadingController.swift +++ b/WordPress/Classes/Utility/Media/ImageLoadingController.swift @@ -27,28 +27,17 @@ final class ImageLoadingController { } /// - parameter completion: Gets called on completion _after_ `onStateChanged`. - func setImage( - with imageURL: URL, - host: MediaHost? = nil, - size: CGSize? = nil, - completion: (@MainActor (Result) -> Void)? = nil - ) { + func setImage(with request: ImageRequest, completion: (@MainActor (Result) -> Void)? = nil) { task?.cancel() - if let image = downloader.cachedImage(for: imageURL, size: size) { + if let image = downloader.cachedImage(for: request) { onStateChanged(.success(image)) completion?(.success(image)) } else { onStateChanged(.loading) task = Task { @MainActor [downloader, weak self] in do { - let options = ImageRequestOptions(size: size) - let image: UIImage - if let host { - image = try await downloader.image(from: imageURL, host: host, options: options) - } else { - image = try await downloader.image(from: imageURL, options: options) - } + let image = try await downloader.image(for: request) // This line guarantees that if you cancel on the main thread, // none of the `onStateChanged` callbacks get called. guard !Task.isCancelled else { return } @@ -63,10 +52,7 @@ final class ImageLoadingController { } } - func setImage( - with media: Media, - size: MediaImageService.ImageSize - ) { + func setImage(with media: Media, size: MediaImageService.ImageSize) { task?.cancel() if let image = service.getCachedThumbnail(for: .init(media), size: size) { diff --git a/WordPress/Classes/Utility/Media/UIImageView+ImageDownloader.swift b/WordPress/Classes/Utility/Media/UIImageView+ImageDownloader.swift index 45ab051e78ab..bed820a60d8f 100644 --- a/WordPress/Classes/Utility/Media/UIImageView+ImageDownloader.swift +++ b/WordPress/Classes/Utility/Media/UIImageView+ImageDownloader.swift @@ -22,13 +22,12 @@ struct ImageViewExtensions { } } - func setImage( - with imageURL: URL, - host: MediaHost? = nil, - size: CGSize? = nil, - completion: (@MainActor (Result) -> Void)? = nil - ) { - controller.setImage(with: imageURL, host: host, size: size, completion: completion) + func setImage(with imageURL: URL, host: MediaHost? = nil, size: CGSize? = nil) { + setImage(with: ImageRequest(url: imageURL, host: host, options: ImageRequestOptions(size: size))) + } + + func setImage(with request: ImageRequest, completion: (@MainActor (Result) -> Void)? = nil) { + controller.setImage(with: request, completion: completion) } var controller: ImageLoadingController { diff --git a/WordPress/Classes/ViewRelated/Media/Lightbox/LightboxImagePageViewController.swift b/WordPress/Classes/ViewRelated/Media/Lightbox/LightboxImagePageViewController.swift index f18934f37aac..fdc0ae966234 100644 --- a/WordPress/Classes/ViewRelated/Media/Lightbox/LightboxImagePageViewController.swift +++ b/WordPress/Classes/ViewRelated/Media/Lightbox/LightboxImagePageViewController.swift @@ -1,5 +1,6 @@ import UIKit import WordPressUI +import WordPressMedia final class LightboxImagePageViewController: UIViewController { private(set) var scrollView = LightboxImageScrollView() @@ -51,7 +52,7 @@ final class LightboxImagePageViewController: UIViewController { case .image(let image): setState(.success(image)) case .asset(let asset): - controller.setImage(with: asset.sourceURL, host: asset.host) + controller.setImage(with: ImageRequest(url: asset.sourceURL, host: asset.host)) case .media(let media): controller.setImage(with: media, size: .original) } diff --git a/WordPress/Classes/ViewRelated/Reader/Detail/Views/ReaderDetailFeaturedImageView.swift b/WordPress/Classes/ViewRelated/Reader/Detail/Views/ReaderDetailFeaturedImageView.swift index 063a836debc5..6c5242a6c3de 100644 --- a/WordPress/Classes/ViewRelated/Reader/Detail/Views/ReaderDetailFeaturedImageView.swift +++ b/WordPress/Classes/ViewRelated/Reader/Detail/Views/ReaderDetailFeaturedImageView.swift @@ -223,7 +223,7 @@ class ReaderDetailFeaturedImageView: UIView, NibLoadable { completionHandler(CGSize(width: 1000, height: 1000 * ReaderPostCell.coverAspectRatio)) } - imageView.setImage(with: imageURL, host: MediaHost(post)) { [weak self] result in + imageView.setImage(with: ImageRequest(url: imageURL, host: MediaHost(post))) { [weak self] result in guard let self else { return } switch result { case .success: diff --git a/WordPress/Classes/ViewRelated/Views/WPRichText/WPRichTextImage.swift b/WordPress/Classes/ViewRelated/Views/WPRichText/WPRichTextImage.swift index 3853c08f8701..dd314f896c58 100644 --- a/WordPress/Classes/ViewRelated/Views/WPRichText/WPRichTextImage.swift +++ b/WordPress/Classes/ViewRelated/Views/WPRichText/WPRichTextImage.swift @@ -57,7 +57,7 @@ class WPRichTextImage: UIControl, WPRichTextMediaAttachment { return } - imageView.setImage(with: contentURL, host: host) { result in + imageView.setImage(with: ImageRequest(url: contentURL, host: host)) { result in switch result { case .success: onSuccess?() case .failure(let error): onError?(error) diff --git a/WordPress/Classes/ViewRelated/WhatsNew/Views/DashboardCustomAnnouncementCell.swift b/WordPress/Classes/ViewRelated/WhatsNew/Views/DashboardCustomAnnouncementCell.swift index 63d1832e235d..f3acd56f02cc 100644 --- a/WordPress/Classes/ViewRelated/WhatsNew/Views/DashboardCustomAnnouncementCell.swift +++ b/WordPress/Classes/ViewRelated/WhatsNew/Views/DashboardCustomAnnouncementCell.swift @@ -1,4 +1,5 @@ import UIKit +import WordPressMedia class DashboardCustomAnnouncementCell: AnnouncementTableViewCell { @@ -65,7 +66,7 @@ class DashboardCustomAnnouncementCell: AnnouncementTableViewCell { func configure(feature: WordPressKit.Feature) { if let url = URL(string: feature.iconUrl) { - announcementImageView.wp.setImage(with: url) { [weak self] result in + announcementImageView.wp.setImage(with: ImageRequest(url: url)) { [weak self] result in guard let self, case .success(let image) = result else { return } From 3b036a08813de09368cda97d46011a1c4af396ae Mon Sep 17 00:00:00 2001 From: kean Date: Mon, 30 Dec 2024 16:29:54 -0500 Subject: [PATCH 2/2] Add ImageSize --- .../Sources/WordPressMedia/ImageDecoder.swift | 2 +- .../WordPressMedia/ImageDownloader.swift | 10 ++--- .../Sources/WordPressMedia/ImageRequest.swift | 40 +++++++++++++++++-- .../ImageDownloaderTests.swift | 6 +-- .../Utility/Media/AsyncImageView.swift | 2 +- .../Media/UIImageView+ImageDownloader.swift | 2 +- .../BlazeCampaignTableViewCell.swift | 3 +- .../Blaze/Overlay/BlazePostPreviewView.swift | 5 +-- .../Blaze/DashboardBlazeCampaignView.swift | 3 +- .../ExternalMediaPickerCollectionCell.swift | 3 +- .../ExternalMediaPickerViewController.swift | 3 +- .../Views/NoteBlockHeaderTableViewCell.swift | 3 +- .../Post/Views/PostCompactCell.swift | 2 +- .../Reader/Cards/ReaderCrossPostCell.swift | 4 +- .../Reader/Cards/ReaderPostCell.swift | 11 +++-- .../Reader/Views/ReaderAvatarView.swift | 3 +- .../StatsLatestPostSummaryInsightsCell.swift | 3 +- 17 files changed, 69 insertions(+), 36 deletions(-) diff --git a/Modules/Sources/WordPressMedia/ImageDecoder.swift b/Modules/Sources/WordPressMedia/ImageDecoder.swift index 899bf7fead2a..8e7e8c0b44ef 100644 --- a/Modules/Sources/WordPressMedia/ImageDecoder.swift +++ b/Modules/Sources/WordPressMedia/ImageDecoder.swift @@ -70,7 +70,7 @@ private extension Data { } } -private extension CGSize { +extension CGSize { func scaled(by scale: CGFloat) -> CGSize { CGSize(width: width * scale, height: height * scale) } diff --git a/Modules/Sources/WordPressMedia/ImageDownloader.swift b/Modules/Sources/WordPressMedia/ImageDownloader.swift index 384aac235b76..2076816867b6 100644 --- a/Modules/Sources/WordPressMedia/ImageDownloader.swift +++ b/Modules/Sources/WordPressMedia/ImageDownloader.swift @@ -39,7 +39,7 @@ public final class ImageDownloader { return image } let data = try await data(for: request) - let image = try await ImageDecoder.makeImage(from: data, size: options.size) + let image = try await ImageDecoder.makeImage(from: data, size: options.size.map(CGSize.init)) if options.isMemoryCacheEnabled { cache[key] = image } @@ -79,20 +79,20 @@ public final class ImageDownloader { /// /// - note: Use it to retrieve the image synchronously, which is no not possible /// with the async functions. - nonisolated public func cachedImage(for imageURL: URL, size: CGSize? = nil) -> UIImage? { + nonisolated public func cachedImage(for imageURL: URL, size: ImageSize? = nil) -> UIImage? { cache[makeKey(for: imageURL, size: size)] } - nonisolated public func setCachedImage(_ image: UIImage?, for imageURL: URL, size: CGSize? = nil) { + nonisolated public func setCachedImage(_ image: UIImage?, for imageURL: URL, size: ImageSize? = nil) { cache[makeKey(for: imageURL, size: size)] = image } - private nonisolated func makeKey(for imageURL: URL?, size: CGSize?) -> String { + private nonisolated func makeKey(for imageURL: URL?, size: ImageSize?) -> String { guard let imageURL else { assertionFailure("The request.url was nil") // This should never happen return "" } - return imageURL.absoluteString + (size.map { "?size=\($0)" } ?? "") + return imageURL.absoluteString + (size.map { "?w=\($0.width),h=\($0.height)" } ?? "") } public func clearURLSessionCache() { diff --git a/Modules/Sources/WordPressMedia/ImageRequest.swift b/Modules/Sources/WordPressMedia/ImageRequest.swift index e5c811381183..0c299c489bba 100644 --- a/Modules/Sources/WordPressMedia/ImageRequest.swift +++ b/Modules/Sources/WordPressMedia/ImageRequest.swift @@ -28,8 +28,8 @@ public final class ImageRequest: Sendable { } public struct ImageRequestOptions: Hashable, Sendable { - /// Resize the thumbnail to the given size (in pixels). By default, `nil`. - public var size: CGSize? + /// Resize the thumbnail to the given size. By default, `nil`. + public var size: ImageSize? /// If enabled, uses ``MemoryCache`` for caching decompressed images. public var isMemoryCacheEnabled = true @@ -39,7 +39,7 @@ public struct ImageRequestOptions: Hashable, Sendable { public var isDiskCacheEnabled = true public init( - size: CGSize? = nil, + size: ImageSize? = nil, isMemoryCacheEnabled: Bool = true, isDiskCacheEnabled: Bool = true ) { @@ -48,3 +48,37 @@ public struct ImageRequestOptions: Hashable, Sendable { self.isDiskCacheEnabled = isDiskCacheEnabled } } + +/// Image size in **pixels**. +public struct ImageSize: Hashable, Sendable { + public let width: CGFloat + public let height: CGFloat + + public init(width: CGFloat, height: CGFloat) { + self.width = width + self.height = height + } + + public init(_ size: CGSize) { + self.width = size.width + self.height = size.height + } + + /// Initializes `ImageSize` with the given size scaled for the given view. + @MainActor + public init(scaling size: CGSize, in view: UIView) { + self.init(size.scaled(by: view.traitCollection.displayScale)) + } + + /// Initializes `ImageSize` with the given size scaled for the current trait + /// collection display scale. + public init(scaling size: CGSize) { + self.init(size.scaled(by: UITraitCollection.current.displayScale)) + } +} + +extension CGSize { + init(_ size: ImageSize) { + self.init(width: size.width, height: size.height) + } +} diff --git a/Modules/Tests/WordPressMediaTests/ImageDownloaderTests.swift b/Modules/Tests/WordPressMediaTests/ImageDownloaderTests.swift index 00e9f4c33f86..f661075ddfb4 100644 --- a/Modules/Tests/WordPressMediaTests/ImageDownloaderTests.swift +++ b/Modules/Tests/WordPressMediaTests/ImageDownloaderTests.swift @@ -27,7 +27,7 @@ import OHHTTPStubsSwift // WHEN let options = ImageRequestOptions( - size: CGSize(width: 256, height: 256), + size: ImageSize(width: 256, height: 256), isMemoryCacheEnabled: false, isDiskCacheEnabled: false ) @@ -46,7 +46,7 @@ import OHHTTPStubsSwift // WHEN let options = ImageRequestOptions( - size: CGSize(width: 256, height: 256), + size: ImageSize(width: 256, height: 256), isMemoryCacheEnabled: false, isDiskCacheEnabled: false ) @@ -72,7 +72,7 @@ import OHHTTPStubsSwift let imageURL = try #require(URL(string: "https://example.files.wordpress.com/2023/09/image.jpg")) try mockResponse(withResource: "test-image", fileExtension: "jpg") - let size = CGSize(width: 256, height: 256) + let size = ImageSize(width: 256, height: 256) let options = ImageRequestOptions( size: size, isMemoryCacheEnabled: true, diff --git a/WordPress/Classes/Utility/Media/AsyncImageView.swift b/WordPress/Classes/Utility/Media/AsyncImageView.swift index 16b0b48df0a9..b094ea94f3fc 100644 --- a/WordPress/Classes/Utility/Media/AsyncImageView.swift +++ b/WordPress/Classes/Utility/Media/AsyncImageView.swift @@ -84,7 +84,7 @@ final class AsyncImageView: UIView { func setImage( with imageURL: URL, host: MediaHost? = nil, - size: CGSize? = nil + size: ImageSize? = nil ) { let request = ImageRequest(url: imageURL, host: host, options: ImageRequestOptions(size: size)) controller.setImage(with: request) diff --git a/WordPress/Classes/Utility/Media/UIImageView+ImageDownloader.swift b/WordPress/Classes/Utility/Media/UIImageView+ImageDownloader.swift index bed820a60d8f..92d5c0619831 100644 --- a/WordPress/Classes/Utility/Media/UIImageView+ImageDownloader.swift +++ b/WordPress/Classes/Utility/Media/UIImageView+ImageDownloader.swift @@ -22,7 +22,7 @@ struct ImageViewExtensions { } } - func setImage(with imageURL: URL, host: MediaHost? = nil, size: CGSize? = nil) { + func setImage(with imageURL: URL, host: MediaHost? = nil, size: ImageSize? = nil) { setImage(with: ImageRequest(url: imageURL, host: host, options: ImageRequestOptions(size: size))) } diff --git a/WordPress/Classes/ViewRelated/Blaze Campaigns/BlazeCampaignTableViewCell.swift b/WordPress/Classes/ViewRelated/Blaze Campaigns/BlazeCampaignTableViewCell.swift index 10d4b6b32a2b..6976b2e9ba62 100644 --- a/WordPress/Classes/ViewRelated/Blaze Campaigns/BlazeCampaignTableViewCell.swift +++ b/WordPress/Classes/ViewRelated/Blaze Campaigns/BlazeCampaignTableViewCell.swift @@ -110,8 +110,7 @@ final class BlazeCampaignTableViewCell: UITableViewCell, Reusable { let host = MediaHost(with: blog, failure: { error in WordPressAppDelegate.crashLogging?.logError(error) }) - let preferredSize = CGSize(width: Metrics.featuredImageSize, height: Metrics.featuredImageSize) - .scaled(by: UITraitCollection.current.displayScale) + let preferredSize = ImageSize(scaling: CGSize(width: Metrics.featuredImageSize, height: Metrics.featuredImageSize), in: self) featuredImageView.setImage(with: imageURL, host: host, size: preferredSize) } diff --git a/WordPress/Classes/ViewRelated/Blaze/Overlay/BlazePostPreviewView.swift b/WordPress/Classes/ViewRelated/Blaze/Overlay/BlazePostPreviewView.swift index c84e478be3a7..3f58ab5c5c3d 100644 --- a/WordPress/Classes/ViewRelated/Blaze/Overlay/BlazePostPreviewView.swift +++ b/WordPress/Classes/ViewRelated/Blaze/Overlay/BlazePostPreviewView.swift @@ -96,9 +96,8 @@ final class BlazePostPreviewView: UIView { if let url = post.featuredImageURL { featuredImageView.isHidden = false - let preferredSize = CGSize(width: featuredImageView.frame.width, height: featuredImageView.frame.height) - .scaled(by: UITraitCollection.current.displayScale) - featuredImageView.setImage(with: url, host: MediaHost(post), size: preferredSize) + let targetSize = ImageSize(scaling: featuredImageView.frame.size, in: self) + featuredImageView.setImage(with: url, host: MediaHost(post), size: targetSize) } else { featuredImageView.isHidden = true diff --git a/WordPress/Classes/ViewRelated/Blog/Blog Dashboard/Cards/Blaze/DashboardBlazeCampaignView.swift b/WordPress/Classes/ViewRelated/Blog/Blog Dashboard/Cards/Blaze/DashboardBlazeCampaignView.swift index 39c61d3e232d..0fc0c6d7163a 100644 --- a/WordPress/Classes/ViewRelated/Blog/Blog Dashboard/Cards/Blaze/DashboardBlazeCampaignView.swift +++ b/WordPress/Classes/ViewRelated/Blog/Blog Dashboard/Cards/Blaze/DashboardBlazeCampaignView.swift @@ -64,8 +64,7 @@ final class DashboardBlazeCampaignView: UIView { let host = MediaHost(with: blog, failure: { error in WordPressAppDelegate.crashLogging?.logError(error) }) - let targetSize = Constants.imageSize - .scaled(by: UITraitCollection.current.displayScale) + let targetSize = ImageSize(scaling: Constants.imageSize, in: self) imageView.setImage(with: imageURL, host: host, size: targetSize) } diff --git a/WordPress/Classes/ViewRelated/Media/External/ExternalMediaPickerCollectionCell.swift b/WordPress/Classes/ViewRelated/Media/External/ExternalMediaPickerCollectionCell.swift index 2a50aeb6b2f3..4d80e39286f1 100644 --- a/WordPress/Classes/ViewRelated/Media/External/ExternalMediaPickerCollectionCell.swift +++ b/WordPress/Classes/ViewRelated/Media/External/ExternalMediaPickerCollectionCell.swift @@ -1,4 +1,5 @@ import UIKit +import WordPressMedia final class ExternalMediaPickerCollectionCell: UICollectionViewCell { private let imageView = AsyncImageView() @@ -22,7 +23,7 @@ final class ExternalMediaPickerCollectionCell: UICollectionViewCell { imageView.prepareForReuse() } - func configure(imageURL: URL, size: CGSize) { + func configure(imageURL: URL, size: ImageSize) { imageView.setImage(with: imageURL, size: size) } diff --git a/WordPress/Classes/ViewRelated/Media/External/ExternalMediaPickerViewController.swift b/WordPress/Classes/ViewRelated/Media/External/ExternalMediaPickerViewController.swift index 62ad231900e3..729b59ba52ca 100644 --- a/WordPress/Classes/ViewRelated/Media/External/ExternalMediaPickerViewController.swift +++ b/WordPress/Classes/ViewRelated/Media/External/ExternalMediaPickerViewController.swift @@ -1,4 +1,5 @@ import UIKit +import WordPressMedia protocol ExternalMediaPickerViewDelegate: AnyObject { /// If the user cancels the flow, the selection is empty. @@ -235,7 +236,7 @@ final class ExternalMediaPickerViewController: UIViewController, UICollectionVie func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: Self.cellReuseID, for: indexPath) as! ExternalMediaPickerCollectionCell let item = dataSource.assets[indexPath.item] - cell.configure(imageURL: item.thumbnailURL, size: flowLayout.itemSize.scaled(by: UIScreen.main.scale)) + cell.configure(imageURL: item.thumbnailURL, size: ImageSize(scaling: flowLayout.itemSize)) return cell } diff --git a/WordPress/Classes/ViewRelated/Notifications/Views/NoteBlockHeaderTableViewCell.swift b/WordPress/Classes/ViewRelated/Notifications/Views/NoteBlockHeaderTableViewCell.swift index acea65a38bf3..0633039f54ba 100644 --- a/WordPress/Classes/ViewRelated/Notifications/Views/NoteBlockHeaderTableViewCell.swift +++ b/WordPress/Classes/ViewRelated/Notifications/Views/NoteBlockHeaderTableViewCell.swift @@ -1,6 +1,7 @@ import Foundation import WordPressShared import WordPressUI +import WordPressMedia import Gravatar // MARK: - NoteBlockHeaderTableViewCell @@ -70,7 +71,7 @@ class NoteBlockHeaderTableViewCell: NoteBlockTableViewCell { if let gravatar = AvatarURL(url: url) { authorAvatarImageView.downloadGravatar(gravatar, placeholder: .gravatarPlaceholderImage, animate: true) } else { - authorAvatarImageView.wp.setImage(with: url, size: SiteIconViewModel.Size.regular.size) + authorAvatarImageView.wp.setImage(with: url, size: ImageSize(scaling: SiteIconViewModel.Size.regular.size)) } } diff --git a/WordPress/Classes/ViewRelated/Post/Views/PostCompactCell.swift b/WordPress/Classes/ViewRelated/Post/Views/PostCompactCell.swift index 0dbfe52398c5..cb84ba4496cc 100644 --- a/WordPress/Classes/ViewRelated/Post/Views/PostCompactCell.swift +++ b/WordPress/Classes/ViewRelated/Post/Views/PostCompactCell.swift @@ -79,7 +79,7 @@ final class PostCompactCell: UITableViewCell, Reusable { featuredImageView.isHidden = false let host = MediaHost(post) - let targetSize = Constants.imageSize.scaled(by: traitCollection.displayScale) + let targetSize = ImageSize(scaling: Constants.imageSize, in: self) featuredImageView.setImage(with: url, host: host, size: targetSize) } else { featuredImageView.isHidden = true diff --git a/WordPress/Classes/ViewRelated/Reader/Cards/ReaderCrossPostCell.swift b/WordPress/Classes/ViewRelated/Reader/Cards/ReaderCrossPostCell.swift index 1f3fa9f6e941..ed69ee523d0c 100644 --- a/WordPress/Classes/ViewRelated/Reader/Cards/ReaderCrossPostCell.swift +++ b/WordPress/Classes/ViewRelated/Reader/Cards/ReaderCrossPostCell.swift @@ -2,6 +2,7 @@ import Foundation import AutomatticTracks import WordPressShared import WordPressUI +import WordPressMedia final class ReaderCrossPostCell: ReaderStreamBaseCell { private let view = ReaderCrossPostView() @@ -132,8 +133,7 @@ private final class ReaderCrossPostView: UIView { avatarView.setPlaceholder(UIImage(named: "post-blavatar-placeholder")) if let avatarURL = post.avatarURLForDisplay() { - let avatarSize = CGSize(width: avatarSize, height: avatarSize) - .scaled(by: UITraitCollection.current.displayScale) + let avatarSize = ImageSize(scaling: CGSize(width: avatarSize, height: avatarSize)) avatarView.setImage(with: avatarURL, size: avatarSize) } } diff --git a/WordPress/Classes/ViewRelated/Reader/Cards/ReaderPostCell.swift b/WordPress/Classes/ViewRelated/Reader/Cards/ReaderPostCell.swift index 844d35587976..29693a544e8d 100644 --- a/WordPress/Classes/ViewRelated/Reader/Cards/ReaderPostCell.swift +++ b/WordPress/Classes/ViewRelated/Reader/Cards/ReaderPostCell.swift @@ -2,6 +2,7 @@ import SwiftUI import UIKit import Combine import WordPressShared +import WordPressMedia final class ReaderPostCell: ReaderStreamBaseCell { private let view = ReaderPostCellView() @@ -51,13 +52,12 @@ final class ReaderPostCell: ReaderStreamBaseCell { super.updateConstraints() } - static func preferredCoverSize(in window: UIWindow, isCompact: Bool) -> CGSize { + static func preferredCoverSize(in window: UIWindow, isCompact: Bool) -> ImageSize { var coverWidth = ReaderPostCell.regularCoverWidth if isCompact { coverWidth = min(window.bounds.width, window.bounds.height) - ReaderStreamBaseCell.insets.left * 2 } - return CGSize(width: coverWidth, height: coverWidth) - .scaled(by: min(2, window.traitCollection.displayScale)) + return ImageSize(scaling: CGSize(width: coverWidth, height: coverWidth), in: window) } } @@ -314,7 +314,7 @@ private final class ReaderPostCellView: UIView { } } - private var preferredCoverSize: CGSize? { + private var preferredCoverSize: ImageSize? { guard let window = window ?? UIApplication.shared.mainWindow else { return nil } return ReaderPostCell.preferredCoverSize(in: window, isCompact: isCompact) } @@ -345,8 +345,7 @@ private final class ReaderPostCellView: UIView { private func setAvatar(with viewModel: ReaderPostCellViewModel) { avatarView.setPlaceholder(UIImage(named: "post-blavatar-placeholder")) - let avatarSize = CGSize(width: ReaderPostCell.avatarSize, height: ReaderPostCell.avatarSize) - .scaled(by: UITraitCollection.current.displayScale) + let avatarSize = ImageSize(scaling: CGSize(width: ReaderPostCell.avatarSize, height: ReaderPostCell.avatarSize)) if let avatarURL = viewModel.avatarURL { avatarView.setImage(with: avatarURL, size: avatarSize) } else { diff --git a/WordPress/Classes/ViewRelated/Reader/Views/ReaderAvatarView.swift b/WordPress/Classes/ViewRelated/Reader/Views/ReaderAvatarView.swift index 7c76771caa4e..87913fe3306a 100644 --- a/WordPress/Classes/ViewRelated/Reader/Views/ReaderAvatarView.swift +++ b/WordPress/Classes/ViewRelated/Reader/Views/ReaderAvatarView.swift @@ -1,4 +1,5 @@ import UIKit +import WordPressMedia final class ReaderAvatarView: UIView { private let asyncImageView = AsyncImageView() @@ -42,7 +43,7 @@ final class ReaderAvatarView: UIView { asyncImageView.image = image } - func setImage(with imageURL: URL, size: CGSize? = nil) { + func setImage(with imageURL: URL, size: ImageSize? = nil) { asyncImageView.setImage(with: imageURL, size: size) } } diff --git a/WordPress/Classes/ViewRelated/Stats/Insights/StatsLatestPostSummaryInsightsCell.swift b/WordPress/Classes/ViewRelated/Stats/Insights/StatsLatestPostSummaryInsightsCell.swift index dfff7c03f493..f07e4b7cad3a 100644 --- a/WordPress/Classes/ViewRelated/Stats/Insights/StatsLatestPostSummaryInsightsCell.swift +++ b/WordPress/Classes/ViewRelated/Stats/Insights/StatsLatestPostSummaryInsightsCell.swift @@ -235,8 +235,7 @@ class StatsLatestPostSummaryInsightsCell: StatsBaseCell, LatestPostSummaryConfig DDLogError("Failed to create media host: \(error.localizedDescription)") }) let targetSize = CGSize(width: Metrics.thumbnailSize, height: Metrics.thumbnailSize) - .scaled(by: traitCollection.displayScale) - postImageView.setImage(with: url, host: host, size: targetSize) + postImageView.setImage(with: url, host: host, size: ImageSize(scaling: targetSize, in: self)) } else { postImageView.isHidden = true }