// // 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) } } }