// // BuyCreditsSheetView.swift // Crush // // Created by Leon on 2025/7/23. // import UIKit import Combine /// 额外购买次数 class BuyCreditsSheetView: EGPopBaseView { var closeButton: EPIconTertiaryButton! var logo :UIImageView! var titleLabel:UILabel! var stackV : UIStackView! // content 1: numberscontent var priceLabel: UILabel! // content 2: var addButton: InDecreaseButton! /// 1-999 var inputBox:NumbersInputBox! var decreaseButton: InDecreaseButton! // content 3: total Price var totalPriceLabel: UILabel! var buyButton:StyleButton! // Data var maxNum = 999 var minNum = 1 /// 单价(每次价格) var pricePer: Int = 7000 @Published var num: Int = 10 private var cancellables = Set() init() { super.init(direction: .bottom) contentView.backgroundColor = .c.csbn contentLength = 444 + UIWindow.safeAreaBottom closeButton = { let v = EPIconTertiaryButton(radius: .round, iconSize: .small, iconCode: .delete) v.addTarget(self, action: #selector(bgButtonPressed), for: .touchUpInside) contentView.addSubview(v) v.snp.makeConstraints { make in make.top.equalToSuperview().offset(20) make.size.equalTo(v.bgImageSize()) make.trailing.equalToSuperview().offset(-16) } return v }() logo = { let v = UIImageView() contentView.addSubview(v) v.image = UIImage(named: "buy_credits_title_logo") v.snp.makeConstraints { make in make.size.equalTo(CGSize(width: 100, height: 100)) make.centerX.equalToSuperview() make.top.equalToSuperview().offset(24) } return v }() titleLabel = { let v = UILabel() contentView.addSubview(v) v.text = "Buy Credits" v.font = .t.ttm v.textColor = .text v.textAlignment = .center v.snp.makeConstraints { make in make.leading.equalToSuperview().offset(24) make.trailing.equalToSuperview().offset(-24) make.top.equalTo(logo.snp.bottom).offset(24) } v.numberOfLines = 0 return v }() stackV = { let v = UIStackView() v.axis = .vertical v.spacing = 0 contentView.addSubview(v) v.snp.makeConstraints { make in make.leading.equalToSuperview().offset(24) make.trailing.equalToSuperview().offset(-24) make.top.equalTo(titleLabel.snp.bottom).offset(24) } return v }() do{ let priceView = { let v = UIView() stackV.addArrangedSubview(v) v.snp.makeConstraints { make in make.height.equalTo(48) } return v }() let tipLabel = { let label = UILabel() label.font = .t.tll label.textColor = .text priceView.addSubview(label) label.snp.makeConstraints { make in make.leading.equalToSuperview() make.centerY.equalToSuperview() } return label }() tipLabel.text = "Price" priceLabel = { let v = UILabel() v.font = .t.tll v.textColor = .text priceView.addSubview(v) v.snp.makeConstraints { make in make.trailing.equalToSuperview() make.centerY.equalToSuperview() } return v }() let coinIv = { let v = UIImageView() priceView.addSubview(v) v.snp.makeConstraints { make in make.trailing.equalTo(priceLabel.snp.leading).offset(-8) make.centerY.equalToSuperview() } return v }() coinIv.image = UIImage(named: "icon_16_diamond") } setupQuantityView() do{ let priceView = { let v = UIView() stackV.addArrangedSubview(v) v.snp.makeConstraints { make in make.height.equalTo(48) } return v }() let tipLabel = { let label = UILabel() label.font = .t.tll label.textColor = .text priceView.addSubview(label) label.snp.makeConstraints { make in make.leading.equalToSuperview() make.centerY.equalToSuperview() } return label }() tipLabel.text = "Total Price" totalPriceLabel = { let v = UILabel() v.font = .t.tll v.textColor = .text priceView.addSubview(v) v.snp.makeConstraints { make in make.trailing.equalToSuperview() make.centerY.equalToSuperview() } v.text = "0" return v }() let coinIv = { let v = UIImageView() v.image = UIImage(named: "icon_16_diamond") priceView.addSubview(v) v.snp.makeConstraints { make in make.trailing.equalTo(totalPriceLabel.snp.leading).offset(-8) make.centerY.equalToSuperview() } return v }() coinIv.isHidden = false } buyButton = { let v = StyleButton() v.primary(size: .large) contentView.addSubview(v) v.addTarget(self, action: #selector(submitAction), for: .touchUpInside) v.snp.makeConstraints { make in make.leading.equalToSuperview().offset(24) make.trailing.equalToSuperview().offset(-24) //make.top.equalTo(titleLabel.snp.bottom).offset(24) make.bottom.equalToSuperview().offset(-16-UIWindow.safeAreaBottom*0.5) } return v }() buyButton.setTitle("Confirm", for: .normal) setupData() setupEvent() //#warning("test") // testData() } private func setupQuantityView(){ let quantityView = { let v = UIView() stackV.addArrangedSubview(v) v.snp.makeConstraints { make in make.height.equalTo(72) } return v }() let quantityLabel = { let v = UILabel() v.font = .t.tll v.textColor = .text quantityView.addSubview(v) v.snp.makeConstraints { make in make.leading.equalToSuperview() make.centerY.equalToSuperview() } return v }() quantityLabel.text = "Quantity" addButton = { let v = InDecreaseButton() v.setupIncreaseState() quantityView.addSubview(v) v.snp.makeConstraints { make in make.trailing.equalToSuperview() make.centerY.equalToSuperview() } v.addTarget(self, action: #selector(tapIncreaseButton), for: .touchUpInside) return v }() inputBox = { let v = NumbersInputBox() quantityView.addSubview(v) v.snp.makeConstraints { make in make.trailing.equalTo(addButton.snp.leading).offset(-8) make.centerY.equalToSuperview() } //v.text = "0" v.placeholder = "0" return v }() decreaseButton = { let v = InDecreaseButton() v.setupDecreaseState() quantityView.addSubview(v) v.snp.makeConstraints { make in make.trailing.equalTo(inputBox.snp.leading).offset(-8) make.centerY.equalToSuperview() } v.addTarget(self, action: #selector(tapDecreaseButton), for: .touchUpInside) return v }() } private func setupData(){ // 单价 let price = Coin(cents: 70*100) let priceLabelText = "\(price.formatted)" priceLabel.text = priceLabelText } private func setupEvent(){ NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillChanged(noti:)), name: UIResponder.keyboardWillChangeFrameNotification, object: nil) inputBox.textDidChanged = {[weak self] textField in guard let self = self else{return} let count = Int(textField.text ?? "1") ?? 0 self.num = count if count > self.maxNum{ textField.text = "\(self.maxNum)" self.num = self.maxNum } self.buyButton.isEnabled = count > 0 } inputBox.textDidEndEditing = {[weak self] textField in guard let self = self else{return} let count = Int(textField.text ?? "1") ?? 1 self.num = count if count < self.minNum{ textField.text = "\(self.minNum)" self.num = self.minNum } } $num.sink {[weak self] count in guard let self = self else{return} self.inputBox.text = "\(count)" let total = count * self.pricePer let totalCoin = Coin(cents: total) totalPriceLabel.text = totalCoin.formatted self.decreaseButton.isEnabled = count > minNum self.addButton.isEnabled = count < maxNum }.store(in: &cancellables) } private func testData(){ // let price = Coin(cents: 70*100) // let priceLabelText = "\(price.formatted) USD" // priceLabel.text = priceLabelText } @available(*, unavailable) required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } override func show() { super.show() } // MARK: - Action @objc func submitAction(){ // let alert = Alert(title: "Buy Credits", text: "Are you sure you want to buy credits?") // let action1 = AlertAction(title: "Cancel", actionStyle: .cancel) // let action2 = AlertAction(title: "Buy", actionStyle: .destructive) // alert.addAction(action1) // alert.addAction(action2) // alert.show() doPurchase() } @objc private func tapDecreaseButton(){ num -= 1 } @objc private func tapIncreaseButton(){ num += 1 } // MARK: - Functions private func doPurchase(){ // #warning("test") // dismiss() // let buyCoinSheet = CoinsRechargeSheet() // buyCoinSheet.show() // return let count = num // 创作次数+X Hud.showIndicator() UserProvider.request(.buyUserCreateCount(count: num), modelType: EmptyModel.self) {[weak self] result in Hud.hideIndicator() switch result { case .success: Hud.toast(str: "创作次数+\(count)") {[weak self] complete in self?.dismiss() } NotificationCenter.post(name: .buyCreditsOnce) case .failure(let failure): switch failure { case let .serviceError(code, _): if code == .insufficentCoin{ self?.dismiss() // 遇到此错误吗会会统一弹出sheet去充值 // let buyCoinSheet = CoinsRechargeSheet() // buyCoinSheet.show() } default: break } break } } } // MARK: - Helper @objc func keyboardWillChanged(noti: Notification) { guard let userInfo = noti.userInfo else { return } //let duration = userInfo[UIResponder.keyboardAnimationDurationUserInfoKey] as! TimeInterval let endFrame = (userInfo[UIResponder.keyboardFrameEndUserInfoKey] as! NSValue).cgRectValue if endFrame.origin.y >= UIScreen.main.bounds.height { bottomKeyboardHeight = 0 refreshLPositon() }else{ bottomKeyboardHeight = endFrame.height refreshLPositon() } } }