Change TrendingLinkCardCollectionViewCell to use CachedImageView
This commit is contained in:
parent
3262fe002b
commit
2958d2b1ac
|
@ -8,14 +8,13 @@
|
||||||
|
|
||||||
import UIKit
|
import UIKit
|
||||||
import Pachyderm
|
import Pachyderm
|
||||||
|
import WebURLFoundationExtras
|
||||||
|
|
||||||
class TrendingLinkCardCollectionViewCell: UICollectionViewCell {
|
class TrendingLinkCardCollectionViewCell: UICollectionViewCell {
|
||||||
|
|
||||||
private var card: Card?
|
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 titleLabel: UILabel!
|
||||||
@IBOutlet weak var descriptionLabel: UILabel!
|
@IBOutlet weak var descriptionLabel: UILabel!
|
||||||
@IBOutlet weak var providerLabel: UILabel!
|
@IBOutlet weak var providerLabel: UILabel!
|
||||||
|
@ -27,14 +26,14 @@ class TrendingLinkCardCollectionViewCell: UICollectionViewCell {
|
||||||
override func awakeFromNib() {
|
override func awakeFromNib() {
|
||||||
super.awakeFromNib()
|
super.awakeFromNib()
|
||||||
|
|
||||||
|
thumbnailView.cache = .attachments
|
||||||
|
|
||||||
layer.shadowOpacity = 0.2
|
layer.shadowOpacity = 0.2
|
||||||
layer.shadowRadius = 8
|
layer.shadowRadius = 8
|
||||||
layer.shadowOffset = .zero
|
layer.shadowOffset = .zero
|
||||||
layer.masksToBounds = false
|
layer.masksToBounds = false
|
||||||
updateLayerColors()
|
updateLayerColors()
|
||||||
|
|
||||||
NotificationCenter.default.addObserver(self, selector: #selector(updateUIForPreferences), name: .preferencesChanged, object: nil)
|
|
||||||
|
|
||||||
addGestureRecognizer(UIHoverGestureRecognizer(target: self, action: #selector(hoverRecognized)))
|
addGestureRecognizer(UIHoverGestureRecognizer(target: self, action: #selector(hoverRecognized)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,8 +47,7 @@ class TrendingLinkCardCollectionViewCell: UICollectionViewCell {
|
||||||
self.card = card
|
self.card = card
|
||||||
self.thumbnailView.image = nil
|
self.thumbnailView.image = nil
|
||||||
|
|
||||||
updateGrayscaleableUI(card: card)
|
thumbnailView.update(for: card.image.flatMap { URL($0) }, blurhash: card.blurhash)
|
||||||
updateUIForPreferences()
|
|
||||||
|
|
||||||
let title = card.title.trimmingCharacters(in: .whitespacesAndNewlines)
|
let title = card.title.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||||
titleLabel.text = title
|
titleLabel.text = title
|
||||||
|
@ -77,33 +75,6 @@ class TrendingLinkCardCollectionViewCell: UICollectionViewCell {
|
||||||
historyView.isHidden = card.history == nil || card.history!.count < 2
|
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) {
|
private func loadBlurHash(card: Card) {
|
||||||
guard let hash = card.blurhash else {
|
guard let hash = card.blurhash else {
|
||||||
return
|
return
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
<rect key="frame" x="0.0" y="0.0" width="300" height="406"/>
|
<rect key="frame" x="0.0" y="0.0" width="300" height="406"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<subviews>
|
<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"/>
|
<rect key="frame" x="0.0" y="0.0" width="300" height="225"/>
|
||||||
<constraints>
|
<constraints>
|
||||||
<constraint firstAttribute="width" secondItem="h3b-Mf-lD6" secondAttribute="height" multiplier="4:3" id="QDY-8a-LYC"/>
|
<constraint firstAttribute="width" secondItem="h3b-Mf-lD6" secondAttribute="height" multiplier="4:3" id="QDY-8a-LYC"/>
|
||||||
|
@ -56,9 +56,9 @@
|
||||||
</constraints>
|
</constraints>
|
||||||
</view>
|
</view>
|
||||||
<visualEffectView opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="cWo-9n-z42">
|
<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">
|
<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"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<subviews>
|
<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">
|
<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 {
|
class CachedImageView: UIImageView {
|
||||||
|
|
||||||
private let cache: ImageCache
|
var cache: ImageCache!
|
||||||
private var url: URL?
|
private var url: URL?
|
||||||
private var isGrayscale = false
|
private var isGrayscale = false
|
||||||
private var fetchTask: Task<Void, Error>?
|
private var fetchTask: Task<Void, Error>?
|
||||||
|
private var blurHashTask: DispatchWorkItem?
|
||||||
|
|
||||||
init(cache: ImageCache) {
|
init(cache: ImageCache) {
|
||||||
self.cache = cache
|
self.cache = cache
|
||||||
|
|
||||||
super.init(frame: .zero)
|
super.init(frame: .zero)
|
||||||
|
commonInit()
|
||||||
NotificationCenter.default.addObserver(self, selector: #selector(preferencesChanged), name: .preferencesChanged, object: nil)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
required init?(coder: NSCoder) {
|
required init?(coder: NSCoder) {
|
||||||
fatalError("init(coder:) has not been implemented")
|
super.init(coder: coder)
|
||||||
|
commonInit()
|
||||||
}
|
}
|
||||||
|
|
||||||
func update(for url: URL?) {
|
private func commonInit() {
|
||||||
if url != self.url {
|
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.url = url
|
||||||
|
self.image = nil
|
||||||
|
updateBlurhash(blurhash, for: url)
|
||||||
updateImage()
|
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() {
|
private func updateImage() {
|
||||||
fetchTask?.cancel()
|
fetchTask?.cancel()
|
||||||
fetchTask = Task(priority: .high) {
|
|
||||||
self.image = nil
|
|
||||||
guard let url else {
|
guard let url else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fetchTask = Task(priority: .high) {
|
||||||
let (_, image) = await cache.get(url)
|
let (_, image) = await cache.get(url)
|
||||||
guard let image else {
|
guard let image else {
|
||||||
return
|
return
|
||||||
|
@ -59,6 +84,7 @@ class CachedImageView: UIImageView {
|
||||||
try Task.checkCancellation()
|
try Task.checkCancellation()
|
||||||
self.image = transformedImage
|
self.image = transformedImage
|
||||||
self.isGrayscale = Preferences.shared.grayscaleImages
|
self.isGrayscale = Preferences.shared.grayscaleImages
|
||||||
|
self.blurHashTask?.cancel()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue