138 lines
5.3 KiB
Swift
138 lines
5.3 KiB
Swift
// Copyright © 2020 Metabolist. All rights reserved.
|
|
|
|
import Kingfisher
|
|
import Mastodon
|
|
import UIKit
|
|
import ViewModels
|
|
|
|
final class CardView: UIView {
|
|
let imageView = UIImageView()
|
|
let titleLabel = UILabel()
|
|
let descriptionLabel = UILabel()
|
|
let urlLabel = UILabel()
|
|
let button = UIButton()
|
|
|
|
var viewModel: CardViewModel? {
|
|
didSet {
|
|
guard let viewModel = viewModel else { return }
|
|
|
|
var accessibilityLabel = NSLocalizedString("card.link.accessibility-label", comment: "")
|
|
.appendingWithSeparator(viewModel.title)
|
|
|
|
imageView.isHidden = viewModel.imageURL == nil
|
|
imageView.kf.setImage(with: viewModel.imageURL)
|
|
|
|
titleLabel.text = viewModel.title
|
|
descriptionLabel.text = viewModel.description
|
|
descriptionLabel.isHidden = descriptionLabel.text == "" || descriptionLabel.text == titleLabel.text
|
|
|
|
if
|
|
let host = viewModel.url.host, host.hasPrefix("www."),
|
|
let withoutWww = host.components(separatedBy: "www.").last {
|
|
urlLabel.text = withoutWww
|
|
} else {
|
|
urlLabel.text = viewModel.url.host
|
|
}
|
|
|
|
if let urlLabelText = urlLabel.text {
|
|
accessibilityLabel.appendWithSeparator(urlLabelText)
|
|
}
|
|
|
|
self.accessibilityLabel = accessibilityLabel
|
|
}
|
|
}
|
|
|
|
override init(frame: CGRect) {
|
|
super.init(frame: frame)
|
|
|
|
initialSetup()
|
|
setupAccessibility()
|
|
}
|
|
|
|
@available(*, unavailable)
|
|
required init?(coder: NSCoder) {
|
|
fatalError("init(coder:) has not been implemented")
|
|
}
|
|
}
|
|
|
|
extension CardView {
|
|
static func estimatedHeight(width: CGFloat,
|
|
identityContext: IdentityContext,
|
|
status: Status,
|
|
configuration: CollectionItem.StatusConfiguration) -> CGFloat {
|
|
if status.displayStatus.card != nil {
|
|
return round(UIFont.preferredFont(forTextStyle: .headline).lineHeight
|
|
+ UIFont.preferredFont(forTextStyle: .subheadline).lineHeight
|
|
+ UIFont.preferredFont(forTextStyle: .footnote).lineHeight
|
|
+ .defaultSpacing * 2
|
|
+ .compactSpacing * 2)
|
|
} else {
|
|
return 0
|
|
}
|
|
}
|
|
}
|
|
|
|
private extension CardView {
|
|
// swiftlint:disable:next function_body_length
|
|
func initialSetup() {
|
|
backgroundColor = .secondarySystemBackground
|
|
layer.cornerRadius = .defaultCornerRadius
|
|
clipsToBounds = true
|
|
|
|
let stackView = UIStackView()
|
|
let innerStackView = UIStackView()
|
|
|
|
addSubview(stackView)
|
|
stackView.translatesAutoresizingMaskIntoConstraints = false
|
|
|
|
addSubview(button)
|
|
button.translatesAutoresizingMaskIntoConstraints = false
|
|
button.setBackgroundImage(.highlightedButtonBackground, for: .highlighted)
|
|
|
|
stackView.addArrangedSubview(imageView)
|
|
stackView.addArrangedSubview(innerStackView)
|
|
|
|
imageView.contentMode = .scaleAspectFill
|
|
imageView.clipsToBounds = true
|
|
imageView.setContentCompressionResistancePriority(.defaultLow, for: .vertical)
|
|
imageView.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
|
|
|
|
innerStackView.axis = .vertical
|
|
innerStackView.isLayoutMarginsRelativeArrangement = true
|
|
innerStackView.directionalLayoutMargins =
|
|
.init(top: .defaultSpacing, leading: .defaultSpacing, bottom: .defaultSpacing, trailing: .defaultSpacing)
|
|
innerStackView.spacing = .compactSpacing
|
|
innerStackView.addArrangedSubview(titleLabel)
|
|
innerStackView.addArrangedSubview(descriptionLabel)
|
|
innerStackView.addArrangedSubview(urlLabel)
|
|
|
|
titleLabel.font = .preferredFont(forTextStyle: .headline)
|
|
titleLabel.adjustsFontForContentSizeCategory = true
|
|
titleLabel.setContentCompressionResistancePriority(.required, for: .vertical)
|
|
descriptionLabel.font = .preferredFont(forTextStyle: .subheadline)
|
|
descriptionLabel.adjustsFontForContentSizeCategory = true
|
|
descriptionLabel.setContentCompressionResistancePriority(.required, for: .vertical)
|
|
urlLabel.font = .preferredFont(forTextStyle: .footnote)
|
|
urlLabel.adjustsFontForContentSizeCategory = true
|
|
urlLabel.setContentCompressionResistancePriority(.required, for: .vertical)
|
|
urlLabel.textColor = .secondaryLabel
|
|
|
|
NSLayoutConstraint.activate([
|
|
stackView.leadingAnchor.constraint(equalTo: leadingAnchor),
|
|
stackView.trailingAnchor.constraint(equalTo: trailingAnchor),
|
|
stackView.topAnchor.constraint(equalTo: topAnchor),
|
|
stackView.bottomAnchor.constraint(equalTo: bottomAnchor),
|
|
button.leadingAnchor.constraint(equalTo: leadingAnchor),
|
|
button.trailingAnchor.constraint(equalTo: trailingAnchor),
|
|
button.topAnchor.constraint(equalTo: topAnchor),
|
|
button.bottomAnchor.constraint(equalTo: bottomAnchor),
|
|
imageView.heightAnchor.constraint(equalTo: innerStackView.heightAnchor),
|
|
imageView.widthAnchor.constraint(equalTo: imageView.heightAnchor)
|
|
])
|
|
}
|
|
|
|
func setupAccessibility() {
|
|
isAccessibilityElement = true
|
|
}
|
|
}
|