forked from shadowfacts/Tusker
146 lines
5.1 KiB
Swift
146 lines
5.1 KiB
Swift
//
|
|
// TrendingLinkCardCollectionViewCell.swift
|
|
// Tusker
|
|
//
|
|
// Created by Shadowfacts on 6/29/22.
|
|
// Copyright © 2022 Shadowfacts. All rights reserved.
|
|
//
|
|
|
|
import UIKit
|
|
import Pachyderm
|
|
|
|
class TrendingLinkCardCollectionViewCell: UICollectionViewCell {
|
|
|
|
private var card: Card?
|
|
private var isGrayscale = false
|
|
private var thumbnailRequest: ImageCache.Request?
|
|
|
|
@IBOutlet weak var thumbnailView: UIImageView!
|
|
@IBOutlet weak var titleLabel: UILabel!
|
|
@IBOutlet weak var providerLabel: UILabel!
|
|
@IBOutlet weak var activityLabel: UILabel!
|
|
@IBOutlet weak var historyView: TrendHistoryView!
|
|
|
|
override func awakeFromNib() {
|
|
super.awakeFromNib()
|
|
|
|
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)
|
|
}
|
|
|
|
override func layoutSubviews() {
|
|
super.layoutSubviews()
|
|
|
|
contentView.layer.cornerRadius = 0.05 * bounds.width
|
|
thumbnailView.layer.cornerRadius = 0.05 * bounds.width
|
|
}
|
|
|
|
func updateUI(card: Card) {
|
|
self.card = card
|
|
self.thumbnailView.image = nil
|
|
|
|
updateGrayscaleableUI(card: card)
|
|
updateUIForPreferences()
|
|
|
|
let title = card.title.trimmingCharacters(in: .whitespacesAndNewlines)
|
|
titleLabel.text = title
|
|
|
|
let provider = card.providerName!.trimmingCharacters(in: .whitespacesAndNewlines)
|
|
providerLabel.text = provider
|
|
|
|
let sorted = card.history!.sorted(by: { $0.day < $1.day })
|
|
let lastTwo = sorted[(sorted.count - 2)...]
|
|
let accounts = lastTwo.map(\.accounts).reduce(0, +)
|
|
let uses = lastTwo.map(\.uses).reduce(0, +)
|
|
|
|
// U+2009 THIN SPACE
|
|
let activityStr = NSMutableAttributedString(string: "\(accounts.formatted())\u{2009}")
|
|
activityStr.append(NSAttributedString(attachment: NSTextAttachment(image: UIImage(systemName: "person")!)))
|
|
activityStr.append(NSAttributedString(string: ", \(uses.formatted())\u{2009}"))
|
|
activityStr.append(NSAttributedString(attachment: NSTextAttachment(image: UIImage(systemName: "square.text.square")!)))
|
|
activityLabel.attributedText = activityStr
|
|
|
|
historyView.setHistory(card.history)
|
|
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
|
|
}
|
|
AttachmentView.queue.async { [weak self] in
|
|
let size: CGSize
|
|
if let width = card.width, let height = card.height {
|
|
let aspectRatio = CGFloat(width) / CGFloat(height)
|
|
if aspectRatio > 1 {
|
|
size = CGSize(width: 32, height: 32 / aspectRatio)
|
|
} else {
|
|
size = CGSize(width: 32 * aspectRatio, height: 32)
|
|
}
|
|
} else {
|
|
size = CGSize(width: 32, height: 32)
|
|
}
|
|
|
|
guard let preview = UIImage(blurHash: hash, size: size) else {
|
|
return
|
|
}
|
|
DispatchQueue.main.async { [weak self] in
|
|
guard let self,
|
|
self.card?.url == card.url,
|
|
self.thumbnailView.image == nil else {
|
|
return
|
|
}
|
|
self.thumbnailView.image = preview
|
|
}
|
|
}
|
|
}
|
|
|
|
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
|
|
super.traitCollectionDidChange(previousTraitCollection)
|
|
updateLayerColors()
|
|
}
|
|
|
|
private func updateLayerColors() {
|
|
if traitCollection.userInterfaceStyle == .dark {
|
|
// clippingView.layer.borderColor = UIColor.darkGray.withAlphaComponent(0.5).cgColor
|
|
layer.shadowColor = UIColor.darkGray.cgColor
|
|
} else {
|
|
// clippingView.layer.borderColor = UIColor.lightGray.withAlphaComponent(0.5).cgColor
|
|
layer.shadowColor = UIColor.black.cgColor
|
|
}
|
|
}
|
|
|
|
}
|