// // SPPlayerDetailViewController.swift // Thimra // // Created by 曾觉新 on 2025/4/10. // import UIKit class SPPlayerDetailViewController: SPPlayerListViewController { override var PlayerCellClass: SPPlayerListCell.Type { return SPPlayerDetailCell.self } override var contentSize: CGSize { return CGSize(width: kSPScreenWidth, height: kSPScreenHeight - kSPTabbarSafeBottomMargin - 35) } var videoId: String? var shortPlayId: String? var playHistoryModel: SPShortModel? private var detailModel: SPVideoDetailModel? //MARK: UI属性 ///选集视图 private weak var episodeView: SPEpisodeView? 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 titleLabel: UILabel = { let label = UILabel() label.font = .fontBold(ofSize: 18) label.textColor = .colorFFFFFF() return label }() private lazy var episodeLabel: UILabel = { let label = UILabel() label.font = .fontMedium(ofSize: 18) label.textColor = .colorFFFFFF(alpha: 0.4) return label }() private lazy var bottomView: UIView = { let view = UIView() view.backgroundColor = .color1C1C1E() return view }() override func viewDidLoad() { super.viewDidLoad() self.autoNextEpisode = true self.dataSource = self self.delegate = self requestDetailData() _addAction() _setupUI() } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) self.navigationController?.setNavigationBarHidden(true, animated: true) } override func play() { super.play() if let _ = self.detailModel, let videoInfo = self.viewModel.currentPlayer?.videoInfo { SPVideoAPI.requestRequestVideoPlayHistory(videoId: videoInfo.short_play_video_id ?? "", shortPlayId: videoInfo.short_play_id ?? "") } } } extension SPPlayerDetailViewController { private func _setupUI() { view.addSubview(backButton) view.addSubview(titleLabel) view.addSubview(episodeLabel) view.addSubview(bottomView) backButton.snp.makeConstraints { make in make.left.equalToSuperview().offset(5) make.top.equalToSuperview().offset(5 + kSPStatusbarHeight) make.width.height.equalTo(37) } titleLabel.snp.makeConstraints { make in make.left.equalTo(backButton.snp.right) make.centerY.equalTo(backButton) // make.right.equalToSuperview().offset(-15) make.width.lessThanOrEqualTo(kSPScreenWidth - 130) } episodeLabel.snp.makeConstraints { make in make.centerY.equalTo(titleLabel) make.left.equalTo(titleLabel.snp.right).offset(16) } bottomView.snp.makeConstraints { make in make.left.right.bottom.equalToSuperview() make.top.equalTo(self.collectionView.snp.bottom) } } private func _addAction() { self.viewModel.handleEpisode = { [weak self] in self?.onEpisode() } } } extension SPPlayerDetailViewController { private func onEpisode() { let view = SPEpisodeView() 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 } } //MARK: -------------- SPPlayerListViewControllerDataSource -------------- extension SPPlayerDetailViewController: SPPlayerListViewControllerDataSource, SPPlayerListViewControllerDelegate { func sp_playerListViewController(_ viewController: SPPlayerListViewController, _ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath, oldCell: UICollectionViewCell) -> UICollectionViewCell { if let cell = oldCell as? SPPlayerDetailCell { cell.shortModel = detailModel?.shortPlayInfo cell.videoInfo = detailModel?.episodeList?[indexPath.row] cell.isLoop = false } return oldCell } func sp_playerListViewController(_ viewController: SPPlayerListViewController, _ collectionView: UICollectionView, numberOfItemsInSection section: Int, oldNumber: Int) -> Int { return detailModel?.episodeList?.count ?? 0 } func sp_playerListViewController(_ viewController: SPPlayerListViewController, didChangeIndexPathForVisible indexPath: IndexPath) { self.episodeView?.currentIndex = indexPath.row let videoInfo = detailModel?.episodeList?[indexPath.row] // titleLabel.text = String(format: "kPlayerDetailTitleString".localized, "\(videoInfo?.episode ?? "0")", self.detailModel?.shortPlayInfo?.name ?? "") titleLabel.text = detailModel?.shortPlayInfo?.name episodeLabel.text = "\(videoInfo?.episode ?? "0")/\(detailModel?.shortPlayInfo?.episode_total ?? 0)" } } extension SPPlayerDetailViewController { private func requestDetailData() { guard let shortPlayId = self.shortPlayId else { return } SPVideoAPI.requestVideoDetail(videoId: videoId, shortPlayId: shortPlayId) { [weak self] model in guard let self = self else { return } if let model = model { self.detailModel = model self.reloadData { [weak self] in guard let self = self else { return } if let playHistoryModel = self.playHistoryModel { var row: Int? self.detailModel?.episodeList?.enumerated().forEach({ if $1.episode == playHistoryModel.current_episode { row = $0 } }) if let row = row { self.scrollToItem(indexPath: IndexPath(row: row, section: 0), animated: false) } self.playHistoryModel = nil } else { self.play() } } } } } }