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
|
|
|
|
2018-09-30 23:29:52 +00:00
|
|
|
protocol ProfileHeaderTableViewCellDelegate: TuskerNavigationDelegate {
|
2018-08-28 21:53:59 +00:00
|
|
|
func showMoreOptions()
|
2018-08-28 01:27:34 +00:00
|
|
|
}
|
|
|
|
|
2018-08-28 23:49:31 +00:00
|
|
|
class ProfileHeaderTableViewCell: UITableViewCell, PreferencesAdaptive {
|
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!
|
2018-10-01 19:14:09 +00:00
|
|
|
@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
|
2018-09-02 22:22:29 +00:00
|
|
|
avatarImageView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(avatarPressed)))
|
|
|
|
avatarImageView.isUserInteractionEnabled = true
|
|
|
|
headerImageView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(headerPressed)))
|
|
|
|
headerImageView.isUserInteractionEnabled = true
|
2018-08-28 01:27:34 +00:00
|
|
|
}
|
|
|
|
|
2018-08-28 23:49:31 +00:00
|
|
|
func updateUIForPreferences() {
|
2018-09-18 16:59:07 +00:00
|
|
|
guard let account = MastodonCache.account(for: accountID) else { fatalError("Missing cached account \(accountID!)") }
|
|
|
|
|
2018-08-28 23:49:31 +00:00
|
|
|
avatarContainerView.layer.cornerRadius = Preferences.shared.avatarStyle.cornerRadius(for: avatarContainerView)
|
|
|
|
avatarImageView.layer.cornerRadius = Preferences.shared.avatarStyle.cornerRadius(for: avatarImageView)
|
2018-08-29 01:18:58 +00:00
|
|
|
displayNameLabel.text = account.realDisplayName
|
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
|
|
|
}
|
|
|
|
}
|
2018-11-09 20:48:08 +00:00
|
|
|
ImageCache.headers.get(account.header) { (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.headerImageView.image = UIImage(data: data)
|
2018-10-02 17:45:39 +00:00
|
|
|
self.headerURL = nil
|
2018-08-28 01:27:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-04-01 23:34:50 +00:00
|
|
|
noteLabel.navigationDelegate = delegate
|
2018-10-01 19:14:09 +00:00
|
|
|
noteLabel.setTextFromHtml(account.note)
|
2019-04-01 23:34:50 +00:00
|
|
|
noteLabel.setEmojis(account.emojis)
|
2018-09-24 12:49:39 +00:00
|
|
|
|
2018-10-03 00:04:41 +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
|
|
|
}
|
|
|
|
|
|
|
|
override func prepareForReuse() {
|
|
|
|
if let url = avatarURL {
|
2018-10-02 17:42:37 +00:00
|
|
|
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()
|
|
|
|
}
|
|
|
|
|
2018-09-02 22:22:29 +00:00
|
|
|
@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
|
|
|
|
2019-06-04 21:04:37 +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),
|
2019-06-04 21:04:37 +00:00
|
|
|
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
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|