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

130 lines
5.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 stackViewLeadingConstraint: NSLayoutConstraint!
@IBOutlet weak var avatarContainerView: UIView!
@IBOutlet weak var avatarContainerWidthConstraint: NSLayoutConstraint!
@IBOutlet weak var replyCountLabel: UILabel!
private var threadLinkView: UIView!
private var threadLinkViewFullHeightConstraint: NSLayoutConstraint!
private var threadLinkViewShortHeightConstraint: NSLayoutConstraint!
private var avatarImageViews: [UIImageView] = []
private var avatarRequests: [ImageCache.Request] = []
override func awakeFromNib() {
super.awakeFromNib()
threadLinkView = UIView()
threadLinkView.translatesAutoresizingMaskIntoConstraints = false
threadLinkView.backgroundColor = tintColor.withAlphaComponent(0.5)
threadLinkView.layer.cornerRadius = 2.5
contentView.addSubview(threadLinkView)
threadLinkViewFullHeightConstraint = threadLinkView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor)
threadLinkViewShortHeightConstraint = threadLinkView.bottomAnchor.constraint(equalTo: avatarContainerView.topAnchor, constant: -2)
NSLayoutConstraint.activate([
threadLinkView.widthAnchor.constraint(equalToConstant: 5),
threadLinkView.centerXAnchor.constraint(equalTo: contentView.layoutMarginsGuide.leadingAnchor, constant: 25),
threadLinkView.topAnchor.constraint(equalTo: contentView.topAnchor),
threadLinkViewFullHeightConstraint,
])
NotificationCenter.default.addObserver(self, selector: #selector(preferencesChanged), name: .preferencesChanged, object: nil)
}
func updateUI(childThreads: [ConversationNode], inline: Bool) {
stackViewLeadingConstraint.constant = inline ? 50 + 4 : 0
threadLinkView.layer.maskedCorners = inline ? [] : [.layerMinXMaxYCorner, .layerMaxXMaxYCorner]
threadLinkViewFullHeightConstraint.isActive = inline
threadLinkViewShortHeightConstraint.isActive = !inline
let format: String
if inline {
format = NSLocalizedString("expand threads inline count", comment: "expnad converstaion threads inline button label")
} else {
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
])
if let avatar = account.avatar {
let req = ImageCache.avatars.get(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() }
}
}