Fableon/Fableon/Object/Class/Player/VC/FAPlayerDetailViewController.swift
2026-02-04 17:25:54 +08:00

242 lines
8.1 KiB
Swift

//
// FAPlayerDetailViewController.swift
// Fableon
//
// Created by on 2025/9/1.
//
import UIKit
import JXPlayer
import FDFullscreenPopGesture
import SnapKit
class FAPlayerDetailViewController: JXPlayerListViewController {
var shortPlayId: String? {
set {
self.fa_viewModel.shortPlayId = newValue ?? ""
}
get {
return self.fa_viewModel.shortPlayId
}
}
var activityId: String?
override var ViewModelClass: JXPlayerListViewModel.Type {
return FAShortDetailViewModel.self
}
var fa_viewModel: FAShortDetailViewModel {
return self.viewModel as! FAShortDetailViewModel
}
private var epText: String? {
didSet {
returnButton.setNeedsUpdateConfiguration()
}
}
private lazy var returnButton: UIButton = {
var configuration = UIButton.Configuration.plain()
configuration.image = UIImage(named: "Frame 3011")
configuration.imagePadding = 4
configuration.contentInsets = .init(top: 0, leading: 10, bottom: 0, trailing: 10)
let button = UIButton(configuration: configuration, primaryAction: UIAction(handler: { [weak self] _ in
self?.handleBackButton()
}))
button.configurationUpdateHandler = { [weak self] button in
guard let self = self else { return }
var newConfiguration = button.configuration
if let text = self.epText {
newConfiguration?.attributedTitle = AttributedString(text, attributes: AttributeContainer([
.font : UIFont.font(ofSize: 18, weight: .regular),
.foregroundColor : UIColor.white
]))
} else {
newConfiguration?.attributedTitle = nil
}
button.configuration = newConfiguration
}
return button
}()
private(set) lazy var nativeAdContentView: UIView = {
let view = UIView()
view.isHidden = true
return view
}()
override func viewDidLoad() {
super.viewDidLoad()
self.fd_interactivePopDisabled = true
view.backgroundColor = .init(named: .color_000000)
// self.fa_viewModel.shortPlayId = shortPlayId ?? ""
self.register(FAPlayerDetailCell.self, forCellWithReuseIdentifier: "FAPlayerDetailCell")
self.delegate = self
self.dataSource = self
requestDetailList()
self.fa_viewModel.loadNativeAd()
fa_setupLayout()
self.fa_viewModel.requestRecommandData()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.navigationController?.setNavigationBarHidden(true, animated: true)
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
FAOpenAdManager.manager.vcAllowedShowAd = false
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
self.viewModel.currentCell?.pause()
}
// override var previousVideoUrl: String? {
// return self.fa_viewModel.previousEpisode?.video_url
// }
//
// override var nextVideoUrl: String? {
// return self.fa_viewModel.nextEpisode?.video_url
// }
override func play() {
let videoInfo = self.viewModel.currentCell?.model as? FAVideoInfoModel
if videoInfo?.is_lock != true {
super.play()
FAAPI.requestCreatePlayHistory(videoId: videoInfo?.short_play_video_id, shortPlayId: videoInfo?.short_play_id)
if let cell = viewModel.currentCell as? FAPlayerDetailCell, let model = cell.shortModel {
FATool.widgetLiveActivityModel = model
FATool.widgetLiveActivityModel?.current_episode = videoInfo?.episode
}
return
}
self.pause()
let myCoins = FALogin.manager.userInfo?.totalCoins ?? 0
let lockCoins = videoInfo?.coins ?? 0
if myCoins < lockCoins, (self.fa_viewModel.currentCell as? FAPlayerDetailCell)?.hasLastEpisodeUnlocked != true {
self.fa_viewModel.openRechargeView()
} else {
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { [weak self] in
guard let self = self else { return }
if (self.fa_viewModel.currentCell as? FAPlayerDetailCell)?.hasLastEpisodeUnlocked != true {
self.fa_viewModel.handleUnlockVideo()
}
}
}
}
@objc private func handleBackButton() {
self.pause()
if !self.fa_viewModel.recommandDataArr.isEmpty, self.fa_viewModel.isShowRecommand {
let view = FADetailRecommendView()
view.dataArr = self.fa_viewModel.recommandDataArr
view.clickCloseButton = { [weak self] in
self?.handleNavigationBack()
}
view.didSelectedVideo = { [weak self] model in
guard let self = self else { return }
self.shortPlayId = model.short_play_id
self.requestDetailList()
}
view.show(in: FATool.keyWindow)
} else {
self.handleNavigationBack()
}
// self.handleNavigationBack()
}
}
extension FAPlayerDetailViewController {
private func fa_setupLayout() {
view.addSubview(nativeAdContentView)
view.addSubview(returnButton)
nativeAdContentView.snp.remakeConstraints { make in
make.center.equalToSuperview()
make.width.equalTo(self.fa_viewModel.nativeAdManager.contentSize.width)
make.height.equalTo(self.fa_viewModel.nativeAdManager.contentSize.height)
}
returnButton.snp.makeConstraints { make in
make.left.equalToSuperview().offset(6)
make.top.equalTo(view.safeAreaLayoutGuide)
make.height.equalTo(44)
}
}
}
//MARK: JXPlayerListViewControllerDelegate JXPlayerListViewControllerDataSource
extension FAPlayerDetailViewController: JXPlayerListViewControllerDelegate, JXPlayerListViewControllerDataSource {
func jx_playerListViewController(_ viewController: JXPlayerListViewController, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = self.dequeueReusableCell(withReuseIdentifier: "FAPlayerDetailCell", for: indexPath) as! FAPlayerDetailCell
cell.model = self.fa_viewModel.dataArr[indexPath.section].episodeList?[indexPath.row]
cell.shortModel = self.fa_viewModel.dataArr[indexPath.section].shortPlayInfo
let upRow = indexPath.row - 1
if upRow >= 0, let videoInfo = self.fa_viewModel.dataArr[indexPath.section].episodeList?[upRow], videoInfo.is_lock == true {
cell.hasLastEpisodeUnlocked = true
} else {
cell.hasLastEpisodeUnlocked = false
}
return cell
}
func jx_playerListViewController(_ viewController: JXPlayerListViewController, numberOfItemsInSection section: Int) -> Int {
self.fa_viewModel.dataArr[section].episodeList?.count ?? 0
}
func jx_numberOfSections(in viewController: JXPlayerListViewController) -> Int {
self.fa_viewModel.dataArr.count
}
func jx_playerListViewController(_ viewController: JXPlayerListViewController, didChangeIndexPathForVisible indexPath: IndexPath) {
let model = self.fa_viewModel.dataArr[indexPath.section].episodeList?[indexPath.row]
self.epText = "Ep.\(model?.episode ?? "")"
}
func jx_shouldAutoScrollNextEpisode(_ viewController: JXPlayerListViewController) -> Bool {
if let _ = self.fa_viewModel.popView {
return false
} else {
return true
}
}
}
extension FAPlayerDetailViewController {
private func requestDetailList() {
self.fa_viewModel.requestDetailData { [weak self] code in
guard let self = self else { return }
}
}
}