Collapsible Cells
* Change the look of the collapsible cell * Add a reason to the collapsed cell
This commit is contained in:
parent
e68100eb71
commit
ea30b9866d
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<UITouch>, with event: UIEvent?) {
|
||||
// Eat event
|
||||
}
|
||||
|
||||
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
|
||||
// Eat event
|
||||
}
|
||||
|
||||
override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
|
||||
// Eat event
|
||||
}
|
||||
|
||||
override func touchesEnded(_ touches: Set<UITouch>, 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)
|
||||
])
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue