forked from zelo72/mastodon-ios
147 lines
5.7 KiB
Swift
147 lines
5.7 KiB
Swift
//
|
|
// AvatarConfigurableView.swift
|
|
// Mastodon
|
|
//
|
|
// Created by Cirno MainasuK on 2021-2-4.
|
|
//
|
|
|
|
import UIKit
|
|
import AlamofireImage
|
|
import Kingfisher
|
|
|
|
protocol AvatarConfigurableView {
|
|
static var configurableAvatarImageViewSize: CGSize { get }
|
|
static var configurableAvatarImageViewBadgeAppearanceStyle: AvatarConfigurableViewConfiguration.BadgeAppearanceStyle { get }
|
|
var configurableAvatarImageView: UIImageView? { get }
|
|
var configurableAvatarButton: UIButton? { get }
|
|
var configurableVerifiedBadgeImageView: UIImageView? { get }
|
|
func configure(withConfigurationInput input: AvatarConfigurableViewConfiguration.Input)
|
|
func avatarConfigurableView(_ avatarConfigurableView: AvatarConfigurableView, didFinishConfiguration configuration: AvatarConfigurableViewConfiguration)
|
|
}
|
|
|
|
extension AvatarConfigurableView {
|
|
|
|
static var configurableAvatarImageViewBadgeAppearanceStyle: AvatarConfigurableViewConfiguration.BadgeAppearanceStyle { return .mini }
|
|
|
|
public func configure(withConfigurationInput input: AvatarConfigurableViewConfiguration.Input) {
|
|
// TODO: set badge
|
|
configurableVerifiedBadgeImageView?.isHidden = true
|
|
|
|
let cornerRadius = Self.configurableAvatarImageViewSize.width * 0.5
|
|
// let scale = (configurableAvatarImageView ?? configurableAvatarButton)?.window?.screen.scale ?? UIScreen.main.scale
|
|
|
|
let placeholderImage: UIImage = {
|
|
let placeholderImage = input.placeholderImage ?? UIImage.placeholder(size: Self.configurableAvatarImageViewSize, color: .systemFill)
|
|
return placeholderImage.af.imageRoundedIntoCircle()
|
|
}()
|
|
|
|
// cancel previous task
|
|
configurableAvatarImageView?.af.cancelImageRequest()
|
|
configurableAvatarImageView?.kf.cancelDownloadTask()
|
|
configurableAvatarButton?.af.cancelImageRequest(for: .normal)
|
|
configurableAvatarButton?.kf.cancelImageDownloadTask()
|
|
|
|
// reset layer attributes
|
|
configurableAvatarImageView?.layer.masksToBounds = false
|
|
configurableAvatarImageView?.layer.cornerRadius = 0
|
|
configurableAvatarImageView?.layer.cornerCurve = .circular
|
|
|
|
configurableAvatarButton?.layer.masksToBounds = false
|
|
configurableAvatarButton?.layer.cornerRadius = 0
|
|
configurableAvatarButton?.layer.cornerCurve = .circular
|
|
|
|
defer {
|
|
let configuration = AvatarConfigurableViewConfiguration(input: input)
|
|
avatarConfigurableView(self, didFinishConfiguration: configuration)
|
|
}
|
|
|
|
// set placeholder if no asset
|
|
guard let avatarImageURL = input.avatarImageURL else {
|
|
configurableAvatarImageView?.image = placeholderImage
|
|
configurableAvatarButton?.setImage(placeholderImage, for: .normal)
|
|
return
|
|
}
|
|
|
|
if let avatarImageView = configurableAvatarImageView {
|
|
// set avatar (GIF using Kingfisher)
|
|
switch avatarImageURL.pathExtension {
|
|
case "gif":
|
|
avatarImageView.kf.setImage(
|
|
with: avatarImageURL,
|
|
placeholder: placeholderImage,
|
|
options: [
|
|
.transition(.fade(0.2))
|
|
]
|
|
)
|
|
avatarImageView.layer.masksToBounds = true
|
|
avatarImageView.layer.cornerRadius = cornerRadius
|
|
avatarImageView.layer.cornerCurve = .circular
|
|
default:
|
|
let filter = ScaledToSizeCircleFilter(size: Self.configurableAvatarImageViewSize)
|
|
avatarImageView.af.setImage(
|
|
withURL: avatarImageURL,
|
|
placeholderImage: placeholderImage,
|
|
filter: filter,
|
|
imageTransition: .crossDissolve(0.3),
|
|
runImageTransitionIfCached: false,
|
|
completion: nil
|
|
)
|
|
}
|
|
}
|
|
|
|
if let avatarButton = configurableAvatarButton {
|
|
switch avatarImageURL.pathExtension {
|
|
case "gif":
|
|
avatarButton.kf.setImage(
|
|
with: avatarImageURL,
|
|
for: .normal,
|
|
placeholder: placeholderImage,
|
|
options: [
|
|
.transition(.fade(0.2))
|
|
]
|
|
)
|
|
avatarButton.layer.masksToBounds = true
|
|
avatarButton.layer.cornerRadius = cornerRadius
|
|
avatarButton.layer.cornerCurve = .circular
|
|
default:
|
|
let filter = ScaledToSizeCircleFilter(size: Self.configurableAvatarImageViewSize)
|
|
avatarButton.af.setImage(
|
|
for: .normal,
|
|
url: avatarImageURL,
|
|
placeholderImage: placeholderImage,
|
|
filter: filter,
|
|
completion: nil
|
|
)
|
|
}
|
|
}
|
|
}
|
|
|
|
func avatarConfigurableView(_ avatarConfigurableView: AvatarConfigurableView, didFinishConfiguration configuration: AvatarConfigurableViewConfiguration) { }
|
|
|
|
}
|
|
|
|
struct AvatarConfigurableViewConfiguration {
|
|
|
|
enum BadgeAppearanceStyle {
|
|
case mini
|
|
case normal
|
|
}
|
|
|
|
struct Input {
|
|
let avatarImageURL: URL?
|
|
let placeholderImage: UIImage?
|
|
let blocked: Bool
|
|
let verified: Bool
|
|
|
|
init(avatarImageURL: URL?, placeholderImage: UIImage? = nil, blocked: Bool = false, verified: Bool = false) {
|
|
self.avatarImageURL = avatarImageURL
|
|
self.placeholderImage = placeholderImage
|
|
self.blocked = blocked
|
|
self.verified = verified
|
|
}
|
|
}
|
|
|
|
let input: Input
|
|
|
|
}
|