From 141e8b96a5c5bae5eb420c6848ab22ad2d047c14 Mon Sep 17 00:00:00 2001 From: Shadowfacts Date: Mon, 4 Dec 2023 16:38:04 -0500 Subject: [PATCH] Show label when attachments are hidden in timelines --- .../Timeline/TimelineViewController.swift | 1 + .../AttachmentsContainerView.swift | 60 ++++++++++++++++--- .../Views/Status/StatusContentContainer.swift | 4 +- .../TimelineStatusCollectionViewCell.swift | 9 +-- 4 files changed, 57 insertions(+), 17 deletions(-) diff --git a/Tusker/Screens/Timeline/TimelineViewController.swift b/Tusker/Screens/Timeline/TimelineViewController.swift index bad9bde6..3479abab 100644 --- a/Tusker/Screens/Timeline/TimelineViewController.swift +++ b/Tusker/Screens/Timeline/TimelineViewController.swift @@ -192,6 +192,7 @@ class TimelineViewController: UIViewController, TimelineLikeCollectionViewContro // separate method because InstanceTimelineViewController needs to be able to customize it func configureStatusCell(_ cell: TimelineStatusCollectionViewCell, id: String, state: CollapseState, filterResult: Filterer.Result, precomputedContent: NSAttributedString?) { cell.delegate = self + cell.showAttachmentsInline = Preferences.shared.showAttachmentsInTimeline if case .home = timeline { cell.showFollowedHashtags = true } else { diff --git a/Tusker/Views/Attachments/AttachmentsContainerView.swift b/Tusker/Views/Attachments/AttachmentsContainerView.swift index ede05727..ea59f6b8 100644 --- a/Tusker/Views/Attachments/AttachmentsContainerView.swift +++ b/Tusker/Views/Attachments/AttachmentsContainerView.swift @@ -30,8 +30,8 @@ class AttachmentsContainerView: UIView { } } - var blurView: UIVisualEffectView? - var hideButtonView: UIVisualEffectView? + private var blurView: UIVisualEffectView? + private var hideButtonView: UIVisualEffectView? var contentHidden: Bool! { didSet { guard let blurView = blurView, @@ -42,6 +42,8 @@ class AttachmentsContainerView: UIView { } } + private var label: UILabel? + override init(frame: CGRect) { super.init(frame: frame) commonInit() @@ -67,22 +69,25 @@ class AttachmentsContainerView: UIView { // MARK: - User Interaface - func updateUI(attachments: [Attachment]) { + func updateUI(attachments: [Attachment], labelOnly: Bool = false) { let newTokens = attachments.map { AttachmentToken(attachment: $0) } + guard !labelOnly else { + self.attachments = attachments + self.attachmentTokens = newTokens + updateLabel(attachments: attachments) + return + } + guard self.attachmentTokens != newTokens else { - self.isHidden = attachments.isEmpty return } self.attachments = attachments self.attachmentTokens = newTokens - attachmentViews.allObjects.forEach { $0.removeFromSuperview() } - attachmentViews.removeAllObjects() - attachmentStacks.allObjects.forEach { $0.removeFromSuperview() } - attachmentStacks.removeAllObjects() - moreView?.removeFromSuperview() + removeAttachmentViews() + hideButtonView?.isHidden = false var accessibilityElements = [Any]() @@ -285,6 +290,14 @@ class AttachmentsContainerView: UIView { self.accessibilityElements = accessibilityElements } + private func removeAttachmentViews() { + attachmentViews.allObjects.forEach { $0.removeFromSuperview() } + attachmentViews.removeAllObjects() + attachmentStacks.allObjects.forEach { $0.removeFromSuperview() } + attachmentStacks.removeAllObjects() + moreView?.removeFromSuperview() + } + private func createAttachmentView(index: Int, hSize: RelativeSize, vSize: RelativeSize) -> AttachmentView { let attachmentView = AttachmentView(attachment: attachments[index], index: index) attachmentView.delegate = delegate @@ -397,6 +410,35 @@ class AttachmentsContainerView: UIView { ]) } + private func updateLabel(attachments: [Attachment]) { + removeAttachmentViews() + blurView?.isHidden = true + hideButtonView?.isHidden = true + aspectRatioConstraint?.isActive = false + + if label == nil { + if attachments.isEmpty { + accessibilityElements = [] + return + } + label = UILabel() + label!.font = .preferredFont(forTextStyle: .body) + label!.adjustsFontForContentSizeCategory = true + label!.textColor = .secondaryLabel + label!.translatesAutoresizingMaskIntoConstraints = false + addSubview(label!) + NSLayoutConstraint.activate([ + label!.leadingAnchor.constraint(equalTo: leadingAnchor), + label!.trailingAnchor.constraint(equalTo: trailingAnchor), + label!.topAnchor.constraint(equalTo: topAnchor), + label!.bottomAnchor.constraint(equalTo: bottomAnchor), + ]) + } + + label!.text = "\(attachments.count) attachment\(attachments.count == 1 ? "" : "s")" + accessibilityElements = [label!] + } + // MARK: - Interaction @objc func blurViewTapped() { diff --git a/Tusker/Views/Status/StatusContentContainer.swift b/Tusker/Views/Status/StatusContentContainer.swift index 11f63fb4..658854b4 100644 --- a/Tusker/Views/Status/StatusContentContainer.swift +++ b/Tusker/Views/Status/StatusContentContainer.swift @@ -14,8 +14,8 @@ protocol StatusContentPollView: UIView { class StatusContentContainer: UIView { - private var useTopSpacer = false - private let topSpacer = UIView().configure { + private let useTopSpacer: Bool + private lazy var topSpacer = UIView().configure { $0.backgroundColor = .clear // other 4pt is provided by this view's own spacing $0.heightAnchor.constraint(equalToConstant: 4).isActive = true diff --git a/Tusker/Views/Status/TimelineStatusCollectionViewCell.swift b/Tusker/Views/Status/TimelineStatusCollectionViewCell.swift index 7064b7d3..c0ec2c6e 100644 --- a/Tusker/Views/Status/TimelineStatusCollectionViewCell.swift +++ b/Tusker/Views/Status/TimelineStatusCollectionViewCell.swift @@ -297,6 +297,7 @@ class TimelineStatusCollectionViewCell: UICollectionViewListCell, StatusCollecti var showReplyIndicator = true var showPinned: Bool = false var showFollowedHashtags: Bool = false + var showAttachmentsInline = true // alas these need to be internal so they're accessible from the protocol extensions var statusID: String! @@ -646,12 +647,8 @@ class TimelineStatusCollectionViewCell: UICollectionViewListCell, StatusCollecti } func updateAttachmentsUI(status: StatusMO) { - if Preferences.shared.showAttachmentsInTimeline { - attachmentsView.delegate = self - attachmentsView.updateUI(attachments: status.attachments) - } else { - attachmentsView.isHidden = true - } + attachmentsView.delegate = self + attachmentsView.updateUI(attachments: status.attachments, labelOnly: !showAttachmentsInline) } func estimateContentHeight() -> CGFloat {