Tusker/Tusker/Views/Profile Header/ProfileHeaderTableViewCell....

172 lines
6.6 KiB
Swift
Raw Normal View History

2018-08-28 01:27:34 +00:00
//
// ProfileHeaderTableViewCell.swift
// Tusker
//
// Created by Shadowfacts on 8/27/18.
// Copyright © 2018 Shadowfacts. All rights reserved.
//
import UIKit
2018-09-11 14:52:21 +00:00
import Pachyderm
2018-08-28 01:27:34 +00:00
protocol ProfileHeaderTableViewCellDelegate: TuskerNavigationDelegate {
2018-08-28 21:53:59 +00:00
func showMoreOptions()
2018-08-28 01:27:34 +00:00
}
class ProfileHeaderTableViewCell: UITableViewCell {
2018-08-28 01:27:34 +00:00
2019-04-01 23:34:50 +00:00
var delegate: ProfileHeaderTableViewCellDelegate?
2018-09-24 12:49:39 +00:00
@IBOutlet weak var headerImageView: UIImageView!
@IBOutlet weak var avatarContainerView: UIView!
@IBOutlet weak var avatarImageView: UIImageView!
2018-08-28 01:27:34 +00:00
@IBOutlet weak var displayNameLabel: UILabel!
@IBOutlet weak var usernameLabel: UILabel!
2018-09-24 12:49:39 +00:00
@IBOutlet weak var followsYouLabel: UILabel!
@IBOutlet weak var noteLabel: StatusContentLabel!
2019-04-01 23:34:50 +00:00
@IBOutlet weak var fieldsStackView: UIStackView!
@IBOutlet weak var fieldNamesStackView: UIStackView!
@IBOutlet weak var fieldValuesStack: UIStackView!
2018-08-28 01:27:34 +00:00
2018-09-18 16:59:07 +00:00
var accountID: String!
2018-08-28 01:27:34 +00:00
var avatarURL: URL?
2018-10-02 17:45:39 +00:00
var headerURL: URL?
2018-08-28 01:27:34 +00:00
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
2018-09-18 16:59:07 +00:00
NotificationCenter.default.addObserver(self, selector: #selector(updateUIForPreferences), name: .preferencesChanged, object: nil)
2018-08-28 23:49:31 +00:00
}
2018-09-18 16:59:07 +00:00
func updateUI(for accountID: String) {
2019-04-01 23:34:50 +00:00
guard accountID != self.accountID else { return }
2018-09-18 16:59:07 +00:00
self.accountID = accountID
2019-04-01 23:34:50 +00:00
2018-09-18 16:59:07 +00:00
guard let account = MastodonCache.account(for: accountID) else { fatalError("Missing cached account \(accountID)") }
2018-08-28 01:27:34 +00:00
2018-08-28 23:49:31 +00:00
updateUIForPreferences()
2018-08-28 01:27:34 +00:00
usernameLabel.text = "@\(account.acct)"
avatarImageView.image = nil
2018-09-11 14:52:21 +00:00
avatarURL = account.avatar
2018-11-09 20:48:08 +00:00
ImageCache.avatars.get(account.avatar) { (data) in
guard let data = data else { return }
2018-09-11 14:52:21 +00:00
DispatchQueue.main.async {
2018-11-09 20:48:08 +00:00
self.avatarImageView.image = UIImage(data: data)
2018-09-11 14:52:21 +00:00
self.avatarURL = nil
2018-08-28 01:27:34 +00:00
}
}
2019-09-24 19:48:57 +00:00
self.headerImageView.image = nil
if let header = account.header {
ImageCache.headers.get(header) { (data) in
guard let data = data else { return }
DispatchQueue.main.async {
self.headerImageView.image = UIImage(data: data)
self.headerURL = nil
}
2018-08-28 01:27:34 +00:00
}
}
2019-04-01 23:34:50 +00:00
noteLabel.navigationDelegate = delegate
noteLabel.setTextFromHtml(account.note)
2019-04-01 23:34:50 +00:00
noteLabel.setEmojis(account.emojis)
2018-09-24 12:49:39 +00:00
if accountID != MastodonController.account.id {
// don't show relationship label for the user's own account
if let relationship = MastodonCache.relationship(for: accountID) {
followsYouLabel.isHidden = !relationship.followedBy
} else {
MastodonCache.relationship(for: accountID) { relationship in
DispatchQueue.main.async {
self.followsYouLabel.isHidden = !(relationship?.followedBy ?? false)
}
2018-09-24 12:49:39 +00:00
}
}
}
2019-04-01 23:34:50 +00:00
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
fieldNamesStackView.addArrangedSubview(nameLabel)
let valueLabel = ContentLabel()
valueLabel.setTextFromHtml(field.value)
valueLabel.setEmojis(account.emojis)
valueLabel.font = .systemFont(ofSize: 17)
valueLabel.textAlignment = .left
valueLabel.awakeFromNib() // TODO: this shouldn't be necessary
valueLabel.navigationDelegate = delegate
fieldValuesStack.addArrangedSubview(valueLabel)
}
} else {
fieldsStackView.isHidden = true
}
2018-08-28 01:27:34 +00:00
}
@objc func updateUIForPreferences() {
guard let account = MastodonCache.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
}
2018-08-28 01:27:34 +00:00
override func prepareForReuse() {
if let url = avatarURL {
ImageCache.avatars.cancel(url)
2018-08-28 01:27:34 +00:00
}
2018-10-02 17:45:39 +00:00
if let url = headerURL {
ImageCache.headers.cancel(url)
2018-08-28 01:27:34 +00:00
}
}
2018-08-28 21:53:59 +00:00
@IBAction func morePressed(_ sender: Any) {
delegate?.showMoreOptions()
}
@objc func avatarPressed() {
delegate?.showLargeImage(avatarImageView.image!, description: nil, animatingFrom: avatarImageView)
}
@objc func headerPressed() {
delegate?.showLargeImage(headerImageView.image!, description: nil, animatingFrom: headerImageView)
}
2018-08-28 01:27:34 +00:00
}
2018-10-31 02:24:49 +00:00
extension ProfileHeaderTableViewCell: MenuPreviewProvider {
func getPreviewProviders(for location: CGPoint, sourceViewController: UIViewController) -> PreviewProviders? {
2018-10-31 02:24:49 +00:00
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)
} else if let hashtag = self.noteLabel.getHashtag(for: link.url, text: text) {
return self.actionsForHashtag(hashtag)
} else {
return self.actionsForURL(link.url)
}
}
)
} else {
return nil
2018-10-31 02:24:49 +00:00
}
}
}