visionOS: Use bordered prominent style for status actions

This commit is contained in:
Shadowfacts 2023-11-08 16:37:12 -05:00
parent 19db78e352
commit 14f32f24fa
3 changed files with 96 additions and 12 deletions

View File

@ -198,27 +198,51 @@ class ConversationMainStatusCollectionViewCell: UICollectionViewListCell, Status
} }
private(set) lazy var replyButton = UIButton().configure { private(set) lazy var replyButton = UIButton().configure {
#if os(visionOS)
var config = UIButton.Configuration.borderedProminent()
config.image = UIImage(systemName: "arrowshape.turn.up.left.fill")
$0.configuration = config
#else
$0.setImage(UIImage(systemName: "arrowshape.turn.up.left.fill"), for: .normal) $0.setImage(UIImage(systemName: "arrowshape.turn.up.left.fill"), for: .normal)
$0.addTarget(self, action: #selector(replyPressed), for: .touchUpInside)
$0.addInteraction(UIPointerInteraction(delegate: self)) $0.addInteraction(UIPointerInteraction(delegate: self))
#endif
$0.addTarget(self, action: #selector(replyPressed), for: .touchUpInside)
} }
private(set) lazy var favoriteButton = ToggleableButton(activeColor: UIColor(displayP3Red: 1, green: 0.8, blue: 0, alpha: 1)).configure { private(set) lazy var favoriteButton = ToggleableButton(activeColor: UIColor(displayP3Red: 1, green: 0.8, blue: 0, alpha: 1)).configure {
#if os(visionOS)
var config = UIButton.Configuration.borderedProminent()
config.image = UIImage(systemName: "star.fill")
$0.configuration = config
#else
$0.setImage(UIImage(systemName: "star.fill"), for: .normal) $0.setImage(UIImage(systemName: "star.fill"), for: .normal)
$0.addTarget(self, action: #selector(favoritePressed), for: .touchUpInside)
$0.addInteraction(UIPointerInteraction(delegate: self)) $0.addInteraction(UIPointerInteraction(delegate: self))
#endif
$0.addTarget(self, action: #selector(favoritePressed), for: .touchUpInside)
} }
private(set) lazy var reblogButton = ToggleableButton(activeColor: UIColor(displayP3Red: 1, green: 0.8, blue: 0, alpha: 1)).configure { private(set) lazy var reblogButton = ToggleableButton(activeColor: UIColor(displayP3Red: 1, green: 0.8, blue: 0, alpha: 1)).configure {
#if os(visionOS)
var config = UIButton.Configuration.borderedProminent()
config.image = UIImage(systemName: "repeat")
$0.configuration = config
#else
$0.setImage(UIImage(systemName: "repeat"), for: .normal) $0.setImage(UIImage(systemName: "repeat"), for: .normal)
$0.addTarget(self, action: #selector(reblogPressed), for: .touchUpInside)
$0.addInteraction(UIPointerInteraction(delegate: self)) $0.addInteraction(UIPointerInteraction(delegate: self))
#endif
$0.addTarget(self, action: #selector(reblogPressed), for: .touchUpInside)
} }
private(set) lazy var moreButton = UIButton().configure { private(set) lazy var moreButton = UIButton().configure {
#if os(visionOS)
var config = UIButton.Configuration.borderedProminent()
config.image = UIImage(systemName: "ellipsis")
$0.configuration = config
#else
$0.setImage(UIImage(systemName: "ellipsis"), for: .normal) $0.setImage(UIImage(systemName: "ellipsis"), for: .normal)
$0.showsMenuAsPrimaryAction = true
$0.addInteraction(UIPointerInteraction(delegate: self)) $0.addInteraction(UIPointerInteraction(delegate: self))
#endif
$0.showsMenuAsPrimaryAction = true
} }
private var actionButtons: [UIButton] { private var actionButtons: [UIButton] {
@ -233,9 +257,13 @@ class ConversationMainStatusCollectionViewCell: UICollectionViewListCell, Status
]).configure { ]).configure {
$0.axis = .horizontal $0.axis = .horizontal
$0.distribution = .fillEqually $0.distribution = .fillEqually
#if os(visionOS)
$0.spacing = 8
#else
NSLayoutConstraint.activate([ NSLayoutConstraint.activate([
$0.heightAnchor.constraint(equalToConstant: 26), $0.heightAnchor.constraint(equalToConstant: 26),
]) ])
#endif
} }
private let accountDetailToContentWarningSpacer = UIView().configure { private let accountDetailToContentWarningSpacer = UIView().configure {
@ -278,8 +306,10 @@ class ConversationMainStatusCollectionViewCell: UICollectionViewListCell, Status
contentContainer.widthAnchor.constraint(equalTo: $0.widthAnchor), contentContainer.widthAnchor.constraint(equalTo: $0.widthAnchor),
firstSeparator.widthAnchor.constraint(equalTo: $0.widthAnchor), firstSeparator.widthAnchor.constraint(equalTo: $0.widthAnchor),
secondSeparator.widthAnchor.constraint(equalTo: $0.widthAnchor), secondSeparator.widthAnchor.constraint(equalTo: $0.widthAnchor),
actionsHStack.widthAnchor.constraint(equalTo: $0.widthAnchor),
]) ])
#if !os(visionOS)
actionsHStack.widthAnchor.constraint(equalTo: $0.widthAnchor).isActive = true
#endif
} }
var prevThreadLinkView: UIView? var prevThreadLinkView: UIView?

