[ABANDONED] Mastodon iOS client.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

213 lines
8.6 KiB

//
// StatusStackView.swift
// elpha-ios
//
// Created by Dwayne Harris on 10/9/18.
// Copyright © 2018 Elpha. All rights reserved.
//
import AlamofireImage
import UIKit
protocol StatusViewDelegate {
func accountTapped(account: AccountMO)
func statusTapped(status: StatusMO)
}
class StatusView: UIView {
@IBOutlet var contentView: UIView!
@IBOutlet var boostView: UIView!
@IBOutlet var boostAvatarImageView: UIImageView!
@IBOutlet var boostDisplayNameLabel: UILabel!
@IBOutlet var boostUsernameLabel: UILabel!
@IBOutlet var replyView: UIView!
@IBOutlet var replyAvatarImageView: UIImageView!
@IBOutlet var replyDisplayNameLabel: UILabel!
@IBOutlet var replyUsernameLabel: UILabel!
@IBOutlet var avatarImageView: UIImageView!
@IBOutlet var displayNameLabel: UILabel!
@IBOutlet var usernameLabel: UILabel!
@IBOutlet var contentLabel: UILabel!
@IBOutlet var timestampLabel: UILabel!
@IBOutlet var repliesImageView: UIImageView!
@IBOutlet var repliesLabel: UILabel!
@IBOutlet var boostsImageView: UIImageView!
@IBOutlet var boostsLabel: UILabel!
@IBOutlet var favoritesImageView: UIImageView!
@IBOutlet var favoritesLabel: UILabel!
@IBOutlet var topDividerView: UIView!
@IBOutlet var bottomDividerView: UIView!
@IBOutlet var attachmentsView: UIView!
@IBOutlet var attachmentsHeightConstraint: NSLayoutConstraint!
var status: StatusMO? = nil
var delegate: StatusViewDelegate? = nil
@IBAction func boostViewTapped(_ sender: Any) {
if let delegate = delegate, let status = status {
delegate.accountTapped(account: status.account!)
}
}
@IBAction func replyViewTapped(_ sender: Any) {
if let delegate = delegate,
let status = status,
let replyAccountID = status.inReplyToAccountID,
let replyAccount = MastodonDataManager.account(id: replyAccountID) {
delegate.accountTapped(account: replyAccount)
}
}
@IBAction func accountViewTapped(_ sender: Any) {
if let delegate = delegate, let status = status {
if let reblog = status.reblog {
delegate.accountTapped(account: reblog.account!)
} else {
delegate.accountTapped(account: status.account!)
}
}
}
@IBAction func mainViewTapped(_ sender: Any) {
if let delegate = delegate, let status = status {
delegate.statusTapped(status: status)
}
}
override init(frame: CGRect) {
super.init(frame: frame)
setup()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setup()
}
private func setup() {
Bundle.main.loadNibNamed("StatusView", owner: self, options: nil)
addSubview(contentView)
contentView.frame = self.bounds
// contentView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
}
public func update(withStatus status: StatusMO) {
self.status = status
topDividerView.isHidden = false
boostView.isHidden = true
replyView.isHidden = true
bottomDividerView.isHidden = false
attachmentsView.backgroundColor = UIColor.white
attachmentsView.isHidden = true
let avatarFilter = AspectScaledToFillSizeWithRoundedCornersFilter(
size: CGSize(width: 40.0, height: 40.0),
radius: 20.0,
divideRadiusByImageScale: true
)
func updateStatusContent(_ status: StatusMO) {
if let account = status.account {
avatarImageView.af_setImage(withURL: account.avatarURL!, filter: avatarFilter)
displayNameLabel.text = account.displayName
usernameLabel.text = account.acct
}
if let attachments = status.attachments, attachments.count > 0 {
attachmentsView.isHidden = false
AttachmentsManager.setupAttachmentsView(attachmentsView, withAttachments: attachments)
}
if let content = status.content {
do {
let styledContent = "<style>html * { font-size: 15px; color: #170c49; font-family: -apple-system } p { margin: 0; padding: 0 }</style> \(content)"
let attributedText = try NSAttributedString(
data: styledContent.data(using: String.Encoding.unicode, allowLossyConversion: true)!,
options: [.documentType: NSAttributedString.DocumentType.html],
documentAttributes: nil
)
contentLabel.attributedText = attributedText
if status.hidden {
let spoilerText = UILabel(frame: contentLabel.frame)
spoilerText.textColor = UIColor(named: "Text")
spoilerText.textAlignment = .center
spoilerText.text = status.spoilerText
spoilerText.translatesAutoresizingMaskIntoConstraints = false
let blurEffectView = UIVisualEffectView(effect: UIBlurEffect(style: UIBlurEffect.Style.prominent))
blurEffectView.translatesAutoresizingMaskIntoConstraints = false
blurEffectView.contentView.addSubview(spoilerText)
NSLayoutConstraint.activate([
spoilerText.leadingAnchor.constraint(equalTo: blurEffectView.leadingAnchor),
spoilerText.trailingAnchor.constraint(equalTo: blurEffectView.trailingAnchor),
spoilerText.centerYAnchor.constraint(equalTo: blurEffectView.centerYAnchor),
])
self.contentView.addSubview(blurEffectView)
NSLayoutConstraint.activate([
blurEffectView.leadingAnchor.constraint(equalTo: contentLabel.trailingAnchor),
blurEffectView.trailingAnchor.constraint(equalTo: contentLabel.trailingAnchor),
blurEffectView.topAnchor.constraint(equalTo: contentLabel.topAnchor),
blurEffectView.bottomAnchor.constraint(equalTo: contentLabel.bottomAnchor),
])
}
} catch {
print("\(error)")
}
}
timestampLabel.text = status.createdAt!.timeAgo()
repliesLabel.text = "0"
boostsLabel.text = NumberFormatter.localizedString(from: NSNumber(value: status.reblogsCount), number: .decimal)
favoritesLabel.text = NumberFormatter.localizedString(from: NSNumber(value: status.favoritesCount), number: .decimal)
if status.reblogged {
boostsImageView.image = UIImage(named: "Boost Bold")
} else {
boostsImageView.image = UIImage(named: "Boost Regular")
}
if status.favorited {
favoritesImageView.image = UIImage(named: "Star Filled")
} else {
favoritesImageView.image = UIImage(named: "Star Regular")
}
}
if let reblog = status.reblog {
boostView.isHidden = false
if let account = status.account {
boostAvatarImageView.af_setImage(withURL: account.avatarURL!, filter: avatarFilter)
boostDisplayNameLabel.text = account.displayName
boostUsernameLabel.text = account.acct
}
updateStatusContent(reblog)
} else {
if let account = status.account {
avatarImageView.af_setImage(withURL: account.avatarURL!, filter: avatarFilter)
displayNameLabel.text = account.displayName
usernameLabel.text = account.acct
}
updateStatusContent(status)
}
if let replyAccountID = status.inReplyToAccountID {
if let replyAccount = MastodonDataManager.account(id: replyAccountID) {
replyView.isHidden = false
replyAvatarImageView.af_setImage(withURL: replyAccount.avatarURL!, filter: avatarFilter)
replyDisplayNameLabel.text = replyAccount.displayName
replyUsernameLabel.text = replyAccount.acct
}
}
}
}