metatext/Views/UIKit/Content Views/StatusView.swift

1102 lines
47 KiB
Swift
Raw Normal View History

2020-09-14 07:20:25 +00:00
// Copyright © 2020 Metabolist. All rights reserved.
2020-10-12 05:37:34 +00:00
// swiftlint:disable file_length
2021-02-02 18:02:30 +00:00
import Combine
2021-01-19 00:46:38 +00:00
import Mastodon
2021-02-22 23:59:33 +00:00
import SDWebImage
2020-09-14 07:20:25 +00:00
import UIKit
2020-12-01 23:53:14 +00:00
import ViewModels
2020-09-14 07:20:25 +00:00
2020-10-12 05:37:34 +00:00
final class StatusView: UIView {
2021-02-22 23:59:33 +00:00
let avatarImageView = SDAnimatedImageView()
2020-10-12 05:37:34 +00:00
let avatarButton = UIButton()
let infoIcon = UIImageView()
2021-02-22 07:10:34 +00:00
let infoLabel = AnimatedAttachmentLabel()
2021-02-07 00:54:11 +00:00
let rebloggerButton = UIButton()
2021-02-22 07:10:34 +00:00
let displayNameLabel = AnimatedAttachmentLabel()
2020-10-12 05:37:34 +00:00
let accountLabel = UILabel()
2021-02-07 01:40:39 +00:00
let nameButton = UIButton()
2020-10-12 05:37:34 +00:00
let timeLabel = UILabel()
2020-10-31 00:29:43 +00:00
let bodyView = StatusBodyView()
2020-10-12 05:37:34 +00:00
let contextParentTimeLabel = UILabel()
2021-01-29 02:50:48 +00:00
let visibilityImageView = UIImageView()
2020-10-12 05:37:34 +00:00
let applicationButton = UIButton(type: .system)
let rebloggedByButton = UIButton()
let favoritedByButton = UIButton()
let replyButton = UIButton()
let reblogButton = UIButton()
let favoriteButton = UIButton()
let shareButton = UIButton()
let menuButton = UIButton()
2020-11-30 02:54:11 +00:00
let buttonsStackView = UIStackView()
2021-03-03 05:02:07 +00:00
let reportSelectionSwitch = UISwitch()
2020-10-12 05:37:34 +00:00
private let containerStackView = UIStackView()
private let sideStackView = UIStackView()
private let mainStackView = UIStackView()
private let nameAccountContainerStackView = UIStackView()
private let nameAccountTimeStackView = UIStackView()
private let contextParentTimeApplicationStackView = UIStackView()
2021-01-29 02:50:48 +00:00
private let timeVisibilityDividerLabel = UILabel()
private let visibilityApplicationDividerLabel = UILabel()
2020-10-12 05:37:34 +00:00
private let contextParentTopNameAccountSpacingView = UIView()
private let contextParentBottomNameAccountSpacingView = UIView()
private let interactionsDividerView = UIView()
private let interactionsStackView = UIStackView()
private let buttonsDividerView = UIView()
private let inReplyToView = UIView()
private let hasReplyFollowingView = UIView()
private var statusConfiguration: StatusContentConfiguration
2021-02-07 00:54:11 +00:00
private var infoIconCenterYConstraint: NSLayoutConstraint?
2021-02-02 18:02:30 +00:00
private var cancellables = Set<AnyCancellable>()
2020-09-14 07:20:25 +00:00
init(configuration: StatusContentConfiguration) {
self.statusConfiguration = configuration
super.init(frame: .zero)
initialSetup()
2020-10-13 20:11:27 +00:00
applyStatusConfiguration()
2020-09-14 07:20:25 +00:00
}
@available(*, unavailable)
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
2021-02-07 02:27:17 +00:00
override func accessibilityActivate() -> Bool {
2021-03-03 05:02:07 +00:00
if reportSelectionSwitch.isHidden, !statusConfiguration.viewModel.shouldShowContent {
2021-02-07 02:27:17 +00:00
statusConfiguration.viewModel.toggleShowContent()
2021-02-25 00:58:50 +00:00
accessibilityAttributedLabel = accessibilityAttributedLabel(forceShowContent: true)
2021-02-23 03:24:57 +00:00
2021-02-07 02:27:17 +00:00
return true
} else {
return super.accessibilityActivate()
}
}
2020-09-14 07:20:25 +00:00
}
2021-01-19 00:46:38 +00:00
extension StatusView {
static func estimatedHeight(width: CGFloat,
2021-01-26 00:06:35 +00:00
identityContext: IdentityContext,
2021-01-19 00:46:38 +00:00
status: Status,
configuration: CollectionItem.StatusConfiguration) -> CGFloat {
var height = CGFloat.defaultSpacing * 2
let bodyWidth = width - .defaultSpacing - .avatarDimension
if status.reblog != nil || configuration.isPinned {
height += UIFont.preferredFont(forTextStyle: .caption1).lineHeight + .compactSpacing
}
if configuration.isContextParent {
height += .avatarDimension + .minimumButtonDimension * 2.5 + .hairline * 2 + .compactSpacing * 4
} else {
height += UIFont.preferredFont(forTextStyle: .headline).lineHeight
+ .compactSpacing + .minimumButtonDimension / 2
}
height += StatusBodyView.estimatedHeight(
width: bodyWidth,
2021-01-26 00:06:35 +00:00
identityContext: identityContext,
2021-01-19 00:46:38 +00:00
status: status,
configuration: configuration)
+ .compactSpacing
return height
}
2021-03-03 05:02:07 +00:00
func refreshAccessibilityLabel() {
accessibilityAttributedLabel = accessibilityAttributedLabel(forceShowContent: false)
}
2021-01-19 00:46:38 +00:00
}
2020-09-14 07:20:25 +00:00
extension StatusView: UIContentView {
var configuration: UIContentConfiguration {
get { statusConfiguration }
set {
guard let statusConfiguration = newValue as? StatusContentConfiguration else { return }
self.statusConfiguration = statusConfiguration
applyStatusConfiguration()
}
}
}
extension StatusView: UITextViewDelegate {
func textView(
_ textView: UITextView,
shouldInteractWith URL: URL,
in characterRange: NSRange,
interaction: UITextItemInteraction) -> Bool {
switch interaction {
2020-09-15 01:39:35 +00:00
case .invokeDefaultAction:
statusConfiguration.viewModel.urlSelected(URL)
return false
case .preview: return false
case .presentActions: return false
@unknown default: return false
}
}
}
2020-09-14 07:20:25 +00:00
private extension StatusView {
2020-10-12 05:37:34 +00:00
static let actionButtonTitleEdgeInsets = UIEdgeInsets(top: 0, left: 2, bottom: 0, right: 0)
2020-10-12 05:37:34 +00:00
var actionButtons: [UIButton] {
[replyButton, reblogButton, favoriteButton, shareButton, menuButton]
}
2020-09-22 06:53:11 +00:00
2020-10-12 05:37:34 +00:00
// swiftlint:disable function_body_length
func initialSetup() {
addSubview(containerStackView)
containerStackView.translatesAutoresizingMaskIntoConstraints = false
containerStackView.spacing = .defaultSpacing
infoIcon.tintColor = .secondaryLabel
2021-02-07 00:54:11 +00:00
infoIcon.contentMode = .scaleAspectFit
2020-10-12 05:37:34 +00:00
infoIcon.setContentCompressionResistancePriority(.required, for: .vertical)
sideStackView.axis = .vertical
sideStackView.alignment = .trailing
sideStackView.spacing = .compactSpacing
sideStackView.addArrangedSubview(infoIcon)
sideStackView.addArrangedSubview(UIView())
containerStackView.addArrangedSubview(sideStackView)
mainStackView.axis = .vertical
mainStackView.spacing = .compactSpacing
containerStackView.addArrangedSubview(mainStackView)
infoLabel.font = .preferredFont(forTextStyle: .caption1)
infoLabel.textColor = .secondaryLabel
infoLabel.adjustsFontForContentSizeCategory = true
2021-02-22 07:10:34 +00:00
infoLabel.isUserInteractionEnabled = true
2020-10-12 05:37:34 +00:00
infoLabel.setContentHuggingPriority(.required, for: .vertical)
mainStackView.addArrangedSubview(infoLabel)
2021-02-22 07:10:34 +00:00
infoLabel.addSubview(rebloggerButton)
rebloggerButton.translatesAutoresizingMaskIntoConstraints = false
2021-02-07 00:54:11 +00:00
rebloggerButton.addAction(
UIAction { [weak self] _ in self?.statusConfiguration.viewModel.rebloggerAccountSelected() },
for: .touchUpInside)
2021-02-22 07:10:34 +00:00
let rebloggerTouchStartAction = UIAction { [weak self] _ in self?.infoLabel.alpha = 0.75 }
rebloggerButton.addAction(rebloggerTouchStartAction, for: .touchDown)
rebloggerButton.addAction(rebloggerTouchStartAction, for: .touchDragEnter)
let rebloggerTouchEnd = UIAction { [weak self] _ in self?.infoLabel.alpha = 1 }
rebloggerButton.addAction(rebloggerTouchEnd, for: .touchDragExit)
rebloggerButton.addAction(rebloggerTouchEnd, for: .touchUpInside)
rebloggerButton.addAction(rebloggerTouchEnd, for: .touchUpOutside)
rebloggerButton.addAction(rebloggerTouchEnd, for: .touchCancel)
2020-10-12 05:37:34 +00:00
displayNameLabel.font = .preferredFont(forTextStyle: .headline)
displayNameLabel.adjustsFontForContentSizeCategory = true
displayNameLabel.setContentHuggingPriority(.required, for: .horizontal)
2021-02-07 02:58:51 +00:00
displayNameLabel.setContentHuggingPriority(.required, for: .vertical)
2020-10-12 05:37:34 +00:00
displayNameLabel.setContentCompressionResistancePriority(.required, for: .horizontal)
nameAccountTimeStackView.addArrangedSubview(displayNameLabel)
accountLabel.font = .preferredFont(forTextStyle: .subheadline)
accountLabel.adjustsFontForContentSizeCategory = true
accountLabel.textColor = .secondaryLabel
2021-02-07 01:40:39 +00:00
accountLabel.setContentHuggingPriority(.required, for: .horizontal)
2021-02-07 02:58:51 +00:00
accountLabel.setContentHuggingPriority(.required, for: .vertical)
2020-10-12 05:37:34 +00:00
nameAccountTimeStackView.addArrangedSubview(accountLabel)
timeLabel.font = .preferredFont(forTextStyle: .subheadline)
timeLabel.adjustsFontForContentSizeCategory = true
timeLabel.textColor = .secondaryLabel
2021-02-07 01:40:39 +00:00
timeLabel.textAlignment = .right
2020-10-12 05:37:34 +00:00
timeLabel.setContentCompressionResistancePriority(.required, for: .horizontal)
2021-02-07 02:58:51 +00:00
timeLabel.setContentHuggingPriority(.required, for: .vertical)
2020-10-12 05:37:34 +00:00
nameAccountTimeStackView.addArrangedSubview(timeLabel)
nameAccountContainerStackView.spacing = .defaultSpacing
nameAccountContainerStackView.addArrangedSubview(nameAccountTimeStackView)
mainStackView.addArrangedSubview(nameAccountContainerStackView)
2021-02-07 01:40:39 +00:00
nameButton.translatesAutoresizingMaskIntoConstraints = false
nameButton.addAction(
UIAction { [weak self] _ in
self?.displayNameLabel.alpha = 1
self?.accountLabel.alpha = 1
self?.statusConfiguration.viewModel.accountSelected()
},
for: .touchUpInside)
nameButton.addAction(
UIAction { [weak self] _ in
self?.displayNameLabel.alpha = 0.5
self?.accountLabel.alpha = 0.5
},
for: .touchDown)
let unhighlightAction = UIAction { [weak self] _ in
self?.displayNameLabel.alpha = 1
self?.accountLabel.alpha = 1
}
nameButton.addAction(unhighlightAction, for: .touchUpOutside)
nameButton.addAction(unhighlightAction, for: .touchCancel)
nameButton.addAction(unhighlightAction, for: .touchDragOutside)
nameAccountContainerStackView.addSubview(nameButton)
2020-10-31 00:29:43 +00:00
mainStackView.addArrangedSubview(bodyView)
2020-10-12 05:37:34 +00:00
contextParentTimeLabel.font = .preferredFont(forTextStyle: .footnote)
contextParentTimeLabel.adjustsFontForContentSizeCategory = true
contextParentTimeLabel.textColor = .secondaryLabel
contextParentTimeLabel.setContentHuggingPriority(.required, for: .horizontal)
contextParentTimeApplicationStackView.addArrangedSubview(contextParentTimeLabel)
2021-01-29 02:50:48 +00:00
for label in [timeVisibilityDividerLabel, visibilityApplicationDividerLabel] {
label.font = .preferredFont(forTextStyle: .footnote)
label.adjustsFontForContentSizeCategory = true
label.textColor = .secondaryLabel
label.text = ""
label.setContentHuggingPriority(.required, for: .horizontal)
2021-02-02 20:18:15 +00:00
label.isAccessibilityElement = false
2021-01-29 02:50:48 +00:00
}
contextParentTimeApplicationStackView.addArrangedSubview(timeVisibilityDividerLabel)
contextParentTimeApplicationStackView.addArrangedSubview(visibilityImageView)
visibilityImageView.contentMode = .scaleAspectFit
visibilityImageView.tintColor = .secondaryLabel
2021-02-02 20:18:15 +00:00
visibilityImageView.isAccessibilityElement = true
2021-01-29 02:50:48 +00:00
contextParentTimeApplicationStackView.addArrangedSubview(visibilityApplicationDividerLabel)
2020-10-12 05:37:34 +00:00
applicationButton.titleLabel?.font = .preferredFont(forTextStyle: .footnote)
applicationButton.titleLabel?.adjustsFontForContentSizeCategory = true
applicationButton.setTitleColor(.secondaryLabel, for: .disabled)
applicationButton.setContentHuggingPriority(.required, for: .horizontal)
applicationButton.addAction(
UIAction { [weak self] _ in
guard
let viewModel = self?.statusConfiguration.viewModel,
let url = viewModel.applicationURL
else { return }
2020-09-29 01:14:43 +00:00
2020-10-12 05:37:34 +00:00
viewModel.urlSelected(url)
},
for: .touchUpInside)
contextParentTimeApplicationStackView.addArrangedSubview(applicationButton)
contextParentTimeApplicationStackView.addArrangedSubview(UIView())
2020-10-12 05:37:34 +00:00
contextParentTimeApplicationStackView.spacing = .compactSpacing
mainStackView.addArrangedSubview(contextParentTimeApplicationStackView)
2020-10-12 05:37:34 +00:00
for view in [interactionsDividerView, buttonsDividerView] {
view.backgroundColor = .opaqueSeparator
view.heightAnchor.constraint(equalToConstant: .hairline).isActive = true
}
mainStackView.addArrangedSubview(interactionsDividerView)
mainStackView.addArrangedSubview(interactionsStackView)
mainStackView.addArrangedSubview(buttonsDividerView)
2020-09-14 23:32:34 +00:00
2020-10-12 05:37:34 +00:00
rebloggedByButton.contentHorizontalAlignment = .leading
rebloggedByButton.addAction(
2020-09-28 23:23:41 +00:00
UIAction { [weak self] _ in self?.statusConfiguration.viewModel.rebloggedBySelected() },
for: .touchUpInside)
2020-10-12 05:37:34 +00:00
interactionsStackView.addArrangedSubview(rebloggedByButton)
2020-09-28 23:23:41 +00:00
2020-10-12 05:37:34 +00:00
favoritedByButton.contentHorizontalAlignment = .leading
favoritedByButton.addAction(
2020-09-23 01:00:56 +00:00
UIAction { [weak self] _ in self?.statusConfiguration.viewModel.favoritedBySelected() },
for: .touchUpInside)
2020-10-12 05:37:34 +00:00
interactionsStackView.addArrangedSubview(favoritedByButton)
interactionsStackView.distribution = .fillEqually
2020-09-14 23:32:34 +00:00
2021-01-10 05:56:15 +00:00
replyButton.addAction(
UIAction { [weak self] _ in self?.statusConfiguration.viewModel.reply() },
for: .touchUpInside)
2021-02-02 18:55:16 +00:00
replyButton.accessibilityLabel = NSLocalizedString("status.reply-button.accessibility-label", comment: "")
2021-01-10 05:56:15 +00:00
2021-01-04 01:51:52 +00:00
reblogButton.addAction(
2021-01-31 19:23:33 +00:00
UIAction { [weak self] _ in
guard let self = self,
!self.statusConfiguration.viewModel.identityContext.appPreferences.requireDoubleTapToReblog
else { return }
self.reblog()
},
2021-01-04 01:51:52 +00:00
for: .touchUpInside)
2021-01-31 19:23:33 +00:00
reblogButton.addTarget(self, action: #selector(reblogButtonDoubleTap(sender:event:)), for: .touchDownRepeat)
2020-10-12 05:37:34 +00:00
favoriteButton.addAction(
2021-01-31 19:23:33 +00:00
UIAction { [weak self] _ in
guard let self = self,
!self.statusConfiguration.viewModel.identityContext.appPreferences.requireDoubleTapToFavorite
else { return }
self.favorite()
},
2020-10-12 05:37:34 +00:00
for: .touchUpInside)
2021-02-02 18:55:16 +00:00
favoriteButton.accessibilityLabel = NSLocalizedString("status.favorite-button.accessibility-label", comment: "")
2021-01-31 19:23:33 +00:00
favoriteButton.addTarget(self, action: #selector(favoriteButtonDoubleTap(sender:event:)), for: .touchDownRepeat)
2020-10-12 05:37:34 +00:00
shareButton.addAction(
UIAction { [weak self] _ in self?.statusConfiguration.viewModel.shareStatus() },
for: .touchUpInside)
2020-11-30 02:54:11 +00:00
menuButton.showsMenuAsPrimaryAction = true
2020-10-12 05:37:34 +00:00
for button in actionButtons {
button.titleLabel?.font = .preferredFont(forTextStyle: .footnote)
button.titleLabel?.adjustsFontSizeToFitWidth = true
button.tintColor = .secondaryLabel
button.setTitleColor(.secondaryLabel, for: .normal)
button.titleEdgeInsets = Self.actionButtonTitleEdgeInsets
buttonsStackView.addArrangedSubview(button)
button.widthAnchor.constraint(greaterThanOrEqualToConstant: .minimumButtonDimension).isActive = true
}
buttonsStackView.distribution = .equalSpacing
mainStackView.addArrangedSubview(buttonsStackView)
avatarImageView.layer.cornerRadius = .avatarDimension / 2
avatarImageView.clipsToBounds = true
let avatarHeightConstraint = avatarImageView.heightAnchor.constraint(equalToConstant: .avatarDimension)
avatarHeightConstraint.priority = .justBelowMax
avatarButton.translatesAutoresizingMaskIntoConstraints = false
avatarImageView.addSubview(avatarButton)
avatarImageView.isUserInteractionEnabled = true
avatarButton.setBackgroundImage(.highlightedButtonBackground, for: .highlighted)
avatarButton.addAction(
UIAction { [weak self] _ in self?.statusConfiguration.viewModel.accountSelected() },
2020-09-29 06:45:41 +00:00
for: .touchUpInside)
2020-10-12 05:37:34 +00:00
for view in [inReplyToView, hasReplyFollowingView] {
addSubview(view)
view.translatesAutoresizingMaskIntoConstraints = false
view.backgroundColor = .opaqueSeparator
view.widthAnchor.constraint(equalToConstant: .hairline).isActive = true
}
2021-03-03 05:02:07 +00:00
containerStackView.addArrangedSubview(reportSelectionSwitch)
reportSelectionSwitch.setContentCompressionResistancePriority(.required, for: .horizontal)
reportSelectionSwitch.setContentHuggingPriority(.required, for: .horizontal)
reportSelectionSwitch.isHidden = true
2020-10-12 05:37:34 +00:00
NSLayoutConstraint.activate([
containerStackView.topAnchor.constraint(equalTo: readableContentGuide.topAnchor),
containerStackView.leadingAnchor.constraint(equalTo: readableContentGuide.leadingAnchor),
containerStackView.trailingAnchor.constraint(equalTo: readableContentGuide.trailingAnchor),
containerStackView.bottomAnchor.constraint(equalTo: readableContentGuide.bottomAnchor),
avatarImageView.widthAnchor.constraint(equalToConstant: .avatarDimension),
avatarHeightConstraint,
sideStackView.widthAnchor.constraint(equalToConstant: .avatarDimension),
avatarButton.leadingAnchor.constraint(equalTo: avatarImageView.leadingAnchor),
avatarButton.topAnchor.constraint(equalTo: avatarImageView.topAnchor),
avatarButton.bottomAnchor.constraint(equalTo: avatarImageView.bottomAnchor),
2021-01-19 00:46:38 +00:00
avatarButton.trailingAnchor.constraint(equalTo: avatarImageView.trailingAnchor),
2021-02-22 07:10:34 +00:00
infoIcon.centerYAnchor.constraint(equalTo: infoLabel.centerYAnchor),
2021-02-07 01:40:39 +00:00
nameButton.leadingAnchor.constraint(equalTo: displayNameLabel.leadingAnchor),
nameButton.topAnchor.constraint(equalTo: displayNameLabel.topAnchor),
nameButton.trailingAnchor.constraint(equalTo: accountLabel.trailingAnchor),
nameButton.bottomAnchor.constraint(equalTo: accountLabel.bottomAnchor),
2021-01-19 00:46:38 +00:00
contextParentTimeApplicationStackView.heightAnchor.constraint(
greaterThanOrEqualToConstant: .minimumButtonDimension / 2),
2021-02-22 07:10:34 +00:00
interactionsStackView.heightAnchor.constraint(greaterThanOrEqualToConstant: .minimumButtonDimension),
rebloggerButton.leadingAnchor.constraint(equalTo: infoLabel.leadingAnchor),
rebloggerButton.topAnchor.constraint(equalTo: infoLabel.topAnchor),
rebloggerButton.trailingAnchor.constraint(equalTo: infoLabel.trailingAnchor),
rebloggerButton.bottomAnchor.constraint(equalTo: infoLabel.bottomAnchor)
2020-10-12 05:37:34 +00:00
])
2021-02-02 18:02:30 +00:00
NotificationCenter.default.publisher(for: UIAccessibility.voiceOverStatusDidChangeNotification)
.sink { [weak self] _ in self?.configureUserInteractionEnabledForAccessibility() }
.store(in: &cancellables)
2020-09-14 07:20:25 +00:00
}
func applyStatusConfiguration() {
let viewModel = statusConfiguration.viewModel
2020-10-12 05:37:34 +00:00
let isContextParent = viewModel.configuration.isContextParent
2021-02-06 22:27:57 +00:00
let mutableDisplayName = NSMutableAttributedString(string: viewModel.accountViewModel.displayName)
2021-01-31 13:38:59 +00:00
let isAuthenticated = viewModel.identityContext.identity.authenticated
&& !viewModel.identityContext.identity.pending
2020-10-15 07:44:01 +00:00
2020-12-01 23:53:14 +00:00
menuButton.menu = menu(viewModel: viewModel)
2021-02-22 23:59:33 +00:00
avatarImageView.sd_setImage(with: viewModel.avatarURL)
2021-02-02 20:18:15 +00:00
avatarButton.accessibilityLabel = String.localizedStringWithFormat(
NSLocalizedString("account.avatar.accessibility-label-%@", comment: ""),
2021-02-06 22:27:57 +00:00
viewModel.accountViewModel.displayName)
2020-10-12 05:37:34 +00:00
sideStackView.isHidden = isContextParent
2021-02-28 23:30:16 +00:00
if isContextParent, avatarImageView.superview !== nameAccountContainerStackView {
2020-10-12 05:37:34 +00:00
nameAccountContainerStackView.insertArrangedSubview(avatarImageView, at: 0)
2021-02-28 23:30:16 +00:00
} else if avatarImageView.superview !== sideStackView {
2020-10-12 05:37:34 +00:00
sideStackView.insertArrangedSubview(avatarImageView, at: 1)
}
NSLayoutConstraint.activate([
inReplyToView.centerXAnchor.constraint(equalTo: avatarImageView.centerXAnchor),
inReplyToView.topAnchor.constraint(equalTo: topAnchor),
inReplyToView.bottomAnchor.constraint(equalTo: avatarImageView.topAnchor),
hasReplyFollowingView.centerXAnchor.constraint(equalTo: avatarImageView.centerXAnchor),
hasReplyFollowingView.topAnchor.constraint(equalTo: avatarImageView.bottomAnchor),
hasReplyFollowingView.bottomAnchor.constraint(equalTo: bottomAnchor)
])
inReplyToView.isHidden = !viewModel.configuration.isReplyInContext
hasReplyFollowingView.isHidden = !viewModel.configuration.hasReplyFollowing
2021-02-22 07:10:34 +00:00
if viewModel.isReblog {
2021-02-07 00:54:11 +00:00
let attributedTitle = "status.reblogged-by".localizedBolding(
2020-10-31 00:29:43 +00:00
displayName: viewModel.rebloggedByDisplayName,
2021-01-12 07:33:35 +00:00
emojis: viewModel.rebloggedByDisplayNameEmojis,
2021-02-22 07:10:34 +00:00
label: infoLabel,
identityContext: viewModel.identityContext)
2021-02-07 00:54:11 +00:00
let highlightedAttributedTitle = NSMutableAttributedString(attributedString: attributedTitle)
highlightedAttributedTitle.addAttribute(
.foregroundColor,
value: UIColor.tertiaryLabel,
range: .init(location: 0, length: highlightedAttributedTitle.length))
2021-02-22 07:10:34 +00:00
infoLabel.attributedText = attributedTitle
2020-10-12 05:37:34 +00:00
infoIcon.image = UIImage(
systemName: "arrow.2.squarepath",
withConfiguration: UIImage.SymbolConfiguration(scale: .small))
2021-02-22 07:10:34 +00:00
infoLabel.isHidden = false
2020-10-12 05:37:34 +00:00
infoIcon.isHidden = false
2021-02-07 00:54:11 +00:00
rebloggerButton.isHidden = false
2020-10-12 05:37:34 +00:00
} else if viewModel.configuration.isPinned {
2021-01-31 01:43:48 +00:00
let pinnedText: String
switch viewModel.identityContext.appPreferences.statusWord {
case .toot:
pinnedText = NSLocalizedString("status.pinned.toot", comment: "")
case .post:
pinnedText = NSLocalizedString("status.pinned.post", comment: "")
}
infoLabel.text = pinnedText
2021-02-07 00:54:11 +00:00
infoIcon.centerYAnchor.constraint(equalTo: infoLabel.centerYAnchor).isActive = true
2020-10-12 05:37:34 +00:00
infoIcon.image = UIImage(
systemName: "pin",
withConfiguration: UIImage.SymbolConfiguration(scale: .small))
infoLabel.isHidden = false
infoIcon.isHidden = false
2021-02-07 00:54:11 +00:00
rebloggerButton.isHidden = true
2020-10-12 05:37:34 +00:00
} else {
2021-02-03 06:00:29 +00:00
infoLabel.text = nil
infoIcon.image = nil
2020-10-12 05:37:34 +00:00
infoLabel.isHidden = true
infoIcon.isHidden = true
2021-02-07 00:54:11 +00:00
rebloggerButton.setTitle(nil, for: .normal)
rebloggerButton.setImage(nil, for: .normal)
rebloggerButton.isHidden = true
}
2021-02-22 07:10:34 +00:00
mutableDisplayName.insert(emojis: viewModel.accountViewModel.emojis,
view: displayNameLabel,
identityContext: viewModel.identityContext)
mutableDisplayName.resizeAttachments(toLineHeight: displayNameLabel.font.lineHeight)
displayNameLabel.attributedText = mutableDisplayName
2021-02-07 01:40:39 +00:00
accountLabel.text = viewModel.accountName
2021-02-09 05:53:52 +00:00
let nameButtonAccessibilityAttributedLabel = NSMutableAttributedString(attributedString: mutableDisplayName)
2021-02-07 01:40:39 +00:00
nameButtonAccessibilityAttributedLabel.appendWithSeparator(viewModel.accountName)
nameButton.accessibilityAttributedLabel = nameButtonAccessibilityAttributedLabel
2020-10-12 05:37:34 +00:00
nameAccountTimeStackView.axis = isContextParent ? .vertical : .horizontal
nameAccountTimeStackView.alignment = isContextParent ? .leading : .fill
nameAccountTimeStackView.spacing = isContextParent ? 0 : .compactSpacing
contextParentTopNameAccountSpacingView.removeFromSuperview()
contextParentBottomNameAccountSpacingView.removeFromSuperview()
if isContextParent {
nameAccountTimeStackView.insertArrangedSubview(contextParentTopNameAccountSpacingView, at: 0)
nameAccountTimeStackView.addArrangedSubview(contextParentBottomNameAccountSpacingView)
contextParentTopNameAccountSpacingView.heightAnchor
.constraint(equalTo: contextParentBottomNameAccountSpacingView.heightAnchor).isActive = true
}
timeLabel.text = viewModel.time
2021-02-02 20:18:15 +00:00
timeLabel.accessibilityLabel = viewModel.accessibilityTime
2020-10-12 05:37:34 +00:00
timeLabel.isHidden = isContextParent
2020-10-31 00:29:43 +00:00
bodyView.viewModel = viewModel
2020-10-12 05:37:34 +00:00
contextParentTimeLabel.text = viewModel.contextParentTime
2021-02-02 20:18:15 +00:00
contextParentTimeLabel.accessibilityLabel = viewModel.accessibilityContextParentTime
2021-01-29 02:50:48 +00:00
visibilityImageView.image = UIImage(systemName: viewModel.visibility.systemImageName)
2021-02-02 20:18:15 +00:00
visibilityImageView.accessibilityLabel = viewModel.visibility.title
2021-01-29 02:50:48 +00:00
visibilityApplicationDividerLabel.isHidden = viewModel.applicationName == nil
applicationButton.isHidden = viewModel.applicationName == nil
applicationButton.setTitle(viewModel.applicationName, for: .normal)
applicationButton.isEnabled = viewModel.applicationURL != nil
2020-10-12 05:37:34 +00:00
contextParentTimeApplicationStackView.isHidden = !isContextParent
let noReblogs = viewModel.reblogsCount == 0
let noFavorites = viewModel.favoritesCount == 0
2020-10-12 05:37:34 +00:00
let noInteractions = !isContextParent || (noReblogs && noFavorites)
2020-12-03 01:06:46 +00:00
rebloggedByButton.setAttributedLocalizedTitle(
localizationKey: "status.reblogs-count",
count: viewModel.reblogsCount)
2020-10-12 05:37:34 +00:00
rebloggedByButton.isHidden = noReblogs
2020-12-03 01:06:46 +00:00
favoritedByButton.setAttributedLocalizedTitle(
localizationKey: "status.favorites-count",
count: viewModel.favoritesCount)
2020-10-12 05:37:34 +00:00
favoritedByButton.isHidden = noFavorites
2020-10-12 05:37:34 +00:00
interactionsDividerView.isHidden = noInteractions
interactionsStackView.isHidden = noInteractions
buttonsDividerView.isHidden = !isContextParent
2020-10-12 05:37:34 +00:00
for button in actionButtons {
button.contentHorizontalAlignment = isContextParent ? .center : .leading
2020-10-12 05:37:34 +00:00
if isContextParent {
button.heightAnchor.constraint(equalToConstant: .minimumButtonDimension).isActive = true
} else {
2021-01-19 00:46:38 +00:00
button.heightAnchor.constraint(
2021-01-31 19:52:19 +00:00
greaterThanOrEqualToConstant: .minimumButtonDimension * 2 / 3).isActive = true
2020-10-12 05:37:34 +00:00
}
}
2020-10-12 05:37:34 +00:00
setButtonImages(scale: isContextParent ? .medium : .small)
2020-10-12 05:37:34 +00:00
replyButton.setCountTitle(count: viewModel.repliesCount, isContextParent: isContextParent)
2021-01-31 13:38:59 +00:00
replyButton.isEnabled = isAuthenticated
if viewModel.identityContext.appPreferences.showReblogAndFavoriteCounts || isContextParent {
reblogButton.setCountTitle(count: viewModel.reblogsCount, isContextParent: isContextParent)
favoriteButton.setCountTitle(count: viewModel.favoritesCount, isContextParent: isContextParent)
} else {
reblogButton.setTitle(nil, for: .normal)
favoriteButton.setTitle(nil, for: .normal)
}
2021-01-31 19:46:19 +00:00
setReblogButtonColor(reblogged: viewModel.reblogged)
2021-01-31 13:38:59 +00:00
reblogButton.isEnabled = viewModel.canBeReblogged && isAuthenticated
2021-01-31 19:46:19 +00:00
setFavoriteButtonColor(favorited: viewModel.favorited)
2021-01-31 13:38:59 +00:00
favoriteButton.isEnabled = isAuthenticated
2021-01-19 19:00:26 +00:00
shareButton.tag = viewModel.sharingURL?.hashValue ?? 0
2021-01-31 13:38:59 +00:00
menuButton.isEnabled = isAuthenticated
2021-02-02 18:02:30 +00:00
2021-03-03 05:02:07 +00:00
reportSelectionSwitch.isOn = viewModel.selectedForReport
2021-02-02 18:02:30 +00:00
isAccessibilityElement = !viewModel.configuration.isContextParent
2021-02-25 00:58:50 +00:00
accessibilityAttributedLabel = accessibilityAttributedLabel(forceShowContent: false)
2021-02-02 18:02:30 +00:00
configureUserInteractionEnabledForAccessibility()
2021-02-02 18:55:16 +00:00
accessibilityCustomActions = accessibilityCustomActions(viewModel: viewModel)
}
2020-12-01 23:53:14 +00:00
func menu(viewModel: StatusViewModel) -> UIMenu {
2021-02-10 07:46:00 +00:00
var sections = [UIMenu]()
var firstSectionItems = [
2020-12-01 23:53:14 +00:00
UIAction(
title: viewModel.bookmarked
? NSLocalizedString("status.unbookmark", comment: "")
: NSLocalizedString("status.bookmark", comment: ""),
image: UIImage(systemName: "bookmark")) { _ in
viewModel.toggleBookmarked()
2021-01-11 03:12:06 +00:00
}
]
if let pinned = viewModel.pinned {
2021-02-10 07:46:00 +00:00
firstSectionItems.append(UIAction(
2021-01-11 03:12:06 +00:00
title: pinned
? NSLocalizedString("status.unpin", comment: "")
: NSLocalizedString("status.pin", comment: ""),
image: UIImage(systemName: "pin")) { _ in
viewModel.togglePinned()
})
}
2021-02-10 07:46:00 +00:00
sections.append(UIMenu(options: .displayInline, children: firstSectionItems))
var secondSectionItems = [UIAction]()
2021-01-11 03:12:06 +00:00
if viewModel.isMine {
2021-02-10 07:46:00 +00:00
secondSectionItems += [
2021-01-11 22:45:30 +00:00
UIAction(
title: viewModel.muted
? NSLocalizedString("status.unmute", comment: "")
: NSLocalizedString("status.mute", comment: ""),
image: UIImage(systemName: viewModel.muted ? "speaker" : "speaker.slash")) { _ in
viewModel.toggleMuted()
},
UIAction(
title: NSLocalizedString("status.delete", comment: ""),
image: UIImage(systemName: "trash"),
attributes: .destructive) { _ in
2021-01-11 23:40:46 +00:00
viewModel.confirmDelete(redraft: false)
2021-01-11 22:45:30 +00:00
},
UIAction(
title: NSLocalizedString("status.delete-and-redraft", comment: ""),
image: UIImage(systemName: "trash.circle"),
attributes: .destructive) { _ in
2021-01-11 23:40:46 +00:00
viewModel.confirmDelete(redraft: true)
2021-01-11 22:45:30 +00:00
}
]
2021-02-11 07:11:37 +00:00
sections.append(UIMenu(options: .displayInline, children: secondSectionItems))
2021-01-11 03:12:06 +00:00
} else {
2021-02-10 07:46:00 +00:00
if let relationship = viewModel.accountViewModel.relationship {
if relationship.muting {
secondSectionItems.append(UIAction(
title: NSLocalizedString("account.unmute", comment: ""),
image: UIImage(systemName: "speaker")) { _ in
2021-02-10 23:41:41 +00:00
viewModel.accountViewModel.confirmUnmute()
2021-02-10 07:46:00 +00:00
})
} else {
secondSectionItems.append(UIAction(
title: NSLocalizedString("account.mute", comment: ""),
image: UIImage(systemName: "speaker.slash")) { _ in
2021-02-10 23:41:41 +00:00
viewModel.accountViewModel.confirmMute()
2021-02-10 07:46:00 +00:00
})
}
if relationship.blocking {
secondSectionItems.append(UIAction(
title: NSLocalizedString("account.unblock", comment: ""),
image: UIImage(systemName: "slash.circle"),
attributes: .destructive) { _ in
viewModel.accountViewModel.confirmUnblock()
})
} else {
secondSectionItems.append(UIAction(
title: NSLocalizedString("account.block", comment: ""),
image: UIImage(systemName: "slash.circle"),
attributes: .destructive) { _ in
viewModel.accountViewModel.confirmBlock()
})
}
}
secondSectionItems.append(UIAction(
2020-12-01 23:53:14 +00:00
title: NSLocalizedString("report", comment: ""),
image: UIImage(systemName: "flag"),
attributes: .destructive) { _ in
viewModel.reportStatus()
2021-01-11 03:12:06 +00:00
})
2021-02-10 07:46:00 +00:00
sections.append(UIMenu(options: .displayInline, children: secondSectionItems))
if !viewModel.accountViewModel.isLocal,
let domain = viewModel.accountViewModel.domain,
let relationship = viewModel.accountViewModel.relationship {
let domainBlockAction: UIAction
if relationship.domainBlocking {
domainBlockAction = UIAction(
title: String.localizedStringWithFormat(
NSLocalizedString("account.domain-unblock-%@", comment: ""),
domain),
image: UIImage(systemName: "slash.circle"),
attributes: .destructive) { _ in
viewModel.accountViewModel.confirmDomainUnblock(domain: domain)
}
} else {
domainBlockAction = UIAction(
title: String.localizedStringWithFormat(
NSLocalizedString("account.domain-block-%@", comment: ""),
domain),
image: UIImage(systemName: "slash.circle"),
attributes: .destructive) { _ in
viewModel.accountViewModel.confirmDomainBlock(domain: domain)
}
}
sections.append(UIMenu(options: .displayInline, children: [domainBlockAction]))
}
2021-01-11 03:12:06 +00:00
}
2021-02-10 07:46:00 +00:00
return UIMenu(children: sections)
2020-12-01 23:53:14 +00:00
}
2021-02-10 07:46:00 +00:00
// swiftlint:enable function_body_length
2020-12-01 23:53:14 +00:00
2021-02-25 00:58:50 +00:00
func accessibilityAttributedLabel(forceShowContent: Bool) -> NSAttributedString {
let accessibilityAttributedLabel = NSMutableAttributedString(string: "")
2021-03-03 05:02:07 +00:00
if !reportSelectionSwitch.isHidden, reportSelectionSwitch.isOn {
accessibilityAttributedLabel.appendWithSeparator(NSLocalizedString("selected", comment: ""))
}
2021-02-25 00:58:50 +00:00
if !infoLabel.isHidden, let infoText = infoLabel.attributedText {
accessibilityAttributedLabel.appendWithSeparator(infoText)
}
if let displayName = displayNameLabel.attributedText {
if accessibilityAttributedLabel.string.isEmpty {
accessibilityAttributedLabel.append(displayName)
} else {
accessibilityAttributedLabel.appendWithSeparator(displayName)
}
}
accessibilityAttributedLabel.appendWithSeparator(
bodyView.accessibilityAttributedLabel(forceShowContent: forceShowContent))
if let accessibilityTime = statusConfiguration.viewModel.accessibilityTime {
accessibilityAttributedLabel.appendWithSeparator(accessibilityTime)
}
if statusConfiguration.viewModel.repliesCount > 0 {
accessibilityAttributedLabel.appendWithSeparator(
String.localizedStringWithFormat(
NSLocalizedString("status.replies-count", comment: ""),
statusConfiguration.viewModel.repliesCount))
}
if statusConfiguration.viewModel.identityContext.appPreferences.showReblogAndFavoriteCounts {
if statusConfiguration.viewModel.reblogsCount > 0 {
accessibilityAttributedLabel.appendWithSeparator(
String.localizedStringWithFormat(
NSLocalizedString("status.reblogs-count", comment: ""),
statusConfiguration.viewModel.reblogsCount))
}
if statusConfiguration.viewModel.favoritesCount > 0 {
accessibilityAttributedLabel.appendWithSeparator(
String.localizedStringWithFormat(
NSLocalizedString("status.favorites-count", comment: ""),
statusConfiguration.viewModel.favoritesCount))
}
}
return accessibilityAttributedLabel
}
2020-10-12 05:37:34 +00:00
func setButtonImages(scale: UIImage.SymbolScale) {
let visibility = statusConfiguration.viewModel.visibility
let reblogSystemImageName: String
if statusConfiguration.viewModel.configuration.isContextParent {
reblogSystemImageName = "arrow.2.squarepath"
} else {
switch visibility {
case .public, .unlisted:
reblogSystemImageName = "arrow.2.squarepath"
default:
reblogSystemImageName = visibility.systemImageName
}
}
2020-10-12 05:37:34 +00:00
replyButton.setImage(UIImage(systemName: "bubble.right",
withConfiguration: UIImage.SymbolConfiguration(scale: scale)), for: .normal)
reblogButton.setImage(UIImage(systemName: reblogSystemImageName,
2020-10-12 05:37:34 +00:00
withConfiguration: UIImage.SymbolConfiguration(scale: scale)), for: .normal)
favoriteButton.setImage(UIImage(systemName: statusConfiguration.viewModel.favorited ? "star.fill" : "star",
withConfiguration: UIImage.SymbolConfiguration(scale: scale)), for: .normal)
shareButton.setImage(UIImage(systemName: "square.and.arrow.up",
withConfiguration: UIImage.SymbolConfiguration(scale: scale)), for: .normal)
menuButton.setImage(UIImage(systemName: "ellipsis",
withConfiguration: UIImage.SymbolConfiguration(scale: scale)), for: .normal)
}
2021-01-31 19:23:33 +00:00
@objc func reblogButtonDoubleTap(sender: UIButton, event: UIEvent) {
guard
statusConfiguration.viewModel.identityContext.appPreferences.requireDoubleTapToReblog,
event.allTouches?.first?.tapCount == 2 else {
return
}
reblog()
}
@objc func favoriteButtonDoubleTap(sender: UIButton, event: UIEvent) {
guard
statusConfiguration.viewModel.identityContext.appPreferences.requireDoubleTapToFavorite,
event.allTouches?.first?.tapCount == 2 else {
return
}
favorite()
}
2021-01-31 19:46:19 +00:00
func setReblogButtonColor(reblogged: Bool) {
let reblogColor: UIColor = reblogged ? .systemGreen : .secondaryLabel
reblogButton.tintColor = reblogColor
reblogButton.setTitleColor(reblogColor, for: .normal)
2021-02-02 18:55:16 +00:00
if reblogged {
reblogButton.accessibilityLabel =
NSLocalizedString("status.reblog-button.undo.accessibility-label", comment: "")
} else {
reblogButton.accessibilityLabel =
NSLocalizedString("status.reblog-button.accessibility-label", comment: "")
}
2021-01-31 19:46:19 +00:00
}
func setFavoriteButtonColor(favorited: Bool) {
let favoriteColor: UIColor = favorited ? .systemYellow : .secondaryLabel
favoriteButton.tintColor = favoriteColor
favoriteButton.setTitleColor(favoriteColor, for: .normal)
2021-02-02 18:55:16 +00:00
if favorited {
favoriteButton.accessibilityLabel =
NSLocalizedString("status.favorite-button.undo.accessibility-label", comment: "")
} else {
favoriteButton.accessibilityLabel =
NSLocalizedString("status.favorite-button.accessibility-label", comment: "")
}
2021-01-31 19:46:19 +00:00
}
2021-01-31 19:23:33 +00:00
func reblog() {
UIImpactFeedbackGenerator(style: .medium).impactOccurred()
2021-01-31 19:46:19 +00:00
if !UIAccessibility.isReduceMotionEnabled {
UIViewPropertyAnimator.runningPropertyAnimator(
withDuration: .defaultAnimationDuration,
delay: 0,
options: .curveLinear) {
self.setReblogButtonColor(reblogged: !self.statusConfiguration.viewModel.reblogged)
self.reblogButton.imageView?.transform =
self.reblogButton.imageView?.transform.rotated(by: .pi) ?? .identity
} completion: { _ in
self.reblogButton.imageView?.transform = .identity
}
}
2021-01-31 19:23:33 +00:00
statusConfiguration.viewModel.toggleReblogged()
}
func favorite() {
UIImpactFeedbackGenerator(style: .medium).impactOccurred()
2021-01-31 19:46:19 +00:00
if !UIAccessibility.isReduceMotionEnabled {
UIViewPropertyAnimator.runningPropertyAnimator(
withDuration: .defaultAnimationDuration,
delay: 0,
options: .curveLinear) {
self.setFavoriteButtonColor(favorited: !self.statusConfiguration.viewModel.favorited)
self.favoriteButton.imageView?.transform =
self.favoriteButton.imageView?.transform.rotated(by: .pi) ?? .identity
} completion: { _ in
self.favoriteButton.imageView?.transform = .identity
}
}
2021-01-31 19:23:33 +00:00
statusConfiguration.viewModel.toggleFavorited()
}
2021-02-02 18:02:30 +00:00
func configureUserInteractionEnabledForAccessibility() {
isUserInteractionEnabled = !UIAccessibility.isVoiceOverRunning
|| statusConfiguration.viewModel.configuration.isContextParent
}
2021-02-02 18:55:16 +00:00
2021-02-11 03:02:54 +00:00
// swiftlint:disable:next function_body_length cyclomatic_complexity
2021-02-02 18:55:16 +00:00
func accessibilityCustomActions(viewModel: StatusViewModel) -> [UIAccessibilityCustomAction] {
2021-03-03 05:02:07 +00:00
guard !viewModel.configuration.isContextParent, reportSelectionSwitch.isHidden else {
2021-02-02 18:55:16 +00:00
return []
}
var actions = [UIAccessibilityCustomAction]()
if replyButton.isEnabled {
actions.append(UIAccessibilityCustomAction(
name: replyButton.accessibilityLabel ?? "") { _ in
viewModel.reply()
return true
})
}
if viewModel.canBeReblogged, reblogButton.isEnabled {
actions.append(UIAccessibilityCustomAction(
name: reblogButton.accessibilityLabel ?? "") { [weak self] _ in
self?.reblog()
return true
})
}
if favoriteButton.isEnabled {
actions.append(UIAccessibilityCustomAction(
name: favoriteButton.accessibilityLabel ?? "") { [weak self] _ in
self?.favorite()
return true
})
}
if shareButton.isEnabled {
actions.append(UIAccessibilityCustomAction(
name: shareButton.accessibilityLabel ?? "") { _ in
viewModel.shareStatus()
return true
})
}
2021-02-03 07:24:45 +00:00
actions.append(
UIAccessibilityCustomAction(
name: NSLocalizedString("status.accessibility.view-author-profile",
comment: "")) { [weak self] _ in
self?.statusConfiguration.viewModel.accountSelected()
return true
})
2021-02-07 00:54:11 +00:00
if viewModel.isReblog {
actions.append(
UIAccessibilityCustomAction(
name: NSLocalizedString("status.accessibility.view-reblogger-profile",
comment: "")) { [weak self] _ in
self?.statusConfiguration.viewModel.rebloggerAccountSelected()
return true
})
}
2021-02-03 21:10:12 +00:00
actions.append(
UIAccessibilityCustomAction(
name: NSLocalizedString("accessibility.copy-text",
comment: "")) { [weak self] _ in
UIPasteboard.general.string = self?.bodyView.contentTextView.text
return true
})
2021-02-03 07:24:45 +00:00
actions.append(contentsOf: bodyView.accessibilityCustomActions ?? [])
2021-02-02 18:55:16 +00:00
if menuButton.isEnabled {
actions.append(UIAccessibilityCustomAction(
name: viewModel.bookmarked
? NSLocalizedString("status.unbookmark", comment: "")
: NSLocalizedString("status.bookmark", comment: "")) { _ in
viewModel.toggleBookmarked()
return true
})
if let pinned = viewModel.pinned {
actions.append(UIAccessibilityCustomAction(
name: pinned
? NSLocalizedString("status.unpin", comment: "")
: NSLocalizedString("status.pin", comment: "")) { _ in
viewModel.togglePinned()
return true
})
}
if viewModel.isMine {
actions += [
UIAccessibilityCustomAction(
name: viewModel.muted
? NSLocalizedString("status.unmute", comment: "")
: NSLocalizedString("status.mute", comment: "")) { _ in
viewModel.toggleMuted()
return true
},
UIAccessibilityCustomAction(
name: NSLocalizedString("status.delete", comment: "")) { _ in
viewModel.confirmDelete(redraft: false)
return true
},
UIAccessibilityCustomAction(
name: NSLocalizedString("status.delete-and-redraft", comment: "")) { _ in
viewModel.confirmDelete(redraft: true)
return true
}
]
} else {
2021-02-11 03:02:54 +00:00
if let relationship = viewModel.accountViewModel.relationship {
if relationship.muting {
actions.append(UIAccessibilityCustomAction(
name: NSLocalizedString("account.unmute", comment: "")) { _ in
viewModel.accountViewModel.confirmUnmute()
return true
})
} else {
actions.append(UIAccessibilityCustomAction(
name: NSLocalizedString("account.mute", comment: "")) { _ in
viewModel.accountViewModel.confirmMute()
return true
})
}
if relationship.blocking {
actions.append(UIAccessibilityCustomAction(
name: NSLocalizedString("account.unblock", comment: "")) { _ in
viewModel.accountViewModel.confirmUnblock()
return true
})
} else {
actions.append(UIAccessibilityCustomAction(
name: NSLocalizedString("account.block", comment: "")) { _ in
viewModel.accountViewModel.confirmBlock()
return true
})
}
}
2021-02-02 18:55:16 +00:00
actions.append(UIAccessibilityCustomAction(
name: NSLocalizedString("report", comment: "")) { _ in
viewModel.reportStatus()
return true
})
2021-02-11 03:02:54 +00:00
if !viewModel.accountViewModel.isLocal,
let domain = viewModel.accountViewModel.domain,
let relationship = viewModel.accountViewModel.relationship {
if relationship.domainBlocking {
actions.append(UIAccessibilityCustomAction(
name: String.localizedStringWithFormat(
NSLocalizedString("account.domain-unblock-%@", comment: ""),
domain)) { _ in
viewModel.accountViewModel.confirmDomainUnblock(domain: domain)
return true
})
} else {
actions.append(UIAccessibilityCustomAction(
name: String.localizedStringWithFormat(
NSLocalizedString("account.domain-block-%@", comment: ""),
domain)) { _ in
viewModel.accountViewModel.confirmDomainBlock(domain: domain)
return true
})
}
}
2021-02-02 18:55:16 +00:00
}
}
return actions
}
2020-09-14 07:20:25 +00:00
}
2020-10-12 05:37:34 +00:00
private extension UIButton {
func setCountTitle(count: Int, isContextParent: Bool) {
setTitle((isContextParent || count == 0) ? nil : String(count), for: .normal)
2020-10-12 05:37:34 +00:00
}
}
// swiftlint:enable file_length