View File

@ -205,6 +205,17 @@ class TimelineStatusCollectionViewCell: UICollectionViewListCell, StatusCollecti
contentContainer.pollView contentContainer.pollView
} }
#if os(visionOS)
private lazy var actionsContainer = UIStackView(arrangedSubviews: [
replyButton,
favoriteButton,
reblogButton,
moreButton,
]).configure {
$0.axis = .horizontal
$0.spacing = 8
}
#else
private var placeholderReplyButtonLeadingConstraint: NSLayoutConstraint! private var placeholderReplyButtonLeadingConstraint: NSLayoutConstraint!
private lazy var actionsContainer = UIView().configure { private lazy var actionsContainer = UIView().configure {
replyButton.translatesAutoresizingMaskIntoConstraints = false replyButton.translatesAutoresizingMaskIntoConstraints = false
@ -239,29 +250,54 @@ class TimelineStatusCollectionViewCell: UICollectionViewListCell, StatusCollecti
moreButton.bottomAnchor.constraint(equalTo: $0.bottomAnchor), moreButton.bottomAnchor.constraint(equalTo: $0.bottomAnchor),
]) ])
} }
#endif
private(set) lazy var replyButton = UIButton().configure { private(set) lazy var replyButton = UIButton().configure {
#if os(visionOS)
var config = UIButton.Configuration.borderedProminent()
config.image = UIImage(systemName: "arrowshape.turn.up.left.fill")
$0.configuration = config
#else
$0.setImage(UIImage(systemName: "arrowshape.turn.up.left.fill"), for: .normal) $0.setImage(UIImage(systemName: "arrowshape.turn.up.left.fill"), for: .normal)
$0.addTarget(self, action: #selector(replyPressed), for: .touchUpInside)
$0.addInteraction(UIPointerInteraction(delegate: self)) $0.addInteraction(UIPointerInteraction(delegate: self))
#endif
$0.addTarget(self, action: #selector(replyPressed), for: .touchUpInside)
} }
private(set) lazy var favoriteButton = ToggleableButton(activeColor: UIColor(displayP3Red: 1, green: 0.8, blue: 0, alpha: 1)).configure { private(set) lazy var favoriteButton = ToggleableButton(activeColor: UIColor(displayP3Red: 1, green: 0.8, blue: 0, alpha: 1)).configure {
#if os(visionOS)
var config = UIButton.Configuration.borderedProminent()
config.image = UIImage(systemName: "star.fill")
$0.configuration = config
#else
$0.setImage(UIImage(systemName: "star.fill"), for: .normal) $0.setImage(UIImage(systemName: "star.fill"), for: .normal)
$0.addTarget(self, action: #selector(favoritePressed), for: .touchUpInside)
$0.addInteraction(UIPointerInteraction(delegate: self)) $0.addInteraction(UIPointerInteraction(delegate: self))
#endif
$0.addTarget(self, action: #selector(favoritePressed), for: .touchUpInside)
} }
private(set) lazy var reblogButton = ToggleableButton(activeColor: UIColor(displayP3Red: 1, green: 0.8, blue: 0, alpha: 1)).configure { private(set) lazy var reblogButton = ToggleableButton(activeColor: UIColor(displayP3Red: 1, green: 0.8, blue: 0, alpha: 1)).configure {
#if os(visionOS)
var config = UIButton.Configuration.borderedProminent()
config.image = UIImage(systemName: "repeat")
$0.configuration = config
#else
$0.setImage(UIImage(systemName: "repeat"), for: .normal) $0.setImage(UIImage(systemName: "repeat"), for: .normal)
$0.addTarget(self, action: #selector(reblogPressed), for: .touchUpInside)
$0.addInteraction(UIPointerInteraction(delegate: self)) $0.addInteraction(UIPointerInteraction(delegate: self))
#endif
$0.addTarget(self, action: #selector(reblogPressed), for: .touchUpInside)
} }
private(set) lazy var moreButton = UIButton().configure { private(set) lazy var moreButton = UIButton().configure {
#if os(visionOS)
var config = UIButton.Configuration.borderedProminent()
config.image = UIImage(systemName: "ellipsis")
$0.configuration = config
#else
$0.setImage(UIImage(systemName: "ellipsis"), for: .normal) $0.setImage(UIImage(systemName: "ellipsis"), for: .normal)
$0.showsMenuAsPrimaryAction = true
$0.addInteraction(UIPointerInteraction(delegate: self)) $0.addInteraction(UIPointerInteraction(delegate: self))
#endif
$0.showsMenuAsPrimaryAction = true
} }
private var actionButtons: [UIButton] { private var actionButtons: [UIButton] {
@ -306,7 +342,9 @@ class TimelineStatusCollectionViewCell: UICollectionViewListCell, StatusCollecti
private var rebloggerID: String? private var rebloggerID: String?
private var filterReason: String? private var filterReason: String?
#if !os(visionOS)
private var firstLayout = true private var firstLayout = true
#endif
var isGrayscale = false var isGrayscale = false
private var updateTimestampWorkItem: DispatchWorkItem? private var updateTimestampWorkItem: DispatchWorkItem?
private var hasCreatedObservers = false private var hasCreatedObservers = false
@ -339,14 +377,23 @@ class TimelineStatusCollectionViewCell: UICollectionViewListCell, StatusCollecti
mainContainer.trailingAnchor.constraint(equalTo: statusContainer.trailingAnchor, constant: -16), mainContainer.trailingAnchor.constraint(equalTo: statusContainer.trailingAnchor, constant: -16),
mainContainerBottomToActionsConstraint, mainContainerBottomToActionsConstraint,
actionsContainer.leadingAnchor.constraint(equalTo: statusContainer.leadingAnchor, constant: 16),
actionsContainer.trailingAnchor.constraint(equalTo: statusContainer.trailingAnchor, constant: -16),
// yes, this is deliberately 6. 4 looks to cramped, 8 looks uneven // yes, this is deliberately 6. 4 looks to cramped, 8 looks uneven
actionsContainer.bottomAnchor.constraint(equalTo: statusContainer.bottomAnchor, constant: -6), actionsContainer.bottomAnchor.constraint(equalTo: statusContainer.bottomAnchor, constant: -6),
metaIndicatorsView.bottomAnchor.constraint(lessThanOrEqualTo: statusContainer.bottomAnchor, constant: -6), metaIndicatorsView.bottomAnchor.constraint(lessThanOrEqualTo: statusContainer.bottomAnchor, constant: -6),
]) ])
#if os(visionOS)
NSLayoutConstraint.activate([
actionsContainer.leadingAnchor.constraint(equalTo: contentVStack.leadingAnchor),
])
#else
NSLayoutConstraint.activate([
actionsContainer.leadingAnchor.constraint(equalTo: statusContainer.leadingAnchor, constant: 16),
actionsContainer.trailingAnchor.constraint(equalTo: statusContainer.trailingAnchor, constant: -16),
])
#endif
updateActionsVisibility() updateActionsVisibility()
NotificationCenter.default.addObserver(self, selector: #selector(preferencesChanged), name: .preferencesChanged, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(preferencesChanged), name: .preferencesChanged, object: nil)
@ -359,6 +406,7 @@ class TimelineStatusCollectionViewCell: UICollectionViewListCell, StatusCollecti
override func layoutSubviews() { override func layoutSubviews() {
super.layoutSubviews() super.layoutSubviews()
#if !os(visionOS)
if firstLayout { if firstLayout {
firstLayout = false firstLayout = false
@ -368,6 +416,7 @@ class TimelineStatusCollectionViewCell: UICollectionViewListCell, StatusCollecti
placeholderReplyButtonLeadingConstraint.isActive = false placeholderReplyButtonLeadingConstraint.isActive = false
replyButton.imageView!.leadingAnchor.constraint(equalTo: contentTextView.leadingAnchor).isActive = true replyButton.imageView!.leadingAnchor.constraint(equalTo: contentTextView.leadingAnchor).isActive = true
} }
#endif
} }
override func updateConfiguration(using state: UICellConfigurationState) { override func updateConfiguration(using state: UICellConfigurationState) {

View File

@ -14,7 +14,12 @@ class ToggleableButton: UIButton {
var active: Bool { var active: Bool {
didSet { didSet {
tintColor = active ? activeColor : nil if var config = self.configuration {
config.baseForegroundColor = active ? activeColor : nil
self.configuration = config
} else {
tintColor = active ? activeColor : nil
}
} }
} }