Migrate to UIContentView instead of UITableViewCell

This commit is contained in:
Justin Mazzocchi 2020-09-14 16:13:43 -07:00
parent fb3a5be6fd
commit 56297a643c
No known key found for this signature in database
GPG key ID: E223E6937AAFB01C
9 changed files with 824 additions and 983 deletions

View file

@ -8,8 +8,6 @@
/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
D0030982250C6C8500EACB32 /* URL+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0030981250C6C8500EACB32 /* URL+Extensions.swift */; }; D0030982250C6C8500EACB32 /* URL+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0030981250C6C8500EACB32 /* URL+Extensions.swift */; };
D01F41D724F880C400D55A2D /* StatusTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = D01F41D424F880C400D55A2D /* StatusTableViewCell.xib */; };
D01F41D824F880C400D55A2D /* StatusTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D01F41D524F880C400D55A2D /* StatusTableViewCell.swift */; };
D01F41D924F880C400D55A2D /* TouchFallthroughTextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D01F41D624F880C400D55A2D /* TouchFallthroughTextView.swift */; }; D01F41D924F880C400D55A2D /* TouchFallthroughTextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D01F41D624F880C400D55A2D /* TouchFallthroughTextView.swift */; };
D01F41E424F8889700D55A2D /* AttachmentsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D01F41E224F8889700D55A2D /* AttachmentsView.swift */; }; D01F41E424F8889700D55A2D /* AttachmentsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D01F41E224F8889700D55A2D /* AttachmentsView.swift */; };
D02E1F95250B13210071AD56 /* SafariView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D02E1F94250B13210071AD56 /* SafariView.swift */; }; D02E1F95250B13210071AD56 /* SafariView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D02E1F94250B13210071AD56 /* SafariView.swift */; };
@ -18,6 +16,7 @@
D0625E5F250F0CFF00502611 /* StatusView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0625E5E250F0CFF00502611 /* StatusView.swift */; }; D0625E5F250F0CFF00502611 /* StatusView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0625E5E250F0CFF00502611 /* StatusView.swift */; };
D06B492324D4611300642749 /* KingfisherSwiftUI in Frameworks */ = {isa = PBXBuildFile; productRef = D06B492224D4611300642749 /* KingfisherSwiftUI */; }; D06B492324D4611300642749 /* KingfisherSwiftUI in Frameworks */ = {isa = PBXBuildFile; productRef = D06B492224D4611300642749 /* KingfisherSwiftUI */; };
D0B32F50250B373600311912 /* RegistrationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0B32F4F250B373600311912 /* RegistrationView.swift */; }; D0B32F50250B373600311912 /* RegistrationView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0B32F4F250B373600311912 /* RegistrationView.swift */; };
D0B7434925100DBB00C13DB6 /* StatusView.xib in Resources */ = {isa = PBXBuildFile; fileRef = D0B7434825100DBB00C13DB6 /* StatusView.xib */; };
D0BEB1F324F8EE8C001B0F04 /* AttachmentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0BEB1F224F8EE8C001B0F04 /* AttachmentView.swift */; }; D0BEB1F324F8EE8C001B0F04 /* AttachmentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0BEB1F224F8EE8C001B0F04 /* AttachmentView.swift */; };
D0BEB1F724F9A84B001B0F04 /* LoadingTableFooterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0BEB1F624F9A84B001B0F04 /* LoadingTableFooterView.swift */; }; D0BEB1F724F9A84B001B0F04 /* LoadingTableFooterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0BEB1F624F9A84B001B0F04 /* LoadingTableFooterView.swift */; };
D0BEB1FF24F9E5BB001B0F04 /* ListsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0BEB1FE24F9E5BB001B0F04 /* ListsView.swift */; }; D0BEB1FF24F9E5BB001B0F04 /* ListsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0BEB1FE24F9E5BB001B0F04 /* ListsView.swift */; };
@ -85,8 +84,6 @@
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
D0030981250C6C8500EACB32 /* URL+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "URL+Extensions.swift"; sourceTree = "<group>"; }; D0030981250C6C8500EACB32 /* URL+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "URL+Extensions.swift"; sourceTree = "<group>"; };
D01F41D424F880C400D55A2D /* StatusTableViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = StatusTableViewCell.xib; sourceTree = "<group>"; };
D01F41D524F880C400D55A2D /* StatusTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StatusTableViewCell.swift; sourceTree = "<group>"; };
D01F41D624F880C400D55A2D /* TouchFallthroughTextView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TouchFallthroughTextView.swift; sourceTree = "<group>"; }; D01F41D624F880C400D55A2D /* TouchFallthroughTextView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TouchFallthroughTextView.swift; sourceTree = "<group>"; };
D01F41E224F8889700D55A2D /* AttachmentsView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AttachmentsView.swift; sourceTree = "<group>"; }; D01F41E224F8889700D55A2D /* AttachmentsView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AttachmentsView.swift; sourceTree = "<group>"; };
D02E1F94250B13210071AD56 /* SafariView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SafariView.swift; sourceTree = "<group>"; }; D02E1F94250B13210071AD56 /* SafariView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SafariView.swift; sourceTree = "<group>"; };
@ -99,6 +96,7 @@
D085C3BB25008DEC008A6C5E /* DB */ = {isa = PBXFileReference; lastKnownFileType = folder; path = DB; sourceTree = "<group>"; }; D085C3BB25008DEC008A6C5E /* DB */ = {isa = PBXFileReference; lastKnownFileType = folder; path = DB; sourceTree = "<group>"; };
D0AD03552505814D0085A466 /* Base16 */ = {isa = PBXFileReference; lastKnownFileType = folder; path = Base16; sourceTree = "<group>"; }; D0AD03552505814D0085A466 /* Base16 */ = {isa = PBXFileReference; lastKnownFileType = folder; path = Base16; sourceTree = "<group>"; };
D0B32F4F250B373600311912 /* RegistrationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RegistrationView.swift; sourceTree = "<group>"; }; D0B32F4F250B373600311912 /* RegistrationView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RegistrationView.swift; sourceTree = "<group>"; };
D0B7434825100DBB00C13DB6 /* StatusView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = StatusView.xib; sourceTree = "<group>"; };
D0BDF66524FD7A6400C7FA1C /* ServiceLayer */ = {isa = PBXFileReference; lastKnownFileType = folder; path = ServiceLayer; sourceTree = "<group>"; }; D0BDF66524FD7A6400C7FA1C /* ServiceLayer */ = {isa = PBXFileReference; lastKnownFileType = folder; path = ServiceLayer; sourceTree = "<group>"; };
D0BEB1F224F8EE8C001B0F04 /* AttachmentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AttachmentView.swift; sourceTree = "<group>"; }; D0BEB1F224F8EE8C001B0F04 /* AttachmentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AttachmentView.swift; sourceTree = "<group>"; };
D0BEB1F624F9A84B001B0F04 /* LoadingTableFooterView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoadingTableFooterView.swift; sourceTree = "<group>"; }; D0BEB1F624F9A84B001B0F04 /* LoadingTableFooterView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoadingTableFooterView.swift; sourceTree = "<group>"; };
@ -171,16 +169,6 @@
/* End PBXFrameworksBuildPhase section */ /* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */ /* Begin PBXGroup section */
D01F41D324F8807E00D55A2D /* Status Cell */ = {
isa = PBXGroup;
children = (
D01F41D524F880C400D55A2D /* StatusTableViewCell.swift */,
D01F41D424F880C400D55A2D /* StatusTableViewCell.xib */,
D01F41D624F880C400D55A2D /* TouchFallthroughTextView.swift */,
);
path = "Status Cell";
sourceTree = "<group>";
};
D01F41E024F8885900D55A2D /* Attachments */ = { D01F41E024F8885900D55A2D /* Attachments */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
@ -230,9 +218,11 @@
D0625E55250F086B00502611 /* Status */ = { D0625E55250F086B00502611 /* Status */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
D0625E58250F092900502611 /* StatusListCell.swift */,
D0625E5C250F0B5C00502611 /* StatusContentConfiguration.swift */, D0625E5C250F0B5C00502611 /* StatusContentConfiguration.swift */,
D0625E58250F092900502611 /* StatusListCell.swift */,
D0625E5E250F0CFF00502611 /* StatusView.swift */, D0625E5E250F0CFF00502611 /* StatusView.swift */,
D0B7434825100DBB00C13DB6 /* StatusView.xib */,
D01F41D624F880C400D55A2D /* TouchFallthroughTextView.swift */,
); );
path = Status; path = Status;
sourceTree = "<group>"; sourceTree = "<group>";
@ -280,7 +270,6 @@
D0C7D42724F76169001EBDBB /* RootView.swift */, D0C7D42724F76169001EBDBB /* RootView.swift */,
D02E1F94250B13210071AD56 /* SafariView.swift */, D02E1F94250B13210071AD56 /* SafariView.swift */,
D0C7D42924F76169001EBDBB /* SecondaryNavigationView.swift */, D0C7D42924F76169001EBDBB /* SecondaryNavigationView.swift */,
D01F41D324F8807E00D55A2D /* Status Cell */,
D0C7D42524F76169001EBDBB /* StatusListView.swift */, D0C7D42524F76169001EBDBB /* StatusListView.swift */,
D0C7D42E24F76169001EBDBB /* TabNavigationView.swift */, D0C7D42E24F76169001EBDBB /* TabNavigationView.swift */,
); );
@ -457,7 +446,7 @@
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
D0C7D4C524F7616A001EBDBB /* Localizable.strings in Resources */, D0C7D4C524F7616A001EBDBB /* Localizable.strings in Resources */,
D01F41D724F880C400D55A2D /* StatusTableViewCell.xib in Resources */, D0B7434925100DBB00C13DB6 /* StatusView.xib in Resources */,
D0C7D4C224F7616A001EBDBB /* Assets.xcassets in Resources */, D0C7D4C224F7616A001EBDBB /* Assets.xcassets in Resources */,
D0C7D4C624F7616A001EBDBB /* Localizable.stringsdict in Resources */, D0C7D4C624F7616A001EBDBB /* Localizable.stringsdict in Resources */,
); );
@ -533,7 +522,6 @@
D0C7D49924F7616A001EBDBB /* AddIdentityView.swift in Sources */, D0C7D49924F7616A001EBDBB /* AddIdentityView.swift in Sources */,
D0C7D4C324F7616A001EBDBB /* MetatextApp.swift in Sources */, D0C7D4C324F7616A001EBDBB /* MetatextApp.swift in Sources */,
D0BEB20524FA1107001B0F04 /* FiltersView.swift in Sources */, D0BEB20524FA1107001B0F04 /* FiltersView.swift in Sources */,
D01F41D824F880C400D55A2D /* StatusTableViewCell.swift in Sources */,
D0C7D49B24F7616A001EBDBB /* PreferencesView.swift in Sources */, D0C7D49B24F7616A001EBDBB /* PreferencesView.swift in Sources */,
D0C7D4D724F7616A001EBDBB /* UIColor+Extensions.swift in Sources */, D0C7D4D724F7616A001EBDBB /* UIColor+Extensions.swift in Sources */,
); );

View file

