Files
2023-03-02 18:28:42 +03:00

221 lines
8.0 KiB
Swift

//
// CommonViewCard.swift
// Wallet
//
// Created by Igor on 21.02.2021.
// Copyright © 2021 AM. All rights reserved.
//
import UIKit
import SkeletonView
extension Common.Model.Menu {
static func cardsTokensEmpty() -> Common.Model.Menu {
.menu(image: Asset.commonToken.image.tinted(with: Asset.deepWater.color),
title: L10n.Common.Card.Token.title)
}
}
extension CommonMenuAction {
static func cards(
collection: [Common.Model.Menu]? = nil,
icon: UIImage? = nil,
tokens: [Network.Model.Token] = [],
selectedMenu: Common.Model.Menu? = nil,
selected: Network.Model.Token? = nil,
empty: Common.Model.Menu? = .cardsTokensEmpty(),
title: String? = L10n.Common.Card.Token.title,
_ completion: ((Common.Model.Menu) -> Void)? = nil
) -> CommonMenuSelect {
.select(
icon: tokens.isEmpty ? nil : icon ?? Asset.commonMenuHorizontal.image,
kind: .cards,
title: title,
empty: empty,
collection: collection ?? tokens.map({ $0.toMenu() }),
selected: selectedMenu ?? selected?.toMenu(),
completion: completion
)
}
}
class CommonViewCard: CommonControlCustom, CommonMenuSender {
enum Style: String {
case `default`
case data
}
@IBInspectable var styleName: String = Style.default.rawValue {
didSet { update(animated: false) }
}
var style: Style {
get { Style(rawValue: styleName) ?? .default }
set { styleName = newValue.rawValue }
}
@IBInspectable var lzHeader: String? {
didSet { update(animated: false) }
}
@IBInspectable var lzSubheader: String? {
didSet { update(animated: false) }
}
@IBInspectable var lzData: String? {
didSet { update(animated: false) }
}
@IBInspectable var icon: UIImage? {
didSet { update(animated: false) }
}
@IBInspectable var badge: String? {
didSet { update(animated: false) }
}
@IBInspectable var badgeColor: UIColor? {
didSet { update(animated: false) }
}
var action: CommonMenuAction? {
didSet { self.update(animated: false) }
}
var middleAction: (() -> Void)?
var rightAction: (() -> Void)?
@IBOutlet private weak var shadowContainer: CommonViewContainer!
@IBOutlet private weak var indicator: UIActivityIndicatorView!
@IBOutlet private weak var imgShadowView: UIImageView!
@IBOutlet private weak var imgView: UIImageView!
@IBOutlet private weak var imgViewOffset: NSLayoutConstraint!
@IBOutlet private weak var imgViewWidth: NSLayoutConstraint!
@IBOutlet private weak var headerLbl: UILabel!
@IBOutlet private weak var badgeBtn: UIButton!
@IBOutlet private weak var subheaderLbl: UILabel!
@IBOutlet private weak var subheaderOffset: NSLayoutConstraint!
@IBOutlet private weak var dataLbl: UILabel!
@IBOutlet private weak var dataStackView: UIStackView!
@IBOutlet private weak var dataOffset: NSLayoutConstraint!
@IBOutlet private weak var actionBtn: UIButton!
@IBOutlet private weak var bottomStackView: UIStackView!
init(action: CommonMenuAction? = nil) {
super.init(frame: .zero)
self.action = action
self.update(animated: false)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
func update(animated: Bool) {
self.superview?.clipsToBounds = false
self.headerLbl.text = nil
self.subheaderLbl.text = nil
self.dataLbl.text = nil
// dataStackView.isHidden = true
self.dataLbl.alpha = 1
self.dataStackView.arrangedSubviews.forEach { $0.removeFromSuperview() }
self.imgView.image = nil
let header = self.action?.menu?.title ?? lzHeader
let subheader = self.action?.menu?.text ?? lzSubheader
let data = self.action?.menu?.details ?? lzData
let badge = self.action?.menu?.badge?.0 ?? self.badge
let icon = self.action?.icon ?? self.icon
if style == .default {
self.headerLbl.attributedText = header?.localized.attributed(style: .medium, size: 14, color: Asset.textGranite.color)
self.subheaderLbl.attributedText = subheader?.localized.attributed(style: .regular, size: 12, color: Asset.textGranite.color)
self.subheaderOffset.constant = subheader?.isEmpty == true ? 0 : 2
self.dataLbl.attributedText = data?.localized.attributed(style: .bold, size: 20, color: Asset.textCoal.color)
self.dataOffset.constant = data?.isEmpty == true ? 0 : 4
} else {
self.headerLbl.attributedText = data?.localized.attributed(style: .bold, size: 20, color: Asset.textCoal.color)
self.subheaderLbl.attributedText = header?.localized.attributed(style: .medium, size: 14, color: Asset.textGranite.color)
self.subheaderOffset.constant = header?.isEmpty == true ? 0 : 2
self.dataLbl.attributedText = subheader?.localized.attributed(style: .regular, size: 12, color: Asset.textGranite.color)
self.dataOffset.constant = subheader?.isEmpty == true ? 0 : 4
}
if let badge = badge?.localized {
self.badgeBtn.isHidden = false
self.badgeBtn.setAttributedTitle(badge.attributed(style: .regular, size: 12, color: Asset.textSnow.color), for: .normal)
if let color = action?.menu?.badge?.1 ?? badgeColor {
self.badgeBtn.backgroundColor = color
}
} else {
self.badgeBtn.isHidden = true
}
self.actionBtn.setImage(icon, for: .normal)
self.imgShadowView.isHidden = true
if let image = self.action?.menu?.image {
self.imgView.image = image
// uncomment for turn on cash tokens shadow
// if (action?.menu?.uuid.contains(ApplicationEnvironment.shared().current.contract(.cash)) ?? false)
// && (action?.menu?.uuid.lowercased().dropFirst(3).starts(with: "cash") ?? false) {
// imgShadowView.isHidden = false
// }
} else if let urls = action?.menu?.imageURLs {
self.downloadImage(urls: urls)
} else {
self.imgView.image = nil
}
self.imgViewOffset.constant = self.imgView.image == nil && (self.action?.menu?.imageURLs ?? []).isEmpty ? 0 : 12
self.imgViewWidth.constant = self.imgView.image == nil && (self.action?.menu?.imageURLs ?? []).isEmpty ? 0 : 40
DispatchQueue.main.async { [weak self] in
guard let self else { return }
animated ? UIView.animate(withDuration: Animation.fast) { self.layoutIfNeeded() } : self.layoutIfNeeded()
}
}
private func downloadImage(urls: [URL]) {
if urls.isEmpty {
self.indicator.stopAnimating()
self.imgView.image = nil
} else {
self.indicator.startAnimating()
self.imgView.af.setImage(withURL: urls.first!,
placeholderImage: UIImage(),
completion: {
guard $0.error.isExist else {
self.indicator.stopAnimating()
return
}
self.downloadImage(urls: Array(urls.dropFirst()))
})
}
}
@IBAction func onAction(_: AnyObject?) {
guard self.isEnabled else { return }
if let middleAction = self.middleAction {
middleAction()
} else {
self.action?.perform(sender: self)
}
}
func prepareForReuse() {
self.imgView.af.cancelImageRequest()
self.imgView.image = nil
self.bottomStackView.arrangedSubviews.forEach { $0.removeFromSuperview() }
}
@IBAction func onRightAction(_: AnyObject?) {
guard self.isEnabled else { return }
if let rightAction = self.rightAction {
rightAction()
} else {
self.action?.perform(sender: self)
}
}
}