Veloria/Veloria/Class/Player/Controller/VPDetailPlayerViewController.swift
2025-06-06 10:20:04 +08:00

259 lines
8.4 KiB
Swift

//
// VPDetailPlayerViewController.swift
// Veloria
//
// Created by on 2025/5/23.
//
import UIKit
class VPDetailPlayerViewController: VPVideoPlayerViewController {
override var PlayerCellClass: VPVideoPlayerCell.Type {
return VPDetailPlayerCell.self
}
override var contentSize: CGSize {
return .init(width: UIScreen.width, height: UIScreen.height)
}
var shortPlayId: String?
var activityId: String?
private var detailModel: VPVideoDetailModel?
//MARK: UI
private lazy var backButton: UIButton = {
let button = UIButton(type: .custom)
button.setImage(UIImage(named: "arrow_left_icon_01"), for: .normal)
button.addTarget(self, action: #selector(handleBack), for: .touchUpInside)
return button
}()
private lazy var videoNameLabel: UILabel = {
let label = UILabel()
label.font = .fontMedium(ofSize: 16)
label.textColor = .colorFFFFFF()
return label
}()
///
private weak var episodeView: VPEpisodeView?
deinit {
NotificationCenter.default.removeObserver(self)
}
override func viewDidLoad() {
super.viewDidLoad()
self.delegate = self
self.dataSource = self
NotificationCenter.default.addObserver(self, selector: #selector(buyVipFinishNotification), name: VPIAPManager.buyVipFinishNotification, object: nil)
requestDetailData()
vp_setupUI()
vp_addAction()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.navigationController?.setNavigationBarHidden(true, animated: true)
}
override func play() {
guard let videoInfo = self.viewModel.currentPlayer?.videoInfo else { return }
if videoInfo.is_lock == true {
self.pause()
let myCoin = VPLoginManager.manager.userInfo?.totalCoin ?? 0
if myCoin < (videoInfo.coins ?? 0), self.viewModel.currentPlayer?.hasLastEpisodeUnlocked != true {
self.onRecharge()
}
return
}
super.play()
VPVideoAPI.requestCreatePlayHistory(videoId: videoInfo.short_play_video_id, shortPlayId: videoInfo.short_play_id)
}
}
extension VPDetailPlayerViewController {
private func vp_setupUI() {
view.addSubview(backButton)
view.addSubview(videoNameLabel)
backButton.snp.makeConstraints { make in
make.left.equalToSuperview()
make.top.equalToSuperview().offset(UIScreen.statusBarHeight)
make.width.equalTo(48)
make.height.equalTo(44)
}
videoNameLabel.snp.makeConstraints { make in
make.centerY.equalTo(backButton)
make.left.equalTo(backButton.snp.right)
make.right.lessThanOrEqualToSuperview().offset(-150)
}
}
private func vp_addAction() {
self.viewModel.handleEpisode = { [weak self] in
self?.onEpisode()
}
self.viewModel.handleUnlock = { [weak self] in
self?.unlockVideo()
}
}
}
extension VPDetailPlayerViewController {
private func onEpisode() {
let view = VPEpisodeView()
view.dataArr = detailModel?.episodeList ?? []
view.shortModel = detailModel?.shortPlayInfo
view.currentIndex = self.currentIndexPath.row
view.didSelectedIndex = { [weak self] (index) in
self?.scrollToItem(indexPath: IndexPath(row: index, section: 0), animated: false)
}
view.present(in: nil)
self.episodeView = view
}
private func unlockVideo() {
guard let videoInfo = self.viewModel.currentPlayer?.videoInfo else { return }
guard let sId = videoInfo.short_play_id, let vId = videoInfo.short_play_video_id else { return }
VPWalletAPI.requestCoinUnlockVideo(shortPlayId: sId, videoId: vId) { [weak self] model in
guard let self = self else { return }
guard let model = model else { return }
switch model.status {
case .jump:
VPToast.show(text: "kLockPreviousEpisodeText".localized)
case .noPlay:
VPToast.show(text: "kLockFailText".localized)
case .notEnough:
self.onRecharge()
break
case .success:
videoInfo.is_lock = false
self.reloadData { [weak self] in
guard let self = self else { return }
self.play()
}
VPLoginManager.manager.updateUserInfo(completer: nil)
default: break
}
}
}
///
private func onRecharge() {
guard let videoInfo = self.viewModel.currentPlayer?.videoInfo else { return }
let view = VPPlayerRechargeView()
view.shortPlayId = videoInfo.short_play_id
view.videoId = videoInfo.short_play_video_id
view.present(in: nil)
}
///
@objc private func buyVipFinishNotification() {
guard VPLoginManager.manager.userInfo?.is_vip == true else { return }
self.detailModel?.episodeList?.forEach({
$0.is_lock = false
})
self.reloadData { [weak self] in
self?.play()
}
}
}
//MARK: -------------- VPPlayerListViewControllerDataSource --------------
extension VPDetailPlayerViewController: VPPlayerListViewControllerDataSource {
func vp_playerListViewController(_ viewController: VPVideoPlayerViewController, _ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath, oldCell: UICollectionViewCell) -> UICollectionViewCell {
guard let cell = oldCell as? VPDetailPlayerCell else { return oldCell }
cell.shortModel = detailModel?.shortPlayInfo
cell.videoInfo = detailModel?.episodeList?[indexPath.row]
cell.isLoop = false
let upRow = indexPath.row - 1
if upRow >= 0, let videoInfo = detailModel?.episodeList?[upRow], videoInfo.is_lock == true {
cell.hasLastEpisodeUnlocked = true
} else {
cell.hasLastEpisodeUnlocked = false
}
return cell
}
func vp_playerListViewController(_ viewController: VPVideoPlayerViewController, _ collectionView: UICollectionView, numberOfItemsInSection section: Int, oldNumber: Int) -> Int {
return self.detailModel?.episodeList?.count ?? 0
}
}
//MARK: -------------- VPPlayerListViewControllerDelegate --------------
extension VPDetailPlayerViewController: VPPlayerListViewControllerDelegate {
func vp_playerListViewController(_ viewController: VPVideoPlayerViewController, didChangeIndexPathForVisible indexPath: IndexPath) {
self.episodeView?.currentIndex = indexPath.row
}
}
extension VPDetailPlayerViewController {
private func requestDetailData() {
guard let shortPlayId = shortPlayId else { return }
VPVideoAPI.requestVideoDetail(shortPlayId: shortPlayId, activityId: activityId) { [weak self] model in
guard let self = self else { return }
guard let model = model else { return }
self.detailModel = model
self.videoNameLabel.text = model.shortPlayInfo?.name
self.reloadData { [weak self] in
guard let self = self else { return }
if let videoInfo = self.detailModel?.video_info {
var row: Int?
self.detailModel?.episodeList?.enumerated().forEach({
if $1.id == videoInfo.id {
row = $0
}
})
if let row = row {
self.scrollToItem(indexPath: .init(row: row, section: 0), animated: false)
} else {
self.scrollToItem(indexPath: .init(row: 0, section: 0), animated: false)
}
} else {
self.scrollToItem(indexPath: .init(row: 0, section: 0), animated: false)
}
}
}
}
}