vip弹窗

This commit is contained in:
zeng 2025-07-30 20:00:47 +08:00
parent dac985f177
commit 9a23f2cb2e
49 changed files with 745 additions and 52 deletions

View File

@ -152,6 +152,8 @@
BFC676B92E1385FC006659E5 /* BRPopularPicksSmallCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFC676B82E1385FC006659E5 /* BRPopularPicksSmallCell.swift */; }; BFC676B92E1385FC006659E5 /* BRPopularPicksSmallCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFC676B82E1385FC006659E5 /* BRPopularPicksSmallCell.swift */; };
BFC676BC2E138ABB006659E5 /* BRNewReleasesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFC676BB2E138ABB006659E5 /* BRNewReleasesViewController.swift */; }; BFC676BC2E138ABB006659E5 /* BRNewReleasesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFC676BB2E138ABB006659E5 /* BRNewReleasesViewController.swift */; };
BFC676BE2E13A8EB006659E5 /* UIScrollView+BRRefresh.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFC676BD2E13A8DD006659E5 /* UIScrollView+BRRefresh.swift */; }; BFC676BE2E13A8EB006659E5 /* UIScrollView+BRRefresh.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFC676BD2E13A8DD006659E5 /* UIScrollView+BRRefresh.swift */; };
F32BAEA92E3A173A00CC203C /* BRVipAlert.swift in Sources */ = {isa = PBXBuildFile; fileRef = F32BAEA82E3A173A00CC203C /* BRVipAlert.swift */; };
F32BAEAB2E3A1BF500CC203C /* BRVipAlertCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = F32BAEAA2E3A1BF500CC203C /* BRVipAlertCell.swift */; };
F39855202E32166300E2D28D /* BRFavoritesPageViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F398551F2E32166300E2D28D /* BRFavoritesPageViewController.swift */; }; F39855202E32166300E2D28D /* BRFavoritesPageViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F398551F2E32166300E2D28D /* BRFavoritesPageViewController.swift */; };
F39855222E32227D00E2D28D /* BRPlayHistorysViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F39855212E32227D00E2D28D /* BRPlayHistorysViewController.swift */; }; F39855222E32227D00E2D28D /* BRPlayHistorysViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F39855212E32227D00E2D28D /* BRPlayHistorysViewController.swift */; };
F39855242E3222BE00E2D28D /* BRPlayHistorysCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = F39855232E3222BE00E2D28D /* BRPlayHistorysCell.swift */; }; F39855242E3222BE00E2D28D /* BRPlayHistorysCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = F39855232E3222BE00E2D28D /* BRPlayHistorysCell.swift */; };
@ -380,6 +382,8 @@
BFC676BD2E13A8DD006659E5 /* UIScrollView+BRRefresh.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIScrollView+BRRefresh.swift"; sourceTree = "<group>"; }; BFC676BD2E13A8DD006659E5 /* UIScrollView+BRRefresh.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIScrollView+BRRefresh.swift"; sourceTree = "<group>"; };
C8F11086BA392585E9563BA7 /* Pods-ShortBox.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ShortBox.release.xcconfig"; path = "Target Support Files/Pods-ShortBox/Pods-ShortBox.release.xcconfig"; sourceTree = "<group>"; }; C8F11086BA392585E9563BA7 /* Pods-ShortBox.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ShortBox.release.xcconfig"; path = "Target Support Files/Pods-ShortBox/Pods-ShortBox.release.xcconfig"; sourceTree = "<group>"; };
F06627B1DEE86552C2A87AEC /* Pods-BeeReel.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-BeeReel.debug.xcconfig"; path = "Target Support Files/Pods-BeeReel/Pods-BeeReel.debug.xcconfig"; sourceTree = "<group>"; }; F06627B1DEE86552C2A87AEC /* Pods-BeeReel.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-BeeReel.debug.xcconfig"; path = "Target Support Files/Pods-BeeReel/Pods-BeeReel.debug.xcconfig"; sourceTree = "<group>"; };
F32BAEA82E3A173A00CC203C /* BRVipAlert.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRVipAlert.swift; sourceTree = "<group>"; };
F32BAEAA2E3A1BF500CC203C /* BRVipAlertCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRVipAlertCell.swift; sourceTree = "<group>"; };
F398551F2E32166300E2D28D /* BRFavoritesPageViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRFavoritesPageViewController.swift; sourceTree = "<group>"; }; F398551F2E32166300E2D28D /* BRFavoritesPageViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRFavoritesPageViewController.swift; sourceTree = "<group>"; };
F39855212E32227D00E2D28D /* BRPlayHistorysViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRPlayHistorysViewController.swift; sourceTree = "<group>"; }; F39855212E32227D00E2D28D /* BRPlayHistorysViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRPlayHistorysViewController.swift; sourceTree = "<group>"; };
F39855232E3222BE00E2D28D /* BRPlayHistorysCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRPlayHistorysCell.swift; sourceTree = "<group>"; }; F39855232E3222BE00E2D28D /* BRPlayHistorysCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BRPlayHistorysCell.swift; sourceTree = "<group>"; };
@ -1194,6 +1198,8 @@
F39855672E37087500E2D28D /* BRRewardCoinsRecordCell.swift */, F39855672E37087500E2D28D /* BRRewardCoinsRecordCell.swift */,
F39855692E3709C500E2D28D /* BRWalletHeaderView.swift */, F39855692E3709C500E2D28D /* BRWalletHeaderView.swift */,
F398556B2E3717A500E2D28D /* BRWalletHeaderItemView.swift */, F398556B2E3717A500E2D28D /* BRWalletHeaderItemView.swift */,
F32BAEA82E3A173A00CC203C /* BRVipAlert.swift */,
F32BAEAA2E3A1BF500CC203C /* BRVipAlertCell.swift */,
); );
path = View; path = View;
sourceTree = "<group>"; sourceTree = "<group>";
@ -1520,6 +1526,7 @@
BF692B1C2E0A7DE800A5C2DA /* BRAppTool.swift in Sources */, BF692B1C2E0A7DE800A5C2DA /* BRAppTool.swift in Sources */,
BFC676622E0E2C8E006659E5 /* WMZBannerView.m in Sources */, BFC676622E0E2C8E006659E5 /* WMZBannerView.m in Sources */,
BFC676632E0E2C8E006659E5 /* WMZBannerOverLayout.m in Sources */, BFC676632E0E2C8E006659E5 /* WMZBannerOverLayout.m in Sources */,
F32BAEAB2E3A1BF500CC203C /* BRVipAlertCell.swift in Sources */,
F39855482E33928400E2D28D /* BRStoreCoinBigCell.swift in Sources */, F39855482E33928400E2D28D /* BRStoreCoinBigCell.swift in Sources */,
BFC676642E0E2C8E006659E5 /* WMZBannerFlowLayout.m in Sources */, BFC676642E0E2C8E006659E5 /* WMZBannerFlowLayout.m in Sources */,
BF02B81E2E2F99D900172177 /* BRWebView.swift in Sources */, BF02B81E2E2F99D900172177 /* BRWebView.swift in Sources */,
@ -1544,6 +1551,7 @@
BF0DBDD12E0D4E150035F6B4 /* BRTabBar.swift in Sources */, BF0DBDD12E0D4E150035F6B4 /* BRTabBar.swift in Sources */,
BF692B562E0AA92100A5C2DA /* BRCollectionViewCell.swift in Sources */, BF692B562E0AA92100A5C2DA /* BRCollectionViewCell.swift in Sources */,
BF02B7E32E2E08BD00172177 /* BRDetailEpButton.swift in Sources */, BF02B7E32E2E08BD00172177 /* BRDetailEpButton.swift in Sources */,
F32BAEA92E3A173A00CC203C /* BRVipAlert.swift in Sources */,
F398553E2E336D3000E2D28D /* BRPayDateModel.swift in Sources */, F398553E2E336D3000E2D28D /* BRPayDateModel.swift in Sources */,
BF692B072E0A771C00A5C2DA /* BRModel.swift in Sources */, BF692B072E0A771C00A5C2DA /* BRModel.swift in Sources */,
BF02B82F2E30895700172177 /* BRSearchRecordView.swift in Sources */, BF02B82F2E30895700172177 /* BRSearchRecordView.swift in Sources */,

