diff --git a/Packages/Pachyderm/Sources/Pachyderm/Utilities/CollapseState.swift b/Packages/Pachyderm/Sources/Pachyderm/Utilities/CollapseState.swift index 6370d7e9..89799ad8 100644 --- a/Packages/Pachyderm/Sources/Pachyderm/Utilities/CollapseState.swift +++ b/Packages/Pachyderm/Sources/Pachyderm/Utilities/CollapseState.swift @@ -11,6 +11,7 @@ import Foundation public class CollapseState: Equatable { public var collapsible: Bool? public var collapsed: Bool? + public var reason = "" public var unknown: Bool { collapsible == nil || collapsed == nil diff --git a/Tusker/Extensions/StatusStateResolver.swift b/Tusker/Extensions/StatusStateResolver.swift index 4c5901bd..e7f1160f 100644 --- a/Tusker/Extensions/StatusStateResolver.swift +++ b/Tusker/Extensions/StatusStateResolver.swift @@ -16,6 +16,7 @@ extension CollapseState { if Preferences.shared.collapseLongPosts, height > 600 || (textLength != nil && textLength! > 500) { longEnoughToCollapse = true + self.reason = "Read More ..." } else { longEnoughToCollapse = false } @@ -25,13 +26,16 @@ extension CollapseState { let collapseDueToContentWarning: Bool? if contentWarningCollapsible { let lowercased = status.spoilerText.lowercased() - let opposite = Preferences.shared.oppositeCollapseKeywords.contains { lowercased.contains($0.trimmingCharacters(in: .whitespacesAndNewlines).lowercased()) } - + let opposite = Preferences.shared.oppositeCollapseKeywords.contains { lowercased.contains($0.trimmingCharacters(in: .whitespacesAndNewlines).lowercased()) + } if Preferences.shared.expandAllContentWarnings { collapseDueToContentWarning = opposite } else { collapseDueToContentWarning = !opposite } + if let collapse = collapseDueToContentWarning, collapse { + self.reason = "Content Warning" + } } else { collapseDueToContentWarning = nil } diff --git a/Tusker/Views/Status/ConversationMainStatusCollectionViewCell.swift b/Tusker/Views/Status/ConversationMainStatusCollectionViewCell.swift index 279c7d26..0991e697 100644 --- a/Tusker/Views/Status/ConversationMainStatusCollectionViewCell.swift +++ b/Tusker/Views/Status/ConversationMainStatusCollectionViewCell.swift @@ -104,16 +104,9 @@ class ConversationMainStatusCollectionViewCell: UICollectionViewListCell, Status $0.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(collapseButtonPressed))) } - private(set) lazy var collapseButton = StatusCollapseButton(configuration: { - var config = UIButton.Configuration.filled() - config.image = UIImage(systemName: "chevron.down") - return config - }()).configure { - // this button is so big that dimming its background color is visually distracting - $0.tintAdjustmentMode = .normal - $0.setContentHuggingPriority(.defaultHigh, for: .vertical) - $0.addTarget(self, action: #selector(collapseButtonPressed), for: .touchUpInside) - } + private(set) lazy var collapseButton = StatusCollapseButton { + self.toggleCollapse() + } let contentContainer = StatusContentContainer(useTopSpacer: true).configure { $0.contentTextView.defaultFont = ConversationMainStatusCollectionViewCell.contentFont diff --git a/Tusker/Views/Status/StatusCollapseButton.swift b/Tusker/Views/Status/StatusCollapseButton.swift index a0a2d513..d4830170 100644 --- a/Tusker/Views/Status/StatusCollapseButton.swift +++ b/Tusker/Views/Status/StatusCollapseButton.swift @@ -8,18 +8,85 @@ import UIKit -class StatusCollapseButton: UIButton { +class StatusCollapseButton: UIView { + var title: String { + get { + return lblTitle.text ?? "" + } + set { + lblTitle.text = newValue + } + } + + private var action: (()->Void)! + private var lblTitle = UILabel() + private var imgView = UIImageView() + private var isCollapsed = true + + convenience init(action: @escaping (()->Void)) { + self.init(frame: CGRect.zero) + self.action = action + } - private var interactionBounds: CGRect! - - override func layoutSubviews() { - super.layoutSubviews() - - interactionBounds = bounds.inset(by: UIEdgeInsets(top: -8, left: 0, bottom: 0, right: 0)) - } - - override func point(inside point: CGPoint, with event: UIEvent?) -> Bool { - return interactionBounds.contains(point) - } + override init(frame: CGRect) { + super.init(frame: frame) + setup() + } + required init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + } + + override func touchesBegan(_ touches: Set, with event: UIEvent?) { + // Eat event + } + + override func touchesMoved(_ touches: Set, with event: UIEvent?) { + // Eat event + } + + override func touchesCancelled(_ touches: Set, with event: UIEvent?) { + // Eat event + } + + override func touchesEnded(_ touches: Set, with event: UIEvent?) { + if isCollapsed { + imgView.image = UIImage(systemName: "chevron.compact.up") + } else { + imgView.image = UIImage(systemName: "chevron.compact.down") + } + isCollapsed.toggle() + action() + } + + // MARK: - Private Methods + private func setup() { + self.isUserInteractionEnabled = true + layer.cornerRadius = 8 + backgroundColor = .lightGray + // Title + lblTitle.translatesAutoresizingMaskIntoConstraints = false + lblTitle.textColor = .white + lblTitle.textAlignment = .center + addSubview(lblTitle) + // Chevron + imgView.translatesAutoresizingMaskIntoConstraints = false + imgView.tintColor = .white + imgView.image = UIImage(systemName: "chevron.compact.down") + addSubview(imgView) + NSLayoutConstraint.activate([ + // Main view + heightAnchor.constraint(equalToConstant: 30), + // Title + lblTitle.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 8), + lblTitle.topAnchor.constraint(equalTo: topAnchor, constant: 8), + lblTitle.trailingAnchor.constraint(equalTo: imgView.leadingAnchor, constant: -4), + lblTitle.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -8), + // Chevron + imgView.widthAnchor.constraint(equalToConstant: 20), + imgView.topAnchor.constraint(equalTo: topAnchor, constant: 5), + imgView.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -8), + imgView.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -5) + ]) + } } diff --git a/Tusker/Views/Status/StatusCollectionViewCell.swift b/Tusker/Views/Status/StatusCollectionViewCell.swift index 9a27d04a..751e0238 100644 --- a/Tusker/Views/Status/StatusCollectionViewCell.swift +++ b/Tusker/Views/Status/StatusCollectionViewCell.swift @@ -113,17 +113,16 @@ extension StatusCollectionViewCell { if statusState.collapsible! && showStatusAutomatically { statusState.collapsed = false } - } + } + collapseButton.title = statusState.reason collapseButton.isHidden = !statusState.collapsible! contentContainer.setCollapsed(statusState.collapsed!) if statusState.collapsed! { contentContainer.alpha = 0 // TODO: is this accessing the image view before the button's been laid out? - collapseButton.imageView!.transform = CGAffineTransform(rotationAngle: 0) collapseButton.accessibilityLabel = NSLocalizedString("Expand Status", comment: "expand status button accessibility label") } else { contentContainer.alpha = 1 - collapseButton.imageView!.transform = CGAffineTransform(rotationAngle: .pi) collapseButton.accessibilityLabel = NSLocalizedString("Collapse Status", comment: "collapse status button accessibility label") } } diff --git a/Tusker/Views/Status/TimelineStatusCollectionViewCell.swift b/Tusker/Views/Status/TimelineStatusCollectionViewCell.swift index b02b475d..524a1974 100644 --- a/Tusker/Views/Status/TimelineStatusCollectionViewCell.swift +++ b/Tusker/Views/Status/TimelineStatusCollectionViewCell.swift @@ -14,7 +14,6 @@ private let reblogIcon = UIImage(systemName: "repeat") private let hashtagIcon = UIImage(systemName: "number") class TimelineStatusCollectionViewCell: UICollectionViewListCell, StatusCollectionViewCell { - static let separatorInsets = NSDirectionalEdgeInsets(top: 0, leading: 16, bottom: 0, trailing: 0) static let contentFont = UIFontMetrics.default.scaledFont(for: .systemFont(ofSize: 16)) static let monospaceFont = UIFontMetrics.default.scaledFont(for: .monospacedSystemFont(ofSize: 16, weight: .regular)) @@ -154,17 +153,10 @@ class TimelineStatusCollectionViewCell: UICollectionViewListCell, StatusCollecti $0.isUserInteractionEnabled = true $0.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(collapseButtonPressed))) } - - private(set) lazy var collapseButton = StatusCollapseButton(configuration: { - var config = UIButton.Configuration.filled() - config.image = UIImage(systemName: "chevron.down") - return config - }()).configure { - // this button is so big that dimming its background color is visually distracting - $0.tintAdjustmentMode = .normal - $0.setContentHuggingPriority(.defaultHigh, for: .vertical) - $0.addTarget(self, action: #selector(collapseButtonPressed), for: .touchUpInside) - } + + private(set) lazy var collapseButton = StatusCollapseButton { + self.toggleCollapse() + } let contentContainer = StatusContentContainer(useTopSpacer: false).configure { $0.contentTextView.defaultFont = TimelineStatusCollectionViewCell.contentFont