// // ProfileHeaderTableViewCell.swift // Tusker // // Created by Shadowfacts on 8/27/18. // Copyright © 2018 Shadowfacts. All rights reserved. // import UIKit import Pachyderm protocol ProfileHeaderTableViewCellDelegate: TuskerNavigationDelegate { func showMoreOptions(cell: ProfileHeaderTableViewCell) } class ProfileHeaderTableViewCell: UITableViewCell { weak var delegate: ProfileHeaderTableViewCellDelegate? var mastodonController: MastodonController! { delegate?.apiController } @IBOutlet weak var headerImageView: UIImageView! @IBOutlet weak var avatarContainerView: UIView! @IBOutlet weak var avatarImageView: UIImageView! @IBOutlet weak var displayNameLabel: UILabel! @IBOutlet weak var usernameLabel: UILabel! @IBOutlet weak var followsYouLabel: UILabel! @IBOutlet weak var noteTextView: StatusContentTextView! @IBOutlet weak var fieldsStackView: UIStackView! @IBOutlet weak var fieldNamesStackView: UIStackView! @IBOutlet weak var fieldValuesStack: UIStackView! @IBOutlet weak var moreButtonVisualEffectView: UIVisualEffectView! var accountID: String! var avatarRequest: ImageCache.Request? var headerRequest: ImageCache.Request? override func awakeFromNib() { avatarContainerView.layer.masksToBounds = true avatarImageView.layer.masksToBounds = true avatarImageView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(avatarPressed))) avatarImageView.isUserInteractionEnabled = true headerImageView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(headerPressed))) headerImageView.isUserInteractionEnabled = true moreButtonVisualEffectView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(morePressed))) let maskLayer = CAShapeLayer() maskLayer.frame = moreButtonVisualEffectView.bounds maskLayer.path = CGPath(ellipseIn: moreButtonVisualEffectView.bounds, transform: nil) moreButtonVisualEffectView.layer.mask = maskLayer NotificationCenter.default.addObserver(self, selector: #selector(updateUIForPreferences), name: .preferencesChanged, object: nil) } func updateUI(for accountID: String) { guard accountID != self.accountID else { return } self.accountID = accountID guard let account = mastodonController.cache.account(for: accountID) else { fatalError("Missing cached account \(accountID)") } updateUIForPreferences() usernameLabel.text = "@\(account.acct)" avatarImageView.image = nil avatarRequest = ImageCache.avatars.get(account.avatar) { [weak self] (data) in guard let self = self, let data = data, self.accountID == accountID else { return } self.avatarRequest = nil DispatchQueue.main.async { self.avatarImageView.image = UIImage(data: data) } } headerImageView.image = nil headerRequest = ImageCache.headers.get(account.header) { [weak self] (data) in guard let self = self, let data = data, self.accountID == accountID else { return } self.headerRequest = nil DispatchQueue.main.async { self.headerImageView.image = UIImage(data: data) } } noteTextView.navigationDelegate = delegate noteTextView.setTextFromHtml(account.note) noteTextView.setEmojis(account.emojis) if accountID != mastodonController.account.id { // don't show relationship label for the user's own account if let relationship = mastodonController.cache.relationship(for: accountID) { followsYouLabel.isHidden = !relationship.followedBy } else { mastodonController.cache.relationship(for: accountID) { relationship in DispatchQueue.main.async { self.followsYouLabel.isHidden = !(relationship?.followedBy ?? false) } } } } if let fields = account.fields, !fields.isEmpty { fieldsStackView.isHidden = false for field in fields { let nameLabel = UILabel() nameLabel.text = field.name nameLabel.font = .boldSystemFont(ofSize: 17) nameLabel.textAlignment = .right nameLabel.numberOfLines = 0 fieldNamesStackView.addArrangedSubview(nameLabel) let valueTextView = ContentTextView() valueTextView.isSelectable = false valueTextView.font = .systemFont(ofSize: 17) valueTextView.setTextFromHtml(field.value) valueTextView.setEmojis(account.emojis) valueTextView.textAlignment = .left valueTextView.awakeFromNib() valueTextView.navigationDelegate = delegate fieldValuesStack.addArrangedSubview(valueTextView) } } else { fieldsStackView.isHidden = true } } @objc func updateUIForPreferences() { guard let account = mastodonController.cache.account(for: accountID) else { fatalError("Missing cached account \(accountID!)") } avatarContainerView.layer.cornerRadius = Preferences.shared.avatarStyle.cornerRadius(for: avatarContainerView) avatarImageView.layer.cornerRadius = Preferences.shared.avatarStyle.cornerRadius(for: avatarImageView) displayNameLabel.text = account.realDisplayName } override func prepareForReuse() { avatarRequest?.cancel() headerRequest?.cancel() } @objc func morePressed() { delegate?.showMoreOptions(cell: self) } @objc func avatarPressed() { delegate?.showLargeImage(avatarImageView.image!, description: nil, animatingFrom: avatarImageView) } @objc func headerPressed() { delegate?.showLargeImage(headerImageView.image!, description: nil, animatingFrom: headerImageView) } } //extension ProfileHeaderTableViewCell: MenuPreviewProvider { // var navigationDelegate: TuskerNavigationDelegate? { return delegate } // func getPreviewProviders(for location: CGPoint, sourceViewController: UIViewController) -> PreviewProviders? { // let noteLabelPoint = noteLabel.convert(location, from: self) // if noteLabel.bounds.contains(noteLabelPoint), // let link = noteLabel.getLink(atPoint: noteLabelPoint) { // return ( // content: { self.noteLabel.getViewController(forLink: link.url, inRange: link.range) }, // actions: { // let text = (self.noteLabel.text! as NSString).substring(with: link.range) // if let mention = self.noteLabel.getMention(for: link.url, text: text) { // return self.actionsForProfile(accountID: mention.id, sourceView: self) // } else if let hashtag = self.noteLabel.getHashtag(for: link.url, text: text) { // return self.actionsForHashtag(hashtag, sourceView: self) // } else { // return self.actionsForURL(link.url, sourceView: self) // } // } // ) // } else { // return nil // } // } //}