159 lines
7.2 KiB
Swift
159 lines
7.2 KiB
Swift
//
|
|
// ExpandThreadCollectionViewCell.swift
|
|
// Tusker
|
|
//
|
|
// Created by Shadowfacts on 1/30/21.
|
|
// Copyright © 2021 Shadowfacts. All rights reserved.
|
|
//
|
|
|
|
import UIKit
|
|
|
|
class ExpandThreadCollectionViewCell: UICollectionViewListCell {
|
|
|
|
private var avatarContainerView: UIView!
|
|
private var avatarContainerWidthConstraint: NSLayoutConstraint!
|
|
|
|
private var replyCountLabel: UILabel!
|
|
|
|
private var hStack: UIStackView!
|
|
private var stackViewLeadingConstraint: NSLayoutConstraint!
|
|
|
|
private var threadLinkView: UIView!
|
|
private var threadLinkViewFullHeightConstraint: NSLayoutConstraint!
|
|
private var threadLinkViewShortHeightConstraint: NSLayoutConstraint!
|
|
|
|
private var avatarImageViews: [UIImageView] = []
|
|
|
|
override init(frame: CGRect) {
|
|
super.init(frame: frame)
|
|
|
|
avatarContainerView = UIView()
|
|
avatarContainerView.backgroundColor = .clear
|
|
avatarContainerWidthConstraint = avatarContainerView.widthAnchor.constraint(equalToConstant: 100)
|
|
|
|
replyCountLabel = UILabel()
|
|
replyCountLabel.textColor = .tintColor
|
|
replyCountLabel.font = .preferredFont(forTextStyle: .body)
|
|
replyCountLabel.adjustsFontForContentSizeCategory = true
|
|
|
|
hStack = UIStackView(arrangedSubviews: [
|
|
avatarContainerView,
|
|
replyCountLabel,
|
|
])
|
|
hStack.spacing = 8
|
|
hStack.alignment = .center
|
|
hStack.translatesAutoresizingMaskIntoConstraints = false
|
|
contentView.addSubview(hStack)
|
|
stackViewLeadingConstraint = hStack.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 16)
|
|
|
|
threadLinkView = UIView()
|
|
threadLinkView.backgroundColor = .tintColor.withAlphaComponent(0.5)
|
|
threadLinkView.layer.cornerRadius = 2.5
|
|
threadLinkView.translatesAutoresizingMaskIntoConstraints = false
|
|
contentView.addSubview(threadLinkView)
|
|
threadLinkViewFullHeightConstraint = threadLinkView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor)
|
|
threadLinkViewShortHeightConstraint = threadLinkView.bottomAnchor.constraint(equalTo: avatarContainerView.topAnchor, constant: -2)
|
|
|
|
let avatarContainerHeightConstraint = avatarContainerView.heightAnchor.constraint(equalToConstant: 32)
|
|
// let this be broken during intermediate layouts when the collection view imposes a height constraint
|
|
avatarContainerHeightConstraint.priority = .init(999)
|
|
NSLayoutConstraint.activate([
|
|
avatarContainerWidthConstraint,
|
|
avatarContainerHeightConstraint,
|
|
|
|
stackViewLeadingConstraint,
|
|
hStack.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -16),
|
|
hStack.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 8),
|
|
hStack.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -8),
|
|
|
|
threadLinkView.widthAnchor.constraint(equalToConstant: 5),
|
|
threadLinkView.topAnchor.constraint(equalTo: contentView.topAnchor),
|
|
threadLinkView.centerXAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 16 + (50 / 2))
|
|
])
|
|
|
|
NotificationCenter.default.addObserver(self, selector: #selector(preferencesChanged), name: .preferencesChanged, object: nil)
|
|
}
|
|
|
|
required init?(coder: NSCoder) {
|
|
fatalError("init(coder:) has not been implemented")
|
|
}
|
|
|
|
func updateUI(childThreads: [ConversationNode], inline: Bool) {
|
|
stackViewLeadingConstraint.constant = 16 + (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: "expand conversation 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 = []
|
|
|
|
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 = CachedImageView(cache: .avatars)
|
|
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,
|
|
])
|
|
|
|
accountImageView.update(for: account.avatar)
|
|
}
|
|
}
|
|
|
|
@objc private func preferencesChanged() {
|
|
for view in avatarImageViews {
|
|
view.layer.cornerRadius = Preferences.shared.avatarStyle.cornerRadius(for: view)
|
|
}
|
|
}
|
|
|
|
override func updateConfiguration(using state: UICellConfigurationState) {
|
|
var config = UIBackgroundConfiguration.listGroupedCell().updated(for: state)
|
|
if state.isFocused {
|
|
// use default
|
|
} else if state.isHighlighted || state.isSelected {
|
|
config.backgroundColor = .appSelectedCellBackground
|
|
} else {
|
|
config.backgroundColor = .appSecondaryBackground
|
|
}
|
|
backgroundConfiguration = config
|
|
}
|
|
|
|
}
|