@ -22,7 +22,6 @@ final class StatusListViewController: UITableViewController {
else { return nil } else { return nil }
cell.viewModel = self.viewModel.statusViewModel(id: statusID) cell.viewModel = self.viewModel.statusViewModel(id: statusID)
// cell.delegate = self
return cell return cell
} }
@ -146,21 +145,7 @@ extension StatusListViewController: UITableViewDataSourcePrefetching {
} }
} }
extension StatusListViewController: StatusTableViewCellDelegate {
func statusTableViewCellDidHaveShareButtonTapped(_ cell: StatusTableViewCell) {
guard let url = cell.viewModel?.sharingURL else { return }
share(url: url)
}
}
private extension StatusListViewController { private extension StatusListViewController {
func share(url: URL) {
let activityViewController = UIActivityViewController(activityItems: [url], applicationActivities: nil)
present(activityViewController, animated: true, completion: nil)
}
func sizeTableHeaderFooterViews() { func sizeTableHeaderFooterViews() {
// https://useyourloaf.com/blog/variable-height-table-view-header/ // https://useyourloaf.com/blog/variable-height-table-view-header/
if let headerView = tableView.tableHeaderView { if let headerView = tableView.tableHeaderView {

View file

@ -1,369 +0,0 @@
// Copyright © 2020 Metabolist. All rights reserved.
import AVKit
import Kingfisher
import UIKit
import ViewModels
protocol StatusTableViewCellDelegate: class {
func statusTableViewCellDidHaveShareButtonTapped(_ cell: StatusTableViewCell)
}
final class StatusTableViewCell: UITableViewCell {
@IBOutlet weak var metaIcon: UIImageView!
@IBOutlet weak var metaLabel: UILabel!
@IBOutlet weak var contentTextView: TouchFallthroughTextView!
@IBOutlet weak var avatarButton: UIButton!
@IBOutlet weak var avatarImageView: AnimatedImageView!
@IBOutlet weak var displayNameLabel: UILabel!
@IBOutlet weak var accountLabel: UILabel!
@IBOutlet weak var timeLabel: UILabel!
@IBOutlet weak var spoilerTextLabel: UILabel!
@IBOutlet weak var toggleSensitiveContentButton: UIButton!
@IBOutlet weak var replyButton: UIButton!
@IBOutlet weak var reblogButton: UIButton!
@IBOutlet weak var favoriteButton: UIButton!
@IBOutlet weak var shareButton: UIButton!
@IBOutlet weak var attachmentsView: AttachmentsView!
@IBOutlet weak var cardView: UIView!
@IBOutlet weak var cardImageView: UIImageView!
@IBOutlet weak var cardTitleLabel: UILabel!
@IBOutlet weak var cardDescriptionLabel: UILabel!
@IBOutlet weak var cardURLLabel: UILabel!
@IBOutlet weak var cardButton: UIButton!
@IBOutlet weak var sensitiveContentView: UIStackView!
@IBOutlet weak var hasReplyFollowingView: UIView!
@IBOutlet weak var inReplyToView: UIView!
@IBOutlet weak var avatarReplyContextView: UIView!
@IBOutlet weak var nameDateView: UIStackView!
@IBOutlet weak var contextParentAvatarNameView: UIStackView!
@IBOutlet weak var contextParentAvatarImageView: AnimatedImageView!
@IBOutlet weak var contextParentAvatarButton: UIButton!
@IBOutlet weak var contextParentDisplayNameLabel: UILabel!
@IBOutlet weak var contextParentAccountLabel: UILabel!
@IBOutlet weak var actionButtonsView: UIStackView!
@IBOutlet weak var contextParentReplyButton: UIButton!
@IBOutlet weak var contextParentReblogButton: UIButton!
@IBOutlet weak var contextParentFavoriteButton: UIButton!
@IBOutlet weak var contextParentShareButton: UIButton!
@IBOutlet weak var contextParentActionsButton: UIButton!
@IBOutlet weak var contextParentTimeLabel: UILabel!
@IBOutlet weak var timeApplicationDividerView: UILabel!
@IBOutlet weak var applicationButton: UIButton!
@IBOutlet weak var contextParentRebloggedByButton: UIButton!
@IBOutlet weak var contextParentFavoritedByButton: UIButton!
@IBOutlet weak var contextParentItems: UIStackView!
@IBOutlet weak var contextParentRebloggedByFavoritedByView: UIStackView!
@IBOutlet weak var contextParentRebloggedByFavoritedBySeparator: UIView!
weak var delegate: StatusTableViewCellDelegate?
@IBOutlet private var separatorConstraints: [NSLayoutConstraint]!
var viewModel: StatusViewModel? {
didSet {
guard let viewModel = viewModel else { return }
let mutableContent = NSMutableAttributedString(attributedString: viewModel.content)
let mutableDisplayName = NSMutableAttributedString(string: viewModel.displayName)
let mutableSpoilerText = NSMutableAttributedString(string: viewModel.spoilerText)
let contentFont = UIFont.preferredFont(forTextStyle: viewModel.isContextParent ? .title3 : .callout)
contentTextView.shouldFallthrough = !viewModel.isContextParent
avatarReplyContextView.isHidden = viewModel.isContextParent
nameDateView.isHidden = viewModel.isContextParent
contextParentAvatarNameView.isHidden = !viewModel.isContextParent
actionButtonsView.isHidden = viewModel.isContextParent
contextParentItems.isHidden = !viewModel.isContextParent
let avatarImageView: UIImageView
let displayNameLabel: UILabel
let accountLabel: UILabel
if viewModel.isContextParent {
avatarImageView = contextParentAvatarImageView
displayNameLabel = contextParentDisplayNameLabel
accountLabel = contextParentAccountLabel
} else {
avatarImageView = self.avatarImageView
displayNameLabel = self.displayNameLabel
accountLabel = self.accountLabel
}
let contentRange = NSRange(location: 0, length: mutableContent.length)
mutableContent.removeAttribute(.font, range: contentRange)
mutableContent.addAttributes(
[.font: contentFont as Any,
.foregroundColor: UIColor.label],
range: contentRange)
mutableContent.insert(emoji: viewModel.contentEmoji, view: contentTextView)
mutableContent.resizeAttachments(toLineHeight: contentFont.lineHeight)
contentTextView.attributedText = mutableContent
contentTextView.isHidden = contentTextView.text == ""
mutableDisplayName.insert(emoji: viewModel.displayNameEmoji, view: displayNameLabel)
mutableDisplayName.resizeAttachments(toLineHeight: displayNameLabel.font.lineHeight)
displayNameLabel.attributedText = mutableDisplayName
mutableSpoilerText.insert(emoji: viewModel.contentEmoji, view: spoilerTextLabel)
mutableSpoilerText.resizeAttachments(toLineHeight: spoilerTextLabel.font.lineHeight)
spoilerTextLabel.attributedText = mutableSpoilerText
spoilerTextLabel.isHidden = !viewModel.sensitive || spoilerTextLabel.text == ""
toggleSensitiveContentButton.setTitle(
viewModel.shouldDisplaySensitiveContent
? NSLocalizedString("status.show-less", comment: "")
: NSLocalizedString("status.show-more", comment: ""),
for: .normal)
accountLabel.text = viewModel.accountName
timeLabel.text = viewModel.time
contextParentTimeLabel.text = viewModel.contextParentTime
timeApplicationDividerView.isHidden = viewModel.applicationName == nil
applicationButton.isHidden = viewModel.applicationName == nil
applicationButton.setTitle(viewModel.applicationName, for: .normal)
applicationButton.isEnabled = viewModel.applicationURL != nil
avatarImageView.kf.setImage(with: viewModel.avatarURL)
toggleSensitiveContentButton.isHidden = !viewModel.sensitive
replyButton.setTitle(viewModel.repliesCount == 0 ? "" : String(viewModel.repliesCount), for: .normal)
reblogButton.setTitle(viewModel.reblogsCount == 0 ? "" : String(viewModel.reblogsCount), for: .normal)
setReblogButtonColor(reblogged: viewModel.reblogged)
favoriteButton.setTitle(viewModel.favoritesCount == 0 ? "" : String(viewModel.favoritesCount), for: .normal)
setFavoriteButtonColor(favorited: viewModel.favorited)
reblogButton.isEnabled = viewModel.canBeReblogged
contextParentReblogButton.isEnabled = viewModel.canBeReblogged
let noReblogs = viewModel.reblogsCount == 0
let noFavorites = viewModel.favoritesCount == 0
let noInteractions = noReblogs && noFavorites
setAttributedLocalizedTitle(
button: contextParentRebloggedByButton,
localizationKey: "status.reblogs-count",
count: viewModel.reblogsCount)
contextParentRebloggedByButton.isHidden = noReblogs
setAttributedLocalizedTitle(
button: contextParentFavoritedByButton,
localizationKey: "status.favorites-count",
count: viewModel.favoritesCount)
contextParentFavoritedByButton.isHidden = noFavorites
contextParentRebloggedByFavoritedByView.isHidden = noInteractions
contextParentRebloggedByFavoritedBySeparator.isHidden = noInteractions
if
viewModel.isReblog {
let metaText = String.localizedStringWithFormat(
NSLocalizedString("status.reblogged-by", comment: ""),
viewModel.rebloggedByDisplayName)
let mutableMetaText = NSMutableAttributedString(string: metaText)
mutableMetaText.insert(emoji: viewModel.rebloggedByDisplayNameEmoji, view: metaLabel)
mutableMetaText.resizeAttachments(toLineHeight: metaLabel.font.lineHeight)
metaLabel.attributedText = mutableMetaText
metaIcon.image = UIImage(
systemName: "arrow.2.squarepath",
withConfiguration: UIImage.SymbolConfiguration(scale: .small))
metaLabel.isHidden = false
metaIcon.isHidden = false
} else if viewModel.isPinned {
metaLabel.text = NSLocalizedString("status.pinned-post", comment: "")
metaIcon.image = UIImage(
systemName: "pin",
withConfiguration: UIImage.SymbolConfiguration(scale: .small))
metaLabel.isHidden = false
metaIcon.isHidden = false
} else {
metaLabel.isHidden = true
metaIcon.isHidden = true
}
attachmentsView.isHidden = viewModel.attachmentViewModels.count == 0
attachmentsView.attachmentViewModels = viewModel.attachmentViewModels
setNeedsLayout()
if let cardURL = viewModel.cardURL {
cardTitleLabel.text = viewModel.cardTitle
cardDescriptionLabel.text = viewModel.cardDescription
cardDescriptionLabel.isHidden = cardDescriptionLabel.text == ""
|| cardDescriptionLabel.text == cardTitleLabel.text
if
let host = cardURL.host, host.hasPrefix("www."),
let withoutWww = cardURL.host?.components(separatedBy: "www.").last {
cardURLLabel.text = withoutWww
} else {
cardURLLabel.text = cardURL.host
}
if let cardImageURL = viewModel.cardImageURL {
cardImageView.isHidden = false
cardImageView.kf.setImage(with: cardImageURL)
} else {
cardImageView.isHidden = true
}
cardView.isHidden = false
} else {
cardView.isHidden = true
}
sensitiveContentView.isHidden = !viewModel.shouldDisplaySensitiveContent
inReplyToView.isHidden = !viewModel.isReplyInContext
hasReplyFollowingView.isHidden = !viewModel.hasReplyFollowing
}
}
override func awakeFromNib() {
super.awakeFromNib()
for constraint in separatorConstraints {
constraint.constant = 1 / UIScreen.main.scale
}
avatarImageView.kf.indicatorType = .activity
contextParentAvatarImageView.kf.indicatorType = .activity
cardImageView.kf.indicatorType = .activity
contentTextView.delegate = self
let highlightedButtonBackgroundImage = UIColor(white: 0, alpha: 0.5).image()
cardButton.setBackgroundImage(highlightedButtonBackgroundImage, for: .highlighted)
avatarButton.setBackgroundImage(highlightedButtonBackgroundImage, for: .highlighted)
contextParentAvatarButton.setBackgroundImage(highlightedButtonBackgroundImage, for: .highlighted)
}
override func prepareForReuse() {
super.prepareForReuse()
avatarImageView.kf.cancelDownloadTask()
cardImageView.kf.cancelDownloadTask()
}
override func layoutSubviews() {
super.layoutSubviews()
for button: UIButton in [toggleSensitiveContentButton] where button.frame.height != 0 {
button.layer.cornerRadius = button.frame.height / 2
}
if hasReplyFollowingView.isHidden {
separatorInset.right = UIDevice.current.userInterfaceIdiom == .phone ? 0 : layoutMargins.right
} else {
separatorInset.right = .greatestFiniteMagnitude
}
separatorInset.left = UIDevice.current.userInterfaceIdiom == .phone ? 0 : layoutMargins.left
}
}
extension StatusTableViewCell {
@IBAction func avatarButtonTapped(_ sender: Any) {
}
@IBAction func toggleSensitiveContentButtonTapped(_ sender: Any) {
}
@IBAction func cardButtonTapped(_ sender: UIButton) {
}
@IBAction func replyButtonTapped(_ sender: UIButton) {
}
@IBAction func reblogButtonTapped(_ sender: UIButton) {
}
@IBAction func favoriteButtonTapped(_ sender: UIButton) {
viewModel?.toggleFavorited()
}
@IBAction func actionsButtonTapped(_ sender: Any) {
}
@IBAction func shareButtonTapped(_ sender: Any) {
delegate?.statusTableViewCellDidHaveShareButtonTapped(self)
}
@IBAction func applicationButtonTapped(_ sender: Any) {
}
@IBAction func contextParentRebloggedByButtonTapped(_ sender: Any) {
}
@IBAction func contextParentFavoritedByButtonTapped(_ sender: Any) {
}
}
extension StatusTableViewCell: UITextViewDelegate {
func textView(
_ textView: UITextView,
shouldInteractWith URL: URL,
in characterRange: NSRange,
interaction: UITextItemInteraction) -> Bool {
switch interaction {
case .invokeDefaultAction: print(URL); return false
case .preview: return false
case .presentActions: return false
@unknown default: return false
}
}
}
private extension StatusTableViewCell {
private static let defaultAspectRatioConstraintMultiplier: CGFloat = 4.0 / 3.0
private static let hasReplyFollowingSeparatorInsets = UIEdgeInsets(
top: 0,
left: 0,
bottom: 0,
right: .greatestFiniteMagnitude)
private func setReblogButtonColor(reblogged: Bool) {
let reblogColor: UIColor = reblogged ? .systemGreen : .secondaryLabel
let reblogButton: UIButton
if viewModel?.isContextParent ?? false {
reblogButton = contextParentReblogButton
} else {
reblogButton = self.reblogButton
}
reblogButton.tintColor = reblogColor
reblogButton.setTitleColor(reblogColor, for: .normal)
}
private func setFavoriteButtonColor(favorited: Bool) {
let favoriteColor: UIColor = favorited ? .systemYellow : .secondaryLabel
let favoriteButton: UIButton
let scale: UIImage.SymbolScale
if viewModel?.isContextParent ?? false {
favoriteButton = contextParentFavoriteButton
scale = .medium
} else {
favoriteButton = self.favoriteButton
scale = .small
}
favoriteButton.tintColor = favoriteColor
favoriteButton.setTitleColor(favoriteColor, for: .normal)
favoriteButton.setImage(UIImage(
systemName: favorited ? "star.fill" : "star",
withConfiguration: UIImage.SymbolConfiguration(scale: scale)),
for: .normal)
}
private func setAttributedLocalizedTitle(button: UIButton, localizationKey: String, count: Int) {
let localizedTitle = String.localizedStringWithFormat(NSLocalizedString(localizationKey, comment: ""), count)
button.setAttributedTitle(localizedTitle.countEmphasizedAttributedString(count: count), for: .normal)
button.setAttributedTitle(
localizedTitle.countEmphasizedAttributedString(count: count, highlighted: true),
for: .highlighted)
}
}

View file

@ -1,563 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="17154" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<device id="retina4_7" orientation="portrait" appearance="light"/>
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="17124"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="System colors in document resources" minToolsVersion="11.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<tableViewCell contentMode="scaleToFill" selectionStyle="default" indentationWidth="10" rowHeight="1003" id="KGk-i7-Jjw" customClass="StatusTableViewCell" customModule="Metatext" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="377" height="1003"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="KGk-i7-Jjw" id="H2p-sc-9uM">
<rect key="frame" x="0.0" y="0.0" width="377" height="1003"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="PuM-4R-mah">
<rect key="frame" x="16" y="11" width="345" height="981"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="NHl-tq-tPi">
<rect key="frame" x="0.0" y="0.0" width="50" height="981"/>
<subviews>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="arrow.2.squarepath" catalog="system" translatesAutoresizingMaskIntoConstraints="NO" id="uhT-HE-MkE">
<rect key="frame" x="29.5" y="0.0" width="20.5" height="14.5"/>
<color key="tintColor" systemColor="secondaryLabelColor"/>
<preferredSymbolConfiguration key="preferredSymbolConfiguration" scale="small"/>
</imageView>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="tqr-8D-x5Z">
<rect key="frame" x="24" y="-11" width="2" height="37.5"/>
<color key="backgroundColor" systemColor="quaternaryLabelColor"/>
<constraints>
<constraint firstAttribute="width" constant="2" id="Zpn-G6-ZXB"/>
</constraints>
</view>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="Rag-3x-Vbq" customClass="AnimatedImageView" customModule="Kingfisher">
<rect key="frame" x="0.0" y="26.5" width="50" height="50"/>
<constraints>
<constraint firstAttribute="height" constant="50" id="OSq-XT-4Ch"/>
<constraint firstAttribute="width" constant="50" id="jO1-At-ia1"/>
</constraints>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="number" keyPath="layer.cornerRadius">
<integer key="value" value="25"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
</imageView>
<button opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="dRj-hF-Ov8">
<rect key="frame" x="0.0" y="26.5" width="50" height="50"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="number" keyPath="layer.cornerRadius">
<integer key="value" value="25"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
<connections>
<action selector="avatarButtonTapped:" destination="KGk-i7-Jjw" eventType="touchUpInside" id="CZ5-0T-jMR"/>
</connections>
</button>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="H9F-5F-FkJ">
<rect key="frame" x="24" y="76.5" width="2" height="915.5"/>
<color key="backgroundColor" systemColor="quaternaryLabelColor"/>
<constraints>
<constraint firstAttribute="width" constant="2" id="zZf-bJ-KBC"/>
</constraints>
</view>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="tqr-8D-x5Z" firstAttribute="centerX" secondItem="Rag-3x-Vbq" secondAttribute="centerX" id="2CR-TM-SV1"/>
<constraint firstItem="H9F-5F-FkJ" firstAttribute="centerX" secondItem="Rag-3x-Vbq" secondAttribute="centerX" id="9GK-oD-aKw"/>
<constraint firstItem="dRj-hF-Ov8" firstAttribute="leading" secondItem="Rag-3x-Vbq" secondAttribute="leading" id="9VS-vb-y46"/>
<constraint firstAttribute="trailing" secondItem="Rag-3x-Vbq" secondAttribute="trailing" id="Cau-hc-kV9"/>
<constraint firstItem="dRj-hF-Ov8" firstAttribute="bottom" secondItem="Rag-3x-Vbq" secondAttribute="bottom" id="M6f-Zs-pEW"/>
<constraint firstItem="dRj-hF-Ov8" firstAttribute="trailing" secondItem="Rag-3x-Vbq" secondAttribute="trailing" id="NIM-Pj-Jrj"/>
<constraint firstItem="dRj-hF-Ov8" firstAttribute="top" secondItem="Rag-3x-Vbq" secondAttribute="top" id="NXO-iK-dvp"/>
<constraint firstItem="Rag-3x-Vbq" firstAttribute="leading" secondItem="NHl-tq-tPi" secondAttribute="leading" id="R0T-s6-Kon"/>
<constraint firstItem="tqr-8D-x5Z" firstAttribute="bottom" secondItem="Rag-3x-Vbq" secondAttribute="top" id="a20-V8-0xV"/>
<constraint firstItem="H9F-5F-FkJ" firstAttribute="top" secondItem="Rag-3x-Vbq" secondAttribute="bottom" id="gby-3L-E2T"/>
<constraint firstAttribute="trailing" secondItem="uhT-HE-MkE" secondAttribute="trailing" id="osH-xC-Krv"/>
</constraints>
</view>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="qtT-hh-JlW">
<rect key="frame" x="58" y="0.0" width="287" height="981"/>
<subviews>
<stackView opaque="NO" contentMode="top" axis="vertical" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="Vfx-Uf-SCV">
<rect key="frame" x="0.0" y="0.0" width="287" height="167"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="ful-we-pCE">
<rect key="frame" x="0.0" y="0.0" width="287" height="14.5"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleCaption1"/>
<color key="textColor" systemColor="secondaryLabelColor"/>
<nil key="highlightedColor"/>
</label>
<stackView opaque="NO" contentMode="scaleToFill" spacing="4" translatesAutoresizingMaskIntoConstraints="NO" id="Cyx-R2-XUe">
<rect key="frame" x="0.0" y="22.5" width="287" height="18"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" horizontalCompressionResistancePriority="751" verticalCompressionResistancePriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="aHQ-z9-LWz">
<rect key="frame" x="0.0" y="0.0" width="43.5" height="18"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleHeadline"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="hrV-68-5hn">
<rect key="frame" x="47.5" y="0.0" width="198" height="18"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleSubhead"/>
<color key="textColor" systemColor="secondaryLabelColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" horizontalCompressionResistancePriority="752" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="lGC-HZ-ZT3">
<rect key="frame" x="249.5" y="0.0" width="37.5" height="18"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleSubhead"/>
<color key="textColor" systemColor="secondaryLabelColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="P6a-zL-9B9">
<rect key="frame" x="0.0" y="48.5" width="287" height="50"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="oXX-vk-ESS">
<rect key="frame" x="0.0" y="0.0" width="50" height="50"/>
<subviews>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="BLe-zN-EsU" customClass="AnimatedImageView" customModule="Kingfisher">
<rect key="frame" x="0.0" y="0.0" width="50" height="50"/>
<constraints>
<constraint firstAttribute="width" constant="50" id="1bA-D3-I4a"/>
<constraint firstAttribute="height" constant="50" id="G3i-Y5-C3e"/>
</constraints>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="number" keyPath="layer.cornerRadius">
<integer key="value" value="25"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
</imageView>
<button opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="aNl-ag-2fc">
<rect key="frame" x="0.0" y="0.0" width="50" height="50"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="number" keyPath="layer.cornerRadius">
<integer key="value" value="25"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
<connections>
<action selector="avatarButtonTapped:" destination="KGk-i7-Jjw" eventType="touchUpInside" id="S3W-K2-aSY"/>
</connections>
</button>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="bottom" secondItem="BLe-zN-EsU" secondAttribute="bottom" id="0vg-93-dFw"/>
<constraint firstItem="aNl-ag-2fc" firstAttribute="leading" secondItem="BLe-zN-EsU" secondAttribute="leading" id="1Mr-NZ-A1g"/>
<constraint firstItem="BLe-zN-EsU" firstAttribute="top" secondItem="oXX-vk-ESS" secondAttribute="top" id="5vR-d6-1ne"/>
<constraint firstItem="BLe-zN-EsU" firstAttribute="leading" secondItem="oXX-vk-ESS" secondAttribute="leading" id="G4T-oU-MdP"/>
<constraint firstItem="aNl-ag-2fc" firstAttribute="bottom" secondItem="BLe-zN-EsU" secondAttribute="bottom" id="HPR-zH-Wia"/>
<constraint firstItem="aNl-ag-2fc" firstAttribute="trailing" secondItem="BLe-zN-EsU" secondAttribute="trailing" id="Xx3-36-S6g"/>
<constraint firstAttribute="trailing" secondItem="BLe-zN-EsU" secondAttribute="trailing" id="baJ-by-gCl"/>
<constraint firstItem="aNl-ag-2fc" firstAttribute="top" secondItem="BLe-zN-EsU" secondAttribute="top" id="zdp-yv-BHJ"/>
</constraints>
</view>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" translatesAutoresizingMaskIntoConstraints="NO" id="mYD-9U-oFJ">
<rect key="frame" x="58" y="0.0" width="229" height="50"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="ya9-zV-dMO">
<rect key="frame" x="0.0" y="0.0" width="229" height="32"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleHeadline"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="252" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="aa2-u6-YBQ">
<rect key="frame" x="0.0" y="32" width="229" height="18"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleSubhead"/>
<color key="textColor" systemColor="secondaryLabelColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
</stackView>
</subviews>
</stackView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="7Mz-X2-wmw">
<rect key="frame" x="0.0" y="106.5" width="287" height="19.5"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleCallout"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<button opaque="NO" contentMode="scaleToFill" verticalHuggingPriority="251" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Occ-DT-kxh">
<rect key="frame" x="0.0" y="134" width="287" height="33"/>
<color key="backgroundColor" systemColor="linkColor"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleHeadline"/>
<state key="normal" title="Show More">
<color key="titleColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</state>
<connections>
<action selector="toggleSensitiveContentButtonTapped:" destination="KGk-i7-Jjw" eventType="touchUpInside" id="m7M-MA-f02"/>
</connections>
</button>
</subviews>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" verticalCompressionResistancePriority="749" axis="vertical" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="Rdc-ZD-zdc">
<rect key="frame" x="0.0" y="175" width="287" height="654.5"/>
<subviews>
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" verticalCompressionResistancePriority="751" scrollEnabled="NO" editable="NO" text="Content" textAlignment="natural" adjustsFontForContentSizeCategory="YES" translatesAutoresizingMaskIntoConstraints="NO" id="GvW-gH-ofw" customClass="TouchFallthroughTextView" customModule="Metatext" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="287" height="175.5"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleCallout"/>
<textInputTraits key="textInputTraits" autocapitalizationType="sentences"/>
</textView>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="KvJ-fF-o4f" customClass="AttachmentsView" customModule="Metatext" customModuleProvider="target">
<rect key="frame" x="0.0" y="183.5" width="287" height="161.5"/>
<constraints>
<constraint firstAttribute="width" secondItem="KvJ-fF-o4f" secondAttribute="height" multiplier="16:9" priority="999" id="Con-eO-cOX"/>
</constraints>
</view>
<view clipsSubviews="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="gCY-Qy-hbS">
<rect key="frame" x="0.0" y="353" width="287" height="301.5"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" translatesAutoresizingMaskIntoConstraints="NO" id="3C9-uk-wu2">
<rect key="frame" x="0.0" y="0.0" width="287" height="301.5"/>
<subviews>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="9jB-zW-tJB">
<rect key="frame" x="0.0" y="0.0" width="287" height="215"/>
<constraints>
<constraint firstAttribute="width" secondItem="9jB-zW-tJB" secondAttribute="height" multiplier="4:3" priority="999" id="ioh-Zj-QGD"/>
</constraints>
</imageView>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="V94-ed-vFr">
<rect key="frame" x="0.0" y="215" width="287" height="86.5"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="252" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" minimumScaleFactor="0.5" adjustsFontForContentSizeCategory="YES" translatesAutoresizingMaskIntoConstraints="NO" id="dS1-ny-kA1">
<rect key="frame" x="8" y="8" width="271" height="20.5"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleHeadline"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="RAj-xv-7Sr">
<rect key="frame" x="8" y="36.5" width="271" height="18"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleSubhead"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="IhY-1O-KAR">
<rect key="frame" x="8" y="62.5" width="271" height="16"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleFootnote"/>
<color key="textColor" systemColor="secondaryLabelColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<directionalEdgeInsets key="directionalLayoutMargins" top="8" leading="8" bottom="8" trailing="8"/>
</stackView>
</subviews>
</stackView>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="6pk-EO-aa0">
<rect key="frame" x="0.0" y="0.0" width="287" height="301.5"/>
<connections>
<action selector="cardButtonTapped:" destination="KGk-i7-Jjw" eventType="touchUpInside" id="0L8-TA-GxD"/>
</connections>
</button>
</subviews>
<color key="backgroundColor" systemColor="secondarySystemBackgroundColor"/>
<constraints>
<constraint firstItem="6pk-EO-aa0" firstAttribute="leading" secondItem="gCY-Qy-hbS" secondAttribute="leading" id="4oF-J2-goz"/>
<constraint firstAttribute="trailing" secondItem="3C9-uk-wu2" secondAttribute="trailing" id="6in-BD-bgA"/>
<constraint firstItem="3C9-uk-wu2" firstAttribute="leading" secondItem="gCY-Qy-hbS" secondAttribute="leading" id="BRL-4d-akw"/>
<constraint firstAttribute="trailing" secondItem="6pk-EO-aa0" secondAttribute="trailing" id="LCI-Ey-TJ0"/>
<constraint firstItem="6pk-EO-aa0" firstAttribute="top" secondItem="gCY-Qy-hbS" secondAttribute="top" id="XYJ-Zq-6iT"/>
<constraint firstItem="3C9-uk-wu2" firstAttribute="top" secondItem="gCY-Qy-hbS" secondAttribute="top" id="dAK-CM-V0l"/>
<constraint firstAttribute="bottom" secondItem="6pk-EO-aa0" secondAttribute="bottom" id="e4U-OB-8hi"/>
<constraint firstAttribute="bottom" secondItem="3C9-uk-wu2" secondAttribute="bottom" id="uvq-Pb-NhR"/>
</constraints>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="number" keyPath="layer.cornerRadius">
<integer key="value" value="8"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
</view>
</subviews>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" distribution="fillEqually" translatesAutoresizingMaskIntoConstraints="NO" id="wFL-zS-Rev">
<rect key="frame" x="0.0" y="837.5" width="287" height="18.5"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" verticalHuggingPriority="251" contentHorizontalAlignment="leading" contentVerticalAlignment="center" adjustsImageSizeForAccessibilityContentSizeCategory="YES" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="1mc-Dy-v2f">
<rect key="frame" x="0.0" y="0.0" width="72" height="18.5"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleCaption2"/>
<color key="tintColor" systemColor="secondaryLabelColor"/>
<inset key="titleEdgeInsets" minX="4" minY="0.0" maxX="0.0" maxY="0.0"/>
<state key="normal" title="69" image="bubble.right" catalog="system">
<color key="titleColor" systemColor="secondaryLabelColor"/>
<preferredSymbolConfiguration key="preferredSymbolConfiguration" scale="small"/>
</state>
<connections>
<action selector="replyButtonTapped:" destination="KGk-i7-Jjw" eventType="touchUpInside" id="fIh-jy-zyy"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" verticalHuggingPriority="251" contentHorizontalAlignment="leading" contentVerticalAlignment="center" adjustsImageSizeForAccessibilityContentSizeCategory="YES" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="25b-IE-HZK">
<rect key="frame" x="72" y="0.0" width="71.5" height="18.5"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleCaption2"/>
<color key="tintColor" systemColor="secondaryLabelColor"/>
<inset key="titleEdgeInsets" minX="4" minY="0.0" maxX="0.0" maxY="0.0"/>
<state key="normal" title="69" image="arrow.2.squarepath" catalog="system">
<color key="titleColor" systemColor="secondaryLabelColor"/>
<preferredSymbolConfiguration key="preferredSymbolConfiguration" scale="small"/>
</state>
<connections>
<action selector="reblogButtonTapped:" destination="KGk-i7-Jjw" eventType="touchUpInside" id="2od-kC-4K5"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" verticalHuggingPriority="251" contentHorizontalAlignment="leading" contentVerticalAlignment="center" adjustsImageSizeForAccessibilityContentSizeCategory="YES" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="7f5-WO-gpi">
<rect key="frame" x="143.5" y="0.0" width="72" height="18.5"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleCaption2"/>
<color key="tintColor" systemColor="secondaryLabelColor"/>
<inset key="titleEdgeInsets" minX="4" minY="0.0" maxX="0.0" maxY="0.0"/>
<state key="normal" title="69" image="star" catalog="system">
<color key="titleColor" systemColor="secondaryLabelColor"/>
<preferredSymbolConfiguration key="preferredSymbolConfiguration" scale="small"/>
</state>
<connections>
<action selector="favoriteButtonTapped:" destination="KGk-i7-Jjw" eventType="touchUpInside" id="hyh-wI-9WM"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" verticalHuggingPriority="251" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageSizeForAccessibilityContentSizeCategory="YES" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="nrc-xp-Llw">
<rect key="frame" x="215.5" y="0.0" width="71.5" height="18.5"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleCaption2"/>
<color key="tintColor" systemColor="secondaryLabelColor"/>
<state key="normal" image="square.and.arrow.up" catalog="system">
<color key="titleColor" systemColor="secondaryLabelColor"/>
<preferredSymbolConfiguration key="preferredSymbolConfiguration" scale="small"/>
</state>
<connections>
<action selector="shareButtonTapped:" destination="KGk-i7-Jjw" eventType="touchUpInside" id="Owv-iB-VxJ"/>
</connections>
</button>
</subviews>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="Fhw-OW-ixv">
<rect key="frame" x="0.0" y="864" width="287" height="117"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" spacing="4" translatesAutoresizingMaskIntoConstraints="NO" id="xvi-yh-xAX">
<rect key="frame" x="0.0" y="0.0" width="287" height="28"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="hRM-1y-2pU">
<rect key="frame" x="0.0" y="0.0" width="33" height="28"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleFootnote"/>
<color key="textColor" systemColor="secondaryLabelColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="•" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="NkD-O9-e9D">
<rect key="frame" x="37" y="0.0" width="6.5" height="28"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleFootnote"/>
<color key="textColor" systemColor="secondaryLabelColor"/>
<nil key="highlightedColor"/>
</label>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="leading" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="hkk-pX-8oP">
<rect key="frame" x="47.5" y="0.0" width="239.5" height="28"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleFootnote"/>
<state key="normal" title="Button"/>
<state key="disabled">
<color key="titleColor" systemColor="secondaryLabelColor"/>
</state>
<connections>
<action selector="applicationButtonTapped:" destination="KGk-i7-Jjw" eventType="touchUpInside" id="yAU-hM-cUP"/>
</connections>
</button>
</subviews>
</stackView>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="4ZR-31-F0G">
<rect key="frame" x="0.0" y="36" width="287" height="1"/>
<color key="backgroundColor" systemColor="separatorColor"/>
<constraints>
<constraint firstAttribute="height" constant="1" id="jaw-Uw-Xby"/>
</constraints>
</view>
<stackView opaque="NO" contentMode="scaleToFill" distribution="fillEqually" translatesAutoresizingMaskIntoConstraints="NO" id="VJg-8P-ax9">
<rect key="frame" x="0.0" y="45" width="287" height="33"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="leading" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="pqY-NQ-5Fz">
<rect key="frame" x="0.0" y="0.0" width="143.5" height="33"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
<color key="tintColor" systemColor="secondaryLabelColor"/>
<state key="normal" title="666">
<color key="titleColor" systemColor="secondaryLabelColor"/>
</state>
<state key="highlighted">
<color key="titleColor" systemColor="tertiaryLabelColor"/>
</state>
<connections>
<action selector="contextParentRebloggedByButtonTapped:" destination="KGk-i7-Jjw" eventType="touchUpInside" id="X5h-c5-5Yq"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="leading" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Olw-ZF-pYB">
<rect key="frame" x="143.5" y="0.0" width="143.5" height="33"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
<state key="normal" title="666">
<color key="titleColor" systemColor="secondaryLabelColor"/>
</state>
<state key="highlighted">
<color key="titleColor" systemColor="tertiaryLabelColor"/>
</state>
<connections>
<action selector="contextParentFavoritedByButtonTapped:" destination="KGk-i7-Jjw" eventType="touchUpInside" id="eFA-jK-7pJ"/>
</connections>
</button>
</subviews>
</stackView>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="SlW-Ii-ozK">
<rect key="frame" x="0.0" y="86" width="287" height="1"/>
<color key="backgroundColor" systemColor="separatorColor"/>
<constraints>
<constraint firstAttribute="height" constant="1" id="DoC-rC-wYG"/>
</constraints>
</view>
<stackView opaque="NO" contentMode="scaleToFill" distribution="fillEqually" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="XOe-fg-wO6">
<rect key="frame" x="0.0" y="95" width="287" height="22"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="38F-f5-8Ha">
<rect key="frame" x="0.0" y="0.0" width="51" height="22"/>
<color key="tintColor" systemColor="secondaryLabelColor"/>
<state key="normal" image="bubble.right" catalog="system">
<preferredSymbolConfiguration key="preferredSymbolConfiguration" scale="medium"/>
</state>
<connections>
<action selector="replyButtonTapped:" destination="KGk-i7-Jjw" eventType="touchUpInside" id="jkz-ad-n2Y"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Rjo-bC-85y">
<rect key="frame" x="59" y="0.0" width="51" height="22"/>
<color key="tintColor" systemColor="secondaryLabelColor"/>
<state key="normal" image="arrow.2.squarepath" catalog="system">
<preferredSymbolConfiguration key="preferredSymbolConfiguration" scale="medium"/>
</state>
<connections>
<action selector="reblogButtonTapped:" destination="KGk-i7-Jjw" eventType="touchUpInside" id="hYp-sm-i4K"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Q79-pC-6ru">
<rect key="frame" x="118" y="0.0" width="51" height="22"/>
<color key="tintColor" systemColor="secondaryLabelColor"/>
<state key="normal" image="star" catalog="system">
<preferredSymbolConfiguration key="preferredSymbolConfiguration" scale="medium"/>
</state>
<connections>
<action selector="favoriteButtonTapped:" destination="KGk-i7-Jjw" eventType="touchUpInside" id="NdC-VQ-9ZD"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="5Ft-M2-BMM">
<rect key="frame" x="177" y="0.0" width="51" height="22"/>
<color key="tintColor" systemColor="secondaryLabelColor"/>
<state key="normal" image="square.and.arrow.up" catalog="system">
<preferredSymbolConfiguration key="preferredSymbolConfiguration" scale="medium"/>
</state>
<connections>
<action selector="shareButtonTapped:" destination="KGk-i7-Jjw" eventType="touchUpInside" id="hUE-mZ-QST"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Z1Y-Ch-xB7">
<rect key="frame" x="236" y="0.0" width="51" height="22"/>
<color key="tintColor" systemColor="secondaryLabelColor"/>
<state key="normal" image="ellipsis" catalog="system">
<preferredSymbolConfiguration key="preferredSymbolConfiguration" scale="medium"/>
</state>
<connections>
<action selector="actionsButtonTapped:" destination="KGk-i7-Jjw" eventType="touchUpInside" id="7qm-km-Ydt"/>
</connections>
</button>
</subviews>
</stackView>
</subviews>
</stackView>
</subviews>
</stackView>
</subviews>
<constraints>
<constraint firstItem="uhT-HE-MkE" firstAttribute="centerY" secondItem="ful-we-pCE" secondAttribute="centerY" id="5rP-PQ-irT"/>
<constraint firstItem="Rag-3x-Vbq" firstAttribute="top" secondItem="Cyx-R2-XUe" secondAttribute="top" constant="4" id="8h6-s3-iOk"/>
</constraints>
</stackView>
</subviews>
<constraints>
<constraint firstAttribute="trailingMargin" secondItem="PuM-4R-mah" secondAttribute="trailing" id="7TB-kA-Oo4"/>
<constraint firstItem="PuM-4R-mah" firstAttribute="top" secondItem="H2p-sc-9uM" secondAttribute="topMargin" id="81w-ID-ymP"/>
<constraint firstAttribute="bottomMargin" secondItem="PuM-4R-mah" secondAttribute="bottom" id="DB9-xL-qNI"/>
<constraint firstItem="PuM-4R-mah" firstAttribute="leading" secondItem="H2p-sc-9uM" secondAttribute="leadingMargin" id="VY2-YX-92L"/>
<constraint firstItem="tqr-8D-x5Z" firstAttribute="top" secondItem="H2p-sc-9uM" secondAttribute="top" id="YwS-sf-Z70"/>
<constraint firstAttribute="bottom" secondItem="H9F-5F-FkJ" secondAttribute="bottom" id="bWC-zo-sgU"/>
</constraints>
</tableViewCellContentView>
<viewLayoutGuide key="safeArea" id="njF-e1-oar"/>
<connections>
<outlet property="accountLabel" destination="hrV-68-5hn" id="Kn4-pt-nQa"/>
<outlet property="actionButtonsView" destination="wFL-zS-Rev" id="h7S-r0-vMa"/>
<outlet property="applicationButton" destination="hkk-pX-8oP" id="tHC-cy-B25"/>
<outlet property="attachmentsView" destination="KvJ-fF-o4f" id="KHT-xe-SeO"/>
<outlet property="avatarButton" destination="dRj-hF-Ov8" id="1aD-hK-1iz"/>
<outlet property="avatarImageView" destination="Rag-3x-Vbq" id="BaZ-ad-Qgs"/>
<outlet property="avatarReplyContextView" destination="NHl-tq-tPi" id="CCJ-SE-Egv"/>
<outlet property="cardButton" destination="6pk-EO-aa0" id="5SC-dt-7P7"/>
<outlet property="cardDescriptionLabel" destination="RAj-xv-7Sr" id="Ph4-KM-qED"/>
<outlet property="cardImageView" destination="9jB-zW-tJB" id="0Vr-xC-rIa"/>
<outlet property="cardTitleLabel" destination="dS1-ny-kA1" id="hYw-f7-WrH"/>
<outlet property="cardURLLabel" destination="IhY-1O-KAR" id="9Cl-2P-Z7x"/>
<outlet property="cardView" destination="gCY-Qy-hbS" id="u7g-iK-qhw"/>
<outlet property="contentTextView" destination="GvW-gH-ofw" id="sVs-dt-0Zt"/>
<outlet property="contextParentAccountLabel" destination="aa2-u6-YBQ" id="NeO-aF-DPZ"/>
<outlet property="contextParentActionsButton" destination="Z1Y-Ch-xB7" id="7S4-vc-gKe"/>
<outlet property="contextParentAvatarButton" destination="aNl-ag-2fc" id="Tah-tr-ckM"/>
<outlet property="contextParentAvatarImageView" destination="BLe-zN-EsU" id="99c-tt-zvI"/>
<outlet property="contextParentAvatarNameView" destination="P6a-zL-9B9" id="eGx-i7-i1a"/>
<outlet property="contextParentDisplayNameLabel" destination="ya9-zV-dMO" id="5QN-x6-V5E"/>
<outlet property="contextParentFavoriteButton" destination="Q79-pC-6ru" id="pZI-Yh-Tbh"/>
<outlet property="contextParentFavoritedByButton" destination="Olw-ZF-pYB" id="AwZ-wP-X55"/>
<outlet property="contextParentItems" destination="Fhw-OW-ixv" id="wws-EA-hjY"/>
<outlet property="contextParentReblogButton" destination="Rjo-bC-85y" id="hGu-h5-nbh"/>
<outlet property="contextParentRebloggedByButton" destination="pqY-NQ-5Fz" id="Cd9-Lf-lTr"/>
<outlet property="contextParentRebloggedByFavoritedBySeparator" destination="SlW-Ii-ozK" id="bKO-mz-IIW"/>
<outlet property="contextParentRebloggedByFavoritedByView" destination="VJg-8P-ax9" id="fzs-Fe-m0t"/>
<outlet property="contextParentReplyButton" destination="38F-f5-8Ha" id="bwI-S3-ZUM"/>
<outlet property="contextParentShareButton" destination="5Ft-M2-BMM" id="EC4-Xj-qcK"/>
<outlet property="contextParentTimeLabel" destination="hRM-1y-2pU" id="nwb-rf-gXn"/>
<outlet property="displayNameLabel" destination="aHQ-z9-LWz" id="v3P-4w-7mg"/>
<outlet property="favoriteButton" destination="7f5-WO-gpi" id="VvN-cW-anv"/>
<outlet property="hasReplyFollowingView" destination="H9F-5F-FkJ" id="abM-Ye-pzJ"/>
<outlet property="inReplyToView" destination="tqr-8D-x5Z" id="l7j-I4-vLJ"/>
<outlet property="metaIcon" destination="uhT-HE-MkE" id="1z9-PN-DvJ"/>
<outlet property="metaLabel" destination="ful-we-pCE" id="FtP-We-cCj"/>
<outlet property="nameDateView" destination="Cyx-R2-XUe" id="FGc-TV-Ufc"/>
<outlet property="reblogButton" destination="25b-IE-HZK" id="iZD-V3-d3T"/>
<outlet property="replyButton" destination="1mc-Dy-v2f" id="p07-xE-ZUI"/>
<outlet property="sensitiveContentView" destination="Rdc-ZD-zdc" id="yAX-uL-QH0"/>
<outlet property="shareButton" destination="nrc-xp-Llw" id="VeC-Mh-brV"/>
<outlet property="spoilerTextLabel" destination="7Mz-X2-wmw" id="7OY-Oa-Lhk"/>
<outlet property="timeApplicationDividerView" destination="NkD-O9-e9D" id="ygX-on-Xqu"/>
<outlet property="timeLabel" destination="lGC-HZ-ZT3" id="4Xu-ia-eDI"/>
<outlet property="toggleSensitiveContentButton" destination="Occ-DT-kxh" id="yd4-xI-94j"/>
<outletCollection property="separatorConstraints" destination="jaw-Uw-Xby" collectionClass="NSMutableArray" id="OvM-ag-v1s"/>
<outletCollection property="separatorConstraints" destination="DoC-rC-wYG" collectionClass="NSMutableArray" id="6NT-uI-Td4"/>
</connections>
<point key="canvasLocation" x="340" y="-525"/>
</tableViewCell>
</objects>
<resources>
<image name="arrow.2.squarepath" catalog="system" width="128" height="89"/>
<image name="bubble.right" catalog="system" width="128" height="110"/>
<image name="ellipsis" catalog="system" width="128" height="37"/>
<image name="square.and.arrow.up" catalog="system" width="115" height="128"/>
<image name="star" catalog="system" width="128" height="116"/>
<systemColor name="linkColor">
<color red="0.0" green="0.47843137254901963" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
<systemColor name="quaternaryLabelColor">
<color red="0.23529411764705882" green="0.23529411764705882" blue="0.2627450980392157" alpha="0.17999999999999999" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
<systemColor name="secondaryLabelColor">
<color red="0.23529411764705882" green="0.23529411764705882" blue="0.2627450980392157" alpha="0.59999999999999998" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
<systemColor name="secondarySystemBackgroundColor">
<color red="0.94901960784313721" green="0.94901960784313721" blue="0.96862745098039216" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
<systemColor name="separatorColor">
<color red="0.23529411764705882" green="0.23529411764705882" blue="0.2627450980392157" alpha="0.28999999999999998" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
<systemColor name="tertiaryLabelColor">
<color red="0.23529411764705882" green="0.23529411764705882" blue="0.2627450980392157" alpha="0.29999999999999999" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
</resources>
</document>

View file

@ -13,7 +13,6 @@ extension StatusContentConfiguration: UIContentConfiguration {
} }
func updated(for state: UIConfigurationState) -> StatusContentConfiguration { func updated(for state: UIConfigurationState) -> StatusContentConfiguration {
// TODO: Update stuff?
self self
} }
} }

View file

@ -15,6 +15,12 @@ class StatusListCell: UITableViewCell {
override func layoutSubviews() { override func layoutSubviews() {
super.layoutSubviews() super.layoutSubviews()
if viewModel?.hasReplyFollowing ?? false {
separatorInset.right = .greatestFiniteMagnitude
} else {
separatorInset.right = UIDevice.current.userInterfaceIdiom == .phone ? 0 : layoutMargins.right
}
separatorInset.left = UIDevice.current.userInterfaceIdiom == .phone ? 0 : layoutMargins.left separatorInset.left = UIDevice.current.userInterfaceIdiom == .phone ? 0 : layoutMargins.left
} }
} }

View file

@ -1,25 +1,79 @@
// Copyright © 2020 Metabolist. All rights reserved. // Copyright © 2020 Metabolist. All rights reserved.
import Kingfisher
import UIKit import UIKit
class StatusView: UIView { class StatusView: UIView {
private var statusConfiguration: StatusContentConfiguration @IBOutlet var baseView: UIView!
@IBOutlet weak var metaIcon: UIImageView!
@IBOutlet weak var metaLabel: UILabel!
@IBOutlet weak var contentTextView: TouchFallthroughTextView!
@IBOutlet weak var avatarButton: UIButton!
@IBOutlet weak var avatarImageView: AnimatedImageView!
@IBOutlet weak var displayNameLabel: UILabel!
@IBOutlet weak var accountLabel: UILabel!
@IBOutlet weak var timeLabel: UILabel!
@IBOutlet weak var spoilerTextLabel: UILabel!
@IBOutlet weak var toggleSensitiveContentButton: UIButton!
@IBOutlet weak var replyButton: UIButton!
@IBOutlet weak var reblogButton: UIButton!
@IBOutlet weak var favoriteButton: UIButton!
@IBOutlet weak var shareButton: UIButton!
@IBOutlet weak var attachmentsView: AttachmentsView!
@IBOutlet weak var cardView: UIView!
@IBOutlet weak var cardImageView: UIImageView!
@IBOutlet weak var cardTitleLabel: UILabel!
@IBOutlet weak var cardDescriptionLabel: UILabel!
@IBOutlet weak var cardURLLabel: UILabel!
@IBOutlet weak var cardButton: UIButton!
@IBOutlet weak var sensitiveContentView: UIStackView!
@IBOutlet weak var hasReplyFollowingView: UIView!
@IBOutlet weak var inReplyToView: UIView!
@IBOutlet weak var avatarReplyContextView: UIView!
@IBOutlet weak var nameDateView: UIStackView!
@IBOutlet weak var contextParentAvatarNameView: UIStackView!
@IBOutlet weak var contextParentAvatarImageView: AnimatedImageView!
@IBOutlet weak var contextParentAvatarButton: UIButton!
@IBOutlet weak var contextParentDisplayNameLabel: UILabel!
@IBOutlet weak var contextParentAccountLabel: UILabel!
@IBOutlet weak var actionButtonsView: UIStackView!
@IBOutlet weak var contextParentReplyButton: UIButton!
@IBOutlet weak var contextParentReblogButton: UIButton!
@IBOutlet weak var contextParentFavoriteButton: UIButton!
@IBOutlet weak var contextParentShareButton: UIButton!
@IBOutlet weak var contextParentActionsButton: UIButton!
@IBOutlet weak var contextParentTimeLabel: UILabel!
@IBOutlet weak var timeApplicationDividerView: UILabel!
@IBOutlet weak var applicationButton: UIButton!
@IBOutlet weak var contextParentRebloggedByButton: UIButton!
@IBOutlet weak var contextParentFavoritedByButton: UIButton!
@IBOutlet weak var contextParentItems: UIStackView!
@IBOutlet weak var contextParentRebloggedByFavoritedByView: UIStackView!
@IBOutlet weak var contextParentRebloggedByFavoritedBySeparator: UIView!
private let content = TouchFallthroughTextView() private var statusConfiguration: StatusContentConfiguration
@IBOutlet private var separatorConstraints: [NSLayoutConstraint]!
init(configuration: StatusContentConfiguration) { init(configuration: StatusContentConfiguration) {
self.statusConfiguration = configuration self.statusConfiguration = configuration
super.init(frame: .zero) super.init(frame: .zero)
setup() initialSetup()
applyStatusConfiguration()
} }
@available(*, unavailable) @available(*, unavailable)
required init?(coder: NSCoder) { required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented") fatalError("init(coder:) has not been implemented")
} }
override func layoutSubviews() {
super.layoutSubviews()
for button: UIButton in [toggleSensitiveContentButton] where button.frame.height != 0 {
button.layer.cornerRadius = button.frame.height / 2
}
}
} }
extension StatusView: UIContentView { extension StatusView: UIContentView {
@ -30,40 +84,263 @@ extension StatusView: UIContentView {
self.statusConfiguration = statusConfiguration self.statusConfiguration = statusConfiguration
avatarImageView.kf.cancelDownloadTask()
contextParentAvatarImageView.kf.cancelDownloadTask()
cardImageView.kf.cancelDownloadTask()
applyStatusConfiguration() applyStatusConfiguration()
} }
} }
} }
extension StatusView: UITextViewDelegate {
func textView(
_ textView: UITextView,
shouldInteractWith URL: URL,
in characterRange: NSRange,
interaction: UITextItemInteraction) -> Bool {
switch interaction {
case .invokeDefaultAction: print(URL); return false
case .preview: return false
case .presentActions: return false
@unknown default: return false
}
}
}
private extension StatusView { private extension StatusView {
func setup() { func initialSetup() {
addSubview(content) Bundle.main.loadNibNamed(String(describing: type(of: self)), owner: self, options: nil)
content.translatesAutoresizingMaskIntoConstraints = false
content.isScrollEnabled = false addSubview(baseView)
content.isEditable = false
content.backgroundColor = .clear baseView.translatesAutoresizingMaskIntoConstraints = false
baseView.backgroundColor = .clear
NSLayoutConstraint.activate([ NSLayoutConstraint.activate([
content.leadingAnchor.constraint(equalTo: readableContentGuide.leadingAnchor), baseView.topAnchor.constraint(equalTo: readableContentGuide.topAnchor),
content.trailingAnchor.constraint(equalTo: readableContentGuide.trailingAnchor), baseView.leadingAnchor.constraint(equalTo: readableContentGuide.leadingAnchor),
content.topAnchor.constraint(equalTo: readableContentGuide.topAnchor), baseView.trailingAnchor.constraint(equalTo: readableContentGuide.trailingAnchor),
content.bottomAnchor.constraint(equalTo: readableContentGuide.bottomAnchor) baseView.bottomAnchor.constraint(equalTo: readableContentGuide.bottomAnchor),
// These have "Placeholder" checked in the xib file so they can
// be set to go beyond the readable content guide
inReplyToView.topAnchor.constraint(equalTo: topAnchor),
hasReplyFollowingView.bottomAnchor.constraint(equalTo: bottomAnchor)
]) ])
for constraint in separatorConstraints {
constraint.constant = 1 / UIScreen.main.scale
} }
avatarImageView.kf.indicatorType = .activity
contextParentAvatarImageView.kf.indicatorType = .activity
cardImageView.kf.indicatorType = .activity
contentTextView.delegate = self
let highlightedButtonBackgroundImage = UIColor(white: 0, alpha: 0.5).image()
cardButton.setBackgroundImage(highlightedButtonBackgroundImage, for: .highlighted)
avatarButton.setBackgroundImage(highlightedButtonBackgroundImage, for: .highlighted)
contextParentAvatarButton.setBackgroundImage(highlightedButtonBackgroundImage, for: .highlighted)
let favoriteAction = UIAction { [weak self] _ in self?.statusConfiguration.viewModel.toggleFavorited() }
favoriteButton.addAction(favoriteAction, for: .touchUpInside)
contextParentFavoriteButton.addAction(favoriteAction, for: .touchUpInside)
applyStatusConfiguration()
}
// swiftlint:disable function_body_length
func applyStatusConfiguration() { func applyStatusConfiguration() {
let viewModel = statusConfiguration.viewModel let viewModel = statusConfiguration.viewModel
let mutableContent = NSMutableAttributedString(attributedString: viewModel.content) let mutableContent = NSMutableAttributedString(attributedString: viewModel.content)
let mutableDisplayName = NSMutableAttributedString(string: viewModel.displayName)
let mutableSpoilerText = NSMutableAttributedString(string: viewModel.spoilerText)
let contentFont = UIFont.preferredFont(forTextStyle: viewModel.isContextParent ? .title3 : .callout) let contentFont = UIFont.preferredFont(forTextStyle: viewModel.isContextParent ? .title3 : .callout)
contentTextView.shouldFallthrough = !viewModel.isContextParent
avatarReplyContextView.isHidden = viewModel.isContextParent
nameDateView.isHidden = viewModel.isContextParent
contextParentAvatarNameView.isHidden = !viewModel.isContextParent
actionButtonsView.isHidden = viewModel.isContextParent
contextParentItems.isHidden = !viewModel.isContextParent
let avatarImageView: UIImageView
let displayNameLabel: UILabel
let accountLabel: UILabel
if viewModel.isContextParent {
avatarImageView = contextParentAvatarImageView
displayNameLabel = contextParentDisplayNameLabel
accountLabel = contextParentAccountLabel
} else {
avatarImageView = self.avatarImageView
displayNameLabel = self.displayNameLabel
accountLabel = self.accountLabel
}
let contentRange = NSRange(location: 0, length: mutableContent.length) let contentRange = NSRange(location: 0, length: mutableContent.length)
mutableContent.removeAttribute(.font, range: contentRange) mutableContent.removeAttribute(.font, range: contentRange)
mutableContent.addAttributes( mutableContent.addAttributes(
[.font: contentFont as Any, [.font: contentFont as Any,
.foregroundColor: UIColor.label], .foregroundColor: UIColor.label],
range: contentRange) range: contentRange)
mutableContent.insert(emoji: viewModel.contentEmoji, view: content) mutableContent.insert(emoji: viewModel.contentEmoji, view: contentTextView)
mutableContent.resizeAttachments(toLineHeight: contentFont.lineHeight) mutableContent.resizeAttachments(toLineHeight: contentFont.lineHeight)
content.attributedText = mutableContent contentTextView.attributedText = mutableContent
// content.isHidden = contentTextView.text == "" contentTextView.isHidden = contentTextView.text == ""
mutableDisplayName.insert(emoji: viewModel.displayNameEmoji, view: displayNameLabel)
mutableDisplayName.resizeAttachments(toLineHeight: displayNameLabel.font.lineHeight)
displayNameLabel.attributedText = mutableDisplayName
mutableSpoilerText.insert(emoji: viewModel.contentEmoji, view: spoilerTextLabel)
mutableSpoilerText.resizeAttachments(toLineHeight: spoilerTextLabel.font.lineHeight)
spoilerTextLabel.attributedText = mutableSpoilerText
spoilerTextLabel.isHidden = !viewModel.sensitive || spoilerTextLabel.text == ""
toggleSensitiveContentButton.setTitle(
viewModel.shouldDisplaySensitiveContent
? NSLocalizedString("status.show-less", comment: "")
: NSLocalizedString("status.show-more", comment: ""),
for: .normal)
accountLabel.text = viewModel.accountName
timeLabel.text = viewModel.time
contextParentTimeLabel.text = viewModel.contextParentTime
timeApplicationDividerView.isHidden = viewModel.applicationName == nil
applicationButton.isHidden = viewModel.applicationName == nil
applicationButton.setTitle(viewModel.applicationName, for: .normal)
applicationButton.isEnabled = viewModel.applicationURL != nil
avatarImageView.kf.setImage(with: viewModel.avatarURL)
toggleSensitiveContentButton.isHidden = !viewModel.sensitive
replyButton.setTitle(viewModel.repliesCount == 0 ? "" : String(viewModel.repliesCount), for: .normal)
reblogButton.setTitle(viewModel.reblogsCount == 0 ? "" : String(viewModel.reblogsCount), for: .normal)
setReblogButtonColor(reblogged: viewModel.reblogged)
favoriteButton.setTitle(viewModel.favoritesCount == 0 ? "" : String(viewModel.favoritesCount), for: .normal)
setFavoriteButtonColor(favorited: viewModel.favorited)
reblogButton.isEnabled = viewModel.canBeReblogged
contextParentReblogButton.isEnabled = viewModel.canBeReblogged
let noReblogs = viewModel.reblogsCount == 0
let noFavorites = viewModel.favoritesCount == 0
let noInteractions = noReblogs && noFavorites
setAttributedLocalizedTitle(
button: contextParentRebloggedByButton,
localizationKey: "status.reblogs-count",
count: viewModel.reblogsCount)
contextParentRebloggedByButton.isHidden = noReblogs
setAttributedLocalizedTitle(
button: contextParentFavoritedByButton,
localizationKey: "status.favorites-count",
count: viewModel.favoritesCount)
contextParentFavoritedByButton.isHidden = noFavorites
contextParentRebloggedByFavoritedByView.isHidden = noInteractions
contextParentRebloggedByFavoritedBySeparator.isHidden = noInteractions
if
viewModel.isReblog {
let metaText = String.localizedStringWithFormat(
NSLocalizedString("status.reblogged-by", comment: ""),
viewModel.rebloggedByDisplayName)
let mutableMetaText = NSMutableAttributedString(string: metaText)
mutableMetaText.insert(emoji: viewModel.rebloggedByDisplayNameEmoji, view: metaLabel)
mutableMetaText.resizeAttachments(toLineHeight: metaLabel.font.lineHeight)
metaLabel.attributedText = mutableMetaText
metaIcon.image = UIImage(
systemName: "arrow.2.squarepath",
withConfiguration: UIImage.SymbolConfiguration(scale: .small))
metaLabel.isHidden = false
metaIcon.isHidden = false
} else if viewModel.isPinned {
metaLabel.text = NSLocalizedString("status.pinned-post", comment: "")
metaIcon.image = UIImage(
systemName: "pin",
withConfiguration: UIImage.SymbolConfiguration(scale: .small))
metaLabel.isHidden = false
metaIcon.isHidden = false
} else {
metaLabel.isHidden = true
metaIcon.isHidden = true
}
attachmentsView.isHidden = viewModel.attachmentViewModels.count == 0
attachmentsView.attachmentViewModels = viewModel.attachmentViewModels
setNeedsLayout()
if let cardURL = viewModel.cardURL {
cardTitleLabel.text = viewModel.cardTitle
cardDescriptionLabel.text = viewModel.cardDescription
cardDescriptionLabel.isHidden = cardDescriptionLabel.text == ""
|| cardDescriptionLabel.text == cardTitleLabel.text
if
let host = cardURL.host, host.hasPrefix("www."),
let withoutWww = cardURL.host?.components(separatedBy: "www.").last {
cardURLLabel.text = withoutWww
} else {
cardURLLabel.text = cardURL.host
}
if let cardImageURL = viewModel.cardImageURL {
cardImageView.isHidden = false
cardImageView.kf.setImage(with: cardImageURL)
} else {
cardImageView.isHidden = true
}
cardView.isHidden = false
} else {
cardView.isHidden = true
}
sensitiveContentView.isHidden = !viewModel.shouldDisplaySensitiveContent
inReplyToView.isHidden = !viewModel.isReplyInContext
hasReplyFollowingView.isHidden = !viewModel.hasReplyFollowing
}
// swiftlint:enable function_body_length
func setReblogButtonColor(reblogged: Bool) {
let reblogColor: UIColor = reblogged ? .systemGreen : .secondaryLabel
let reblogButton: UIButton
if statusConfiguration.viewModel.isContextParent {
reblogButton = contextParentReblogButton
} else {
reblogButton = self.reblogButton
}
reblogButton.tintColor = reblogColor
reblogButton.setTitleColor(reblogColor, for: .normal)
}
func setFavoriteButtonColor(favorited: Bool) {
let favoriteColor: UIColor = favorited ? .systemYellow : .secondaryLabel
let favoriteButton: UIButton
let scale: UIImage.SymbolScale
if statusConfiguration.viewModel.isContextParent {
favoriteButton = contextParentFavoriteButton
scale = .medium
} else {
favoriteButton = self.favoriteButton
scale = .small
}
favoriteButton.tintColor = favoriteColor
favoriteButton.setTitleColor(favoriteColor, for: .normal)
favoriteButton.setImage(UIImage(
systemName: favorited ? "star.fill" : "star",
withConfiguration: UIImage.SymbolConfiguration(scale: scale)),
for: .normal)
}
private func setAttributedLocalizedTitle(button: UIButton, localizationKey: String, count: Int) {
let localizedTitle = String.localizedStringWithFormat(NSLocalizedString(localizationKey, comment: ""), count)
button.setAttributedTitle(localizedTitle.countEmphasizedAttributedString(count: count), for: .normal)
button.setAttributedTitle(
localizedTitle.countEmphasizedAttributedString(count: count, highlighted: true),
for: .highlighted)
} }
} }

