diff --git a/ThimraTV.xcodeproj/project.pbxproj b/ThimraTV.xcodeproj/project.pbxproj index 5e38fac..35a864e 100644 --- a/ThimraTV.xcodeproj/project.pbxproj +++ b/ThimraTV.xcodeproj/project.pbxproj @@ -316,7 +316,6 @@ /* Begin PBXFileReference section */ 0538826A0638D33FEF3A2E38 /* Pods-ThimraTV.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ThimraTV.debug.xcconfig"; path = "Target Support Files/Pods-ThimraTV/Pods-ThimraTV.debug.xcconfig"; sourceTree = ""; }; - 109EB01BE447EE135493CA38 /* Pods-MoviaBox.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MoviaBox.release.xcconfig"; path = "Target Support Files/Pods-MoviaBox/Pods-MoviaBox.release.xcconfig"; sourceTree = ""; }; 1BB91BBD2E04FD6A00A2C715 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 1BB91BBE2E04FD6A00A2C715 /* AppDelegate+APNS.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AppDelegate+APNS.swift"; sourceTree = ""; }; 1BB91BBF2E04FD6A00A2C715 /* AppDelegate+Config.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AppDelegate+Config.swift"; sourceTree = ""; }; @@ -606,11 +605,8 @@ 1BF513202E2662DC009750EA /* SPAdmobBannerAd.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SPAdmobBannerAd.swift; sourceTree = ""; }; 1BF513222E273479009750EA /* SPApplovinBannerAd.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SPApplovinBannerAd.swift; sourceTree = ""; }; 1DBC40592DA4EDFC0093FCB0 /* ThimraTV.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ThimraTV.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 1F666DE0B12C863F26BE5027 /* Pods-MoviaBox.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MoviaBox.debug.xcconfig"; path = "Target Support Files/Pods-MoviaBox/Pods-MoviaBox.debug.xcconfig"; sourceTree = ""; }; A1174E10BCF2C606F7818792 /* Pods-ThimraTV.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ThimraTV.release.xcconfig"; path = "Target Support Files/Pods-ThimraTV/Pods-ThimraTV.release.xcconfig"; sourceTree = ""; }; B64805795B479324EB764157 /* Pods_ThimraTV.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_ThimraTV.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - F7763FEFB6BEB1A75D6FBA0A /* Pods-Thimra.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Thimra.debug.xcconfig"; path = "Target Support Files/Pods-Thimra/Pods-Thimra.debug.xcconfig"; sourceTree = ""; }; - FEA583158A7C05D8D7C5A9FC /* Pods-Thimra.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Thimra.release.xcconfig"; path = "Target Support Files/Pods-Thimra/Pods-Thimra.release.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -640,10 +636,6 @@ 0061C3496D158807460301A9 /* Pods */ = { isa = PBXGroup; children = ( - F7763FEFB6BEB1A75D6FBA0A /* Pods-Thimra.debug.xcconfig */, - FEA583158A7C05D8D7C5A9FC /* Pods-Thimra.release.xcconfig */, - 1F666DE0B12C863F26BE5027 /* Pods-MoviaBox.debug.xcconfig */, - 109EB01BE447EE135493CA38 /* Pods-MoviaBox.release.xcconfig */, 0538826A0638D33FEF3A2E38 /* Pods-ThimraTV.debug.xcconfig */, A1174E10BCF2C606F7818792 /* Pods-ThimraTV.release.xcconfig */, ); diff --git a/ThimraTV/Base/Networking/API/SPVideoAPI.swift b/ThimraTV/Base/Networking/API/SPVideoAPI.swift index 2a1772d..ba1d6c8 100644 --- a/ThimraTV/Base/Networking/API/SPVideoAPI.swift +++ b/ThimraTV/Base/Networking/API/SPVideoAPI.swift @@ -23,7 +23,7 @@ class SPVideoAPI: NSObject { var param = SPNetworkParameters(path: "/getVideoDetails") param.method = .get param.parameters = parameters - param.isLoding = true + param.isLoding = false param.isToast = false SPNetwork.request(parameters: param) { (response: SPNetworkResponse) in diff --git a/ThimraTV/Class/Player/Controller/SPPlayerDetailViewController.swift b/ThimraTV/Class/Player/Controller/SPPlayerDetailViewController.swift index 385c592..95514c0 100644 --- a/ThimraTV/Class/Player/Controller/SPPlayerDetailViewController.swift +++ b/ThimraTV/Class/Player/Controller/SPPlayerDetailViewController.swift @@ -23,7 +23,9 @@ class SPPlayerDetailViewController: SPPlayerListViewController { var activityId: String? var playHistoryModel: SPShortModel? - private var detailModel: SPVideoDetailModel? +// private var detailModel: SPVideoDetailModel? + + private var detailDataArr: [Any] = [] ///上一次上报播放时长的节点 private var lastUploadTime: Int = 0 @@ -247,12 +249,16 @@ extension SPPlayerDetailViewController { extension SPPlayerDetailViewController { private func onEpisode() { + guard detailDataArr.count > 0 else { return } + guard let detailModel = detailDataArr[self.viewModel.currentIndexPath.section] as? SPVideoDetailModel else { return } + + let view = SPEpisodeView() - view.dataArr = detailModel?.episodeList ?? [] - view.shortModel = detailModel?.shortPlayInfo + view.dataArr = detailModel.episodeList ?? [] + view.shortModel = detailModel.shortPlayInfo view.currentIndex = self.viewModel.currentIndexPath.row view.didSelectedIndex = { [weak self] (index) in - self?.scrollToItem(indexPath: IndexPath(row: index, section: 0), animated: false) + self?.scrollToItem(indexPath: IndexPath(row: index, section: self?.viewModel.currentIndexPath.section ?? 0), animated: false) } view.present(in: nil) self.episodeView = view @@ -321,7 +327,7 @@ extension SPPlayerDetailViewController { } ///网络切换通知 @objc private func reachabilityDidChangeNotification() { - if SPNetworkReachabilityManager.manager.isReachable == true && self.detailModel == nil { + if SPNetworkReachabilityManager.manager.isReachable == true && self.detailDataArr.isEmpty { self.requestDetailData() } } @@ -345,6 +351,8 @@ extension SPPlayerDetailViewController { //MARK: -------------- SPPlayerListViewControllerDataSource -------------- extension SPPlayerDetailViewController: SPPlayerListViewControllerDataSource, SPPlayerListViewControllerDelegate { func sp_playerListViewController(_ viewController: SPPlayerListViewController, _ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath, oldCell: UICollectionViewCell) -> UICollectionViewCell { + let detailModel = self.detailDataArr[indexPath.section] as? SPVideoDetailModel + if let cell = oldCell as? SPPlayerDetailCell { cell.shortModel = detailModel?.shortPlayInfo cell.videoInfo = detailModel?.episodeList?[indexPath.row] @@ -372,15 +380,40 @@ extension SPPlayerDetailViewController: SPPlayerListViewControllerDataSource, SP } func sp_playerListViewController(_ viewController: SPPlayerListViewController, _ collectionView: UICollectionView, numberOfItemsInSection section: Int, oldNumber: Int) -> Int { - return detailModel?.episodeList?.count ?? 0 + if let model = self.detailDataArr[section] as? SPVideoDetailModel { + return model.episodeList?.count ?? 0 + } else { + return 1 + } } func sp_playerListViewController(_ viewController: SPPlayerListViewController, didChangeIndexPathForVisible indexPath: IndexPath) { - self.episodeView?.currentIndex = indexPath.row - let videoInfo = detailModel?.episodeList?[indexPath.row] - - titleLabel.text = detailModel?.shortPlayInfo?.name - episodeLabel.text = "\(videoInfo?.episode ?? "0")/\(detailModel?.shortPlayInfo?.episode_total ?? 0)" +// self.episodeView?.currentIndex = indexPath.row + + if let detailModel = self.detailDataArr[indexPath.section] as? SPVideoDetailModel { + let videoInfo = detailModel.episodeList?[indexPath.row] + + titleLabel.text = detailModel.shortPlayInfo?.name + episodeLabel.text = "\(videoInfo?.episode ?? "0")/\(detailModel.shortPlayInfo?.episode_total ?? 0)" + } else { + titleLabel.text = "" + episodeLabel.text = "" + } + } + + func sp_numberOfSections(in viewController: SPPlayerListViewController) -> Int { + return self.detailDataArr.count + } + + func sp_shouldAutoScrollNextEpisode(_ viewController: SPPlayerListViewController) -> Bool { + if episodeView != nil { + return false + } + return true + } + + func sp_playerViewControllerLoadMoreData(playerViewController: SPPlayerListViewController) { + } } @@ -403,7 +436,10 @@ extension SPPlayerDetailViewController { recommandTimer = nil recommandTimer = Timer.scheduledTimer(timeInterval: 6, target: YYWeakProxy(target: self), selector: #selector(handleRecommandTimer), userInfo: nil, repeats: false) + + SPHUD.show(containerView: self.view) SPVideoAPI.requestVideoDetail(videoId: videoId, shortPlayId: shortPlayId, activityId: activityId) { [weak self] model, code, msg in + SPHUD.dismiss() guard let self = self else { return } if code == 10014 { self.navigationController?.popViewController(animated: true) @@ -411,16 +447,19 @@ extension SPPlayerDetailViewController { } guard let model = model else { return } - self.detailModel = model + self.detailDataArr.removeAll() + self.detailDataArr.append(model) + + self.reloadData { [weak self] in guard let self = self else { return } if let indexPath = indexPath, indexPath.row < (model.episodeList?.count ?? 0) { self.scrollToItem(indexPath: indexPath, animated: false) - } else if let videoInfo = self.detailModel?.video_info { + } else if let videoInfo = model.video_info { var row: Int? - self.detailModel?.episodeList?.enumerated().forEach({ + model.episodeList?.enumerated().forEach({ if $1.id == videoInfo.id { row = $0 } diff --git a/ThimraTV/Class/Player/Controller/SPPlayerListViewController.swift b/ThimraTV/Class/Player/Controller/SPPlayerListViewController.swift index 3174692..1d6f9d0 100644 --- a/ThimraTV/Class/Player/Controller/SPPlayerListViewController.swift +++ b/ThimraTV/Class/Player/Controller/SPPlayerListViewController.swift @@ -17,15 +17,14 @@ import AVKit @objc optional func sp_playerViewControllerShouldLoadMoreData(playerViewController: SPPlayerListViewController) -> Bool ///加载更多数据 @objc optional func sp_playerViewControllerLoadMoreData(playerViewController: SPPlayerListViewController) - ///向上加载更多数据 - @objc optional func sp_playerViewControllerLoadUpMoreData(playerViewController: SPPlayerListViewController) ///当前展示的发生变化 @objc optional func sp_playerListViewController(_ viewController: SPPlayerListViewController, didChangeIndexPathForVisible indexPath: IndexPath) -// @objc optional func sp_playerListViewController(_ viewController: SPPlayerListViewController, didScrollFromIndex fromIndex: Int, toIndex: Int) - ///新页面展示完成 -// @objc optional func yd_playerViewController(playerListViewController: BCListPlayerViewController, didShowPlayerPage playerViewController: YDBasePlayerViewController) + ///即将自动滑至下一级 + @objc optional func sp_shouldAutoScrollNextEpisode(_ viewController: SPPlayerListViewController) -> Bool + + } @objc protocol SPPlayerListViewControllerDataSource { @@ -35,7 +34,7 @@ import AVKit func sp_playerListViewController(_ viewController: SPPlayerListViewController, _ collectionView: UICollectionView, numberOfItemsInSection section: Int, oldNumber: Int) -> Int - + @objc optional func sp_numberOfSections(in viewController: SPPlayerListViewController) -> Int } @@ -59,9 +58,6 @@ class SPPlayerListViewController: SPViewController { ///自动下一级 var autoNextEpisode = false - ///是否为首次播放 - private(set) var isFirstPlay = true - private(set) var viewModel = SPPlayerListViewModel() @@ -173,20 +169,10 @@ class SPPlayerListViewController: SPViewController { self.viewModel.isPlaying = true - if getDataCount() - self.viewModel.currentIndexPath.row <= 2 { + if (self.collectionView.contentSize.height - self.collectionView.contentOffset.y) / self.contentSize.height <= 3 { self.loadMoreData() } - if isFirstPlay { - isFirstPlay = false - let offset = self.collectionView.contentOffset.y + 0.2 - self.collectionView.setContentOffset(CGPoint(x: 0, y: offset), animated: false) - - DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { - let offset = self.collectionView.contentOffset.y - self.collectionView.setContentOffset(CGPoint(x: 0, y: floor(offset)), animated: false) - } - } } func pause() { @@ -210,7 +196,8 @@ class SPPlayerListViewController: SPViewController { } func getDataCount() -> Int { - return self.collectionView(self.collectionView, numberOfItemsInSection: 0) + return Int(self.collectionView.contentSize.height / self.contentSize.height) +// return self.collectionView(self.collectionView, numberOfItemsInSection: 0) } func scrollToItem(indexPath: IndexPath, animated: Bool = true, completer: (() -> Void)? = nil) { @@ -232,10 +219,19 @@ class SPPlayerListViewController: SPViewController { ///当前播放完成 子类可重写 func currentPlayFinish() { - if self.autoNextEpisode { - scrollToNextEpisode() - } self.viewModel.currentPlayer?.videoInfo?.play_seconds = 0 + + var autoNextEpisode = self.autoNextEpisode + + if let result = self.delegate?.sp_shouldAutoScrollNextEpisode?(self) { + autoNextEpisode = result + } + + if autoNextEpisode { + scrollToNextEpisode() + } else { + viewModel.currentPlayer?.replay() + } } ///当前播放进度变更 子类可重写 @@ -356,6 +352,10 @@ extension SPPlayerListViewController: UICollectionViewDelegate, UICollectionView } } + func numberOfSections(in collectionView: UICollectionView) -> Int { + return self.dataSource?.sp_numberOfSections?(in: self) ?? 1 + } + //滑动停止 func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) { scrollDidEnd(scrollView) @@ -415,13 +415,6 @@ extension SPPlayerListViewController { } } - private func loadUpMoreData() { -// DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { [weak self] in -// guard let self = self else { return } -// } - self.delegate?.sp_playerViewControllerLoadUpMoreData?(playerViewController: self) - } - private func didChangeIndexPathForVisible() { self.delegate?.sp_playerListViewController?(self, didChangeIndexPathForVisible: self.viewModel.currentIndexPath) } diff --git a/ThimraTV/Libs/HUD/SPHUD.swift b/ThimraTV/Libs/HUD/SPHUD.swift index 547b08c..1eb6c54 100644 --- a/ThimraTV/Libs/HUD/SPHUD.swift +++ b/ThimraTV/Libs/HUD/SPHUD.swift @@ -12,9 +12,9 @@ class SPHUD: NSObject { SVProgressHUD.setDefaultMaskType(.clear) } - static func show(status: String? = nil) { + static func show(status: String? = nil, containerView: UIView? = nil) { + SVProgressHUD.setContainerView(containerView) SVProgressHUD.setDefaultMaskType(.clear) -// SVProgressHUD.show() SVProgressHUD.show(withStatus: status) } diff --git a/ThimraTV/Thirdparty/JXIAPManager/JXIAPManager.swift b/ThimraTV/Thirdparty/JXIAPManager/JXIAPManager.swift index 8094f87..be1a2ff 100644 --- a/ThimraTV/Thirdparty/JXIAPManager/JXIAPManager.swift +++ b/ThimraTV/Thirdparty/JXIAPManager/JXIAPManager.swift @@ -95,7 +95,7 @@ class JXIAPManager: NSObject { } func requestProductList(productIdArr: [String]) { - guard self.operationType == .idle else { return } +// guard self.operationType == .idle else { return } self.operationType = .request let set = Set(productIdArr)