426 lines
13 KiB
Swift
426 lines
13 KiB
Swift
//
|
||
// 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<AnyCancellable>()
|
||
|
||
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()
|
||
}
|
||
}
|
||
|
||
}
|