Change TrendingLinkCardCollectionViewCell to use CachedImageView

This commit is contained in:
Shadowfacts 2023-01-22 18:07:16 -05:00
parent 3262fe002b
commit 2958d2b1ac
3 changed files with 45 additions and 48 deletions

View File

@ -8,14 +8,13 @@
import UIKit
import Pachyderm
import WebURLFoundationExtras
class TrendingLinkCardCollectionViewCell: UICollectionViewCell {
private var card: Card?
private var isGrayscale = false
private var thumbnailRequest: ImageCache.Request?
@IBOutlet weak var thumbnailView: UIImageView!
@IBOutlet weak var thumbnailView: CachedImageView!
@IBOutlet weak var titleLabel: UILabel!
@IBOutlet weak var descriptionLabel: UILabel!
@IBOutlet weak var providerLabel: UILabel!
@ -27,14 +26,14 @@ class TrendingLinkCardCollectionViewCell: UICollectionViewCell {
override func awakeFromNib() {
super.awakeFromNib()
thumbnailView.cache = .attachments
layer.shadowOpacity = 0.2
layer.shadowRadius = 8
layer.shadowOffset = .zero
layer.masksToBounds = false
updateLayerColors()
NotificationCenter.default.addObserver(self, selector: #selector(updateUIForPreferences), name: .preferencesChanged, object: nil)
addGestureRecognizer(UIHoverGestureRecognizer(target: self, action: #selector(hoverRecognized)))
}
@ -48,8 +47,7 @@ class TrendingLinkCardCollectionViewCell: UICollectionViewCell {
self.card = card
self.thumbnailView.image = nil
updateGrayscaleableUI(card: card)
updateUIForPreferences()
thumbnailView.update(for: card.image.flatMap { URL($0) }, blurhash: card.blurhash)
let title = card.title.trimmingCharacters(in: .whitespacesAndNewlines)
titleLabel.text = title
@ -77,33 +75,6 @@ class TrendingLinkCardCollectionViewCell: UICollectionViewCell {
historyView.isHidden = card.history == nil || card.history!.count < 2
}
@objc private func updateUIForPreferences() {
if isGrayscale != Preferences.shared.grayscaleImages,
let card {
updateGrayscaleableUI(card: card)
}
}
private func updateGrayscaleableUI(card: Card) {
isGrayscale = Preferences.shared.grayscaleImages
if let imageURL = card.image,
let url = URL(imageURL) {
thumbnailRequest = ImageCache.attachments.get(url, completion: { _, image in
guard let image,
let transformedImage = ImageGrayscalifier.convertIfNecessary(url: url, image: image) else {
return
}
DispatchQueue.main.async {
self.thumbnailView.image = transformedImage
}
})
if thumbnailRequest != nil {
loadBlurHash(card: card)
}
}
}
private func loadBlurHash(card: Card) {
guard let hash = card.blurhash else {
return

View File

@ -18,7 +18,7 @@
<rect key="frame" x="0.0" y="0.0" width="300" height="406"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="h3b-Mf-lD6">
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="h3b-Mf-lD6" customClass="CachedImageView" customModule="Tusker" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="300" height="225"/>
<constraints>
<constraint firstAttribute="width" secondItem="h3b-Mf-lD6" secondAttribute="height" multiplier="4:3" id="QDY-8a-LYC"/>
@ -56,9 +56,9 @@
</constraints>
</view>
<visualEffectView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="cWo-9n-z42">
<rect key="frame" x="0.0" y="196.33333333333334" width="300" height="28.666666666666657"/>
<rect key="frame" x="0.0" y="196.66666666666666" width="300" height="28.333333333333343"/>
<view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" insetsLayoutMarginsFromSafeArea="NO" id="ktv-3s-cp9">
<rect key="frame" x="0.0" y="0.0" width="300" height="29"/>
<rect key="frame" x="0.0" y="0.0" width="300" height="28"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Title" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="2" baselineAdjustment="alignBaselines" adjustsLetterSpacingToFitWidth="YES" showsExpansionTextWhenTruncated="YES" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Ho3-cU-IGi">

View File

@ -10,26 +10,32 @@ import UIKit
class CachedImageView: UIImageView {
private let cache: ImageCache
var cache: ImageCache!
private var url: URL?
private var isGrayscale = false
private var fetchTask: Task<Void, Error>?
private var blurHashTask: DispatchWorkItem?
init(cache: ImageCache) {
self.cache = cache
super.init(frame: .zero)
NotificationCenter.default.addObserver(self, selector: #selector(preferencesChanged), name: .preferencesChanged, object: nil)
commonInit()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
super.init(coder: coder)
commonInit()
}
func update(for url: URL?) {
if url != self.url {
private func commonInit() {
NotificationCenter.default.addObserver(self, selector: #selector(preferencesChanged), name: .preferencesChanged, object: nil)
}
func update(for url: URL?, blurhash: String? = nil) {
if url != self.url || (url != nil && self.image == nil) {
self.url = url
self.image = nil
updateBlurhash(blurhash, for: url)
updateImage()
}
}
@ -40,13 +46,32 @@ class CachedImageView: UIImageView {
}
}
private func updateBlurhash(_ blurhash: String?, for url: URL?) {
blurHashTask?.cancel()
if let blurhash {
let aspectRatio = self.bounds.width > 0 ? self.bounds.height / self.bounds.width : 1
blurHashTask = DispatchWorkItem {
let size = CGSize(width: 60, height: aspectRatio * 60)
let image = UIImage(blurHash: blurhash, size: size)
DispatchQueue.main.async {
if self.image == nil && self.url == url && self.blurHashTask?.isCancelled == false {
self.image = image
}
}
}
AttachmentView.queue.async(execute: blurHashTask!)
}
}
private func updateImage() {
fetchTask?.cancel()
fetchTask = Task(priority: .high) {
self.image = nil
guard let url else {
return
}
fetchTask = Task(priority: .high) {
let (_, image) = await cache.get(url)
guard let image else {
return
@ -59,6 +84,7 @@ class CachedImageView: UIImageView {
try Task.checkCancellation()
self.image = transformedImage
self.isGrayscale = Preferences.shared.grayscaleImages
self.blurHashTask?.cancel()
}
}