1
@ -179,6 +179,13 @@
|
||||
F3F389292F6A98C9001B0E15 /* XSAlert.swift in Sources */ = {isa = PBXBuildFile; fileRef = F3F389282F6A98C9001B0E15 /* XSAlert.swift */; };
|
||||
F3F3892B2F6AAC25001B0E15 /* XSVersionUpdateModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F3F3892A2F6AAC25001B0E15 /* XSVersionUpdateModel.swift */; };
|
||||
F3F3892D2F6B86F7001B0E15 /* XSLoginView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F3F3892C2F6B86F7001B0E15 /* XSLoginView.swift */; };
|
||||
F3F3892F2F6D3D95001B0E15 /* UIImage+XS.swift in Sources */ = {isa = PBXBuildFile; fileRef = F3F3892E2F6D3D8E001B0E15 /* UIImage+XS.swift */; };
|
||||
F3F389312F6D44BC001B0E15 /* XSCoinsPackHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F3F389302F6D44BC001B0E15 /* XSCoinsPackHeaderView.swift */; };
|
||||
F3F389332F6D5024001B0E15 /* XSCoinsPackModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F3F389322F6D5024001B0E15 /* XSCoinsPackModel.swift */; };
|
||||
F3F389352F6D54DC001B0E15 /* XSCoinsPackBuyView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F3F389342F6D54DC001B0E15 /* XSCoinsPackBuyView.swift */; };
|
||||
F3F389372F6E35EA001B0E15 /* XSCoinsPackConfirmView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F3F389362F6E35EA001B0E15 /* XSCoinsPackConfirmView.swift */; };
|
||||
F3F389392F6E4268001B0E15 /* XSCoinsPackConfirmItem1View.swift in Sources */ = {isa = PBXBuildFile; fileRef = F3F389382F6E4268001B0E15 /* XSCoinsPackConfirmItem1View.swift */; };
|
||||
F3F3893B2F6E47E6001B0E15 /* XSCoinsPackConfirmItem2View.swift in Sources */ = {isa = PBXBuildFile; fileRef = F3F3893A2F6E47E6001B0E15 /* XSCoinsPackConfirmItem2View.swift */; };
|
||||
F3F683ED2F56C380008AF250 /* XSHomeHistoryView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F3F683EC2F56C380008AF250 /* XSHomeHistoryView.swift */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
@ -359,6 +366,13 @@
|
||||
F3F389282F6A98C9001B0E15 /* XSAlert.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XSAlert.swift; sourceTree = "<group>"; };
|
||||
F3F3892A2F6AAC25001B0E15 /* XSVersionUpdateModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XSVersionUpdateModel.swift; sourceTree = "<group>"; };
|
||||
F3F3892C2F6B86F7001B0E15 /* XSLoginView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XSLoginView.swift; sourceTree = "<group>"; };
|
||||
F3F3892E2F6D3D8E001B0E15 /* UIImage+XS.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIImage+XS.swift"; sourceTree = "<group>"; };
|
||||
F3F389302F6D44BC001B0E15 /* XSCoinsPackHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XSCoinsPackHeaderView.swift; sourceTree = "<group>"; };
|
||||
F3F389322F6D5024001B0E15 /* XSCoinsPackModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XSCoinsPackModel.swift; sourceTree = "<group>"; };
|
||||
F3F389342F6D54DC001B0E15 /* XSCoinsPackBuyView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XSCoinsPackBuyView.swift; sourceTree = "<group>"; };
|
||||
F3F389362F6E35EA001B0E15 /* XSCoinsPackConfirmView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XSCoinsPackConfirmView.swift; sourceTree = "<group>"; };
|
||||
F3F389382F6E4268001B0E15 /* XSCoinsPackConfirmItem1View.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XSCoinsPackConfirmItem1View.swift; sourceTree = "<group>"; };
|
||||
F3F3893A2F6E47E6001B0E15 /* XSCoinsPackConfirmItem2View.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XSCoinsPackConfirmItem2View.swift; sourceTree = "<group>"; };
|
||||
F3F683EC2F56C380008AF250 /* XSHomeHistoryView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XSHomeHistoryView.swift; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
@ -527,6 +541,7 @@
|
||||
F347D29D2F03A65F00786648 /* Extension */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
F3F3892E2F6D3D8E001B0E15 /* UIImage+XS.swift */,
|
||||
F35548382F52B913006F28CD /* Dictionary+XS.swift */,
|
||||
F355480B2F503983006F28CD /* NSNumber+XS.swift */,
|
||||
F35548032F4EDF21006F28CD /* UIStackView+XS.swift */,
|
||||
@ -904,6 +919,11 @@
|
||||
F3F3890F2F695C5A001B0E15 /* XSSegmentedGradientIndicatorView.swift */,
|
||||
F3F389112F6A37E3001B0E15 /* XSCoinsOrderRecordCell.swift */,
|
||||
F3F389152F6A3AD3001B0E15 /* XSVipOrderRecordCell.swift */,
|
||||
F3F389302F6D44BC001B0E15 /* XSCoinsPackHeaderView.swift */,
|
||||
F3F389342F6D54DC001B0E15 /* XSCoinsPackBuyView.swift */,
|
||||
F3F389362F6E35EA001B0E15 /* XSCoinsPackConfirmView.swift */,
|
||||
F3F389382F6E4268001B0E15 /* XSCoinsPackConfirmItem1View.swift */,
|
||||
F3F3893A2F6E47E6001B0E15 /* XSCoinsPackConfirmItem2View.swift */,
|
||||
);
|
||||
path = View;
|
||||
sourceTree = "<group>";
|
||||
@ -916,6 +936,7 @@
|
||||
F3F389012F693785001B0E15 /* XSBuyRecordsModel.swift */,
|
||||
F3F389092F694109001B0E15 /* XSSendCoinRecordModel.swift */,
|
||||
F3F389132F6A3812001B0E15 /* XSOrderRecordModel.swift */,
|
||||
F3F389322F6D5024001B0E15 /* XSCoinsPackModel.swift */,
|
||||
);
|
||||
path = Model;
|
||||
sourceTree = "<group>";
|
||||
@ -1081,8 +1102,10 @@
|
||||
F3F388EC2F680CEE001B0E15 /* XSIapManager.swift in Sources */,
|
||||
F347D3082F0A134500786648 /* XSHud.swift in Sources */,
|
||||
F347D29E2F03750000786648 /* XSTabBarItemContentView.swift in Sources */,
|
||||
F3F3893B2F6E47E6001B0E15 /* XSCoinsPackConfirmItem2View.swift in Sources */,
|
||||
F3F3891E2F6A4484001B0E15 /* XSStoreCoinsSpreadCell.swift in Sources */,
|
||||
F347D2FE2F0A0D0700786648 /* XSUserDefaultsKey.swift in Sources */,
|
||||
F3F3892F2F6D3D95001B0E15 /* UIImage+XS.swift in Sources */,
|
||||
F347D2EE2F0A06FB00786648 /* XSURLPath.swift in Sources */,
|
||||
F347D2DC2F04EE5F00786648 /* XSHomeRankingsCell.swift in Sources */,
|
||||
F35547FC2F4EA069006F28CD /* XSButton.swift in Sources */,
|
||||
@ -1108,6 +1131,7 @@
|
||||
F304E6102F67A9B600E9B0A6 /* XSShortDetailLockView.swift in Sources */,
|
||||
F3585C3A2F14999700EEC469 /* XSProgressView.swift in Sources */,
|
||||
F3F389062F6939EE001B0E15 /* XSRewardCoinsViewController.swift in Sources */,
|
||||
F3F389332F6D5024001B0E15 /* XSCoinsPackModel.swift in Sources */,
|
||||
F3585C382F1497AF00EEC469 /* XSDiscoverControlView.swift in Sources */,
|
||||
F3F388D52F67DDBC001B0E15 /* XSMineWalletView.swift in Sources */,
|
||||
F3F389272F6A9597001B0E15 /* XSBaseAlert.swift in Sources */,
|
||||
@ -1130,6 +1154,7 @@
|
||||
F35547DC2F3DB33C006F28CD /* XSMineHeaderView.swift in Sources */,
|
||||
F347D2B52F03B2B500786648 /* UIFont+XS.swift in Sources */,
|
||||
F3585C362F148FE500EEC469 /* XSHomeModuleItem.swift in Sources */,
|
||||
F3F389312F6D44BC001B0E15 /* XSCoinsPackHeaderView.swift in Sources */,
|
||||
F35547F82F3F0720006F28CD /* XSMyListHistoryCell.swift in Sources */,
|
||||
F347D2EA2F0A047A00786648 /* XSNetwork.swift in Sources */,
|
||||
F347D2A32F03A93200786648 /* XSDefine.swift in Sources */,
|
||||
@ -1148,12 +1173,14 @@
|
||||
F3F388FA2F69240E001B0E15 /* XSWalletHeaderView.swift in Sources */,
|
||||
F35548122F5129F2006F28CD /* XSEpSelectorCell.swift in Sources */,
|
||||
F3F388E32F680316001B0E15 /* XSStoreCoinsView.swift in Sources */,
|
||||
F3F389372F6E35EA001B0E15 /* XSCoinsPackConfirmView.swift in Sources */,
|
||||
F355480C2F50398B006F28CD /* NSNumber+XS.swift in Sources */,
|
||||
F347D2E02F04F7ED00786648 /* XSHomeCategoriesCell.swift in Sources */,
|
||||
F3F3890A2F694109001B0E15 /* XSSendCoinRecordModel.swift in Sources */,
|
||||
F347D3032F0A10B600786648 /* XSCryptorService.swift in Sources */,
|
||||
F3F3891C2F6A4465001B0E15 /* XSStoreCoinsSmallCell.swift in Sources */,
|
||||
F35547D42F3DA7A8006F28CD /* XSTableViewCell.swift in Sources */,
|
||||
F3F389392F6E4268001B0E15 /* XSCoinsPackConfirmItem1View.swift in Sources */,
|
||||
F3F388F62F68F746001B0E15 /* XSPayDataRequest.swift in Sources */,
|
||||
F347D30E2F0A39DE00786648 /* XSHomeAPI.swift in Sources */,
|
||||
F3F3891A2F6A444D001B0E15 /* XSStoreCoinsBigCell.swift in Sources */,
|
||||
@ -1183,6 +1210,7 @@
|
||||
F3F683ED2F56C380008AF250 /* XSHomeHistoryView.swift in Sources */,
|
||||
F347D2A12F03A84300786648 /* XSScreen.swift in Sources */,
|
||||
F3F389202F6A487B001B0E15 /* XSStoreVipCell.swift in Sources */,
|
||||
F3F389352F6D54DC001B0E15 /* XSCoinsPackBuyView.swift in Sources */,
|
||||
F35548062F4FD6DA006F28CD /* XSMinePlayHistoryView.swift in Sources */,
|
||||
F3F3890E2F695068001B0E15 /* XSVipOrderRecordViewController.swift in Sources */,
|
||||
F3F388E72F6805DE001B0E15 /* XSPayItem.swift in Sources */,
|
||||
|
||||
26
XSeri/Base/Extension/UIImage+XS.swift
Normal file
@ -0,0 +1,26 @@
|
||||
//
|
||||
// UIImage+XS.swift
|
||||
// XSeri
|
||||
//
|
||||
// Created by 长沙鸿瑶 on 2026/3/20.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
|
||||
extension UIImage {
|
||||
|
||||
///纵向翻转图片
|
||||
func xs_flippedVertically() -> UIImage {
|
||||
let format = UIGraphicsImageRendererFormat.default()
|
||||
format.scale = scale
|
||||
format.opaque = false
|
||||
|
||||
return UIGraphicsImageRenderer(size: size, format: format).image { context in
|
||||
let cgContext = context.cgContext
|
||||
cgContext.translateBy(x: 0, y: size.height)
|
||||
cgContext.scaleBy(x: 1, y: -1)
|
||||
draw(in: CGRect(origin: .zero, size: size))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -143,4 +143,13 @@ struct XSStoreAPI {
|
||||
let response: XSNetwork.Response<XSNetwork.List<XSOrderRecordModel>> = await XSNetwork.request(parameters: param)
|
||||
return response.data
|
||||
}
|
||||
|
||||
static func requestCoinsPackData() async -> XSCoinsPackModel? {
|
||||
|
||||
var param = XSNetwork.Parameters(path: "/getReceiveDayCoinInfo")
|
||||
param.method = .get
|
||||
|
||||
let response: XSNetwork.Response<XSCoinsPackModel> = await XSNetwork.request(parameters: param)
|
||||
return response.data
|
||||
}
|
||||
}
|
||||
|
||||
@ -20,7 +20,7 @@ class XSMineCoinsPackView: UIView {
|
||||
return imageView
|
||||
}()
|
||||
|
||||
private lazy var giftsIconImageView = UIImageView(image: UIImage(named: "gifts_icon_01"))
|
||||
private lazy var giftsIconImageView = UIImageView(image: UIImage(named: "gift_icon_01"))
|
||||
|
||||
private lazy var titleLabel: XSLabel = {
|
||||
let label = XSLabel()
|
||||
|
||||
@ -9,27 +9,121 @@ import UIKit
|
||||
import SnapKit
|
||||
|
||||
class XSCoinsPackViewController: XSViewController {
|
||||
|
||||
|
||||
private let contentBgCornerRadius: CGFloat = 26
|
||||
|
||||
|
||||
private var model: XSCoinsPackModel? {
|
||||
didSet {
|
||||
self.headerView.model = model
|
||||
// claimView.dataArr = model?.receive_list ?? []
|
||||
}
|
||||
}
|
||||
|
||||
private var payDataModel : XSPayDateModel? {
|
||||
didSet {
|
||||
var arr: [XSPayItem] = []
|
||||
|
||||
payDataModel?.list_coins?.forEach {
|
||||
if $0.buy_type == .subCoins {
|
||||
arr.append($0)
|
||||
}
|
||||
}
|
||||
self.buyView.dataArr = arr
|
||||
}
|
||||
}
|
||||
|
||||
var payDataRequest: XSPayDataRequest?
|
||||
|
||||
private let contentBgBorderImage = UIImage(named: "gradient_color_image_03")?.xs_flippedVertically()
|
||||
|
||||
private lazy var mainBgView = UIImageView(image: UIImage(named: "coins_pack_bg_01"))
|
||||
|
||||
private lazy var contentBgView: UIImageView = {
|
||||
let view = UIImageView(image: UIImage(named: "coins_pack_bg_02"))
|
||||
view.layer.cornerRadius = contentBgCornerRadius
|
||||
view.isUserInteractionEnabled = true
|
||||
view.layer.cornerRadius = 26
|
||||
view.layer.masksToBounds = true
|
||||
view.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]
|
||||
view.layer.borderWidth = 1
|
||||
view.addObserver(self, forKeyPath: "bounds", context: nil)
|
||||
return view
|
||||
}()
|
||||
|
||||
private lazy var calendarImageView: UIImageView = UIImageView(image: UIImage(named: "calendar_icon_02"))
|
||||
|
||||
private lazy var scrollView: XSScrollView = {
|
||||
let scrollView = XSScrollView()
|
||||
return scrollView
|
||||
}()
|
||||
|
||||
private lazy var headerView: XSCoinsPackHeaderView = {
|
||||
let view = XSCoinsPackHeaderView()
|
||||
return view
|
||||
}()
|
||||
|
||||
private lazy var stackView: UIStackView = {
|
||||
let stackView = UIStackView()
|
||||
stackView.axis = .vertical
|
||||
stackView.spacing = 10
|
||||
return stackView
|
||||
}()
|
||||
|
||||
private lazy var buyView: XSCoinsPackBuyView = {
|
||||
let view = XSCoinsPackBuyView()
|
||||
view.buyFinishHandle = { [weak self] in
|
||||
self?.requestCoinsPackData()
|
||||
}
|
||||
return view
|
||||
}()
|
||||
|
||||
private lazy var tipView: UIView = {
|
||||
let view = UIView()
|
||||
view.addSubview(tipTitleLabel)
|
||||
view.addSubview(tipTextLabel)
|
||||
|
||||
tipTitleLabel.snp.makeConstraints { make in
|
||||
make.top.equalToSuperview()
|
||||
make.left.equalToSuperview().offset(16)
|
||||
}
|
||||
|
||||
tipTextLabel.snp.makeConstraints { make in
|
||||
make.left.equalToSuperview().offset(16)
|
||||
make.right.lessThanOrEqualToSuperview().offset(-16)
|
||||
make.top.equalTo(tipTitleLabel.snp.bottom).offset(4)
|
||||
make.bottom.equalToSuperview()
|
||||
}
|
||||
return view
|
||||
}()
|
||||
|
||||
private lazy var tipTitleLabel: UILabel = {
|
||||
let label = UILabel()
|
||||
label.font = .font(ofSize: 12, weight: .bold)
|
||||
label.textColor = .white.withAlphaComponent(0.5)
|
||||
label.text = "coins_pack_tips_title".localized
|
||||
return label
|
||||
}()
|
||||
|
||||
private lazy var tipTextLabel: UILabel = {
|
||||
let att = NSMutableAttributedString(string: "coins_pack_tips".localized)
|
||||
att.yy_lineSpacing = 3
|
||||
|
||||
let label = UILabel()
|
||||
label.font = .font(ofSize: 12, weight: .regular)
|
||||
label.textColor = .white.withAlphaComponent(0.5)
|
||||
label.attributedText = att
|
||||
label.numberOfLines = 0
|
||||
return label
|
||||
}()
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
self.title = "My Refills".localized
|
||||
|
||||
self.payDataModel = XSIapManager.manager.payDateModel
|
||||
|
||||
xs_setupUI()
|
||||
|
||||
self.requestCoinsPackData()
|
||||
|
||||
self.reloadData()
|
||||
}
|
||||
|
||||
|
||||
@ -42,8 +136,26 @@ class XSCoinsPackViewController: XSViewController {
|
||||
override func viewWillLayoutSubviews() {
|
||||
super.viewWillLayoutSubviews()
|
||||
|
||||
guard let borderImage = contentBgBorderImage?.xs_resized(to: contentBgView.bounds.size) else { return }
|
||||
contentBgView.layer.borderColor = UIColor(patternImage: borderImage).cgColor
|
||||
|
||||
}
|
||||
|
||||
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
|
||||
if keyPath == "bounds" {
|
||||
guard let borderImage = contentBgBorderImage?.xs_resized(to: contentBgView.bounds.size) else { return }
|
||||
contentBgView.layer.borderColor = UIColor(patternImage: borderImage).cgColor
|
||||
}
|
||||
}
|
||||
|
||||
private func reloadData() {
|
||||
stackView.xs_removeAllArrangedSubview()
|
||||
|
||||
// if self.claimView.dataArr.count > 0 {
|
||||
// stackView.addArrangedSubview(self.claimView)
|
||||
// } else if self.buyView.dataArr.count > 0 {
|
||||
stackView.addArrangedSubview(self.buyView)
|
||||
// }
|
||||
|
||||
stackView.addArrangedSubview(tipView)
|
||||
}
|
||||
|
||||
}
|
||||
@ -53,7 +165,11 @@ extension XSCoinsPackViewController {
|
||||
|
||||
private func xs_setupUI() {
|
||||
view.addSubview(mainBgView)
|
||||
view.addSubview(calendarImageView)
|
||||
view.addSubview(contentBgView)
|
||||
contentBgView.addSubview(scrollView)
|
||||
scrollView.addSubview(headerView)
|
||||
scrollView.addSubview(stackView)
|
||||
|
||||
mainBgView.snp.makeConstraints { make in
|
||||
make.edges.equalToSuperview()
|
||||
@ -63,22 +179,67 @@ extension XSCoinsPackViewController {
|
||||
make.left.right.bottom.equalToSuperview()
|
||||
make.top.equalTo(self.view.safeAreaLayoutGuide)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private extension UIImage {
|
||||
|
||||
func xs_flippedVertically() -> UIImage {
|
||||
let format = UIGraphicsImageRendererFormat.default()
|
||||
format.scale = scale
|
||||
format.opaque = false
|
||||
|
||||
return UIGraphicsImageRenderer(size: size, format: format).image { context in
|
||||
let cgContext = context.cgContext
|
||||
cgContext.translateBy(x: 0, y: size.height)
|
||||
cgContext.scaleBy(x: 1, y: -1)
|
||||
draw(in: CGRect(origin: .zero, size: size))
|
||||
|
||||
calendarImageView.snp.makeConstraints { make in
|
||||
make.top.equalToSuperview()
|
||||
make.right.equalToSuperview()
|
||||
}
|
||||
|
||||
scrollView.snp.makeConstraints { make in
|
||||
make.left.right.bottom.equalToSuperview()
|
||||
make.top.equalToSuperview().offset(10)
|
||||
}
|
||||
|
||||
headerView.snp.makeConstraints { make in
|
||||
make.left.centerX.equalToSuperview()
|
||||
make.top.equalToSuperview().offset(12)
|
||||
}
|
||||
|
||||
stackView.snp.makeConstraints { make in
|
||||
make.left.centerX.equalToSuperview()
|
||||
make.top.equalTo(headerView.snp.bottom).offset(16)
|
||||
make.bottom.equalToSuperview().offset(-(XSScreen.safeBottom + 10))
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension XSCoinsPackViewController {
|
||||
|
||||
private func requestCoinsPackData() {
|
||||
Task {
|
||||
guard let model = await XSStoreAPI.requestCoinsPackData() else { return }
|
||||
self.model = model
|
||||
|
||||
if (model.receive_list?.count ?? 0) == 0 {
|
||||
self.requestPayData()
|
||||
}
|
||||
|
||||
self.reloadData()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private func requestPayData() {
|
||||
self.payDataRequest = XSPayDataRequest()
|
||||
self.payDataRequest?.requestProducts { [weak self] model in
|
||||
guard let self = self else { return }
|
||||
guard let model = model else { return }
|
||||
self.payDataModel = model
|
||||
|
||||
self.reloadData()
|
||||
}
|
||||
}
|
||||
|
||||
// private func requestReceiveCoins(_ id: String?) {
|
||||
// FAStoreAPI.requestReceiveCoinsPackCoins(id: id) { [weak self] finish in
|
||||
// guard let self = self else { return }
|
||||
// self.requestCoinsPackData()
|
||||
// if finish {
|
||||
// self.showVideoRecommand()
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
|
||||
41
XSeri/Class/Store/Model/XSCoinsPackModel.swift
Normal file
@ -0,0 +1,41 @@
|
||||
//
|
||||
// XSCoinsPackModel.swift
|
||||
// XSeri
|
||||
//
|
||||
// Created by 长沙鸿瑶 on 2026/3/20.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import SmartCodable
|
||||
|
||||
struct XSCoinsPackModel: SmartCodable {
|
||||
//已领取累计金币总数
|
||||
var week_total: Int?
|
||||
//当前可领取订阅数
|
||||
var receive_count: Int?
|
||||
//订阅可领取累计金币总数
|
||||
var week_max_total: Int?
|
||||
//剩余可领取金币数
|
||||
var week_remaining_total: Int?
|
||||
//当前可领取金币总数
|
||||
var receive_coins: Int?
|
||||
|
||||
var receive_list: [XSCoinsPackReceiveModel]?
|
||||
}
|
||||
|
||||
|
||||
struct XSCoinsPackReceiveModel: SmartCodable {
|
||||
|
||||
var id: String?
|
||||
var title: String?
|
||||
//当前可领取金币数
|
||||
var receive_coins: Int?
|
||||
//可领取累计金币总数
|
||||
var week_max_total: Int?
|
||||
//已领取累计金币总数
|
||||
var week_total: Int?
|
||||
//领取天数文本
|
||||
var day_text: String?
|
||||
//剩余可领取金币数
|
||||
var week_remaining_total: Int?
|
||||
}
|
||||
140
XSeri/Class/Store/View/XSCoinsPackBuyView.swift
Normal file
@ -0,0 +1,140 @@
|
||||
//
|
||||
// XSCoinsPackBuyView.swift
|
||||
// XSeri
|
||||
//
|
||||
// Created by 长沙鸿瑶 on 2026/3/20.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import SnapKit
|
||||
|
||||
class XSCoinsPackBuyView: UIView {
|
||||
|
||||
var buyFinishHandle: (() -> Void)?
|
||||
|
||||
var dataArr: [XSPayItem] = [] {
|
||||
didSet {
|
||||
self.collectionView.reloadData()
|
||||
}
|
||||
}
|
||||
|
||||
private lazy var titleLabel: UILabel = {
|
||||
let label = UILabel()
|
||||
label.font = .font(ofSize: 14, weight: .bold).withBoldItalic()
|
||||
label.textColor = .FFDAA_4
|
||||
label.text = "Rewards Overview".localized
|
||||
return label
|
||||
}()
|
||||
|
||||
private lazy var titleLineView: UIView = {
|
||||
let view = UIImageView(image: UIImage(named: "coins_pack_line_image"))
|
||||
return view
|
||||
}()
|
||||
|
||||
private lazy var collectionViewLayout: UICollectionViewCompositionalLayout = {
|
||||
let config = UICollectionViewCompositionalLayoutConfiguration()
|
||||
config.interSectionSpacing = 12
|
||||
|
||||
let layout = UICollectionViewCompositionalLayout { [weak self] section, environment in
|
||||
guard let self = self else { return nil}
|
||||
return self.spreadLayoutSection(environment)
|
||||
}
|
||||
layout.configuration = config
|
||||
|
||||
return layout
|
||||
}()
|
||||
|
||||
private lazy var collectionView: XSCollectionView = {
|
||||
let collectionView = XSCollectionView(frame: .zero, collectionViewLayout: collectionViewLayout)
|
||||
collectionView.delegate = self
|
||||
collectionView.dataSource = self
|
||||
collectionView.isScrollEnabled = false
|
||||
collectionView.register(XSStoreCoinsSpreadCell.self, forCellWithReuseIdentifier: XSPayItem.SizeType.spread.rawValue)
|
||||
collectionView.addObserver(self, forKeyPath: "contentSize", context: nil)
|
||||
return collectionView
|
||||
}()
|
||||
|
||||
deinit {
|
||||
collectionView.removeObserver(self, forKeyPath: "contentSize")
|
||||
}
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
|
||||
xs_setupUI()
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
|
||||
if keyPath == "contentSize" {
|
||||
let height = self.collectionView.contentSize.height + 1
|
||||
self.collectionView.snp.updateConstraints { make in
|
||||
make.height.equalTo(height)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func spreadLayoutSection(_ environment: NSCollectionLayoutEnvironment) -> NSCollectionLayoutSection {
|
||||
let item = NSCollectionLayoutItem(layoutSize: .init(widthDimension: .fractionalWidth(1), heightDimension: .fractionalHeight(1)))
|
||||
|
||||
let group = NSCollectionLayoutGroup.horizontal(layoutSize: .init(widthDimension: .fractionalWidth(1), heightDimension: .absolute(84)), subitems: [item])
|
||||
|
||||
|
||||
let layoutSection = NSCollectionLayoutSection(group: group)
|
||||
layoutSection.interGroupSpacing = 12
|
||||
layoutSection.contentInsets = .zero
|
||||
return layoutSection
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
extension XSCoinsPackBuyView {
|
||||
|
||||
private func xs_setupUI() {
|
||||
addSubview(titleLabel)
|
||||
addSubview(titleLineView)
|
||||
addSubview(collectionView)
|
||||
|
||||
titleLabel.snp.makeConstraints { make in
|
||||
make.centerX.equalToSuperview()
|
||||
make.top.equalToSuperview()
|
||||
}
|
||||
|
||||
titleLineView.snp.makeConstraints { make in
|
||||
make.left.right.equalToSuperview().inset(28)
|
||||
make.top.equalTo(titleLabel.snp.bottom).offset(6)
|
||||
}
|
||||
|
||||
collectionView.snp.makeConstraints { make in
|
||||
make.left.right.equalToSuperview().inset(16)
|
||||
make.top.equalTo(titleLineView.snp.bottom).offset(16)
|
||||
make.bottom.equalToSuperview()
|
||||
make.height.equalTo(1)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//MARK: UICollectionViewDelegate & UICollectionViewDataSource
|
||||
extension XSCoinsPackBuyView: UICollectionViewDelegate, UICollectionViewDataSource {
|
||||
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
|
||||
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: XSPayItem.SizeType.spread.rawValue, for: indexPath) as! XSStoreCoinsSpreadCell
|
||||
cell.item = self.dataArr[indexPath.row]
|
||||
return cell
|
||||
}
|
||||
|
||||
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
|
||||
return self.dataArr.count
|
||||
}
|
||||
|
||||
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
|
||||
let item = self.dataArr[indexPath.row]
|
||||
let view = XSCoinsPackConfirmView()
|
||||
view.item = item
|
||||
view.present(in: nil)
|
||||
}
|
||||
}
|
||||
75
XSeri/Class/Store/View/XSCoinsPackConfirmItem1View.swift
Normal file
@ -0,0 +1,75 @@
|
||||
//
|
||||
// XSCoinsPackConfirmItem1View.swift
|
||||
// XSeri
|
||||
//
|
||||
// Created by 长沙鸿瑶 on 2026/3/21.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import SnapKit
|
||||
|
||||
class XSCoinsPackConfirmItem1View: UIView {
|
||||
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
|
||||
let view1 = getItemView(image: UIImage(named: "gift_icon_02"), text: "Weekly Refill Package".localized)
|
||||
let view2 = getItemView(image: UIImage(named: "calendar_icon_03"), text: "Daily Bonuses".localized)
|
||||
|
||||
addSubview(view1)
|
||||
addSubview(view2)
|
||||
|
||||
view1.snp.makeConstraints { make in
|
||||
make.left.equalToSuperview().offset(14)
|
||||
make.top.equalToSuperview()
|
||||
make.height.equalTo(83)
|
||||
make.bottom.equalToSuperview()
|
||||
}
|
||||
|
||||
view2.snp.makeConstraints { make in
|
||||
make.left.equalTo(view1.snp.right).offset(5)
|
||||
make.right.equalToSuperview().offset(-14)
|
||||
make.width.height.top.equalTo(view1)
|
||||
}
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
private func getItemView(image: UIImage?, text: String) -> UIView {
|
||||
let view = UIView()
|
||||
view.backgroundColor = .FBB_4_FF.withAlphaComponent(0.18)
|
||||
view.layer.cornerRadius = 8
|
||||
view.layer.masksToBounds = true
|
||||
|
||||
let imageView = UIImageView(image: image)
|
||||
imageView.setContentHuggingPriority(.required, for: .horizontal)
|
||||
imageView.setContentCompressionResistancePriority(.required, for: .horizontal)
|
||||
|
||||
let label = UILabel()
|
||||
label.numberOfLines = 0
|
||||
label.font = .font(ofSize: 12, weight: .bold)
|
||||
label.textColor = .white
|
||||
label.text = text
|
||||
|
||||
|
||||
view.addSubview(imageView)
|
||||
view.addSubview(label)
|
||||
|
||||
imageView.snp.makeConstraints { make in
|
||||
make.centerY.equalToSuperview()
|
||||
make.left.equalToSuperview().offset(10)
|
||||
}
|
||||
|
||||
label.snp.makeConstraints { make in
|
||||
make.centerY.equalToSuperview()
|
||||
make.left.equalTo(imageView.snp.right).offset(10)
|
||||
make.right.lessThanOrEqualToSuperview().offset(-8)
|
||||
}
|
||||
|
||||
return view
|
||||
}
|
||||
|
||||
}
|
||||
136
XSeri/Class/Store/View/XSCoinsPackConfirmItem2View.swift
Normal file
@ -0,0 +1,136 @@
|
||||
//
|
||||
// XSCoinsPackConfirmItem2View.swift
|
||||
// XSeri
|
||||
//
|
||||
// Created by 长沙鸿瑶 on 2026/3/21.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import SnapKit
|
||||
|
||||
class XSCoinsPackConfirmItem2View: UIView {
|
||||
|
||||
var list: [String]? {
|
||||
didSet {
|
||||
|
||||
self.stackView.xs_removeAllArrangedSubview()
|
||||
|
||||
list?.forEach {
|
||||
let view = XSCoinsPackConfirmItem2View.ItemView()
|
||||
view.text = $0
|
||||
self.stackView.addArrangedSubview(view)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private lazy var titleLabel: UILabel = {
|
||||
let label = UILabel()
|
||||
label.font = .font(ofSize: 18, weight: .bold)
|
||||
label.textColor = .FFDAA_4
|
||||
label.text = "coin_pack_buy_tip_title".localized
|
||||
return label
|
||||
}()
|
||||
|
||||
private lazy var lineView: UIView = {
|
||||
let view = UIImageView(image: UIImage(named: "coins_pack_line_image"))
|
||||
return view
|
||||
}()
|
||||
|
||||
private lazy var stackView: UIStackView = {
|
||||
let view = UIStackView()
|
||||
view.axis = .vertical
|
||||
view.spacing = 24
|
||||
return view
|
||||
}()
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
xs_setupUI()
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension XSCoinsPackConfirmItem2View {
|
||||
|
||||
private func xs_setupUI() {
|
||||
addSubview(titleLabel)
|
||||
addSubview(lineView)
|
||||
addSubview(stackView)
|
||||
|
||||
titleLabel.snp.makeConstraints { make in
|
||||
make.centerX.equalToSuperview()
|
||||
make.top.equalToSuperview()
|
||||
make.right.lessThanOrEqualToSuperview().offset(14)
|
||||
}
|
||||
|
||||
lineView.snp.makeConstraints { make in
|
||||
make.left.right.equalToSuperview().inset(10)
|
||||
make.top.equalToSuperview().offset(40)
|
||||
// make.bottom.equalToSuperview()
|
||||
}
|
||||
|
||||
stackView.snp.makeConstraints { make in
|
||||
make.left.equalToSuperview().offset(16)
|
||||
make.centerX.equalToSuperview()
|
||||
make.top.equalTo(lineView.snp.bottom).offset(16)
|
||||
make.bottom.equalToSuperview()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension XSCoinsPackConfirmItem2View {
|
||||
|
||||
class ItemView: UIView {
|
||||
var text: String? {
|
||||
didSet {
|
||||
textLabel.text = text
|
||||
}
|
||||
}
|
||||
|
||||
private lazy var iconImageView: UIImageView = {
|
||||
let imageView = UIImageView(image: UIImage(named: "coins_icon_07"))
|
||||
return imageView
|
||||
}()
|
||||
|
||||
private lazy var textLabel: UILabel = {
|
||||
let label = UILabel()
|
||||
label.font = .font(ofSize: 14, weight: .regular)
|
||||
label.textColor = .white
|
||||
label.numberOfLines = 0
|
||||
return label
|
||||
}()
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
|
||||
addSubview(iconImageView)
|
||||
addSubview(textLabel)
|
||||
|
||||
iconImageView.snp.makeConstraints { make in
|
||||
make.left.equalToSuperview()
|
||||
make.top.equalToSuperview()
|
||||
}
|
||||
|
||||
textLabel.snp.makeConstraints { make in
|
||||
make.left.equalTo(iconImageView.snp.right).offset(12)
|
||||
make.right.lessThanOrEqualToSuperview()
|
||||
make.top.equalToSuperview()
|
||||
make.bottom.equalToSuperview()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
251
XSeri/Class/Store/View/XSCoinsPackConfirmView.swift
Normal file
@ -0,0 +1,251 @@
|
||||
//
|
||||
// XSCoinsPackConfirmView.swift
|
||||
// XSeri
|
||||
//
|
||||
// Created by 长沙鸿瑶 on 2026/3/21.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import SnapKit
|
||||
import HWPanModal
|
||||
|
||||
class XSCoinsPackConfirmView: XSPanModalContentView {
|
||||
|
||||
var buyFinishHandle: (() -> Void)?
|
||||
|
||||
var shortPlayId: String?
|
||||
var videoId: String?
|
||||
|
||||
var item: XSPayItem? {
|
||||
didSet {
|
||||
item2View.list = item?.ext_info?.sub_coins_txt_list
|
||||
|
||||
var price = item?.price ?? ""
|
||||
if let discount_price = item?.discount_price {
|
||||
price = discount_price
|
||||
}
|
||||
|
||||
priceLabel.text = "\(item?.currency ?? "")\(price)/\(item?.getTimeString() ?? "")"
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private let bgBorderImage = UIImage(named: "gradient_color_image_03")?.xs_flippedVertically()
|
||||
|
||||
private lazy var bgView: UIImageView = {
|
||||
let view = UIImageView(image: UIImage(named: "coins_pack_bg_03"))
|
||||
view.isUserInteractionEnabled = true
|
||||
view.layer.cornerRadius = 26
|
||||
view.layer.masksToBounds = true
|
||||
view.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner]
|
||||
view.layer.borderWidth = 1
|
||||
view.addObserver(self, forKeyPath: "bounds", context: nil)
|
||||
return view
|
||||
}()
|
||||
|
||||
private lazy var titleLabel: UILabel = {
|
||||
let label = UILabel()
|
||||
label.font = .font(ofSize: 24, weight: .bold)
|
||||
label.textColor = .FFDAA_4
|
||||
label.text = "What You Get".localized
|
||||
return label
|
||||
}()
|
||||
|
||||
private lazy var closeButton: UIButton = {
|
||||
let button = UIButton(type: .custom, primaryAction: UIAction(handler: { [weak self] _ in
|
||||
guard let self = self else { return }
|
||||
self.dismiss(animated: true) {
|
||||
|
||||
}
|
||||
}))
|
||||
button.setImage(UIImage(named: "close_icon_03"), for: .normal)
|
||||
return button
|
||||
}()
|
||||
|
||||
private lazy var scrollView: XSScrollView = {
|
||||
let scrollView = XSScrollView()
|
||||
scrollView.addObserver(self, forKeyPath: "contentSize", context: nil)
|
||||
return scrollView
|
||||
}()
|
||||
|
||||
private lazy var contentTitleView: UIView = {
|
||||
let view = UIImageView(image: UIImage(named: "coins_pack_confirm_title_bg"))
|
||||
return view
|
||||
}()
|
||||
|
||||
private lazy var contentTitleLabel: UILabel = {
|
||||
let label = UILabel()
|
||||
label.font = .font(ofSize: 14, weight: .bold).withBoldItalic()
|
||||
label.textColor = ._5_B_2300
|
||||
label.text = "Bonus You Get".localized
|
||||
return label
|
||||
}()
|
||||
|
||||
private lazy var contentView: UIView = {
|
||||
let view = UIView()
|
||||
view.layer.cornerRadius = 18
|
||||
view.layer.masksToBounds = true
|
||||
view.backgroundColor = .F_08_FFF.withAlphaComponent(0.1)
|
||||
return view
|
||||
}()
|
||||
|
||||
private lazy var item1View: XSCoinsPackConfirmItem1View = {
|
||||
let view = XSCoinsPackConfirmItem1View()
|
||||
return view
|
||||
}()
|
||||
|
||||
private lazy var item2View: XSCoinsPackConfirmItem2View = {
|
||||
let view = XSCoinsPackConfirmItem2View()
|
||||
return view
|
||||
}()
|
||||
|
||||
private lazy var priceLabel: UILabel = {
|
||||
let label = UILabel()
|
||||
label.font = .font(ofSize: 18, weight: .bold)
|
||||
label.textColor = .FFE_17_D
|
||||
return label
|
||||
}()
|
||||
|
||||
private lazy var continueBgView: UIView = {
|
||||
let view = XSView()
|
||||
view.xs_colors = [UIColor.F_5_BD_7_E.cgColor, UIColor.FFEABC.cgColor, UIColor.FFCF_99.cgColor]
|
||||
view.xs_startPoint = .init(x: 0, y: 0.5)
|
||||
view.xs_endPoint = .init(x: 1, y: 0.5)
|
||||
return view
|
||||
}()
|
||||
|
||||
private lazy var continueButton: UIButton = {
|
||||
var configuration = UIButton.Configuration.plain()
|
||||
configuration.background.customView = continueBgView
|
||||
configuration.background.cornerRadius = 24
|
||||
configuration.attributedTitle = AttributedString("Continue".localized, attributes: AttributeContainer([
|
||||
.font : UIFont.font(ofSize: 18, weight: .bold),
|
||||
.foregroundColor : UIColor._763200
|
||||
]))
|
||||
let button = UIButton(configuration: configuration, primaryAction: UIAction(handler: { [weak self] _ in
|
||||
guard let self = self else { return }
|
||||
}))
|
||||
return button
|
||||
}()
|
||||
|
||||
deinit {
|
||||
self.bgView.removeObserver(self, forKeyPath: "bounds")
|
||||
self.scrollView.removeObserver(self, forKeyPath: "contentSize")
|
||||
}
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
// self.contentHeight = 300
|
||||
|
||||
xs_setupUI()
|
||||
}
|
||||
|
||||
@MainActor required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
|
||||
if keyPath == "bounds" {
|
||||
guard let borderImage = bgBorderImage?.xs_resized(to: bgView.bounds.size) else { return }
|
||||
bgView.layer.borderColor = UIColor(patternImage: borderImage).cgColor
|
||||
|
||||
} else if keyPath == "contentSize" {
|
||||
self.setNeedsLayoutUpdate()
|
||||
|
||||
let height = self.scrollView.contentSize.height
|
||||
scrollView.snp.updateConstraints { make in
|
||||
make.height.equalTo(height + 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override func allowsTapBackgroundToDismiss() -> Bool {
|
||||
return false
|
||||
}
|
||||
|
||||
override func cornerRadius() -> CGFloat {
|
||||
return 0
|
||||
}
|
||||
|
||||
override func longFormHeight() -> PanModalHeight {
|
||||
let height = 78 + scrollView.contentSize.height + 92 + 10
|
||||
return PanModalHeightMake(.content, height + XSScreen.safeBottom)
|
||||
}
|
||||
}
|
||||
|
||||
extension XSCoinsPackConfirmView {
|
||||
|
||||
private func xs_setupUI() {
|
||||
addSubview(bgView)
|
||||
addSubview(titleLabel)
|
||||
addSubview(closeButton)
|
||||
addSubview(scrollView)
|
||||
scrollView.addSubview(contentView)
|
||||
scrollView.addSubview(contentTitleView)
|
||||
contentTitleView.addSubview(contentTitleLabel)
|
||||
contentView.addSubview(item1View)
|
||||
contentView.addSubview(item2View)
|
||||
addSubview(priceLabel)
|
||||
addSubview(continueButton)
|
||||
|
||||
bgView.snp.makeConstraints { make in
|
||||
make.edges.equalToSuperview()
|
||||
}
|
||||
|
||||
titleLabel.snp.makeConstraints { make in
|
||||
make.centerX.equalToSuperview()
|
||||
make.top.equalToSuperview().offset(30)
|
||||
}
|
||||
|
||||
closeButton.snp.makeConstraints { make in
|
||||
make.right.equalToSuperview().offset(-16)
|
||||
make.top.equalToSuperview().offset(24)
|
||||
}
|
||||
|
||||
scrollView.snp.makeConstraints { make in
|
||||
make.left.right.equalToSuperview()
|
||||
make.top.equalToSuperview().offset(78)
|
||||
make.height.equalTo(1)
|
||||
}
|
||||
|
||||
contentView.snp.makeConstraints { make in
|
||||
make.left.equalToSuperview().offset(16)
|
||||
make.centerX.equalToSuperview()
|
||||
make.top.equalToSuperview().offset(7)
|
||||
make.bottom.equalToSuperview()
|
||||
}
|
||||
|
||||
contentTitleView.snp.makeConstraints { make in
|
||||
make.centerX.equalToSuperview()
|
||||
make.top.equalToSuperview()
|
||||
}
|
||||
|
||||
contentTitleLabel.snp.makeConstraints { make in
|
||||
make.centerX.equalToSuperview()
|
||||
make.left.equalToSuperview().offset(28)
|
||||
make.top.equalToSuperview().offset(9)
|
||||
}
|
||||
|
||||
item1View.snp.makeConstraints { make in
|
||||
make.left.right.equalToSuperview()
|
||||
make.top.equalToSuperview().offset(46)
|
||||
}
|
||||
|
||||
item2View.snp.makeConstraints { make in
|
||||
make.left.right.equalToSuperview()
|
||||
make.top.equalTo(item1View.snp.bottom).offset(24)
|
||||
make.bottom.equalToSuperview().offset(-40)
|
||||
}
|
||||
|
||||
priceLabel.snp.makeConstraints { make in
|
||||
make.centerX.equalToSuperview()
|
||||
make.centerY.equalTo(scrollView.snp.bottom).offset(22)
|
||||
}
|
||||
|
||||
continueButton.snp.makeConstraints { make in
|
||||
make.left.right.equalToSuperview().inset(16)
|
||||
make.bottom.equalToSuperview().offset(-(10 + XSScreen.safeBottom))
|
||||
make.height.equalTo(48)
|
||||
}
|
||||
}
|
||||
}
|
||||
275
XSeri/Class/Store/View/XSCoinsPackHeaderView.swift
Normal file
@ -0,0 +1,275 @@
|
||||
//
|
||||
// XSCoinsPackHeaderView.swift
|
||||
// XSeri
|
||||
//
|
||||
// Created by 长沙鸿瑶 on 2026/3/20.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import SnapKit
|
||||
|
||||
class XSCoinsPackHeaderView: UIView {
|
||||
|
||||
var model: XSCoinsPackModel? {
|
||||
didSet {
|
||||
coinsView1.coins = model?.week_max_total
|
||||
coinsView2.coins = model?.week_total
|
||||
|
||||
|
||||
let activeRefillsStr = NSMutableAttributedString(string: "Active Refills:".localized + " ")
|
||||
activeRefillsStr.yy_font = .font(ofSize: 12, weight: .regular)
|
||||
activeRefillsStr.yy_color = .white.withAlphaComponent(0.5)
|
||||
|
||||
let activeRefillsCount = NSMutableAttributedString(string: "\(model?.receive_count ?? 0)")
|
||||
activeRefillsCount.yy_font = .font(ofSize: 12, weight: .medium)
|
||||
activeRefillsCount.yy_color = .white
|
||||
activeRefillsStr.append(activeRefillsCount)
|
||||
activeRefillsLabel.attributedText = activeRefillsStr
|
||||
|
||||
if let coin = model?.receive_coins, coin > 0 {
|
||||
claimButton.isEnabled = true
|
||||
} else {
|
||||
claimButton.isEnabled = false
|
||||
}
|
||||
|
||||
claimButton.setNeedsUpdateConfiguration()
|
||||
}
|
||||
}
|
||||
|
||||
private lazy var titleLabel: UILabel = {
|
||||
let label = UILabel()
|
||||
label.font = .font(ofSize: 14, weight: .bold).withBoldItalic()
|
||||
label.textColor = .FFDAA_4
|
||||
label.text = "Rewards Overview".localized
|
||||
return label
|
||||
}()
|
||||
|
||||
private lazy var titleLineView: UIView = {
|
||||
let view = UIImageView(image: UIImage(named: "coins_pack_line_image"))
|
||||
return view
|
||||
}()
|
||||
|
||||
private lazy var coinsView1: CoinsView = {
|
||||
let view = CoinsView()
|
||||
view.title = "Weekly Total".localized
|
||||
view.coins = 0
|
||||
return view
|
||||
}()
|
||||
|
||||
private lazy var coinsView2: CoinsView = {
|
||||
let view = CoinsView()
|
||||
view.title = "Claimable Coins".localized
|
||||
view.coins = 0
|
||||
return view
|
||||
}()
|
||||
|
||||
private lazy var coinsLineView: UIView = {
|
||||
let view = UIImageView(image: UIImage(named: "line_image_01"))
|
||||
return view
|
||||
}()
|
||||
|
||||
private lazy var activeRefillsLabel: UILabel = {
|
||||
let label = UILabel()
|
||||
return label
|
||||
}()
|
||||
|
||||
private lazy var claimButton: UIButton = {
|
||||
var config = UIButton.Configuration.plain()
|
||||
config.background.customView = self.buttonBgView
|
||||
config.background.cornerRadius = 24
|
||||
|
||||
let button = UIButton(configuration: config, primaryAction: UIAction(handler: { [weak self] _ in
|
||||
// self?.clickClaimButton?()
|
||||
self?.claimButton.isEnabled = false
|
||||
}))
|
||||
button.isEnabled = false
|
||||
button.configurationUpdateHandler = { [weak self] button in
|
||||
guard let self = self else { return }
|
||||
if button.isEnabled {
|
||||
self.buttonBgView.xs_colors = [UIColor.F_5_BD_7_E.cgColor, UIColor.FFEABC.cgColor, UIColor.FFCF_99.cgColor]
|
||||
|
||||
let coinImage = UIImage(named: "coins_icon_01")!
|
||||
let coinText = NSTextAttachment(image: coinImage)
|
||||
coinText.bounds = .init(x: 0, y: -2.5, width: coinImage.size.width, height: coinImage.size.height)
|
||||
let coinAtt = AttributedString(NSAttributedString(attachment: coinText))
|
||||
|
||||
let textAtt = AttributedString("Claim All".localized + " ", attributes: AttributeContainer([
|
||||
.font : UIFont.font(ofSize: 14, weight: .bold),
|
||||
.foregroundColor : UIColor._763200
|
||||
]))
|
||||
|
||||
// let countAtt = AttributedString(" \(self.model?.receive_coins ?? 0)".localized, attributes: AttributeContainer([
|
||||
// .font : UIFont.font(ofSize: 14, weight: .bold),
|
||||
// .foregroundColor : UIColor.FFFFFF
|
||||
// ]))
|
||||
let countAtt = AttributedString(" 10".localized, attributes: AttributeContainer([
|
||||
.font : UIFont.font(ofSize: 14, weight: .bold),
|
||||
.foregroundColor : UIColor.FF_7700
|
||||
]))
|
||||
|
||||
button.configuration?.attributedTitle = textAtt + coinAtt + countAtt
|
||||
|
||||
|
||||
} else {
|
||||
self.buttonBgView.xs_colors = [UIColor._616161.cgColor, UIColor._616161.cgColor, UIColor._616161.cgColor]
|
||||
|
||||
button.configuration?.attributedTitle = AttributedString("Get a Refill to Claim".localized, attributes: AttributeContainer([
|
||||
.font : UIFont.font(ofSize: 14, weight: .bold),
|
||||
.foregroundColor : UIColor.white.withAlphaComponent(0.5)
|
||||
]))
|
||||
}
|
||||
|
||||
}
|
||||
return button
|
||||
}()
|
||||
|
||||
private lazy var buttonBgView: XSView = {
|
||||
let view = XSView()
|
||||
view.xs_startPoint = .init(x: 0, y: 0.5)
|
||||
view.xs_endPoint = .init(x: 1, y: 0.5)
|
||||
return view
|
||||
}()
|
||||
|
||||
private lazy var lineView: UIView = {
|
||||
let view = UIImageView(image: UIImage(named: "line_image_02"))
|
||||
return view
|
||||
}()
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
|
||||
xs_setupUI()
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension XSCoinsPackHeaderView {
|
||||
|
||||
private func xs_setupUI() {
|
||||
addSubview(titleLabel)
|
||||
addSubview(titleLineView)
|
||||
addSubview(coinsLineView)
|
||||
addSubview(coinsView1)
|
||||
addSubview(coinsView2)
|
||||
addSubview(activeRefillsLabel)
|
||||
addSubview(claimButton)
|
||||
addSubview(lineView)
|
||||
|
||||
titleLabel.snp.makeConstraints { make in
|
||||
make.centerX.equalToSuperview()
|
||||
make.top.equalToSuperview()
|
||||
}
|
||||
|
||||
titleLineView.snp.makeConstraints { make in
|
||||
make.left.right.equalToSuperview().inset(28)
|
||||
make.top.equalTo(titleLabel.snp.bottom).offset(6)
|
||||
}
|
||||
|
||||
coinsLineView.snp.makeConstraints { make in
|
||||
make.centerX.equalToSuperview()
|
||||
make.top.equalTo(titleLineView.snp.bottom).offset(27)
|
||||
}
|
||||
|
||||
coinsView1.snp.makeConstraints { make in
|
||||
make.centerY.equalTo(coinsLineView)
|
||||
make.right.equalTo(coinsLineView.snp.left).offset(-18)
|
||||
}
|
||||
|
||||
coinsView2.snp.makeConstraints { make in
|
||||
make.centerY.equalTo(coinsLineView)
|
||||
make.left.equalTo(coinsLineView.snp.right).offset(18)
|
||||
}
|
||||
|
||||
activeRefillsLabel.snp.makeConstraints { make in
|
||||
make.centerX.equalToSuperview()
|
||||
make.top.equalTo(coinsLineView.snp.bottom).offset(25)
|
||||
}
|
||||
|
||||
claimButton.snp.makeConstraints { make in
|
||||
make.left.equalToSuperview().offset(28)
|
||||
make.centerX.equalToSuperview()
|
||||
make.top.equalTo(activeRefillsLabel.snp.bottom).offset(12)
|
||||
make.height.equalTo(48)
|
||||
}
|
||||
|
||||
lineView.snp.makeConstraints { make in
|
||||
make.left.right.equalToSuperview().inset(28)
|
||||
make.top.equalTo(claimButton.snp.bottom).offset(16)
|
||||
make.bottom.equalToSuperview()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
extension XSCoinsPackHeaderView {
|
||||
|
||||
class CoinsView: UIView {
|
||||
|
||||
var title: String? {
|
||||
didSet {
|
||||
titleLabel.text = title
|
||||
}
|
||||
}
|
||||
|
||||
var coins: Int? {
|
||||
didSet {
|
||||
coinsLabel.text = "\(coins ?? 0)"
|
||||
}
|
||||
}
|
||||
|
||||
private lazy var titleLabel: UILabel = {
|
||||
let label = UILabel()
|
||||
label.font = .font(ofSize: 12, weight: .bold)
|
||||
label.textColor = .white.withAlphaComponent(0.5)
|
||||
return label
|
||||
}()
|
||||
|
||||
private lazy var coinsIconImageView: UIImageView = {
|
||||
let imageView = UIImageView(image: UIImage(named: "coins_icon_06"))
|
||||
return imageView
|
||||
}()
|
||||
|
||||
private lazy var coinsLabel: UILabel = {
|
||||
let label = UILabel()
|
||||
label.font = .font(ofSize: 18, weight: .bold)
|
||||
label.textColor = .FFDAA_4
|
||||
return label
|
||||
}()
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
|
||||
addSubview(titleLabel)
|
||||
addSubview(coinsIconImageView)
|
||||
addSubview(coinsLabel)
|
||||
|
||||
titleLabel.snp.makeConstraints { make in
|
||||
make.left.equalToSuperview()
|
||||
make.top.equalToSuperview()
|
||||
make.right.lessThanOrEqualToSuperview()
|
||||
}
|
||||
|
||||
coinsIconImageView.snp.makeConstraints { make in
|
||||
make.left.bottom.equalToSuperview()
|
||||
make.top.equalTo(titleLabel.snp.bottom).offset(4)
|
||||
}
|
||||
|
||||
coinsLabel.snp.makeConstraints { make in
|
||||
make.left.equalTo(coinsIconImageView.snp.right).offset(4)
|
||||
make.centerY.equalTo(coinsIconImageView)
|
||||
make.right.lessThanOrEqualToSuperview()
|
||||
}
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
{
|
||||
"colors" : [
|
||||
{
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0x00",
|
||||
"green" : "0x23",
|
||||
"red" : "0x5B"
|
||||
}
|
||||
},
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
{
|
||||
"colors" : [
|
||||
{
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0x61",
|
||||
"green" : "0x61",
|
||||
"red" : "0x61"
|
||||
}
|
||||
},
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
{
|
||||
"colors" : [
|
||||
{
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0x00",
|
||||
"green" : "0x32",
|
||||
"red" : "0x76"
|
||||
}
|
||||
},
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
{
|
||||
"colors" : [
|
||||
{
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0x4B",
|
||||
"green" : "0x05",
|
||||
"red" : "0xB4"
|
||||
}
|
||||
},
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
{
|
||||
"colors" : [
|
||||
{
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0x7F",
|
||||
"green" : "0x3B",
|
||||
"red" : "0xE4"
|
||||
}
|
||||
},
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
{
|
||||
"colors" : [
|
||||
{
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0xFF",
|
||||
"green" : "0x8F",
|
||||
"red" : "0xF0"
|
||||
}
|
||||
},
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
{
|
||||
"colors" : [
|
||||
{
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0xFF",
|
||||
"green" : "0xB4",
|
||||
"red" : "0xFB"
|
||||
}
|
||||
},
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
{
|
||||
"colors" : [
|
||||
{
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0x00",
|
||||
"green" : "0x77",
|
||||
"red" : "0xFF"
|
||||
}
|
||||
},
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
{
|
||||
"colors" : [
|
||||
{
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0x7D",
|
||||
"green" : "0xE1",
|
||||
"red" : "0xFF"
|
||||
}
|
||||
},
|
||||
"idiom" : "universal"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
@ -5,27 +5,9 @@
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0xFF",
|
||||
"green" : "0xFF",
|
||||
"red" : "0xFE"
|
||||
}
|
||||
},
|
||||
"idiom" : "universal"
|
||||
},
|
||||
{
|
||||
"appearances" : [
|
||||
{
|
||||
"appearance" : "luminosity",
|
||||
"value" : "dark"
|
||||
}
|
||||
],
|
||||
"color" : {
|
||||
"color-space" : "srgb",
|
||||
"components" : {
|
||||
"alpha" : "1.000",
|
||||
"blue" : "0xFF",
|
||||
"green" : "0xFF",
|
||||
"red" : "0xFE"
|
||||
"blue" : "0xB3",
|
||||
"green" : "0xE6",
|
||||
"red" : "0xFF"
|
||||
}
|
||||
},
|
||||
"idiom" : "universal"
|
||||
|
||||
22
XSeri/Source/Assets.xcassets/Image/icon/calendar_icon_02.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"filename" : "配图@2x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "配图@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
BIN
XSeri/Source/Assets.xcassets/Image/icon/calendar_icon_02.imageset/配图@2x.png
vendored
Normal file
|
After Width: | Height: | Size: 56 KiB |
BIN
XSeri/Source/Assets.xcassets/Image/icon/calendar_icon_02.imageset/配图@3x.png
vendored
Normal file
|
After Width: | Height: | Size: 112 KiB |
22
XSeri/Source/Assets.xcassets/Image/icon/calendar_icon_03.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"filename" : "calendar_icon_03@2x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "calendar_icon_03@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
BIN
XSeri/Source/Assets.xcassets/Image/icon/calendar_icon_03.imageset/calendar_icon_03@2x.png
vendored
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
XSeri/Source/Assets.xcassets/Image/icon/calendar_icon_03.imageset/calendar_icon_03@3x.png
vendored
Normal file
|
After Width: | Height: | Size: 23 KiB |
22
XSeri/Source/Assets.xcassets/Image/icon/close_icon_03.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"filename" : "Group 959@2x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "Group 959@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
BIN
XSeri/Source/Assets.xcassets/Image/icon/close_icon_03.imageset/Group 959@2x.png
vendored
Normal file
|
After Width: | Height: | Size: 943 B |
BIN
XSeri/Source/Assets.xcassets/Image/icon/close_icon_03.imageset/Group 959@3x.png
vendored
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
22
XSeri/Source/Assets.xcassets/Image/icon/coins_icon_06.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"filename" : "查看图片 24@2x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "查看图片 24@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
BIN
XSeri/Source/Assets.xcassets/Image/icon/coins_icon_06.imageset/查看图片 24@2x.png
vendored
Normal file
|
After Width: | Height: | Size: 3.5 KiB |
BIN
XSeri/Source/Assets.xcassets/Image/icon/coins_icon_06.imageset/查看图片 24@3x.png
vendored
Normal file
|
After Width: | Height: | Size: 6.7 KiB |
22
XSeri/Source/Assets.xcassets/Image/icon/coins_icon_07.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"filename" : "coins_icon_07@2x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "coins_icon_07@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
BIN
XSeri/Source/Assets.xcassets/Image/icon/coins_icon_07.imageset/coins_icon_07@2x.png
vendored
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
BIN
XSeri/Source/Assets.xcassets/Image/icon/coins_icon_07.imageset/coins_icon_07@3x.png
vendored
Normal file
|
After Width: | Height: | Size: 5.3 KiB |
22
XSeri/Source/Assets.xcassets/Image/icon/coins_pack_bg_03.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"filename" : "bg@2x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "bg@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
BIN
XSeri/Source/Assets.xcassets/Image/icon/coins_pack_bg_03.imageset/bg@2x.png
vendored
Normal file
|
After Width: | Height: | Size: 40 KiB |
BIN
XSeri/Source/Assets.xcassets/Image/icon/coins_pack_bg_03.imageset/bg@3x.png
vendored
Normal file
|
After Width: | Height: | Size: 74 KiB |
44
XSeri/Source/Assets.xcassets/Image/icon/coins_pack_confirm_title_bg.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,44 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"filename" : "Frame 2085663266@2x.png",
|
||||
"idiom" : "universal",
|
||||
"resizing" : {
|
||||
"cap-insets" : {
|
||||
"left" : 57,
|
||||
"right" : 68
|
||||
},
|
||||
"center" : {
|
||||
"mode" : "tile",
|
||||
"width" : 1
|
||||
},
|
||||
"mode" : "3-part-horizontal"
|
||||
},
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "Frame 2085663266@3x.png",
|
||||
"idiom" : "universal",
|
||||
"resizing" : {
|
||||
"cap-insets" : {
|
||||
"left" : 81,
|
||||
"right" : 83
|
||||
},
|
||||
"center" : {
|
||||
"mode" : "tile",
|
||||
"width" : 1
|
||||
},
|
||||
"mode" : "3-part-horizontal"
|
||||
},
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
BIN
XSeri/Source/Assets.xcassets/Image/icon/coins_pack_confirm_title_bg.imageset/Frame 2085663266@2x.png
vendored
Normal file
|
After Width: | Height: | Size: 8.1 KiB |
BIN
XSeri/Source/Assets.xcassets/Image/icon/coins_pack_confirm_title_bg.imageset/Frame 2085663266@3x.png
vendored
Normal file
|
After Width: | Height: | Size: 14 KiB |
22
XSeri/Source/Assets.xcassets/Image/icon/coins_pack_line_image.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"filename" : "Line 13@2x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "Line 13@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
BIN
XSeri/Source/Assets.xcassets/Image/icon/coins_pack_line_image.imageset/Line 13@2x.png
vendored
Normal file
|
After Width: | Height: | Size: 318 B |
BIN
XSeri/Source/Assets.xcassets/Image/icon/coins_pack_line_image.imageset/Line 13@3x.png
vendored
Normal file
|
After Width: | Height: | Size: 403 B |
|
Before Width: | Height: | Size: 9.7 KiB After Width: | Height: | Size: 9.7 KiB |
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
22
XSeri/Source/Assets.xcassets/Image/icon/gift_icon_02.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"filename" : "gift_icon_02@2x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "gift_icon_02@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
BIN
XSeri/Source/Assets.xcassets/Image/icon/gift_icon_02.imageset/gift_icon_02@2x.png
vendored
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
XSeri/Source/Assets.xcassets/Image/icon/gift_icon_02.imageset/gift_icon_02@3x.png
vendored
Normal file
|
After Width: | Height: | Size: 21 KiB |
22
XSeri/Source/Assets.xcassets/Image/icon/line_image_01.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"filename" : "间隔线@2x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "间隔线@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
BIN
XSeri/Source/Assets.xcassets/Image/icon/line_image_01.imageset/间隔线@2x.png
vendored
Normal file
|
After Width: | Height: | Size: 170 B |
BIN
XSeri/Source/Assets.xcassets/Image/icon/line_image_01.imageset/间隔线@3x.png
vendored
Normal file
|
After Width: | Height: | Size: 184 B |
22
XSeri/Source/Assets.xcassets/Image/icon/line_image_02.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"filename" : "line_image_01@2x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "line_image_01@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
BIN
XSeri/Source/Assets.xcassets/Image/icon/line_image_02.imageset/line_image_01@2x.png
vendored
Normal file
|
After Width: | Height: | Size: 276 B |
BIN
XSeri/Source/Assets.xcassets/Image/icon/line_image_02.imageset/line_image_01@3x.png
vendored
Normal file
|
After Width: | Height: | Size: 334 B |
@ -74,10 +74,25 @@
|
||||
"Yearly VIP" = "Yearly VIP";
|
||||
"+ Extra ## Bonus" = "+ Extra ## Bonus";
|
||||
"My Refills" = "My Refills";
|
||||
"Rewards Overview" = "Rewards Overview";
|
||||
"Weekly Total" = "Weekly Total";
|
||||
"Claimable Coins" = "Claimable Coins";
|
||||
"Claim All" = "Claim All";
|
||||
"Get a Refill to Claim" = "Get a Refill to Claim";
|
||||
"Active Refills:" = "Active Refills:";
|
||||
"What You Get" = "What You Get";
|
||||
"Bonus You Get" = "Bonus You Get";
|
||||
"Weekly Refill Package" = "Weekly Refill Package";
|
||||
"Daily Bonuses" = "Daily Bonuses";
|
||||
"Continue" = "Continue";
|
||||
|
||||
"me_daily_1" = "Daily reward ready!";
|
||||
"me_daily_2" = "Claim your rewards now.";
|
||||
|
||||
"coins_pack_tips_title" = "Subscription Rules";
|
||||
"coins_pack_tips" = "1.Coins are delivered instantly upon purchase.<br>2.Daily bonus coins available from the next day.<br>3.All coins will be revoked when the subscription expires, including both initial and daily coins.";
|
||||
"coin_pack_buy_tip_title" = "How Do I Receive Coins?";
|
||||
|
||||
"empty_title_01" = "We couldn’t find any dramas";
|
||||
|
||||
"buy_fail_toast_01" = "Purchase failed, please try again later!";
|
||||
|
||||