265 lines
8.9 KiB
Swift
265 lines
8.9 KiB
Swift
//
|
|
// BRVideoDetailViewController.swift
|
|
// BeeReel
|
|
//
|
|
// Created by 长沙鸿瑶 on 2025/6/30.
|
|
//
|
|
|
|
import UIKit
|
|
|
|
class BRVideoDetailViewController: BRPlayerListViewController {
|
|
|
|
|
|
override var contentSize: CGSize {
|
|
return .init(width: UIScreen.width, height: UIScreen.height)
|
|
}
|
|
|
|
override var CellClass: BRPlayerListCell.Type {
|
|
return BRDetailPlayerCell.self
|
|
}
|
|
|
|
var shortPlayId: String?
|
|
var activityId: String?
|
|
|
|
private var detailArr: [BRVideoDetailModel] = []
|
|
|
|
///是否展示推荐
|
|
private lazy var isAllowShowRecommand = false
|
|
private var recommandTimer: Timer?
|
|
|
|
///上一次上报播放时长的节点
|
|
private var lastUploadTime: TimeInterval = 0
|
|
|
|
//MARK: UI属性
|
|
private lazy var backButton: UIButton = {
|
|
let button = UIButton(type: .custom)
|
|
button.setImage(UIImage(named: "nav_back_icon_01"), for: .normal)
|
|
button.addTarget(self, action: #selector(handleBackButton), for: .touchUpInside)
|
|
return button
|
|
}()
|
|
|
|
///弹窗视图
|
|
private weak var popUpView: UIView?
|
|
|
|
override func viewDidLoad() {
|
|
super.viewDidLoad()
|
|
self.delegate = self
|
|
self.dataSource = self
|
|
self.fd_interactivePopDisabled = true
|
|
|
|
self.requestDetailData()
|
|
self.viewModel.asyncGetRecommandDataArr()
|
|
|
|
br_setupUI()
|
|
}
|
|
|
|
|
|
override func viewWillAppear(_ animated: Bool) {
|
|
super.viewWillAppear(animated)
|
|
self.navigationController?.setNavigationBarHidden(true, animated: true)
|
|
}
|
|
|
|
override var previousVideoUrl: String? {
|
|
let index = self.viewModel.currentIndexPath.row - 1
|
|
guard index > 0 else { return nil }
|
|
let model = self.detailArr[self.viewModel.currentIndexPath.section]
|
|
return model.episodeList?[index].video_url
|
|
}
|
|
|
|
override var nextVideoUrl: String? {
|
|
let index = self.viewModel.currentIndexPath.row + 1
|
|
let model = self.detailArr[self.viewModel.currentIndexPath.section]
|
|
guard index < (model.episodeList?.count ?? 0) else { return nil }
|
|
return model.episodeList?[index].video_url
|
|
}
|
|
|
|
override func play() {
|
|
let videoInfo = self.viewModel.currentPlayer?.videoInfo
|
|
guard videoInfo?.is_lock == true else {
|
|
super.play()
|
|
BRVideoAPI.requestAddPlayHistory(videoId: self.viewModel.currentPlayer?.videoInfo?.short_play_video_id, shortPlayId: self.viewModel.currentPlayer?.videoInfo?.short_play_id)
|
|
return
|
|
}
|
|
|
|
|
|
self.pause()
|
|
|
|
let myCoins = BRLoginManager.manager.userInfo?.totalCoin ?? 0
|
|
let coins = videoInfo?.coins ?? 0
|
|
if myCoins < coins, self.viewModel.currentPlayer?.hasLastEpisodeUnlocked != true {
|
|
self.viewModel.openRechargeView()
|
|
}
|
|
}
|
|
|
|
@objc private func handleBackButton() {
|
|
|
|
if !self.viewModel.recommandList.isEmpty, isAllowShowRecommand {
|
|
self.pause()
|
|
let view = BRVideoDetailRecommendView()
|
|
view.videoList = self.viewModel.recommandList
|
|
view.didDismissBlock = { [weak self] in
|
|
self?.handleNavBack()
|
|
}
|
|
view.didSelectedVideo = { [weak self] model in
|
|
guard let self = self else { return }
|
|
self.shortPlayId = model.short_play_id
|
|
self.requestDetailData()
|
|
}
|
|
view.present(in: nil)
|
|
} else {
|
|
self.handleNavBack()
|
|
}
|
|
}
|
|
}
|
|
|
|
extension BRVideoDetailViewController {
|
|
|
|
private func br_setupUI() {
|
|
view.addSubview(backButton)
|
|
|
|
backButton.snp.makeConstraints { make in
|
|
make.left.equalToSuperview().offset(15)
|
|
make.top.equalToSuperview().offset(UIScreen.statusBarHeight + 10)
|
|
}
|
|
}
|
|
}
|
|
|
|
extension BRVideoDetailViewController {
|
|
|
|
@objc private func handleRecommandTimer() {
|
|
self.isAllowShowRecommand = true
|
|
}
|
|
}
|
|
|
|
//MARK: -------------- BRPlayerViewModelDelegate --------------
|
|
//重写父类的代理
|
|
extension BRVideoDetailViewController {
|
|
///打开选集
|
|
override func br_onEpisodeView(viewModel: BRPlayerViewModel) {
|
|
let indexPath = self.viewModel.currentIndexPath
|
|
let model = self.detailArr[indexPath.section]
|
|
|
|
let view = BREpisodeSelectorView()
|
|
view.shortModel = model.shortPlayInfo
|
|
view.epList = model.episodeList ?? []
|
|
view.index = viewModel.currentIndexPath.row
|
|
view.didSelectedIndex = { [weak self] index in
|
|
self?.scrollToItem(indexPath: IndexPath(row: index, section: indexPath.section), animated: false)
|
|
}
|
|
view.present(in: nil)
|
|
|
|
self.popUpView = view
|
|
}
|
|
///速率
|
|
override func br_clickRateButton(viewModel: BRPlayerViewModel) {
|
|
|
|
let view = BRRateSelectorView()
|
|
view.didSelectedRate = { [weak self] model in
|
|
guard let self = self else { return }
|
|
self.viewModel.rateModel = model
|
|
}
|
|
view.show()
|
|
|
|
self.popUpView = view
|
|
}
|
|
|
|
override func br_playProgressDidChange(viewModel: BRPlayerViewModel, time: TimeInterval) {
|
|
if (time >= lastUploadTime + 5 || time < lastUploadTime) && time >= 5 {
|
|
lastUploadTime = time
|
|
self.viewModel.uploadPlayTime()
|
|
}
|
|
}
|
|
|
|
override func br_needUpdateAllData(viewModel: BRPlayerViewModel, scrollTo indexPath: IndexPath?) {
|
|
self.requestDetailData(indexPath: indexPath)
|
|
}
|
|
|
|
}
|
|
|
|
//MARK: -------------- BRPlayerListViewControllerDataSource BRPlayerListViewControllerDelegate --------------
|
|
extension BRVideoDetailViewController: BRPlayerListViewControllerDataSource, BRPlayerListViewControllerDelegate {
|
|
|
|
func br_playerListViewController(_ viewController: BRPlayerListViewController, _ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
|
|
|
|
let model = self.detailArr[indexPath.section]
|
|
|
|
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! BRDetailPlayerCell
|
|
cell.videoInfo = model.episodeList?[indexPath.row]
|
|
cell.shortModel = model.shortPlayInfo
|
|
|
|
let upRow = indexPath.row - 1
|
|
if upRow >= 0, let videoInfo = model.episodeList?[upRow], videoInfo.is_lock == true {
|
|
cell.hasLastEpisodeUnlocked = true
|
|
} else {
|
|
cell.hasLastEpisodeUnlocked = false
|
|
}
|
|
|
|
return cell
|
|
}
|
|
|
|
func br_playerListViewController(_ viewController: BRPlayerListViewController, _ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
|
|
return self.detailArr[section].episodeList?.count ?? 0
|
|
}
|
|
|
|
func br_numberOfSections(in viewController: BRPlayerListViewController) -> Int {
|
|
return self.detailArr.count
|
|
}
|
|
|
|
func br_shouldAutoScrollNextEpisode(_ viewController: BRPlayerListViewController) -> Bool {
|
|
if self.popUpView == nil {
|
|
return true
|
|
} else {
|
|
return false
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
|
|
extension BRVideoDetailViewController {
|
|
|
|
private func requestDetailData(indexPath: IndexPath? = nil) {
|
|
guard let shortPlayId = shortPlayId else { return }
|
|
|
|
|
|
isAllowShowRecommand = false
|
|
recommandTimer?.invalidate()
|
|
recommandTimer = nil
|
|
recommandTimer = Timer.scheduledTimer(timeInterval: 6, target: YYTextWeakProxy(target: self), selector: #selector(handleRecommandTimer), userInfo: nil, repeats: false)
|
|
|
|
BRHUD.show(containerView: self.view)
|
|
BRVideoAPI.requestVideoDetail(shortPlayId: shortPlayId, activityId: activityId) { [weak self] model in
|
|
BRHUD.dismiss()
|
|
|
|
guard let self = self else { return }
|
|
guard let model = model else { return }
|
|
self.detailArr.removeAll()
|
|
self.detailArr.append(model)
|
|
|
|
self.reloadData { [weak self] in
|
|
guard let self = self else { return }
|
|
self.play()
|
|
var targetIndexPath = IndexPath(row: 0, section: 0)
|
|
|
|
if let indexPath = indexPath, indexPath.row < (model.episodeList?.count ?? 0) {
|
|
targetIndexPath = indexPath
|
|
|
|
} else if let videoInfo = model.video_info {
|
|
var row: Int?
|
|
model.episodeList?.enumerated().forEach({
|
|
if $1.id == videoInfo.id {
|
|
row = $0
|
|
}
|
|
})
|
|
if let row = row {
|
|
targetIndexPath = .init(row: row, section: 0)
|
|
}
|
|
}
|
|
self.scrollToItem(indexPath: targetIndexPath, animated: false)
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
}
|