diff --git a/ViewModels/Sources/ViewModels/AccountViewModel.swift b/ViewModels/Sources/ViewModels/AccountViewModel.swift index de0edac..1d35f9f 100644 --- a/ViewModels/Sources/ViewModels/AccountViewModel.swift +++ b/ViewModels/Sources/ViewModels/AccountViewModel.swift @@ -18,11 +18,13 @@ public class AccountViewModel: ObservableObject { } public extension AccountViewModel { - var avatarURL: URL { - accountService.account.avatar - } + var avatarURL: URL { accountService.account.avatar } - var note: NSAttributedString { - accountService.account.note.attributed - } + var displayName: String { accountService.account.displayName } + + var accountName: String { "@".appending(accountService.account.acct) } + + var note: NSAttributedString { accountService.account.note.attributed } + + var emoji: [Emoji] { accountService.account.emojis } } diff --git a/Views/AccountView.swift b/Views/AccountView.swift index 05d6d4c..a5fea2d 100644 --- a/Views/AccountView.swift +++ b/Views/AccountView.swift @@ -5,6 +5,8 @@ import UIKit class AccountView: UIView { let avatarImageView = AnimatedImageView() + let displayNameLabel = UILabel() + let accountLabel = UILabel() let noteTextView = TouchFallthroughTextView() private var accountConfiguration: AccountContentConfiguration @@ -38,20 +40,44 @@ extension AccountView: UIContentView { } private extension AccountView { - func initialSetup() { - let baseStackView = UIStackView() + static let spacing: CGFloat = 8 + static let stackViewSpacing: CGFloat = 4 + static let avatarDimension: CGFloat = 50 - addSubview(baseStackView) - baseStackView.translatesAutoresizingMaskIntoConstraints = false - baseStackView.addArrangedSubview(avatarImageView) - baseStackView.addArrangedSubview(noteTextView) + func initialSetup() { + let stackView = UIStackView() + + addSubview(avatarImageView) + addSubview(stackView) + avatarImageView.translatesAutoresizingMaskIntoConstraints = false + avatarImageView.layer.cornerRadius = Self.avatarDimension / 2 + avatarImageView.clipsToBounds = true + stackView.translatesAutoresizingMaskIntoConstraints = false + stackView.axis = .vertical + stackView.spacing = Self.stackViewSpacing + stackView.addArrangedSubview(displayNameLabel) + stackView.addArrangedSubview(accountLabel) + stackView.addArrangedSubview(noteTextView) + displayNameLabel.numberOfLines = 0 + displayNameLabel.font = .preferredFont(forTextStyle: .headline) + displayNameLabel.adjustsFontForContentSizeCategory = true + accountLabel.numberOfLines = 0 + accountLabel.font = .preferredFont(forTextStyle: .subheadline) + accountLabel.adjustsFontForContentSizeCategory = true + accountLabel.textColor = .secondaryLabel noteTextView.isScrollEnabled = false + noteTextView.backgroundColor = .clear NSLayoutConstraint.activate([ - baseStackView.topAnchor.constraint(equalTo: readableContentGuide.topAnchor), - baseStackView.leadingAnchor.constraint(equalTo: readableContentGuide.leadingAnchor), - baseStackView.trailingAnchor.constraint(equalTo: readableContentGuide.trailingAnchor), - baseStackView.bottomAnchor.constraint(equalTo: readableContentGuide.bottomAnchor) + avatarImageView.widthAnchor.constraint(equalToConstant: Self.avatarDimension), + avatarImageView.heightAnchor.constraint(equalToConstant: Self.avatarDimension), + avatarImageView.topAnchor.constraint(equalTo: readableContentGuide.topAnchor), + avatarImageView.leadingAnchor.constraint(equalTo: readableContentGuide.leadingAnchor), + avatarImageView.bottomAnchor.constraint(lessThanOrEqualTo: readableContentGuide.bottomAnchor), + stackView.leadingAnchor.constraint(equalTo: avatarImageView.trailingAnchor, constant: Self.spacing), + stackView.topAnchor.constraint(equalTo: readableContentGuide.topAnchor), + stackView.trailingAnchor.constraint(equalTo: readableContentGuide.trailingAnchor), + stackView.bottomAnchor.constraint(equalTo: readableContentGuide.bottomAnchor) ]) applyAccountConfiguration() @@ -59,6 +85,31 @@ private extension AccountView { func applyAccountConfiguration() { avatarImageView.kf.setImage(with: accountConfiguration.viewModel.avatarURL) - noteTextView.attributedText = accountConfiguration.viewModel.note + + if accountConfiguration.viewModel.displayName == "" { + displayNameLabel.isHidden = true + } else { + let mutableDisplayName = NSMutableAttributedString(string: accountConfiguration.viewModel.displayName) + + mutableDisplayName.insert(emoji: accountConfiguration.viewModel.emoji, view: displayNameLabel) + mutableDisplayName.resizeAttachments(toLineHeight: displayNameLabel.font.lineHeight) + displayNameLabel.attributedText = mutableDisplayName + } + + accountLabel.text = accountConfiguration.viewModel.accountName + + let noteFont = UIFont.preferredFont(forTextStyle: .callout) + let mutableNote = NSMutableAttributedString(attributedString: accountConfiguration.viewModel.note) + let noteRange = NSRange(location: 0, length: mutableNote.length) + + mutableNote.removeAttribute(.font, range: noteRange) + mutableNote.addAttributes( + [.font: noteFont as Any, + .foregroundColor: UIColor.label], + range: noteRange) + mutableNote.insert(emoji: accountConfiguration.viewModel.emoji, view: noteTextView) + mutableNote.resizeAttachments(toLineHeight: noteFont.lineHeight) + + noteTextView.attributedText = mutableNote } }