// // LNBeanViewController.swift // Gami // // Created by OneeChan on 2026/1/27. // import Foundation import UIKit import SnapKit extension UIView { func pushToBeanView() { let vc = LNBeanViewController() navigationController?.pushViewController(vc, animated: true) } } class LNBeanViewController: LNViewController { private let totalLabel = UILabel() private let unsettleLabel = UILabel() private let availableLabtl = UILabel() override func viewDidLoad() { super.viewDidLoad() setupViews() updateContent() } override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) LNPurchaseManager.shared.reloadWalletInfo() } } extension LNBeanViewController: LNPurchaseManagerNotify { func onUserWalletInfoChanged(info: LNUserWalletInfo) { updateContent() } } extension LNBeanViewController { private func updateContent() { totalLabel.text = myWalletInfo.bean.toDisplay unsettleLabel.text = myWalletInfo.unsettledBean.toDisplay availableLabtl.text = myWalletInfo.availableBean.toDisplay } private func setupViews() { navigationBarColor = .primary_1 view.backgroundColor = .primary_1 title = .init(key: "A00215") let currencyView = buildCurrencyView() view.addSubview(currencyView) currencyView.snp.makeConstraints { make in make.horizontalEdges.equalToSuperview().inset(16) make.top.equalToSuperview().offset(9) } let exchangeView = buildExchangeView() view.addSubview(exchangeView) exchangeView.snp.makeConstraints { make in make.horizontalEdges.equalToSuperview() make.bottom.equalToSuperview() make.top.equalTo(currencyView.snp.bottom).offset(-39) } } private func buildCurrencyView() -> UIView { let container = UIView() let bg = UIImageView() bg.image = .icBeanBg container.addSubview(bg) bg.snp.makeConstraints { make in make.edges.equalToSuperview() } if myUserInfo.playmate, LNConfigManager.shared.isBeanAvailable { let tag = UIImageView() tag.image = switch LNAppConfig.shared.curLang { case .chiness: .icBeanValueBgCn case .english: .icBeanValueBgEn case .indonesian: .icBeanValueBgId } tag.onTap { [weak self] in guard let self else { return } view.pushToWebView(.init(url: .beanUrl)) } container.addSubview(tag) tag.snp.makeConstraints { make in make.top.trailing.equalToSuperview() } } let totalView = UIView() container.addSubview(totalView) totalView.snp.makeConstraints { make in make.leading.equalToSuperview().offset(30) make.top.equalToSuperview().offset(30) } let totalTitle = UILabel() totalTitle.text = .init(key: "A00268") totalTitle.font = .heading_h4 totalTitle.textColor = .text_5 totalView.addSubview(totalTitle) totalTitle.snp.makeConstraints { make in make.leading.top.equalToSuperview() } totalLabel.text = "0" totalLabel.font = .heading_h1 totalLabel.textColor = .text_5 totalView.addSubview(totalLabel) totalLabel.snp.makeConstraints { make in make.bottom.equalToSuperview() make.trailing.equalToSuperview() make.top.equalTo(totalTitle.snp.bottom).offset(4) } let totalBean = UIImageView.beanImageView() totalView.addSubview(totalBean) totalBean.snp.makeConstraints { make in make.centerY.equalTo(totalLabel) make.leading.equalToSuperview() make.trailing.equalTo(totalLabel.snp.leading).offset(-2) make.width.height.equalTo(24) } let stackView = UIStackView() stackView.axis = .horizontal stackView.spacing = 36 stackView.distribution = .fillEqually stackView.alignment = .center container.addSubview(stackView) stackView.snp.makeConstraints { make in make.horizontalEdges.equalToSuperview().inset(30) make.top.equalTo(totalView.snp.bottom).offset(16) } stackView.addArrangedSubview(buildUnsetttleView()) stackView.addArrangedSubview(buildAvailableView()) let line = UIView() line.backgroundColor = .init(hex: "#F3DBBC") stackView.addSubview(line) line.snp.makeConstraints { make in make.center.equalToSuperview() make.width.equalTo(1) make.height.equalTo(40) } return container } private func buildUnsetttleView() -> UIView { let container = UIView() let titleLabel = UILabel() titleLabel.text = .init(key: "B00103") titleLabel.font = .heading_h5 titleLabel.textColor = .text_5 container.addSubview(titleLabel) titleLabel.snp.makeConstraints { make in make.top.equalToSuperview() make.leading.equalToSuperview() } let about = UIButton() about.setImage(.icAbout.withRenderingMode(.alwaysTemplate), for: .normal) about.tintColor = .text_4 about.addAction(UIAction(handler: { [weak self] _ in guard self != nil else { return } let alert = LNCommonAlertView() alert.messageLabel.text = .init(key: "B00108") alert.showConfirm { } alert.popup() }), for: .touchUpInside) container.addSubview(about) about.snp.makeConstraints { make in make.top.equalTo(titleLabel).offset(1) make.leading.equalTo(titleLabel.snp.trailing).offset(2) make.trailing.lessThanOrEqualToSuperview() make.width.height.equalTo(16) } unsettleLabel.text = "0" unsettleLabel.font = .heading_h3 unsettleLabel.textColor = .text_5 container.addSubview(unsettleLabel) unsettleLabel.snp.makeConstraints { make in make.trailing.equalToSuperview() make.bottom.equalToSuperview() make.top.equalTo(titleLabel.snp.bottom).offset(5) } let bean = UIImageView.beanImageView() container.addSubview(bean) bean.snp.makeConstraints { make in make.leading.equalToSuperview() make.centerY.equalTo(unsettleLabel) make.width.height.equalTo(18) make.trailing.equalTo(unsettleLabel.snp.leading).offset(-2) } return container } private func buildAvailableView() -> UIView { let container = UIView() let titleLabel = UILabel() titleLabel.text = .init(key: "B00104") titleLabel.font = .heading_h5 titleLabel.textColor = .text_5 container.addSubview(titleLabel) titleLabel.snp.makeConstraints { make in make.top.equalToSuperview() make.horizontalEdges.equalToSuperview() } availableLabtl.text = "0" availableLabtl.font = .heading_h3 availableLabtl.textColor = .text_5 container.addSubview(availableLabtl) availableLabtl.snp.makeConstraints { make in make.trailing.equalToSuperview() make.bottom.equalToSuperview() make.top.equalTo(titleLabel.snp.bottom).offset(5) } let bean = UIImageView.beanImageView() container.addSubview(bean) bean.snp.makeConstraints { make in make.leading.equalToSuperview() make.centerY.equalTo(availableLabtl) make.width.height.equalTo(18) make.trailing.equalTo(availableLabtl.snp.leading).offset(-2) } return container } private func buildExchangeView() -> UIView { let container = UIView() container.backgroundColor = .fill container.layer.cornerRadius = 20 container.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner] let stackView = UIStackView() stackView.axis = .horizontal stackView.spacing = 13 stackView.distribution = .fillEqually container.addSubview(stackView) stackView.snp.makeConstraints { make in make.horizontalEdges.equalToSuperview().inset(16) make.top.equalToSuperview().offset(22) } let toCoin = buildExchangeItemView(title: .init(key: "A00273"), color: .init(hex: "#FFF8E1"), icon: .icCoin42) toCoin.onTap { [weak self] in guard self != nil else { return } let panel = LNExchangePanel(exchangeType: .beanToCoin) panel.popup() } stackView.addArrangedSubview(toCoin) let toDiamond = buildExchangeItemView(title: .init(key: "A00264"), color: .init(hex: "#E3F2FF"), icon: .icDiamond42) toDiamond.onTap { [weak self] in guard self != nil else { return } let panel = LNExchangePanel(exchangeType: .beanToDiamond) panel.popup() } stackView.addArrangedSubview(toDiamond) return container } private func buildExchangeItemView(title: String, color: UIColor, icon: UIImage) -> UIView { let container = UIView() container.backgroundColor = color container.layer.cornerRadius = 12 container.snp.makeConstraints { make in make.height.equalTo(95) } let iconView = UIImageView() iconView.image = icon iconView.alpha = 0.3 container.addSubview(iconView) iconView.snp.makeConstraints { make in make.trailing.bottom.equalToSuperview() make.width.height.equalTo(55) } let titleLabel = UILabel() titleLabel.text = title titleLabel.font = .heading_h4 titleLabel.textColor = .text_5 titleLabel.numberOfLines = 2 container.addSubview(titleLabel) titleLabel.snp.makeConstraints { make in make.leading.equalToSuperview().offset(12) make.top.equalToSuperview().offset(14) make.trailing.equalToSuperview().offset(-50) } let exchangeButton = UIButton() exchangeButton.setBackgroundImage(.primary_8, for: .normal) exchangeButton.layer.cornerRadius = 12 exchangeButton.clipsToBounds = true container.addSubview(exchangeButton) exchangeButton.snp.makeConstraints { make in make.leading.equalToSuperview().offset(12) make.bottom.equalToSuperview().offset(-13) make.height.equalTo(24) } let convertView = UIView() exchangeButton.addSubview(convertView) convertView.snp.makeConstraints { make in make.center.equalToSuperview() make.leading.greaterThanOrEqualToSuperview().offset(8) } let convert = UILabel() convert.font = .heading_h5 convert.textColor = .text_1 convert.text = .init(key: "B00105") convertView.addSubview(convert) convert.snp.makeConstraints { make in make.centerY.equalToSuperview() make.leading.equalToSuperview() } let arrow = UIImageView.arrowImageView(size: 13, weight: .semibold) arrow.tintColor = .text_1 convertView.addSubview(arrow) arrow.snp.makeConstraints { make in make.leading.equalTo(convert.snp.trailing).offset(2) make.verticalEdges.equalToSuperview() make.trailing.equalToSuperview() } return container } } #if DEBUG import SwiftUI struct LNBeanViewControllerPreview: UIViewControllerRepresentable { func makeUIViewController(context: Context) -> some UIViewController { LNBeanViewController() } func updateUIViewController(_ uiViewController: UIViewControllerType, context: Context) { } } #Preview(body: { LNBeanViewControllerPreview() }) #endif