// // 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 } 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() { } 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 } let imageViewSize = self.thumbnailView.bounds.size AttachmentView.queue.async { [weak self] in let size: CGSize if let width = card.width, let height = card.height { size = CGSize(width: width, height: height) } else { size = imageViewSize } 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 } } } }