221 lines
8.0 KiB
Swift
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)
|
|
}
|
|
}
|
|
}
|