518
Views/Status/StatusView.xib Normal file
View file

@ -0,0 +1,518 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="17154" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<device id="retina6_1" orientation="portrait" appearance="light"/>
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="17124"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="System colors in document resources" minToolsVersion="11.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="StatusView" customModule="Metatext" customModuleProvider="target">
<connections>
<outlet property="accountLabel" destination="NMr-1N-vQB" id="v2W-oV-3FP"/>
<outlet property="actionButtonsView" destination="zJg-bJ-uzd" id="iFx-AO-sJP"/>
<outlet property="applicationButton" destination="Rdt-TR-8S5" id="8dq-u9-oZ7"/>
<outlet property="attachmentsView" destination="diz-eN-CAY" id="7Ns-7h-laI"/>
<outlet property="avatarButton" destination="Xr7-Jl-psM" id="rKv-sF-8as"/>
<outlet property="avatarImageView" destination="5nP-eN-kWB" id="uxB-BV-s8N"/>
<outlet property="avatarReplyContextView" destination="H9l-Fc-4W4" id="gqR-14-5D9"/>
<outlet property="baseView" destination="iN0-l3-epB" id="Uv8-kN-29p"/>
<outlet property="cardButton" destination="0dd-dr-kRv" id="1I9-dk-IwM"/>
<outlet property="cardDescriptionLabel" destination="ad9-Cs-OwJ" id="H9s-3b-3ip"/>
<outlet property="cardImageView" destination="kdP-9H-oGY" id="T4H-1P-Dv8"/>
<outlet property="cardTitleLabel" destination="RDi-25-Ez4" id="VMN-AS-4Dy"/>
<outlet property="cardURLLabel" destination="pJj-LK-GQa" id="29l-Da-gSK"/>
<outlet property="cardView" destination="3dp-0a-Tpx" id="HnM-qF-c1Q"/>
<outlet property="contentTextView" destination="hxc-Pn-Vwz" id="VpV-ct-ngH"/>
<outlet property="contextParentAccountLabel" destination="8eU-OP-ovw" id="ovL-ho-3QQ"/>
<outlet property="contextParentActionsButton" destination="fN1-ao-eiV" id="VWJ-cv-jv0"/>
<outlet property="contextParentAvatarButton" destination="biC-25-AyX" id="2LZ-VP-sHm"/>
<outlet property="contextParentAvatarImageView" destination="Mkl-wW-t1y" id="KaW-YP-bih"/>
<outlet property="contextParentAvatarNameView" destination="JJo-vZ-2Ei" id="TDO-oC-Pxl"/>
<outlet property="contextParentDisplayNameLabel" destination="ONj-pm-o1o" id="cMf-BW-MBe"/>
<outlet property="contextParentFavoriteButton" destination="vKK-ho-Mc8" id="gUM-L7-Xvd"/>
<outlet property="contextParentFavoritedByButton" destination="dCB-Ba-lgt" id="5Ms-YL-of5"/>
<outlet property="contextParentItems" destination="dcp-zF-sHI" id="fk0-E0-a1C"/>
<outlet property="contextParentReblogButton" destination="c9q-Xj-ZhU" id="r6E-eC-ARj"/>
<outlet property="contextParentRebloggedByButton" destination="OaH-fg-fwa" id="VRW-Nv-ciu"/>
<outlet property="contextParentRebloggedByFavoritedBySeparator" destination="zAt-7g-Zg4" id="qHu-jW-D7F"/>
<outlet property="contextParentRebloggedByFavoritedByView" destination="M1E-qU-AAW" id="1jR-TT-38d"/>
<outlet property="contextParentReplyButton" destination="v8s-eL-K9J" id="OXs-A1-gof"/>
<outlet property="contextParentShareButton" destination="jXx-KF-3pu" id="Jbo-lf-AeG"/>
<outlet property="contextParentTimeLabel" destination="6Fo-vD-qjJ" id="3tZ-Ei-90H"/>
<outlet property="displayNameLabel" destination="8mm-Xw-oKi" id="f1U-Vb-70M"/>
<outlet property="favoriteButton" destination="ewo-qO-lvX" id="Hp2-L2-sHu"/>
<outlet property="hasReplyFollowingView" destination="EJV-En-WBg" id="5Ky-IG-ZmG"/>
<outlet property="inReplyToView" destination="gwb-UL-Eqa" id="WsQ-X0-Tw6"/>
<outlet property="metaIcon" destination="aO2-AK-zwO" id="zUW-ls-ofz"/>
<outlet property="metaLabel" destination="FMa-fP-vr2" id="SpH-Uz-Juk"/>
<outlet property="nameDateView" destination="svp-hj-Xn6" id="SzA-ME-jU0"/>
<outlet property="reblogButton" destination="ZKl-Hp-Y42" id="bxe-wr-kB7"/>
<outlet property="replyButton" destination="6HD-MP-H72" id="5fb-z4-qlm"/>
<outlet property="sensitiveContentView" destination="BXI-3E-NWh" id="sXO-EM-fTI"/>
<outlet property="shareButton" destination="zAD-2Z-vhu" id="ZzV-wg-rOZ"/>
<outlet property="spoilerTextLabel" destination="5Gq-2q-Cvx" id="owo-VU-cIm"/>
<outlet property="timeApplicationDividerView" destination="hYj-vy-Net" id="F8o-xH-FFP"/>
<outlet property="timeLabel" destination="FEN-6u-xs5" id="epT-vQ-T9R"/>
<outlet property="toggleSensitiveContentButton" destination="XqE-Oj-oxH" id="EQB-cR-eOL"/>
<outletCollection property="separatorConstraints" destination="VEz-6j-37B" collectionClass="NSMutableArray" id="liC-8J-DV0"/>
<outletCollection property="separatorConstraints" destination="H9G-jZ-cek" collectionClass="NSMutableArray" id="E4b-tA-2gG"/>
</connections>
</placeholder>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<view contentMode="scaleToFill" id="iN0-l3-epB">
<rect key="frame" x="0.0" y="0.0" width="536" height="864"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="B6h-6a-Lty">
<rect key="frame" x="0.0" y="0.0" width="536" height="864"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="H9l-Fc-4W4">
<rect key="frame" x="0.0" y="0.0" width="50" height="864"/>
<subviews>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="arrow.2.squarepath" catalog="system" translatesAutoresizingMaskIntoConstraints="NO" id="aO2-AK-zwO">
<rect key="frame" x="29.5" y="-7.5" width="20.5" height="14.5"/>
<color key="tintColor" systemColor="secondaryLabelColor"/>
<preferredSymbolConfiguration key="preferredSymbolConfiguration" scale="small"/>
</imageView>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="gwb-UL-Eqa">
<rect key="frame" x="24" y="0.0" width="2" height="12"/>
<color key="backgroundColor" systemColor="quaternaryLabelColor"/>
<constraints>
<constraint firstAttribute="width" constant="2" id="CTo-LC-S4B"/>
</constraints>
</view>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="5nP-eN-kWB" customClass="AnimatedImageView" customModule="Kingfisher">
<rect key="frame" x="0.0" y="12" width="50" height="50"/>
<constraints>
<constraint firstAttribute="height" constant="50" id="MOY-NI-L3C"/>
<constraint firstAttribute="width" constant="50" id="dHx-9Y-qH0"/>
</constraints>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="number" keyPath="layer.cornerRadius">
<integer key="value" value="25"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
</imageView>
<button opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Xr7-Jl-psM">
<rect key="frame" x="0.0" y="12" width="50" height="50"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="number" keyPath="layer.cornerRadius">
<integer key="value" value="25"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
</button>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="EJV-En-WBg">
<rect key="frame" x="24" y="62" width="2" height="802"/>
<color key="backgroundColor" systemColor="quaternaryLabelColor"/>
<constraints>
<constraint firstAttribute="width" constant="2" id="cPl-wP-HET"/>
</constraints>
</view>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="Xr7-Jl-psM" firstAttribute="bottom" secondItem="5nP-eN-kWB" secondAttribute="bottom" id="59c-8Y-WwT"/>
<constraint firstItem="5nP-eN-kWB" firstAttribute="leading" secondItem="H9l-Fc-4W4" secondAttribute="leading" id="AnF-cy-TF6"/>
<constraint firstItem="Xr7-Jl-psM" firstAttribute="leading" secondItem="5nP-eN-kWB" secondAttribute="leading" id="AtE-EW-2bE"/>
<constraint firstItem="gwb-UL-Eqa" firstAttribute="bottom" secondItem="5nP-eN-kWB" secondAttribute="top" id="M5s-gS-nod"/>
<constraint firstItem="EJV-En-WBg" firstAttribute="centerX" secondItem="5nP-eN-kWB" secondAttribute="centerX" id="ZbS-CP-EPR"/>
<constraint firstItem="Xr7-Jl-psM" firstAttribute="trailing" secondItem="5nP-eN-kWB" secondAttribute="trailing" id="aDG-XX-Aj3"/>
<constraint firstItem="EJV-En-WBg" firstAttribute="top" secondItem="5nP-eN-kWB" secondAttribute="bottom" id="aaW-v3-Deb"/>
<constraint firstAttribute="trailing" secondItem="aO2-AK-zwO" secondAttribute="trailing" id="fTn-dx-kgl"/>
<constraint firstItem="Xr7-Jl-psM" firstAttribute="top" secondItem="5nP-eN-kWB" secondAttribute="top" id="nEr-NK-zNi"/>
<constraint firstAttribute="trailing" secondItem="5nP-eN-kWB" secondAttribute="trailing" id="scQ-5M-FoQ"/>
<constraint firstItem="gwb-UL-Eqa" firstAttribute="centerX" secondItem="5nP-eN-kWB" secondAttribute="centerX" id="yRg-Yx-Q4A"/>
</constraints>
</view>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="JXH-S7-Gjf">
<rect key="frame" x="58" y="0.0" width="478" height="864"/>
<subviews>
<stackView opaque="NO" contentMode="top" axis="vertical" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="0RV-3u-4W7">
<rect key="frame" x="0.0" y="0.0" width="478" height="82"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="FMa-fP-vr2">
<rect key="frame" x="0.0" y="0.0" width="478" height="0.0"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleCaption1"/>
<color key="textColor" systemColor="secondaryLabelColor"/>
<nil key="highlightedColor"/>
</label>
<stackView opaque="NO" contentMode="scaleToFill" spacing="4" translatesAutoresizingMaskIntoConstraints="NO" id="svp-hj-Xn6">
<rect key="frame" x="0.0" y="8" width="478" height="0.0"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" horizontalCompressionResistancePriority="751" verticalCompressionResistancePriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="8mm-Xw-oKi">
<rect key="frame" x="0.0" y="0.0" width="43.5" height="0.0"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleHeadline"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="NMr-1N-vQB">
<rect key="frame" x="47.5" y="0.0" width="389" height="0.0"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleSubhead"/>
<color key="textColor" systemColor="secondaryLabelColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" horizontalCompressionResistancePriority="752" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="FEN-6u-xs5">
<rect key="frame" x="440.5" y="0.0" width="37.5" height="0.0"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleSubhead"/>
<color key="textColor" systemColor="secondaryLabelColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="JJo-vZ-2Ei">
<rect key="frame" x="0.0" y="16" width="478" height="50"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="G9w-4E-gst">
<rect key="frame" x="0.0" y="0.0" width="50" height="50"/>
<subviews>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="Mkl-wW-t1y" customClass="AnimatedImageView" customModule="Kingfisher">
<rect key="frame" x="0.0" y="0.0" width="50" height="50"/>
<constraints>
<constraint firstAttribute="height" constant="50" id="CUB-dd-5ES"/>
<constraint firstAttribute="width" constant="50" id="OWd-GZ-pzg"/>
</constraints>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="number" keyPath="layer.cornerRadius">
<integer key="value" value="25"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
</imageView>
<button opaque="NO" clipsSubviews="YES" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="biC-25-AyX">
<rect key="frame" x="0.0" y="0.0" width="50" height="50"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="number" keyPath="layer.cornerRadius">
<integer key="value" value="25"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
</button>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="biC-25-AyX" firstAttribute="top" secondItem="Mkl-wW-t1y" secondAttribute="top" id="I2W-iP-K1d"/>
<constraint firstItem="biC-25-AyX" firstAttribute="bottom" secondItem="Mkl-wW-t1y" secondAttribute="bottom" id="U0p-m9-fGR"/>
<constraint firstItem="Mkl-wW-t1y" firstAttribute="top" secondItem="G9w-4E-gst" secondAttribute="top" id="UcU-Ds-jfN"/>
<constraint firstAttribute="trailing" secondItem="Mkl-wW-t1y" secondAttribute="trailing" id="Xh4-dE-t47"/>
<constraint firstItem="biC-25-AyX" firstAttribute="leading" secondItem="Mkl-wW-t1y" secondAttribute="leading" id="Z5c-u3-6tE"/>
<constraint firstItem="biC-25-AyX" firstAttribute="trailing" secondItem="Mkl-wW-t1y" secondAttribute="trailing" id="fcB-JW-KmC"/>
<constraint firstAttribute="bottom" secondItem="Mkl-wW-t1y" secondAttribute="bottom" id="pR8-fI-zaO"/>
<constraint firstItem="Mkl-wW-t1y" firstAttribute="leading" secondItem="G9w-4E-gst" secondAttribute="leading" id="vWz-29-nLh"/>
</constraints>
</view>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" translatesAutoresizingMaskIntoConstraints="NO" id="JxA-h1-ocA">
<rect key="frame" x="58" y="0.0" width="420" height="50"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="ONj-pm-o1o">
<rect key="frame" x="0.0" y="0.0" width="420" height="32"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleHeadline"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="252" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="8eU-OP-ovw">
<rect key="frame" x="0.0" y="32" width="420" height="18"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleSubhead"/>
<color key="textColor" systemColor="secondaryLabelColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
</stackView>
</subviews>
</stackView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="5Gq-2q-Cvx">
<rect key="frame" x="0.0" y="74" width="478" height="0.0"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleCallout"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<button opaque="NO" contentMode="scaleToFill" verticalHuggingPriority="251" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="XqE-Oj-oxH">
<rect key="frame" x="0.0" y="82" width="478" height="0.0"/>
<color key="backgroundColor" systemColor="linkColor"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleHeadline"/>
<state key="normal" title="Show More">
<color key="titleColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</state>
</button>
</subviews>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" verticalCompressionResistancePriority="749" axis="vertical" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="BXI-3E-NWh">
<rect key="frame" x="0.0" y="90" width="478" height="712.5"/>
<subviews>
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" verticalCompressionResistancePriority="751" scrollEnabled="NO" editable="NO" text="Content" textAlignment="natural" adjustsFontForContentSizeCategory="YES" translatesAutoresizingMaskIntoConstraints="NO" id="hxc-Pn-Vwz" customClass="TouchFallthroughTextView" customModule="Metatext" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="478" height="37"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleCallout"/>
<textInputTraits key="textInputTraits" autocapitalizationType="sentences"/>
</textView>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="diz-eN-CAY" customClass="AttachmentsView" customModule="Metatext" customModuleProvider="target">
<rect key="frame" x="0.0" y="45" width="478" height="269"/>
<constraints>
<constraint firstAttribute="width" secondItem="diz-eN-CAY" secondAttribute="height" multiplier="16:9" priority="999" id="yvF-tL-A5X"/>
</constraints>
</view>
<view clipsSubviews="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="3dp-0a-Tpx">
<rect key="frame" x="0.0" y="322" width="478" height="390.5"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" translatesAutoresizingMaskIntoConstraints="NO" id="InD-Bl-xMp">
<rect key="frame" x="0.0" y="0.0" width="478" height="390.5"/>
<subviews>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="kdP-9H-oGY">
<rect key="frame" x="0.0" y="0.0" width="478" height="358.5"/>
<constraints>
<constraint firstAttribute="width" secondItem="kdP-9H-oGY" secondAttribute="height" multiplier="4:3" priority="999" id="Pi5-Mu-x9m"/>
</constraints>
</imageView>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="6GY-Bg-957">
<rect key="frame" x="0.0" y="358.5" width="478" height="32"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="252" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" minimumScaleFactor="0.5" adjustsFontForContentSizeCategory="YES" translatesAutoresizingMaskIntoConstraints="NO" id="RDi-25-Ez4">
<rect key="frame" x="8" y="8" width="462" height="0.0"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleHeadline"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="ad9-Cs-OwJ">
<rect key="frame" x="8" y="16" width="462" height="0.0"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleSubhead"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="pJj-LK-GQa">
<rect key="frame" x="8" y="24" width="462" height="0.0"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleFootnote"/>
<color key="textColor" systemColor="secondaryLabelColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<directionalEdgeInsets key="directionalLayoutMargins" top="8" leading="8" bottom="8" trailing="8"/>
</stackView>
</subviews>
</stackView>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="0dd-dr-kRv">
<rect key="frame" x="0.0" y="0.0" width="478" height="390.5"/>
</button>
</subviews>
<color key="backgroundColor" systemColor="secondarySystemBackgroundColor"/>
<constraints>
<constraint firstAttribute="bottom" secondItem="InD-Bl-xMp" secondAttribute="bottom" id="9sj-tg-MDu"/>
<constraint firstAttribute="bottom" secondItem="0dd-dr-kRv" secondAttribute="bottom" id="EJ1-Fe-4Hk"/>
<constraint firstAttribute="trailing" secondItem="0dd-dr-kRv" secondAttribute="trailing" id="F5A-mO-hup"/>
<constraint firstItem="0dd-dr-kRv" firstAttribute="top" secondItem="3dp-0a-Tpx" secondAttribute="top" id="Gif-tV-8yk"/>
<constraint firstItem="InD-Bl-xMp" firstAttribute="leading" secondItem="3dp-0a-Tpx" secondAttribute="leading" id="TkA-DT-C7q"/>
<constraint firstAttribute="trailing" secondItem="InD-Bl-xMp" secondAttribute="trailing" id="bsr-QN-via"/>
<constraint firstItem="InD-Bl-xMp" firstAttribute="top" secondItem="3dp-0a-Tpx" secondAttribute="top" id="pwn-1Y-2kG"/>
<constraint firstItem="0dd-dr-kRv" firstAttribute="leading" secondItem="3dp-0a-Tpx" secondAttribute="leading" id="vJZ-Qe-3zt"/>
</constraints>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="number" keyPath="layer.cornerRadius">
<integer key="value" value="8"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
</view>
</subviews>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" distribution="fillEqually" translatesAutoresizingMaskIntoConstraints="NO" id="zJg-bJ-uzd">
<rect key="frame" x="0.0" y="810.5" width="478" height="0.0"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" verticalHuggingPriority="251" contentHorizontalAlignment="leading" contentVerticalAlignment="center" adjustsImageSizeForAccessibilityContentSizeCategory="YES" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="6HD-MP-H72">
<rect key="frame" x="0.0" y="0.0" width="119.5" height="0.0"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleCaption2"/>
<color key="tintColor" systemColor="secondaryLabelColor"/>
<inset key="titleEdgeInsets" minX="4" minY="0.0" maxX="0.0" maxY="0.0"/>
<state key="normal" title="1" image="bubble.right" catalog="system">
<color key="titleColor" systemColor="secondaryLabelColor"/>
<preferredSymbolConfiguration key="preferredSymbolConfiguration" scale="small"/>
</state>
</button>
<button opaque="NO" contentMode="scaleToFill" verticalHuggingPriority="251" contentHorizontalAlignment="leading" contentVerticalAlignment="center" adjustsImageSizeForAccessibilityContentSizeCategory="YES" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="ZKl-Hp-Y42">
<rect key="frame" x="119.5" y="0.0" width="119.5" height="0.0"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleCaption2"/>
<color key="tintColor" systemColor="secondaryLabelColor"/>
<inset key="titleEdgeInsets" minX="4" minY="0.0" maxX="0.0" maxY="0.0"/>
<state key="normal" title="1" image="arrow.2.squarepath" catalog="system">
<color key="titleColor" systemColor="secondaryLabelColor"/>
<preferredSymbolConfiguration key="preferredSymbolConfiguration" scale="small"/>
</state>
</button>
<button opaque="NO" contentMode="scaleToFill" verticalHuggingPriority="251" contentHorizontalAlignment="leading" contentVerticalAlignment="center" adjustsImageSizeForAccessibilityContentSizeCategory="YES" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="ewo-qO-lvX">
<rect key="frame" x="239" y="0.0" width="119.5" height="0.0"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleCaption2"/>
<color key="tintColor" systemColor="secondaryLabelColor"/>
<inset key="titleEdgeInsets" minX="4" minY="0.0" maxX="0.0" maxY="0.0"/>
<state key="normal" title="1" image="star" catalog="system">
<color key="titleColor" systemColor="secondaryLabelColor"/>
<preferredSymbolConfiguration key="preferredSymbolConfiguration" scale="small"/>
</state>
</button>
<button opaque="NO" contentMode="scaleToFill" verticalHuggingPriority="251" contentHorizontalAlignment="center" contentVerticalAlignment="center" adjustsImageSizeForAccessibilityContentSizeCategory="YES" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="zAD-2Z-vhu">
<rect key="frame" x="358.5" y="0.0" width="119.5" height="0.0"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleCaption2"/>
<color key="tintColor" systemColor="secondaryLabelColor"/>
<state key="normal" image="square.and.arrow.up" catalog="system">
<color key="titleColor" systemColor="secondaryLabelColor"/>
<preferredSymbolConfiguration key="preferredSymbolConfiguration" scale="small"/>
</state>
</button>
</subviews>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="dcp-zF-sHI">
<rect key="frame" x="0.0" y="818.5" width="478" height="45.5"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" spacing="4" translatesAutoresizingMaskIntoConstraints="NO" id="hTG-pM-6Kn">
<rect key="frame" x="0.0" y="0.0" width="478" height="0.0"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="6Fo-vD-qjJ">
<rect key="frame" x="0.0" y="0.0" width="33" height="0.0"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleFootnote"/>
<color key="textColor" systemColor="secondaryLabelColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="•" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="hYj-vy-Net">
<rect key="frame" x="37" y="0.0" width="6.5" height="0.0"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleFootnote"/>
<color key="textColor" systemColor="secondaryLabelColor"/>
<nil key="highlightedColor"/>
</label>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="leading" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Rdt-TR-8S5">
<rect key="frame" x="47.5" y="0.0" width="430.5" height="0.0"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleFootnote"/>
<state key="normal" title="Button"/>
<state key="disabled">
<color key="titleColor" systemColor="secondaryLabelColor"/>
</state>
</button>
</subviews>
</stackView>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="4eO-Vd-vy5">
<rect key="frame" x="0.0" y="8" width="478" height="1"/>
<color key="backgroundColor" systemColor="separatorColor"/>
<constraints>
<constraint firstAttribute="height" constant="1" id="H9G-jZ-cek"/>
</constraints>
</view>
<stackView opaque="NO" contentMode="scaleToFill" distribution="fillEqually" translatesAutoresizingMaskIntoConstraints="NO" id="M1E-qU-AAW">
<rect key="frame" x="0.0" y="17" width="478" height="0.0"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="leading" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="OaH-fg-fwa">
<rect key="frame" x="0.0" y="0.0" width="239" height="0.0"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
<color key="tintColor" systemColor="secondaryLabelColor"/>
<state key="normal" title="1">
<color key="titleColor" systemColor="secondaryLabelColor"/>
</state>
<state key="highlighted">
<color key="titleColor" systemColor="tertiaryLabelColor"/>
</state>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="leading" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="dCB-Ba-lgt">
<rect key="frame" x="239" y="0.0" width="239" height="0.0"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
<state key="normal" title="1">
<color key="titleColor" systemColor="secondaryLabelColor"/>
</state>
<state key="highlighted">
<color key="titleColor" systemColor="tertiaryLabelColor"/>
</state>
</button>
</subviews>
</stackView>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="zAt-7g-Zg4">
<rect key="frame" x="0.0" y="25" width="478" height="1"/>
<color key="backgroundColor" systemColor="separatorColor"/>
<constraints>
<constraint firstAttribute="height" constant="1" id="VEz-6j-37B"/>
</constraints>
</view>
<stackView opaque="NO" contentMode="scaleToFill" distribution="fillEqually" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="3d0-Jf-WT4">
<rect key="frame" x="0.0" y="34" width="478" height="11.5"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="v8s-eL-K9J">
<rect key="frame" x="0.0" y="0.0" width="89" height="11.5"/>
<color key="tintColor" systemColor="secondaryLabelColor"/>
<state key="normal" image="bubble.right" catalog="system">
<preferredSymbolConfiguration key="preferredSymbolConfiguration" scale="medium"/>
</state>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="c9q-Xj-ZhU">
<rect key="frame" x="97" y="0.0" width="89.5" height="11.5"/>
<color key="tintColor" systemColor="secondaryLabelColor"/>
<state key="normal" image="arrow.2.squarepath" catalog="system">
<preferredSymbolConfiguration key="preferredSymbolConfiguration" scale="medium"/>
</state>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="vKK-ho-Mc8">
<rect key="frame" x="194.5" y="0.0" width="89" height="11.5"/>
<color key="tintColor" systemColor="secondaryLabelColor"/>
<state key="normal" image="star" catalog="system">
<preferredSymbolConfiguration key="preferredSymbolConfiguration" scale="medium"/>
</state>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="jXx-KF-3pu">
<rect key="frame" x="291.5" y="0.0" width="89.5" height="11.5"/>
<color key="tintColor" systemColor="secondaryLabelColor"/>
<state key="normal" image="square.and.arrow.up" catalog="system">
<preferredSymbolConfiguration key="preferredSymbolConfiguration" scale="medium"/>
</state>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="fN1-ao-eiV">
<rect key="frame" x="389" y="0.0" width="89" height="11.5"/>
<color key="tintColor" systemColor="secondaryLabelColor"/>
<state key="normal" image="ellipsis" catalog="system">
<preferredSymbolConfiguration key="preferredSymbolConfiguration" scale="medium"/>
</state>
</button>
</subviews>
</stackView>
</subviews>
</stackView>
</subviews>
</stackView>
</subviews>
<constraints>
<constraint firstItem="aO2-AK-zwO" firstAttribute="centerY" secondItem="FMa-fP-vr2" secondAttribute="centerY" id="7BM-p3-f6D"/>
<constraint firstItem="5nP-eN-kWB" firstAttribute="top" secondItem="svp-hj-Xn6" secondAttribute="top" constant="4" id="RnL-bC-GDa"/>
</constraints>
</stackView>
</subviews>
<viewLayoutGuide key="safeArea" id="vUN-kp-3ea"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<constraints>
<constraint firstItem="EJV-En-WBg" firstAttribute="bottom" secondItem="H9l-Fc-4W4" secondAttribute="bottom" placeholder="YES" id="Lth-9x-m02"/>
<constraint firstItem="B6h-6a-Lty" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="RT6-M5-ebc"/>
<constraint firstItem="H9l-Fc-4W4" firstAttribute="top" secondItem="gwb-UL-Eqa" secondAttribute="top" placeholder="YES" id="XC0-mr-t3K"/>
<constraint firstAttribute="trailing" secondItem="B6h-6a-Lty" secondAttribute="trailing" id="bec-RP-T0Q"/>
<constraint firstItem="B6h-6a-Lty" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="lcG-od-cwq"/>
<constraint firstAttribute="bottom" secondItem="B6h-6a-Lty" secondAttribute="bottom" id="ub9-zr-Efi"/>
</constraints>
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
<point key="canvasLocation" x="125" y="60"/>
</view>
</objects>
<resources>
<image name="arrow.2.squarepath" catalog="system" width="128" height="89"/>
<image name="bubble.right" catalog="system" width="128" height="110"/>
<image name="ellipsis" catalog="system" width="128" height="37"/>
<image name="square.and.arrow.up" catalog="system" width="115" height="128"/>
<image name="star" catalog="system" width="128" height="116"/>
<systemColor name="linkColor">
<color red="0.0" green="0.47843137254901963" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
<systemColor name="quaternaryLabelColor">
<color red="0.23529411764705882" green="0.23529411764705882" blue="0.2627450980392157" alpha="0.17999999999999999" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
<systemColor name="secondaryLabelColor">
<color red="0.23529411764705882" green="0.23529411764705882" blue="0.2627450980392157" alpha="0.59999999999999998" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
<systemColor name="secondarySystemBackgroundColor">
<color red="0.94901960784313721" green="0.94901960784313721" blue="0.96862745098039216" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
<systemColor name="separatorColor">
<color red="0.23529411764705882" green="0.23529411764705882" blue="0.2627450980392157" alpha="0.28999999999999998" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
<systemColor name="systemBackgroundColor">
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor>
<systemColor name="tertiaryLabelColor">
<color red="0.23529411764705882" green="0.23529411764705882" blue="0.2627450980392157" alpha="0.29999999999999999" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
</resources>
</document>