LNMoneyNotEnoughAlertView.swift 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. //
  2. // LNMoneyNotEnoughAlertView.swift
  3. // Gami
  4. //
  5. // Created by OneeChan on 2026/3/30.
  6. //
  7. import Foundation
  8. import UIKit
  9. import SnapKit
  10. class LNMoneyNotEnoughAlertView: LNCommonAlertView {
  11. private let subMessageLabel = UILabel()
  12. private var exchangeType: LNCurrencyType?
  13. private let remainButton = UIButton()
  14. var exchangeHandler: (() -> Void)?
  15. func update(_ currency: LNCurrencyType, exchange: LNCurrencyType? = nil) {
  16. if let exchange, let exchangeType = LNExchangeType.map(from: exchange, to: currency) {
  17. titleLabel.text = .init(key: "B00132", currency.name(lowcase: true))
  18. messageLabel.font = .heading_h4
  19. messageLabel.textColor = .text_4
  20. messageLabel.attributedText = buildRemainString(exchangeType: exchange)
  21. if let rate = exchangeType.rate {
  22. subMessageLabel.textAlignment = .center
  23. subMessageLabel.numberOfLines = 0
  24. subMessageLabel.font = .body_xs
  25. subMessageLabel.textColor = .text_4
  26. showCustomMessage(subMessageLabel)
  27. subMessageLabel.attributedText = buildExchangeString(from: currency, fromValue: "1", exchange: exchange, exchangeValue: rate.toDisplay)
  28. }
  29. showConfirm(.init(key: "A00262")) { [weak self] in
  30. guard let self else { return }
  31. dismiss()
  32. if remainButton.isSelected {
  33. LNUserDefaults[.remainExchange] = curTime
  34. }
  35. exchangeHandler?()
  36. }
  37. showCancel()
  38. remainButton.setTitle(String(key: "B00134"), for: .normal)
  39. remainButton.setImage(.icCheck, for: .selected)
  40. remainButton.setImage(.icUncheck, for: .normal)
  41. remainButton.setTitleColor(.text_4, for: .normal)
  42. remainButton.titleLabel?.font = .body_s
  43. remainButton.imageEdgeInsets = .init(top: 0, left: 0, bottom: 0, right: 8)
  44. remainButton.addAction(UIAction(handler: { [weak remainButton] _ in
  45. guard let remainButton else { return }
  46. remainButton.isSelected.toggle()
  47. }), for: .touchUpInside)
  48. showCustomAction(remainButton)
  49. } else {
  50. titleLabel.text = .init(key: "B00131", currency.name(lowcase: true))
  51. showConfirm { [weak self] in
  52. guard let self else { return }
  53. dismiss()
  54. let panel = LNPurchasePanel()
  55. panel.update(currency)
  56. panel.popup(self)
  57. }
  58. showCancel()
  59. }
  60. }
  61. func buildRemainString(exchangeType: LNCurrencyType) -> NSMutableAttributedString {
  62. let icon = NSTextAttachment(image: exchangeType.icon)
  63. icon.bounds = .init(x: 0, y: -4, width: 19, height: 19)
  64. let text = String(key: "B00133", exchangeType.name(lowcase: true), exchangeType.currentValue.toDisplay)
  65. let attrString = NSMutableAttributedString(string: text)
  66. let iconRange = (text as NSString).range(of: "{icon}")
  67. attrString.replaceCharacters(in: iconRange, with: .init(attachment: icon))
  68. return attrString
  69. }
  70. func buildExchangeString(from: LNCurrencyType, fromValue: String,
  71. exchange: LNCurrencyType, exchangeValue: String) -> NSMutableAttributedString {
  72. let text = String(key: "B00138", fromValue, exchangeValue)
  73. let attrString = NSMutableAttributedString(string: text)
  74. let toIcon = NSTextAttachment(image: exchange.icon)
  75. toIcon.bounds = .init(x: 0, y: -3, width: 14, height: 14)
  76. let toIconRange = (text as NSString).range(of: "{icon2}")
  77. attrString.replaceCharacters(in: toIconRange, with: .init(attachment: toIcon))
  78. let fromIcon = NSTextAttachment(image: from.icon)
  79. fromIcon.bounds = .init(x: 0, y: -3, width: 14, height: 14)
  80. let fromIconRange = (text as NSString).range(of: "{icon1}")
  81. attrString.replaceCharacters(in: fromIconRange, with: .init(attachment: fromIcon))
  82. return attrString
  83. }
  84. }
  85. #if DEBUG
  86. import SwiftUI
  87. struct LNMoneyNotEnoughAlertViewPreview: UIViewRepresentable {
  88. func makeUIView(context: Context) -> some UIView {
  89. let container = UIView()
  90. container.backgroundColor = .lightGray
  91. let button = UIButton()
  92. button.backgroundColor = .red
  93. button.addAction(UIAction(handler: { [weak container] _ in
  94. guard let container else { return }
  95. let view = LNMoneyNotEnoughAlertView()
  96. view.update(.diamond, exchange: .coin)
  97. view.popup(container)
  98. }), for: .touchUpInside)
  99. container.addSubview(button)
  100. button.snp.makeConstraints { make in
  101. make.center.equalToSuperview()
  102. make.width.height.equalTo(50)
  103. }
  104. return container
  105. }
  106. func updateUIView(_ uiView: UIViewType, context: Context) { }
  107. }
  108. #Preview(body: {
  109. LNMoneyNotEnoughAlertViewPreview()
  110. })
  111. #endif