LNBeanViewController.swift 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371
  1. //
  2. // LNBeanViewController.swift
  3. // Gami
  4. //
  5. // Created by OneeChan on 2026/1/27.
  6. //
  7. import Foundation
  8. import UIKit
  9. import SnapKit
  10. extension UIView {
  11. func pushToBeanView() {
  12. let vc = LNBeanViewController()
  13. navigationController?.pushViewController(vc, animated: true)
  14. }
  15. }
  16. class LNBeanViewController: LNViewController {
  17. private let totalLabel = UILabel()
  18. private let unsettleLabel = UILabel()
  19. private let availableLabtl = UILabel()
  20. override func viewDidLoad() {
  21. super.viewDidLoad()
  22. setupViews()
  23. updateContent()
  24. }
  25. override func viewDidAppear(_ animated: Bool) {
  26. super.viewDidAppear(animated)
  27. LNPurchaseManager.shared.reloadWalletInfo()
  28. }
  29. }
  30. extension LNBeanViewController: LNPurchaseManagerNotify {
  31. func onUserWalletInfoChanged(info: LNUserWalletInfo) {
  32. updateContent()
  33. }
  34. }
  35. extension LNBeanViewController {
  36. private func updateContent() {
  37. totalLabel.text = myWalletInfo.bean.toDisplay
  38. unsettleLabel.text = myWalletInfo.unsettledBean.toDisplay
  39. availableLabtl.text = myWalletInfo.availableBean.toDisplay
  40. }
  41. private func setupViews() {
  42. navigationBarColor = .primary_1
  43. view.backgroundColor = .primary_1
  44. title = .init(key: "A00215")
  45. let currencyView = buildCurrencyView()
  46. view.addSubview(currencyView)
  47. currencyView.snp.makeConstraints { make in
  48. make.horizontalEdges.equalToSuperview().inset(16)
  49. make.top.equalToSuperview().offset(9)
  50. }
  51. let exchangeView = buildExchangeView()
  52. view.addSubview(exchangeView)
  53. exchangeView.snp.makeConstraints { make in
  54. make.horizontalEdges.equalToSuperview()
  55. make.bottom.equalToSuperview()
  56. make.top.equalTo(currencyView.snp.bottom).offset(-39)
  57. }
  58. }
  59. private func buildCurrencyView() -> UIView {
  60. let container = UIView()
  61. let bg = UIImageView()
  62. bg.image = .icBeanBg
  63. container.addSubview(bg)
  64. bg.snp.makeConstraints { make in
  65. make.edges.equalToSuperview()
  66. }
  67. if LNConfigManager.shared.isBeanAvailable {
  68. let tag = UIImageView()
  69. tag.image = switch LNAppConfig.shared.curLang {
  70. case .chiness: .icBeanValueBgCn
  71. case .english: .icBeanValueBgEn
  72. case .indonesian: .icBeanValueBgId
  73. }
  74. tag.onTap { [weak self] in
  75. guard let self else { return }
  76. view.pushToWebView(.init(url: .beanUrl))
  77. }
  78. container.addSubview(tag)
  79. tag.snp.makeConstraints { make in
  80. make.top.trailing.equalToSuperview()
  81. }
  82. }
  83. let totalView = UIView()
  84. container.addSubview(totalView)
  85. totalView.snp.makeConstraints { make in
  86. make.leading.equalToSuperview().offset(30)
  87. make.top.equalToSuperview().offset(30)
  88. }
  89. let totalTitle = UILabel()
  90. totalTitle.text = .init(key: "A00268")
  91. totalTitle.font = .heading_h4
  92. totalTitle.textColor = .text_5
  93. totalView.addSubview(totalTitle)
  94. totalTitle.snp.makeConstraints { make in
  95. make.leading.top.equalToSuperview()
  96. }
  97. totalLabel.text = "0"
  98. totalLabel.font = .heading_h1
  99. totalLabel.textColor = .text_5
  100. totalView.addSubview(totalLabel)
  101. totalLabel.snp.makeConstraints { make in
  102. make.bottom.equalToSuperview()
  103. make.trailing.equalToSuperview()
  104. make.top.equalTo(totalTitle.snp.bottom).offset(4)
  105. }
  106. let totalBean = UIImageView.beanImageView()
  107. totalView.addSubview(totalBean)
  108. totalBean.snp.makeConstraints { make in
  109. make.centerY.equalTo(totalLabel)
  110. make.leading.equalToSuperview()
  111. make.trailing.equalTo(totalLabel.snp.leading).offset(-2)
  112. make.width.height.equalTo(24)
  113. }
  114. let stackView = UIStackView()
  115. stackView.axis = .horizontal
  116. stackView.spacing = 36
  117. stackView.distribution = .fillEqually
  118. stackView.alignment = .center
  119. container.addSubview(stackView)
  120. stackView.snp.makeConstraints { make in
  121. make.horizontalEdges.equalToSuperview().inset(30)
  122. make.top.equalTo(totalView.snp.bottom).offset(16)
  123. }
  124. stackView.addArrangedSubview(buildUnsetttleView())
  125. stackView.addArrangedSubview(buildAvailableView())
  126. let line = UIView()
  127. line.backgroundColor = .init(hex: "#F3DBBC")
  128. stackView.addSubview(line)
  129. line.snp.makeConstraints { make in
  130. make.center.equalToSuperview()
  131. make.width.equalTo(1)
  132. make.height.equalTo(40)
  133. }
  134. return container
  135. }
  136. private func buildUnsetttleView() -> UIView {
  137. let container = UIView()
  138. let titleLabel = UILabel()
  139. titleLabel.text = .init(key: "B00103")
  140. titleLabel.font = .heading_h5
  141. titleLabel.textColor = .text_5
  142. container.addSubview(titleLabel)
  143. titleLabel.snp.makeConstraints { make in
  144. make.top.equalToSuperview()
  145. make.leading.equalToSuperview()
  146. }
  147. let about = UIButton()
  148. about.setImage(.icAbout.withRenderingMode(.alwaysTemplate), for: .normal)
  149. about.tintColor = .text_4
  150. about.addAction(UIAction(handler: { [weak self] _ in
  151. guard self != nil else { return }
  152. let alert = LNCommonAlertView()
  153. alert.messageLabel.text = .init(key: "B00108")
  154. alert.showConfirm { }
  155. alert.popup()
  156. }), for: .touchUpInside)
  157. container.addSubview(about)
  158. about.snp.makeConstraints { make in
  159. make.top.equalTo(titleLabel).offset(1)
  160. make.leading.equalTo(titleLabel.snp.trailing).offset(2)
  161. make.trailing.lessThanOrEqualToSuperview()
  162. make.width.height.equalTo(16)
  163. }
  164. unsettleLabel.text = "0"
  165. unsettleLabel.font = .heading_h3
  166. unsettleLabel.textColor = .text_5
  167. container.addSubview(unsettleLabel)
  168. unsettleLabel.snp.makeConstraints { make in
  169. make.trailing.equalToSuperview()
  170. make.bottom.equalToSuperview()
  171. make.top.equalTo(titleLabel.snp.bottom).offset(5)
  172. }
  173. let bean = UIImageView.beanImageView()
  174. container.addSubview(bean)
  175. bean.snp.makeConstraints { make in
  176. make.leading.equalToSuperview()
  177. make.centerY.equalTo(unsettleLabel)
  178. make.width.height.equalTo(18)
  179. make.trailing.equalTo(unsettleLabel.snp.leading).offset(-2)
  180. }
  181. return container
  182. }
  183. private func buildAvailableView() -> UIView {
  184. let container = UIView()
  185. let titleLabel = UILabel()
  186. titleLabel.text = .init(key: "B00104")
  187. titleLabel.font = .heading_h5
  188. titleLabel.textColor = .text_5
  189. container.addSubview(titleLabel)
  190. titleLabel.snp.makeConstraints { make in
  191. make.top.equalToSuperview()
  192. make.horizontalEdges.equalToSuperview()
  193. }
  194. availableLabtl.text = "0"
  195. availableLabtl.font = .heading_h3
  196. availableLabtl.textColor = .text_5
  197. container.addSubview(availableLabtl)
  198. availableLabtl.snp.makeConstraints { make in
  199. make.trailing.equalToSuperview()
  200. make.bottom.equalToSuperview()
  201. make.top.equalTo(titleLabel.snp.bottom).offset(5)
  202. }
  203. let bean = UIImageView.beanImageView()
  204. container.addSubview(bean)
  205. bean.snp.makeConstraints { make in
  206. make.leading.equalToSuperview()
  207. make.centerY.equalTo(availableLabtl)
  208. make.width.height.equalTo(18)
  209. make.trailing.equalTo(availableLabtl.snp.leading).offset(-2)
  210. }
  211. return container
  212. }
  213. private func buildExchangeView() -> UIView {
  214. let container = UIView()
  215. container.backgroundColor = .fill
  216. container.layer.cornerRadius = 20
  217. container.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]
  218. let stackView = UIStackView()
  219. stackView.axis = .horizontal
  220. stackView.spacing = 13
  221. stackView.distribution = .fillEqually
  222. container.addSubview(stackView)
  223. stackView.snp.makeConstraints { make in
  224. make.horizontalEdges.equalToSuperview().inset(16)
  225. make.top.equalToSuperview().offset(22)
  226. }
  227. let toCoin = buildExchangeItemView(title: .init(key: "A00273"), color: .init(hex: "#FFF8E1"), icon: .icCoin42)
  228. toCoin.onTap { [weak self] in
  229. guard self != nil else { return }
  230. let panel = LNExchangePanel(exchangeType: .beanToCoin)
  231. panel.popup()
  232. }
  233. stackView.addArrangedSubview(toCoin)
  234. let toDiamond = buildExchangeItemView(title: .init(key: "A00264"), color: .init(hex: "#E3F2FF"), icon: .icDiamond42)
  235. toDiamond.onTap { [weak self] in
  236. guard self != nil else { return }
  237. let panel = LNExchangePanel(exchangeType: .beanToDiamond)
  238. panel.popup()
  239. }
  240. stackView.addArrangedSubview(toDiamond)
  241. return container
  242. }
  243. private func buildExchangeItemView(title: String, color: UIColor, icon: UIImage) -> UIView {
  244. let container = UIView()
  245. container.backgroundColor = color
  246. container.layer.cornerRadius = 12
  247. container.snp.makeConstraints { make in
  248. make.height.equalTo(95)
  249. }
  250. let iconView = UIImageView()
  251. iconView.image = icon
  252. iconView.alpha = 0.3
  253. container.addSubview(iconView)
  254. iconView.snp.makeConstraints { make in
  255. make.trailing.bottom.equalToSuperview()
  256. make.width.height.equalTo(55)
  257. }
  258. let titleLabel = UILabel()
  259. titleLabel.text = title
  260. titleLabel.font = .heading_h4
  261. titleLabel.textColor = .text_5
  262. titleLabel.numberOfLines = 2
  263. container.addSubview(titleLabel)
  264. titleLabel.snp.makeConstraints { make in
  265. make.leading.equalToSuperview().offset(12)
  266. make.top.equalToSuperview().offset(14)
  267. make.trailing.equalToSuperview().offset(-50)
  268. }
  269. let exchangeButton = UIButton()
  270. exchangeButton.setBackgroundImage(.primary_8, for: .normal)
  271. exchangeButton.layer.cornerRadius = 12
  272. exchangeButton.clipsToBounds = true
  273. container.addSubview(exchangeButton)
  274. exchangeButton.snp.makeConstraints { make in
  275. make.leading.equalToSuperview().offset(12)
  276. make.bottom.equalToSuperview().offset(-13)
  277. make.height.equalTo(24)
  278. }
  279. let convertView = UIView()
  280. exchangeButton.addSubview(convertView)
  281. convertView.snp.makeConstraints { make in
  282. make.center.equalToSuperview()
  283. make.leading.greaterThanOrEqualToSuperview().offset(8)
  284. }
  285. let convert = UILabel()
  286. convert.font = .heading_h5
  287. convert.textColor = .text_1
  288. convert.text = .init(key: "B00105")
  289. convertView.addSubview(convert)
  290. convert.snp.makeConstraints { make in
  291. make.centerY.equalToSuperview()
  292. make.leading.equalToSuperview()
  293. }
  294. let arrow = UIImageView.arrowImageView(size: 13, weight: .semibold)
  295. arrow.tintColor = .text_1
  296. convertView.addSubview(arrow)
  297. arrow.snp.makeConstraints { make in
  298. make.leading.equalTo(convert.snp.trailing).offset(2)
  299. make.verticalEdges.equalToSuperview()
  300. make.trailing.equalToSuperview()
  301. }
  302. return container
  303. }
  304. }
  305. #if DEBUG
  306. import SwiftUI
  307. struct LNBeanViewControllerPreview: UIViewControllerRepresentable {
  308. func makeUIViewController(context: Context) -> some UIViewController {
  309. LNBeanViewController()
  310. }
  311. func updateUIViewController(_ uiViewController: UIViewControllerType, context: Context) { }
  312. }
  313. #Preview(body: {
  314. LNBeanViewControllerPreview()
  315. })
  316. #endif