Tusker/Tusker/Screens/Explore/TrendingLinkTableViewCell.s...

184 lines
6.6 KiB
Swift

//
// TrendingLinkTableViewCell.swift
// Tusker
//
// Created by Shadowfacts on 4/2/22.
// Copyright © 2022 Shadowfacts. All rights reserved.
//
import UIKit
import Pachyderm
import WebURLFoundationExtras
class TrendingLinkTableViewCell: UITableViewCell {
private var card: Card?
private var isGrayscale = false
private var thumbnailRequest: ImageCache.Request?
private let thumbnailView = UIImageView()
private let titleLabel = UILabel()
private let providerLabel = UILabel()
private let activityLabel = UILabel()
private let historyView = TrendHistoryView()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
thumbnailView.contentMode = .scaleAspectFill
thumbnailView.clipsToBounds = true
titleLabel.font = UIFont(descriptor: .preferredFontDescriptor(withTextStyle: .headline).withSymbolicTraits(.traitBold)!, size: 0)
titleLabel.numberOfLines = 2
providerLabel.font = .preferredFont(forTextStyle: .subheadline)
activityLabel.font = .preferredFont(forTextStyle: .caption1)
let vStack = UIStackView(arrangedSubviews: [
titleLabel,
providerLabel,
activityLabel,
])
vStack.axis = .vertical
vStack.spacing = 4
let hStack = UIStackView(arrangedSubviews: [
thumbnailView,
vStack,
historyView,
])
hStack.axis = .horizontal
hStack.spacing = 4
hStack.alignment = .center
hStack.translatesAutoresizingMaskIntoConstraints = false
addSubview(hStack)
NSLayoutConstraint.activate([
thumbnailView.heightAnchor.constraint(equalToConstant: 75),
thumbnailView.widthAnchor.constraint(equalTo: thumbnailView.heightAnchor),
historyView.widthAnchor.constraint(equalToConstant: 75),
historyView.heightAnchor.constraint(equalToConstant: 44),
hStack.leadingAnchor.constraint(equalToSystemSpacingAfter: safeAreaLayoutGuide.leadingAnchor, multiplier: 1),
safeAreaLayoutGuide.trailingAnchor.constraint(equalToSystemSpacingAfter: hStack.trailingAnchor, multiplier: 1),
hStack.topAnchor.constraint(equalToSystemSpacingBelow: topAnchor, multiplier: 1),
bottomAnchor.constraint(equalToSystemSpacingBelow: hStack.bottomAnchor, multiplier: 1),
])
NotificationCenter.default.addObserver(self, selector: #selector(updateUIForPreferences), name: .preferencesChanged, object: nil)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func layoutSubviews() {
super.layoutSubviews()
thumbnailView.layer.cornerRadius = 0.05 * thumbnailView.bounds.width
}
override func updateConfiguration(using state: UICellConfigurationState) {
var config = UIBackgroundConfiguration.listGroupedCell().updated(for: state)
if state.isHighlighted || state.isSelected {
config.backgroundColor = .appSelectedCellBackground
} else {
config.backgroundColor = .appGroupedCellBackground
}
backgroundConfiguration = config
}
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
titleLabel.isHidden = title.isEmpty
let provider = card.providerName?.trimmingCharacters(in: .whitespacesAndNewlines)
providerLabel.text = provider
providerLabel.isHidden = provider?.isEmpty ?? true
if let history = card.history {
let sorted = 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, +)
let format = NSLocalizedString("trending hashtag info", comment: "trending hashtag posts and people")
activityLabel.text = String.localizedStringWithFormat(format, accounts, uses)
activityLabel.isHidden = false
} else {
activityLabel.isHidden = true
}
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 = 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,
self.card?.url == card.url,
self.thumbnailView.image == nil else {
return
}
self.thumbnailView.image = preview
}
}
}
}