View File

@ -21,3 +21,5 @@ let kBRHasBeenOpenedAPPDefaultsKey = "kBRHasBeenOpenedAPPDefaultsKey"
let kBRApnsAlertDefaultsKey = "kBRApnsAlertDefaultsKey" let kBRApnsAlertDefaultsKey = "kBRApnsAlertDefaultsKey"
let kBRWaitRestoreIAPDefaultsKey = "kBRWaitRestoreIAPDefaultsKey" let kBRWaitRestoreIAPDefaultsKey = "kBRWaitRestoreIAPDefaultsKey"
let kBRVipAlertDateDefaultsKey = "kBRVipAlertDateDefaultsKey"

View File

@ -214,4 +214,16 @@ extension UIColor {
static func color499C20(alpha: CGFloat = 1) -> UIColor { static func color499C20(alpha: CGFloat = 1) -> UIColor {
return UIColor(rgb: 0x499C20, alpha: alpha) return UIColor(rgb: 0x499C20, alpha: alpha)
} }
static func colorF7F7F7(alpha: CGFloat = 1) -> UIColor {
return UIColor(rgb: 0xF7F7F7, alpha: alpha)
}
static func colorC5ED8A(alpha: CGFloat = 1) -> UIColor {
return UIColor(rgb: 0xC5ED8A, alpha: alpha)
}
static func color495047(alpha: CGFloat = 1) -> UIColor {
return UIColor(rgb: 0x495047, alpha: alpha)
}
} }

View File

@ -9,7 +9,7 @@ import UIKit
class BRVideoAPI { class BRVideoAPI {
/// ///
static func requestVideoDetail(shortPlayId: String, activityId: String? = nil, revolution: BRShortModel.VideoRevolution? = nil, completer: ((_ model: BRVideoDetailModel?) -> Void)?) { static func requestVideoDetail(shortPlayId: String, activityId: String? = nil, revolution: BRShortModel.VideoRevolution? = nil, completer: ((_ model: BRVideoDetailModel?, _ code: Int?, _ msg: String?) -> Void)?) {
var parameters: [String : Any] = [ var parameters: [String : Any] = [
"short_play_id" : shortPlayId, "short_play_id" : shortPlayId,
"video_id" : "0" "video_id" : "0"
@ -25,10 +25,15 @@ class BRVideoAPI {
var param = BRNetworkParameters(path: "/getVideoDetails") var param = BRNetworkParameters(path: "/getVideoDetails")
param.method = .get param.method = .get
param.isToast = false
param.parameters = parameters param.parameters = parameters
BRNetwork.request(parameters: param) { (response: BRNetworkResponse<BRVideoDetailModel>) in BRNetwork.request(parameters: param) { (response: BRNetworkResponse<BRVideoDetailModel>) in
completer?(response.data) if response.code == BRNetworkCodeSucceed {
completer?(response.data, response.code, response.msg)
} else {
completer?(nil, response.code, response.msg)
}
} }
} }

View File

@ -9,7 +9,7 @@ import UIKit
class BRImageView: UIImageView { class BRImageView: UIImageView {
var placeholderColor = UIColor.black var placeholderColor = UIColor.colorF7F7F7()
private lazy var placeholderImageView: UIImageView = { private lazy var placeholderImageView: UIImageView = {
let imageView = UIImageView(image: UIImage(named: "placeholder_image_01")) let imageView = UIImageView(image: UIImage(named: "placeholder_image_01"))

View File

@ -7,8 +7,8 @@
<key>com.apple.developer.associated-domains</key> <key>com.apple.developer.associated-domains</key>
<array> <array>
<string>applinks:beereel.go.link</string> <string>applinks:beereel.go.link</string>
<string>applinks:www.breeltv.com</string>
<string>applinks:jyev.adj.st</string> <string>applinks:jyev.adj.st</string>
<string>applinks:www.breeltv.com</string>
</array> </array>
<key>keychain-access-groups</key> <key>keychain-access-groups</key>
<array/> <array/>

View File

@ -47,7 +47,7 @@ class BRHomeHeaderView: UIView {
param.wEffect = false param.wEffect = false
param.wAutoScroll = false param.wAutoScroll = false
/// ///
param.wRepeat = true param.wRepeat = false
param.wHideBannerControl = true param.wHideBannerControl = true
param.wCanFingerSliding = false param.wCanFingerSliding = false

View File

@ -33,6 +33,9 @@ class BRMineViewController: BRViewController {
return arr return arr
}() }()
private weak var vipAlertView: BRVipAlert?
private var payDataRequest: BRPayDataRequest = BRPayDataRequest()
private lazy var lightImageView: UIImageView = { private lazy var lightImageView: UIImageView = {
let imageView = UIImageView(image: UIImage(named: "light_icon_03")) let imageView = UIImageView(image: UIImage(named: "light_icon_03"))
return imageView return imageView
@ -70,6 +73,7 @@ class BRMineViewController: BRViewController {
override func viewDidAppear(_ animated: Bool) { override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated) super.viewDidAppear(animated)
BRLoginManager.manager.updateUserInfo(completer: nil) BRLoginManager.manager.updateUserInfo(completer: nil)
// self.showVipAlert()
} }
} }
@ -100,7 +104,24 @@ extension BRMineViewController {
self.tableView.reloadData() self.tableView.reloadData()
} }
private func showVipAlert() {
guard BRLoginManager.manager.userInfo?.is_vip != true else { return }
guard BRVipAlert.isAllowShowAlert else { return }
payDataRequest.requestProducts(isToast: false) { [weak self] model in
guard let self = self else { return }
guard self.isDidAppear else { return }
guard self.vipAlertView == nil else { return }
// guard let list = model?.list_sub_vip, list.count > 0 else { return }
let alert = BRVipAlert().show(in: BRAppTool.keyWindow)
alert.listArr = model?.list_sub_vip ?? []
self.vipAlertView = alert
}
}
} }
//MARK: -------------- UITableViewDelegate UITableViewDataSource -------------- //MARK: -------------- UITableViewDelegate UITableViewDataSource --------------

View File

@ -228,11 +228,20 @@ extension BRVideoDetailViewController {
recommandTimer = Timer.scheduledTimer(timeInterval: 6, target: YYTextWeakProxy(target: self), selector: #selector(handleRecommandTimer), userInfo: nil, repeats: false) recommandTimer = Timer.scheduledTimer(timeInterval: 6, target: YYTextWeakProxy(target: self), selector: #selector(handleRecommandTimer), userInfo: nil, repeats: false)
BRHUD.show(containerView: self.view) BRHUD.show(containerView: self.view)
BRVideoAPI.requestVideoDetail(shortPlayId: shortPlayId, activityId: activityId) { [weak self] model in BRVideoAPI.requestVideoDetail(shortPlayId: shortPlayId, activityId: activityId) { [weak self] model, code, msg in
BRHUD.dismiss() BRHUD.dismiss()
guard let self = self else { return } guard let self = self else { return }
guard let model = model else { return } guard let model = model else {
if code == 10014 {
self.navigationController?.popViewController(animated: true)
BRToast.show(text: "No Short Found".localized)
} else {
BRToast.show(text: msg)
}
return
}
self.detailArr.removeAll() self.detailArr.removeAll()
self.detailArr.append(model) self.detailArr.append(model)

View File

@ -35,6 +35,8 @@ class BRVideoRechargeView: BRPanModalContentView {
} }
} }
self.stackView.addArrangedSubview(self.tipView)
self.setNeedsLayoutUpdate() self.setNeedsLayoutUpdate()
} }
} }
@ -117,6 +119,13 @@ class BRVideoRechargeView: BRPanModalContentView {
return button return button
}() }()
private lazy var closeButton: UIButton = {
let button = UIButton(type: .custom)
button.setImage(UIImage(named: "Frame 9"), for: .normal)
button.addTarget(self, action: #selector(handleCloseButton), for: .touchUpInside)
return button
}()
private lazy var stackView: UIStackView = { private lazy var stackView: UIStackView = {
let stackView = UIStackView() let stackView = UIStackView()
stackView.axis = .vertical stackView.axis = .vertical
@ -146,6 +155,25 @@ class BRVideoRechargeView: BRPanModalContentView {
return view return view
}() }()
private lazy var tipView: UIView = {
let view = UIView()
let label = UILabel()
label.font = .fontRegular(ofSize: 12)
label.textColor = .colorD3D3D3()
label.numberOfLines = 0
label.text = "kStoreTipText".localized
view.addSubview(label)
label.snp.makeConstraints { make in
make.left.equalToSuperview().offset(15)
make.top.bottom.equalToSuperview()
make.right.lessThanOrEqualToSuperview().offset(-15)
}
return view
}()
deinit { deinit {
NotificationCenter.default.removeObserver(self) NotificationCenter.default.removeObserver(self)
} }
@ -153,7 +181,7 @@ class BRVideoRechargeView: BRPanModalContentView {
override init(frame: CGRect) { override init(frame: CGRect) {
super.init(frame: frame) super.init(frame: frame)
NotificationCenter.default.addObserver(self, selector: #selector(updateUserInfo), name: BRLoginManager.userInfoUpdateNotification, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(updateUserInfo), name: BRLoginManager.userInfoUpdateNotification, object: nil)
self.contentHeight = UIScreen.height - UIScreen.navBarHeight self.contentHeight = UIScreen.height - UIScreen.statusBarHeight
self.mainScrollView = self.scrollView self.mainScrollView = self.scrollView
br_setupUI() br_setupUI()
@ -165,6 +193,12 @@ class BRVideoRechargeView: BRPanModalContentView {
fatalError("init(coder:) has not been implemented") fatalError("init(coder:) has not been implemented")
} }
@objc private func handleCloseButton() {
self.dismiss(animated: true) {
}
}
override func allowsPullDownWhenShortState() -> Bool { override func allowsPullDownWhenShortState() -> Bool {
return true return true
@ -185,6 +219,7 @@ extension BRVideoRechargeView {
addSubview(coinLabel) addSubview(coinLabel)
addSubview(coinIconView) addSubview(coinIconView)
addSubview(unlockCoinsView) addSubview(unlockCoinsView)
addSubview(closeButton)
scrollView.snp.makeConstraints { make in scrollView.snp.makeConstraints { make in
make.left.right.bottom.equalToSuperview() make.left.right.bottom.equalToSuperview()
@ -214,10 +249,16 @@ extension BRVideoRechargeView {
unlockCoinsView.snp.makeConstraints { make in unlockCoinsView.snp.makeConstraints { make in
make.centerY.equalTo(coinIconView) make.centerY.equalTo(coinIconView)
make.right.equalToSuperview().offset(-15) // make.right.equalToSuperview().offset(-15)
make.left.equalTo(coinIconView.snp.right).offset(20)
make.height.equalTo(26) make.height.equalTo(26)
} }
closeButton.snp.makeConstraints { make in
make.centerY.equalTo(unlockCoinsView)
make.right.equalToSuperview().offset(-15)
}
} }
} }

View File

@ -76,6 +76,8 @@ class BRStoreViewController: BRViewController {
br_setupUI() br_setupUI()
requestPayData() requestPayData()
self.restore(isLoding: false)
} }
override func viewWillAppear(_ animated: Bool) { override func viewWillAppear(_ animated: Bool) {
@ -85,11 +87,16 @@ class BRStoreViewController: BRViewController {
} }
@objc private func handleRestore() { @objc private func handleRestore() {
BRIAP.manager.restore { isFinish in
self.restore(isLoding: true)
}
private func restore(isLoding: Bool) {
BRIAP.manager.restore(isLoding: isLoding) { isFinish in
guard isFinish else { return } guard isFinish else { return }
BRLoginManager.manager.updateUserInfo(completer: nil) BRLoginManager.manager.updateUserInfo(completer: nil)
} }
} }
} }

View File

@ -11,6 +11,7 @@ import StoreKit
class BRPayDataRequest: NSObject { class BRPayDataRequest: NSObject {
private var oldTemplateModel: BRPayDateModel? private var oldTemplateModel: BRPayDateModel?
private(set) var newTemplateModel: BRPayDateModel?
private var completerBlock: ((_ model: BRPayDateModel?) -> Void)? private var completerBlock: ((_ model: BRPayDateModel?) -> Void)?
@ -23,35 +24,54 @@ class BRPayDataRequest: NSObject {
self.isLoding = isLoding self.isLoding = isLoding
self.isToast = isToast self.isToast = isToast
// if let model = self.newTemplateModel {
// self.completerBlock?(model)
// return
// }
if isLoding { if isLoding {
BRHUD.show() BRHUD.show()
} }
BRStoreAPI.requestPayTemplate(isToast: isToast) { [weak self] model in BRStoreAPI.requestPayTemplate(isToast: isToast) { [weak self] model in
if isLoding {
BRHUD.dismiss()
}
guard let self = self else { return } guard let self = self else { return }
guard let model = model else { guard let model = model else {
if isLoding {
BRHUD.dismiss()
}
self.completerBlock?(nil) self.completerBlock?(nil)
return return
} }
self.oldTemplateModel = model self.newTemplateModel = model
completer?(model)
var productIdArr: [String] = []
model.list_sub_vip?.forEach { item in
productIdArr.append(BRIAP.manager.getProductId(templateId: item.ios_template_id) ?? "")
}
model.list_coins?.forEach { item in
productIdArr.append(BRIAP.manager.getProductId(templateId: item.ios_template_id) ?? "")
}
let set = Set(productIdArr)
let productsRequest = SKProductsRequest(productIdentifiers: set)
productsRequest.delegate = self
productsRequest.start()
} }
// BRStoreAPI.requestPayTemplate(isToast: isToast) { [weak self] model in
// guard let self = self else { return }
// guard let model = model else {
// if isLoding {
// BRHUD.dismiss()
// }
// self.completerBlock?(nil)
// return
// }
// self.oldTemplateModel = model
//
// var productIdArr: [String] = []
// model.list_sub_vip?.forEach { item in
// productIdArr.append(BRIAP.manager.getProductId(templateId: item.ios_template_id) ?? "")
// }
// model.list_coins?.forEach { item in
// productIdArr.append(BRIAP.manager.getProductId(templateId: item.ios_template_id) ?? "")
// }
//
// let set = Set(productIdArr)
// let productsRequest = SKProductsRequest(productIdentifiers: set)
// productsRequest.delegate = self
// productsRequest.start()
//
// }
} }
} }
@ -96,6 +116,8 @@ extension BRPayDataRequest: SKProductsRequestDelegate {
templateModel.list_coins = newCoinList templateModel.list_coins = newCoinList
templateModel.list_sub_vip = newVipList templateModel.list_sub_vip = newVipList
self.newTemplateModel = templateModel
DispatchQueue.main.async { DispatchQueue.main.async {
self.completerBlock?(templateModel) self.completerBlock?(templateModel)
} }

View File

@ -12,7 +12,7 @@ class BRConsumptionRecordCell: BRCollectionViewCell {
var model: BRConsumptionRecordsModel? { var model: BRConsumptionRecordsModel? {
didSet { didSet {
timeLabel.text = model?.created_at timeLabel.text = model?.created_at
let episode = "EP.##".localizedReplace(text: "\(model?.episode ?? "0")") + "\(model?.name ?? "")" let episode = "EP.##".localizedReplace(text: "\(model?.episode ?? "0")") + " \(model?.name ?? "")"
contentLabel.text = episode contentLabel.text = episode
coinView.setNeedsUpdateConfiguration() coinView.setNeedsUpdateConfiguration()

View File

@ -11,18 +11,11 @@ class BRStoreCoinBigCell: BRStoreCoinCell {
override var item: BRPayItem? { override var item: BRPayItem? {
didSet { didSet {
if item?.corner_marker?.isEmpty == false {
self.hotView.isHidden = false
} else {
self.hotView.isHidden = true
}
} }
} }
lazy var hotView: UIImageView = {
let imageView = UIImageView(image: UIImage(named: "hot_icon_04"))
return imageView
}()
override init(frame: CGRect) { override init(frame: CGRect) {
super.init(frame: frame) super.init(frame: frame)
@ -43,12 +36,9 @@ class BRStoreCoinBigCell: BRStoreCoinCell {
sendRatioBgView.backgroundColor = .colorFFB635() sendRatioBgView.backgroundColor = .colorFFB635()
bgView.addSubview(hotView)
hotView.snp.makeConstraints { make in
make.right.equalToSuperview().offset(-5)
make.top.equalToSuperview().offset(4)
}
coinBgView.snp.makeConstraints { make in coinBgView.snp.makeConstraints { make in

View File

@ -29,6 +29,12 @@ class BRStoreCoinCell: BRCollectionViewCell {
unitLabel.text = item?.currency unitLabel.text = item?.currency
priceLabel.text = item?.price priceLabel.text = item?.price
if item?.corner_marker?.isEmpty == false {
self.hotView.isHidden = false
} else {
self.hotView.isHidden = true
}
} }
} }
@ -85,6 +91,11 @@ class BRStoreCoinCell: BRCollectionViewCell {
return label return label
}() }()
lazy var hotView: UIImageView = {
let imageView = UIImageView(image: UIImage(named: "hot_icon_04"))
return imageView
}()
override init(frame: CGRect) { override init(frame: CGRect) {
super.init(frame: frame) super.init(frame: frame)
@ -98,6 +109,7 @@ class BRStoreCoinCell: BRCollectionViewCell {
priceBgView.addSubview(priceLabel) priceBgView.addSubview(priceLabel)
bgView.addSubview(sendRatioBgView) bgView.addSubview(sendRatioBgView)
sendRatioBgView.addSubview(sendRatioLabel) sendRatioBgView.addSubview(sendRatioLabel)
bgView.addSubview(hotView)
bgView.snp.makeConstraints { make in bgView.snp.makeConstraints { make in
make.edges.equalToSuperview() make.edges.equalToSuperview()
@ -141,6 +153,11 @@ class BRStoreCoinCell: BRCollectionViewCell {
make.right.equalToSuperview().offset(-8) make.right.equalToSuperview().offset(-8)
} }
hotView.snp.makeConstraints { make in
make.right.equalToSuperview().offset(-5)
make.top.equalToSuperview().offset(4)
}
} }
@MainActor required init?(coder: NSCoder) { @MainActor required init?(coder: NSCoder) {

View File

@ -61,6 +61,12 @@ class BRStoreVipCell: BRCollectionViewCell {
} }
} }
var br_isSelected: Bool = false {
didSet {
selectedView.isHidden = !br_isSelected
}
}
private lazy var bgView: UIImageView = { private lazy var bgView: UIImageView = {
let view = UIImageView() let view = UIImageView()
@ -128,6 +134,11 @@ class BRStoreVipCell: BRCollectionViewCell {
return view return view
}() }()
private lazy var selectedView: UIView = {
let imageView = UIImageView(image: UIImage(named: "选中框"))
return imageView
}()
override init(frame: CGRect) { override init(frame: CGRect) {
super.init(frame: frame) super.init(frame: frame)
@ -146,6 +157,7 @@ extension BRStoreVipCell {
private func br_setupUI() { private func br_setupUI() {
contentView.addSubview(bgView) contentView.addSubview(bgView)
contentView.addSubview(bgIconView) contentView.addSubview(bgIconView)
contentView.addSubview(selectedView)
bgView.addSubview(vipIconView) bgView.addSubview(vipIconView)
bgView.addSubview(vipNameLabel) bgView.addSubview(vipNameLabel)
bgView.addSubview(unitLabel) bgView.addSubview(unitLabel)
@ -166,6 +178,10 @@ extension BRStoreVipCell {
make.right.equalToSuperview().offset(-2) make.right.equalToSuperview().offset(-2)
} }
selectedView.snp.makeConstraints { make in
make.edges.equalTo(bgView)
}
vipIconView.snp.makeConstraints { make in vipIconView.snp.makeConstraints { make in
make.left.equalToSuperview().offset(11) make.left.equalToSuperview().offset(11)
make.top.equalToSuperview().offset(8) make.top.equalToSuperview().offset(8)

View File

@ -20,6 +20,8 @@ class BRStoreVipView: UIView {
var shortPlayId: String? var shortPlayId: String?
var videoId: String? var videoId: String?
private var selectedIndex: Int?
private lazy var titleLabel: UILabel = { private lazy var titleLabel: UILabel = {
let label = UILabel() let label = UILabel()
label.textColor = .colorFFFFFF() label.textColor = .colorFFFFFF()
@ -101,10 +103,14 @@ extension BRStoreVipView: UICollectionViewDelegate, UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! BRStoreVipCell let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! BRStoreVipCell
cell.item = list[indexPath.row] cell.item = list[indexPath.row]
cell.br_isSelected = indexPath.row == selectedIndex
return cell return cell
} }
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
self.selectedIndex = indexPath.row
collectionView.reloadData()
let item = list[indexPath.row] let item = list[indexPath.row]
BRIAP.manager.start(model: item, shortPlayId: shortPlayId, videoId: videoId) { [weak self] finish in BRIAP.manager.start(model: item, shortPlayId: shortPlayId, videoId: videoId) { [weak self] finish in

View File

@ -0,0 +1,162 @@
//
// BRVipAlert.swift
// BeeReel
//
// Created by 鸿 on 2025/7/30.
//
import UIKit
class BRVipAlert: BRBaseAlert {
///
static var lastAlertDate: Date? = UserDefaults.standard.object(forKey: kBRVipAlertDateDefaultsKey) as? Date {
didSet {
UserDefaults.standard.set(lastAlertDate, forKey: kBRVipAlertDateDefaultsKey)
UserDefaults.standard.synchronize()
}
}
///
static var isAllowShowAlert: Bool {
#if DEBUG
return true
#else
guard let lastAlertDate = lastAlertDate else { return true }
let nowDate = Date()
let interval = nowDate.timeIntervalSince1970 - lastAlertDate.timeIntervalSince1970
//
if interval > 60 * 60 {
return true
} else {
return false
}
#endif
}
var listArr: [BRPayItem] = [] {
didSet {
self.collectionView.reloadData()
}
}
private var selectedIndex: Int?
private lazy var bgView: UIView = {
let view = UIImageView(image: UIImage(named: "bg 4"))
view.isUserInteractionEnabled = true
return view
}()
private lazy var titleImageView: UIImageView = {
let imageView = UIImageView(image: UIImage(named: "Go VIP Watch Everything"))
return imageView
}()
// private lazy var
private lazy var tipLabel: UILabel = {
let label = UILabel()
label.font = .fontBold(ofSize: 10)
label.textColor = .colorC5ED8A()
label.text = "kVipAlertTipText".localized
return label
}()
private lazy var collectionViewLayout: UICollectionViewFlowLayout = {
let layout = UICollectionViewFlowLayout()
layout.itemSize = .init(width: 240, height: 50)
layout.minimumInteritemSpacing = 8
layout.minimumLineSpacing = 8
return layout
}()
private lazy var collectionView: BRCollectionView = {
let collectionView = BRCollectionView(frame: .zero, collectionViewLayout: collectionViewLayout)
collectionView.addObserver(self, forKeyPath: "contentSize", context: nil)
collectionView.delegate = self
collectionView.dataSource = self
collectionView.register(BRVipAlertCell.self, forCellWithReuseIdentifier: "cell")
return collectionView
}()
deinit {
self.collectionView.removeObserver(self, forKeyPath: "contentSize")
}
override init(frame: CGRect) {
super.init(frame: frame)
br_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 == "contentSize" {
collectionView.snp.updateConstraints { make in
make.height.equalTo(collectionView.contentSize.height + 1)
}
}
}
}
extension BRVipAlert {
private func br_setupUI() {
contentView.addSubview(bgView)
bgView.addSubview(titleImageView)
bgView.addSubview(tipLabel)
bgView.addSubview(collectionView)
bgView.snp.makeConstraints { make in
make.left.right.top.equalToSuperview()
make.bottom.equalToSuperview().offset(-70)
make.width.equalTo(279)
}
titleImageView.snp.makeConstraints { make in
make.left.equalToSuperview().offset(28)
make.top.equalToSuperview().offset(49)
}
tipLabel.snp.makeConstraints { make in
make.centerX.equalToSuperview().offset(2)
make.top.equalToSuperview().offset(132)
}
collectionView.snp.makeConstraints { make in
make.left.equalToSuperview().offset(21)
make.width.equalTo(collectionViewLayout.itemSize.width)
make.top.equalToSuperview().offset(152)
make.bottom.equalToSuperview().offset(-17)
make.height.equalTo(1)
}
}
}
extension BRVipAlert: UICollectionViewDelegate, UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! BRVipAlertCell
cell.br_isSelected = indexPath.row == self.selectedIndex
return cell
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 4
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
self.selectedIndex = indexPath.row
self.collectionView.reloadData()
}
}

View File

@ -0,0 +1,126 @@
//
// BRVipAlertCell.swift
// BeeReel
//
// Created by 鸿 on 2025/7/30.
//
import UIKit
class BRVipAlertCell: BRCollectionViewCell {
var item: BRPayItem? {
didSet {
nameLabel.text = item?.title
currencyLabel.text = item?.currency
priceLabel.text = item?.price
switch item?.vip_type_key {
case .week:
bgView.image = UIImage(named: "bg-周")
vipIconImageView.image = UIImage(named: "")
case .month:
bgView.image = UIImage(named: "bg-月")
vipIconImageView.image = UIImage(named: "")
case .quarter:
bgView.image = UIImage(named: "bg-季")
vipIconImageView.image = UIImage(named: "Frame 1")
case .year:
bgView.image = UIImage(named: "bg-年")
vipIconImageView.image = UIImage(named: "Frame 2")
default:
break
}
}
}
var br_isSelected: Bool = false {
didSet {
}
}
private lazy var bgView: UIImageView = {
let view = UIImageView()
return view
}()
private lazy var vipIconImageView: UIImageView = {
let imageView = UIImageView()
return imageView
}()
private lazy var nameLabel: UILabel = {
let label = UILabel()
label.font = .fontMedium(ofSize: 12)
label.textColor = .color495047()
return label
}()
private lazy var currencyLabel: UILabel = {
let label = UILabel()
label.font = .fontRegular(ofSize: 12)
label.textColor = .color2C042C()
return label
}()
private lazy var priceLabel: UILabel = {
let label = UILabel()
label.font = .aaHouDiHei(ofSize: 18)
label.textColor = .color2C042C()
return label
}()
override init(frame: CGRect) {
super.init(frame: frame)
br_setupUI()
}
@MainActor required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
extension BRVipAlertCell {
private func br_setupUI() {
contentView.addSubview(bgView)
contentView.addSubview(vipIconImageView)
contentView.addSubview(nameLabel)
contentView.addSubview(currencyLabel)
contentView.addSubview(priceLabel)
bgView.snp.makeConstraints { make in
make.edges.equalToSuperview()
}
vipIconImageView.snp.makeConstraints { make in
make.centerY.equalToSuperview()
make.left.equalToSuperview().offset(12)
}
nameLabel.snp.makeConstraints { make in
make.centerY.equalToSuperview()
make.left.equalTo(vipIconImageView.snp.right).offset(2)
}
currencyLabel.snp.makeConstraints { make in
make.left.equalToSuperview().offset(150)
make.centerY.equalToSuperview()
}
priceLabel.snp.makeConstraints { make in
make.centerY.equalToSuperview()
make.left.equalTo(currencyLabel.snp.right).offset(0)
}
}
}

View File

@ -38,9 +38,10 @@ extension AppDelegate {
UserDefaults.standard.set(Date(), forKey: kBRApnsAlertDefaultsKey) UserDefaults.standard.set(Date(), forKey: kBRApnsAlertDefaultsKey)
return return
} }
#if !DEBUG
if date.br_isToday { return } if date.br_isToday { return }
UserDefaults.standard.set(Date(), forKey: kBRApnsAlertDefaultsKey) UserDefaults.standard.set(Date(), forKey: kBRApnsAlertDefaultsKey)
#endif
let alert = BRAlert(title: "kApnsAlertTitle".localized, detail: "kApnsAlertContent".localized, image: UIImage(named: "通知"), normalButtonText: "Later".localized, highlightButtonText: "Allow".localized).show() let alert = BRAlert(title: "kApnsAlertTitle".localized, detail: "kApnsAlertContent".localized, image: UIImage(named: "通知"), normalButtonText: "Later".localized, highlightButtonText: "Allow".localized).show()
alert.clickNormalButton = { alert.clickNormalButton = {
@ -53,6 +54,14 @@ extension AppDelegate {
} }
func setBadgeCount(_ count: Int) {
if #available(iOS 16.0, *) {
UNUserNotificationCenter.current().setBadgeCount(count)
} else {
UIApplication.shared.applicationIconBadgeNumber = count
}
}
} }
//MARK: -------------- UNUserNotificationCenterDelegate -------------- //MARK: -------------- UNUserNotificationCenterDelegate --------------
@ -72,11 +81,7 @@ extension AppDelegate: UNUserNotificationCenterDelegate {
///app ///app
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) { func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
if #available(iOS 16.0, *) { setBadgeCount(0)
UNUserNotificationCenter.current().setBadgeCount(0)
} else {
UIApplication.shared.applicationIconBadgeNumber = 0
}
guard let userInfo: [String : Any] = response.notification.request.content.userInfo as? [String : Any] else { guard let userInfo: [String : Any] = response.notification.request.content.userInfo as? [String : Any] else {
completionHandler() completionHandler()

View File

@ -25,6 +25,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
requestAPNS() requestAPNS()
setBadgeCount(0)
BRIAP.manager.restore(isLoding: false) { isFinish in BRIAP.manager.restore(isLoding: false) { isFinish in
guard isFinish else { return } guard isFinish else { return }
BRLoginManager.manager.updateUserInfo(completer: nil) BRLoginManager.manager.updateUserInfo(completer: nil)

View File

@ -0,0 +1,22 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "Frame@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "Frame@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 473 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 655 B

View File

@ -0,0 +1,22 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "Go VIP Watch Everything@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "Go VIP Watch Everything@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -0,0 +1,44 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "bg@2x.png",
"idiom" : "universal",
"resizing" : {
"cap-insets" : {
"bottom" : 78,
"top" : 424
},
"center" : {
"height" : 1,
"mode" : "tile"
},
"mode" : "3-part-vertical"
},
"scale" : "2x"
},
{
"filename" : "bg@3x.png",
"idiom" : "universal",
"resizing" : {
"cap-insets" : {
"bottom" : 102,
"top" : 582
},
"center" : {
"height" : 1,
"mode" : "tile"
},
"mode" : "3-part-vertical"
},
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 189 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 350 KiB

View 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
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

View 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
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

View 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
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

View 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
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 KiB

View 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
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

View 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
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

@ -524,6 +524,17 @@
} }
} }
}, },
"kVipAlertTipText" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "500+ DRAMAS WAITING"
}
}
}
},
"kVipTipText" : { "kVipTipText" : {
"extractionState" : "manual", "extractionState" : "manual",
"localizations" : { "localizations" : {
@ -645,6 +656,17 @@
} }
} }
}, },
"No Short Found" : {
"extractionState" : "manual",
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "No Short Found"
}
}
}
},
"Order Record" : { "Order Record" : {
"extractionState" : "manual", "extractionState" : "manual",
"localizations" : { "localizations" : {