Tusker/Tusker/Screens/Conversation/ExpandThreadTableViewCell.s...

113 lines
4.7 KiB
Swift

//
// ExpandThreadTableViewCell.swift
// Tusker
//
// Created by Shadowfacts on 1/30/21.
// Copyright © 2021 Shadowfacts. All rights reserved.
//
import UIKit
class ExpandThreadTableViewCell: UITableViewCell {
@IBOutlet weak var avatarContainerView: UIView!
@IBOutlet weak var avatarContainerWidthConstraint: NSLayoutConstraint!
@IBOutlet weak var replyCountLabel: UILabel!
var avatarImageViews: [UIImageView] = []
private var avatarRequests: [ImageCache.Request] = []
override func awakeFromNib() {
super.awakeFromNib()
let prevThreadLinkView = UIView()
prevThreadLinkView.translatesAutoresizingMaskIntoConstraints = false
prevThreadLinkView.backgroundColor = tintColor.withAlphaComponent(0.5)
prevThreadLinkView.layer.cornerRadius = 2.5
prevThreadLinkView.layer.maskedCorners = [.layerMinXMaxYCorner, .layerMaxXMaxYCorner]
contentView.addSubview(prevThreadLinkView)
NSLayoutConstraint.activate([
prevThreadLinkView.widthAnchor.constraint(equalToConstant: 5),
prevThreadLinkView.centerXAnchor.constraint(equalTo: leadingAnchor, constant: 16 + 25),
prevThreadLinkView.topAnchor.constraint(equalTo: topAnchor),
prevThreadLinkView.bottomAnchor.constraint(equalTo: avatarContainerView.topAnchor, constant: -2),
])
NotificationCenter.default.addObserver(self, selector: #selector(preferencesChanged), name: .preferencesChanged, object: nil)
}
func updateUI(childThreads: [ConversationNode]) {
let format = NSLocalizedString("expand threads count", comment: "expand conversation threads button label")
replyCountLabel.text = String.localizedStringWithFormat(format, childThreads.count)
let accounts = childThreads.map(\.status.account).uniques().prefix(3)
avatarImageViews.forEach { $0.removeFromSuperview() }
avatarImageViews = []
avatarRequests = []
let avatarImageSize: CGFloat = 44 - 12
if accounts.count == 1 {
avatarContainerWidthConstraint.constant = avatarImageSize
} else {
avatarContainerWidthConstraint.constant = CGFloat(accounts.count) * avatarImageSize * 3 / 4
}
for (index, account) in accounts.enumerated() {
let accountImageView = UIImageView()
accountImageView.translatesAutoresizingMaskIntoConstraints = false
accountImageView.contentMode = .scaleAspectFit
accountImageView.layer.cornerRadius = Preferences.shared.avatarStyle.cornerRadiusFraction * avatarImageSize
accountImageView.layer.masksToBounds = true
accountImageView.layer.borderWidth = 1
accountImageView.layer.borderColor = UIColor.secondarySystemBackground.cgColor
// need a solid background color so semi-transparent avatars don't look bad
accountImageView.backgroundColor = .secondarySystemBackground
avatarContainerView.addSubview(accountImageView)
avatarImageViews.append(accountImageView)
accountImageView.layer.zPosition = CGFloat(-index)
let xConstraint: NSLayoutConstraint
if index == 0 {
xConstraint = accountImageView.leadingAnchor.constraint(equalTo: avatarContainerView.leadingAnchor)
} else if index == accounts.count - 1 {
xConstraint = accountImageView.trailingAnchor.constraint(equalTo: avatarContainerView.trailingAnchor)
} else {
xConstraint = accountImageView.centerXAnchor.constraint(equalTo: avatarContainerView.centerXAnchor)
}
NSLayoutConstraint.activate([
accountImageView.widthAnchor.constraint(equalToConstant: avatarImageSize),
accountImageView.heightAnchor.constraint(equalToConstant: avatarImageSize),
accountImageView.centerYAnchor.constraint(equalTo: avatarContainerView.centerYAnchor),
xConstraint
])
let req = ImageCache.avatars.get(account.avatar) { [weak accountImageView] (_, image) in
DispatchQueue.main.async {
accountImageView?.image = image
}
}
if let req = req {
avatarRequests.append(req)
}
}
}
@objc private func preferencesChanged() {
avatarImageViews.forEach {
$0.layer.cornerRadius = Preferences.shared.avatarStyle.cornerRadius(for: $0)
}
}
override func prepareForReuse() {
super.prepareForReuse()
avatarRequests.forEach { $0.cancel() }
}
}