forked from shadowfacts/Tusker
Change TrendingLinkCardCollectionViewCell to use CachedImageView
This commit is contained in:
parent
3262fe002b
commit
2958d2b1ac
|
@ -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
|
||||
|
|
|
@ -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">
|
||||
|
|
|
@ -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()
|
||||
|
||||
guard let url else {
|
||||
return
|
||||
}
|
||||
|
||||
fetchTask = Task(priority: .high) {
|
||||
self.image = nil
|
||||
guard let url else {
|
||||
return
|
||||
}
|
||||
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()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue