Tusker/Tusker/Views/Profile Header/ProfileHeaderMovedOverlayVi...

159 lines
6.7 KiB
Swift

//
// ProfileHeaderMovedOverlayView.swift
// Tusker
//
// Created by Shadowfacts on 2/23/23.
// Copyright © 2023 Shadowfacts. All rights reserved.
//
import UIKit
class ProfileHeaderMovedOverlayView: UIView {
private var movedToID: String!
weak var delegate: TuskerNavigationDelegate?
var collapse: (() -> Void)?
private var avatarImageView: CachedImageView!
private var displayNameLabel: EmojiLabel!
private var usernameLabel: UILabel!
private(set) var collapseButton: UIButton!
init() {
super.init(frame: .zero)
let blur = UIBlurEffect(style: .systemUltraThinMaterial)
let blurView = UIVisualEffectView(effect: blur)
blurView.translatesAutoresizingMaskIntoConstraints = false
addSubview(blurView)
let vibrancy = UIVibrancyEffect(blurEffect: blur, style: .label)
let vibrancyView = UIVisualEffectView(effect: vibrancy)
vibrancyView.translatesAutoresizingMaskIntoConstraints = false
blurView.contentView.addSubview(vibrancyView)
let label = UILabel()
label.text = "This account has moved to"
label.font = .preferredFont(forTextStyle: .title3).withTraits(.traitBold)
label.adjustsFontForContentSizeCategory = true
label.textColor = .label
avatarImageView = CachedImageView(cache: .avatars)
avatarImageView.layer.masksToBounds = true
avatarImageView.layer.cornerRadius = Preferences.shared.avatarStyle.cornerRadiusFraction * 50
avatarImageView.addInteraction(UIPointerInteraction(delegate: self))
avatarImageView.isUserInteractionEnabled = true
displayNameLabel = EmojiLabel()
displayNameLabel.adjustsFontForContentSizeCategory = true
displayNameLabel.font = UIFont(descriptor: .preferredFontDescriptor(withTextStyle: .body).addingAttributes([
.traits: [
UIFontDescriptor.TraitKey.weight: UIFont.Weight.semibold.rawValue,
]
]), size: 0)
usernameLabel = UILabel()
usernameLabel.adjustsFontForContentSizeCategory = true
usernameLabel.font = .preferredFont(forTextStyle: .body)
usernameLabel.textColor = .secondaryLabel
let nameVStack = UIStackView(arrangedSubviews: [
displayNameLabel,
usernameLabel,
])
nameVStack.axis = .vertical
nameVStack.alignment = .leading
nameVStack.spacing = 4
let accountHStack = UIStackView(arrangedSubviews: [
avatarImageView,
nameVStack,
])
accountHStack.axis = .horizontal
accountHStack.alignment = .top
accountHStack.spacing = 4
accountHStack.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(accountTapped)))
let stack = UIStackView(arrangedSubviews: [
label,
accountHStack,
])
stack.axis = .vertical
stack.alignment = .center
stack.spacing = 8
stack.translatesAutoresizingMaskIntoConstraints = false
vibrancyView.contentView.addSubview(stack)
var config = UIButton.Configuration.plain()
config.image = UIImage(systemName: "chevron.up")
collapseButton = UIButton(configuration: config, primaryAction: UIAction(handler: { [unowned self] _ in
self.collapse?()
}))
collapseButton.accessibilityLabel = "Shrink banner"
collapseButton.isPointerInteractionEnabled = true
collapseButton.translatesAutoresizingMaskIntoConstraints = false
addSubview(collapseButton)
NSLayoutConstraint.activate([
blurView.leadingAnchor.constraint(equalTo: leadingAnchor),
blurView.trailingAnchor.constraint(equalTo: trailingAnchor),
blurView.topAnchor.constraint(equalTo: topAnchor),
blurView.bottomAnchor.constraint(equalTo: bottomAnchor),
vibrancyView.leadingAnchor.constraint(equalTo: blurView.contentView.leadingAnchor),
vibrancyView.trailingAnchor.constraint(equalTo: blurView.contentView.trailingAnchor),
vibrancyView.topAnchor.constraint(equalTo: blurView.contentView.topAnchor),
vibrancyView.bottomAnchor.constraint(equalTo: blurView.contentView.bottomAnchor),
stack.centerXAnchor.constraint(equalTo: vibrancyView.contentView.readableContentGuide.centerXAnchor),
stack.centerYAnchor.constraint(equalTo: vibrancyView.contentView.centerYAnchor),
stack.leadingAnchor.constraint(greaterThanOrEqualTo: vibrancyView.contentView.readableContentGuide.leadingAnchor),
stack.trailingAnchor.constraint(lessThanOrEqualTo: vibrancyView.contentView.readableContentGuide.trailingAnchor),
stack.topAnchor.constraint(greaterThanOrEqualTo: vibrancyView.contentView.topAnchor),
stack.bottomAnchor.constraint(lessThanOrEqualTo: vibrancyView.contentView.bottomAnchor),
avatarImageView.widthAnchor.constraint(equalToConstant: 50),
avatarImageView.heightAnchor.constraint(equalToConstant: 50),
bottomAnchor.constraint(equalToSystemSpacingBelow: collapseButton.bottomAnchor, multiplier: 1),
collapseButton.centerXAnchor.constraint(equalTo: centerXAnchor),
])
NotificationCenter.default.addObserver(self, selector: #selector(preferencesChanged), name: .preferencesChanged, object: nil)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
@objc private func preferencesChanged() {
avatarImageView.layer.cornerRadius = Preferences.shared.avatarStyle.cornerRadiusFraction * 50
}
func updateUI(movedTo: AccountMO) {
movedToID = movedTo.id
avatarImageView.update(for: movedTo.avatar)
displayNameLabel.text = movedTo.displayOrUserName
displayNameLabel.setEmojis(movedTo.emojis, identifier: movedTo.id)
usernameLabel.text = "@\(movedTo.acct)"
}
@objc private func accountTapped() {
delegate?.selected(account: movedToID)
}
}
extension ProfileHeaderMovedOverlayView: UIPointerInteractionDelegate {
func pointerInteraction(_ interaction: UIPointerInteraction, regionFor request: UIPointerRegionRequest, defaultRegion: UIPointerRegion) -> UIPointerRegion? {
return defaultRegion
}
func pointerInteraction(_ interaction: UIPointerInteraction, styleFor region: UIPointerRegion) -> UIPointerStyle? {
let preview = UITargetedPreview(view: interaction.view!)
return UIPointerStyle(effect: .lift(preview))
}
}