Fahim/cw-filter #342
|
@ -11,6 +11,7 @@ import Foundation
|
||||||
public class CollapseState: Equatable {
|
public class CollapseState: Equatable {
|
||||||
public var collapsible: Bool?
|
public var collapsible: Bool?
|
||||||
public var collapsed: Bool?
|
public var collapsed: Bool?
|
||||||
|
public var reason = ""
|
||||||
|
|
||||||
public var unknown: Bool {
|
public var unknown: Bool {
|
||||||
collapsible == nil || collapsed == nil
|
collapsible == nil || collapsed == nil
|
||||||
|
|
|
@ -16,6 +16,7 @@ extension CollapseState {
|
||||||
if Preferences.shared.collapseLongPosts,
|
if Preferences.shared.collapseLongPosts,
|
||||||
height > 600 || (textLength != nil && textLength! > 500) {
|
height > 600 || (textLength != nil && textLength! > 500) {
|
||||||
longEnoughToCollapse = true
|
longEnoughToCollapse = true
|
||||||
|
self.reason = "Read More ..."
|
||||||
} else {
|
} else {
|
||||||
longEnoughToCollapse = false
|
longEnoughToCollapse = false
|
||||||
}
|
}
|
||||||
|
@ -25,13 +26,16 @@ extension CollapseState {
|
||||||
let collapseDueToContentWarning: Bool?
|
let collapseDueToContentWarning: Bool?
|
||||||
if contentWarningCollapsible {
|
if contentWarningCollapsible {
|
||||||
let lowercased = status.spoilerText.lowercased()
|
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 {
|
if Preferences.shared.expandAllContentWarnings {
|
||||||
collapseDueToContentWarning = opposite
|
collapseDueToContentWarning = opposite
|
||||||
} else {
|
} else {
|
||||||
collapseDueToContentWarning = !opposite
|
collapseDueToContentWarning = !opposite
|
||||||
}
|
}
|
||||||
|
if let collapse = collapseDueToContentWarning, collapse {
|
||||||
|
self.reason = "Content Warning"
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
collapseDueToContentWarning = nil
|
collapseDueToContentWarning = nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,15 +104,8 @@ class ConversationMainStatusCollectionViewCell: UICollectionViewListCell, Status
|
||||||
$0.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(collapseButtonPressed)))
|
$0.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(collapseButtonPressed)))
|
||||||
}
|
}
|
||||||
|
|
||||||
private(set) lazy var collapseButton = StatusCollapseButton(configuration: {
|
private(set) lazy var collapseButton = StatusCollapseButton {
|
||||||
var config = UIButton.Configuration.filled()
|
self.toggleCollapse()
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let contentContainer = StatusContentContainer(useTopSpacer: true).configure {
|
let contentContainer = StatusContentContainer(useTopSpacer: true).configure {
|
||||||
|
|
|
@ -8,18 +8,85 @@
|
||||||
|
|
||||||
import UIKit
|
import UIKit
|
||||||
|
|
||||||
class StatusCollapseButton: UIButton {
|
class StatusCollapseButton: UIView {
|
||||||
|
var title: String {
|
||||||
private var interactionBounds: CGRect!
|
get {
|
||||||
|
return lblTitle.text ?? ""
|
||||||
override func layoutSubviews() {
|
}
|
||||||
super.layoutSubviews()
|
set {
|
||||||
|
lblTitle.text = newValue
|
||||||
interactionBounds = bounds.inset(by: UIEdgeInsets(top: -8, left: 0, bottom: 0, right: 0))
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
|
private var action: (()->Void)!
|
||||||
return interactionBounds.contains(point)
|
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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
])
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -114,16 +114,15 @@ extension StatusCollectionViewCell {
|
||||||
statusState.collapsed = false
|
statusState.collapsed = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
collapseButton.title = statusState.reason
|
||||||
collapseButton.isHidden = !statusState.collapsible!
|
collapseButton.isHidden = !statusState.collapsible!
|
||||||
contentContainer.setCollapsed(statusState.collapsed!)
|
contentContainer.setCollapsed(statusState.collapsed!)
|
||||||
if statusState.collapsed! {
|
if statusState.collapsed! {
|
||||||
contentContainer.alpha = 0
|
contentContainer.alpha = 0
|
||||||
// TODO: is this accessing the image view before the button's been laid out?
|
// 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")
|
collapseButton.accessibilityLabel = NSLocalizedString("Expand Status", comment: "expand status button accessibility label")
|
||||||
} else {
|
} else {
|
||||||
contentContainer.alpha = 1
|
contentContainer.alpha = 1
|
||||||
collapseButton.imageView!.transform = CGAffineTransform(rotationAngle: .pi)
|
|
||||||
collapseButton.accessibilityLabel = NSLocalizedString("Collapse Status", comment: "collapse status button accessibility label")
|
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")
|
private let hashtagIcon = UIImage(systemName: "number")
|
||||||
|
|
||||||
class TimelineStatusCollectionViewCell: UICollectionViewListCell, StatusCollectionViewCell {
|
class TimelineStatusCollectionViewCell: UICollectionViewListCell, StatusCollectionViewCell {
|
||||||
|
|
||||||
static let separatorInsets = NSDirectionalEdgeInsets(top: 0, leading: 16, bottom: 0, trailing: 0)
|
static let separatorInsets = NSDirectionalEdgeInsets(top: 0, leading: 16, bottom: 0, trailing: 0)
|
||||||
static let contentFont = UIFontMetrics.default.scaledFont(for: .systemFont(ofSize: 16))
|
static let contentFont = UIFontMetrics.default.scaledFont(for: .systemFont(ofSize: 16))
|
||||||
static let monospaceFont = UIFontMetrics.default.scaledFont(for: .monospacedSystemFont(ofSize: 16, weight: .regular))
|
static let monospaceFont = UIFontMetrics.default.scaledFont(for: .monospacedSystemFont(ofSize: 16, weight: .regular))
|
||||||
|
@ -155,15 +154,8 @@ class TimelineStatusCollectionViewCell: UICollectionViewListCell, StatusCollecti
|
||||||
$0.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(collapseButtonPressed)))
|
$0.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(collapseButtonPressed)))
|
||||||
}
|
}
|
||||||
|
|
||||||
private(set) lazy var collapseButton = StatusCollapseButton(configuration: {
|
private(set) lazy var collapseButton = StatusCollapseButton {
|
||||||
var config = UIButton.Configuration.filled()
|
self.toggleCollapse()
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let contentContainer = StatusContentContainer(useTopSpacer: false).configure {
|
let contentContainer = StatusContentContainer(useTopSpacer: false).configure {
|
||||||
|
|
Loading…
Reference in New Issue