清晰度功能开发
This commit is contained in:
parent
b9cb5596db
commit
6a54c45a7c
@ -146,6 +146,14 @@
|
||||
BF5E75D32DE5692D00DE9DFE /* JXBaseAnimatedTransition.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF5E75C12DE5692D00DE9DFE /* JXBaseAnimatedTransition.swift */; };
|
||||
BF5E75D52DE56B2000DE9DFE /* VPHomeCagetoryRecommandContentCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF5E75D42DE56B2000DE9DFE /* VPHomeCagetoryRecommandContentCell.swift */; };
|
||||
BF5E75DB2DE5B8B700DE9DFE /* VPMarqueeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF5E75DA2DE5B8B700DE9DFE /* VPMarqueeView.swift */; };
|
||||
BF692AB52E0644B500A5C2DA /* VPRevolutionSelectedView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF692AB42E0644B500A5C2DA /* VPRevolutionSelectedView.swift */; };
|
||||
BF692AB72E06450C00A5C2DA /* VPRevolutionSelectedCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF692AB62E06450C00A5C2DA /* VPRevolutionSelectedCell.swift */; };
|
||||
BFA21D982E01477200B3573D /* VPStoreViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFA21D972E01477200B3573D /* VPStoreViewController.swift */; };
|
||||
BFA21D9A2E01497F00B3573D /* VPStoreVipBuyView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFA21D992E01497F00B3573D /* VPStoreVipBuyView.swift */; };
|
||||
BFA21D9C2E01628F00B3573D /* VPStoreCoinsBuyView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFA21D9B2E01628F00B3573D /* VPStoreCoinsBuyView.swift */; };
|
||||
BFA21D9E2E01684E00B3573D /* VPStoreCoinsItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFA21D9D2E01684E00B3573D /* VPStoreCoinsItemView.swift */; };
|
||||
BFA21DA02E01688D00B3573D /* VPStoreCoinsBigItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFA21D9F2E01688D00B3573D /* VPStoreCoinsBigItemView.swift */; };
|
||||
BFA21DA22E01696700B3573D /* VPStoreCoinsSmallItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFA21DA12E01696700B3573D /* VPStoreCoinsSmallItemView.swift */; };
|
||||
BFCCE10D2DF951F600EDE165 /* SceneDelegate+APNS.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFCCE10C2DF951ED00EDE165 /* SceneDelegate+APNS.swift */; };
|
||||
BFCCE1122DF9638B00EDE165 /* VPVipAlertView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFCCE1112DF9638B00EDE165 /* VPVipAlertView.swift */; };
|
||||
BFCCE1142DFAAC0900EDE165 /* VPLanguageViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFCCE1132DFAAC0900EDE165 /* VPLanguageViewController.swift */; };
|
||||
@ -162,12 +170,6 @@
|
||||
BFCCE13D2DFFFAC500EDE165 /* NotificationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFCCE13B2DFFFAC500EDE165 /* NotificationService.swift */; };
|
||||
BFCCE1402E000ACE00EDE165 /* VPAnpsAlertView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFCCE13F2E000ACE00EDE165 /* VPAnpsAlertView.swift */; };
|
||||
BFCCE1422E000F4800EDE165 /* VPHomePlayHistoricalView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFCCE1412E000F4800EDE165 /* VPHomePlayHistoricalView.swift */; };
|
||||
BFA21D982E01477200B3573D /* VPStoreViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFA21D972E01477200B3573D /* VPStoreViewController.swift */; };
|
||||
BFA21D9A2E01497F00B3573D /* VPStoreVipBuyView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFA21D992E01497F00B3573D /* VPStoreVipBuyView.swift */; };
|
||||
BFA21D9C2E01628F00B3573D /* VPStoreCoinsBuyView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFA21D9B2E01628F00B3573D /* VPStoreCoinsBuyView.swift */; };
|
||||
BFA21D9E2E01684E00B3573D /* VPStoreCoinsItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFA21D9D2E01684E00B3573D /* VPStoreCoinsItemView.swift */; };
|
||||
BFA21DA02E01688D00B3573D /* VPStoreCoinsBigItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFA21D9F2E01688D00B3573D /* VPStoreCoinsBigItemView.swift */; };
|
||||
BFA21DA22E01696700B3573D /* VPStoreCoinsSmallItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFA21DA12E01696700B3573D /* VPStoreCoinsSmallItemView.swift */; };
|
||||
BFF5AFA42DE6F15E0044227A /* VPMeVipCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF5AFA32DE6F15E0044227A /* VPMeVipCell.swift */; };
|
||||
BFF5AFA62DE700420044227A /* VPMeVipPrivilegeItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF5AFA52DE700420044227A /* VPMeVipPrivilegeItemView.swift */; };
|
||||
BFF5AFA82DE704DC0044227A /* VPMeCoinCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF5AFA72DE704DC0044227A /* VPMeCoinCell.swift */; };
|
||||
@ -418,6 +420,14 @@
|
||||
BF5E75C92DE5692D00DE9DFE /* UIViewController+JXTransition.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIViewController+JXTransition.swift"; sourceTree = "<group>"; };
|
||||
BF5E75D42DE56B2000DE9DFE /* VPHomeCagetoryRecommandContentCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPHomeCagetoryRecommandContentCell.swift; sourceTree = "<group>"; };
|
||||
BF5E75DA2DE5B8B700DE9DFE /* VPMarqueeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPMarqueeView.swift; sourceTree = "<group>"; };
|
||||
BF692AB42E0644B500A5C2DA /* VPRevolutionSelectedView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPRevolutionSelectedView.swift; sourceTree = "<group>"; };
|
||||
BF692AB62E06450C00A5C2DA /* VPRevolutionSelectedCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPRevolutionSelectedCell.swift; sourceTree = "<group>"; };
|
||||
BFA21D972E01477200B3573D /* VPStoreViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPStoreViewController.swift; sourceTree = "<group>"; };
|
||||
BFA21D992E01497F00B3573D /* VPStoreVipBuyView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPStoreVipBuyView.swift; sourceTree = "<group>"; };
|
||||
BFA21D9B2E01628F00B3573D /* VPStoreCoinsBuyView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPStoreCoinsBuyView.swift; sourceTree = "<group>"; };
|
||||
BFA21D9D2E01684E00B3573D /* VPStoreCoinsItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPStoreCoinsItemView.swift; sourceTree = "<group>"; };
|
||||
BFA21D9F2E01688D00B3573D /* VPStoreCoinsBigItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPStoreCoinsBigItemView.swift; sourceTree = "<group>"; };
|
||||
BFA21DA12E01696700B3573D /* VPStoreCoinsSmallItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPStoreCoinsSmallItemView.swift; sourceTree = "<group>"; };
|
||||
BFCCE10C2DF951ED00EDE165 /* SceneDelegate+APNS.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SceneDelegate+APNS.swift"; sourceTree = "<group>"; };
|
||||
BFCCE1112DF9638B00EDE165 /* VPVipAlertView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPVipAlertView.swift; sourceTree = "<group>"; };
|
||||
BFCCE1132DFAAC0900EDE165 /* VPLanguageViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPLanguageViewController.swift; sourceTree = "<group>"; };
|
||||
@ -433,12 +443,6 @@
|
||||
BFCCE13B2DFFFAC500EDE165 /* NotificationService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationService.swift; sourceTree = "<group>"; };
|
||||
BFCCE13F2E000ACE00EDE165 /* VPAnpsAlertView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPAnpsAlertView.swift; sourceTree = "<group>"; };
|
||||
BFCCE1412E000F4800EDE165 /* VPHomePlayHistoricalView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPHomePlayHistoricalView.swift; sourceTree = "<group>"; };
|
||||
BFA21D972E01477200B3573D /* VPStoreViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPStoreViewController.swift; sourceTree = "<group>"; };
|
||||
BFA21D992E01497F00B3573D /* VPStoreVipBuyView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPStoreVipBuyView.swift; sourceTree = "<group>"; };
|
||||
BFA21D9B2E01628F00B3573D /* VPStoreCoinsBuyView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPStoreCoinsBuyView.swift; sourceTree = "<group>"; };
|
||||
BFA21D9D2E01684E00B3573D /* VPStoreCoinsItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPStoreCoinsItemView.swift; sourceTree = "<group>"; };
|
||||
BFA21D9F2E01688D00B3573D /* VPStoreCoinsBigItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPStoreCoinsBigItemView.swift; sourceTree = "<group>"; };
|
||||
BFA21DA12E01696700B3573D /* VPStoreCoinsSmallItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPStoreCoinsSmallItemView.swift; sourceTree = "<group>"; };
|
||||
BFF5AFA32DE6F15E0044227A /* VPMeVipCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPMeVipCell.swift; sourceTree = "<group>"; };
|
||||
BFF5AFA52DE700420044227A /* VPMeVipPrivilegeItemView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPMeVipPrivilegeItemView.swift; sourceTree = "<group>"; };
|
||||
BFF5AFA72DE704DC0044227A /* VPMeCoinCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VPMeCoinCell.swift; sourceTree = "<group>"; };
|
||||
@ -1002,6 +1006,8 @@
|
||||
BFF5B2742DF2C3750044227A /* VPDetailRecommandView.swift */,
|
||||
BFF5B2762DF2CA4B0044227A /* VPDetailRecommandBannerCell.swift */,
|
||||
BFF5B4AE2DF6B6630044227A /* VPMutualCollectionView.swift */,
|
||||
BF692AB42E0644B500A5C2DA /* VPRevolutionSelectedView.swift */,
|
||||
BF692AB62E06450C00A5C2DA /* VPRevolutionSelectedCell.swift */,
|
||||
);
|
||||
path = View;
|
||||
sourceTree = "<group>";
|
||||
@ -1480,10 +1486,14 @@
|
||||
inputFileListPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-Veloria/Pods-Veloria-frameworks-${CONFIGURATION}-input-files.xcfilelist",
|
||||
);
|
||||
inputPaths = (
|
||||
);
|
||||
name = "[CP] Embed Pods Frameworks";
|
||||
outputFileListPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-Veloria/Pods-Veloria-frameworks-${CONFIGURATION}-output-files.xcfilelist",
|
||||
);
|
||||
outputPaths = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Veloria/Pods-Veloria-frameworks.sh\"\n";
|
||||
@ -1511,6 +1521,7 @@
|
||||
BF0FA7B32DE447FE00C9E5F2 /* VPMeCell.swift in Sources */,
|
||||
BF0FA6DF2DDC5E4D00C9E5F2 /* String+VPAdd.swift in Sources */,
|
||||
BF0FA7002DDC665300C9E5F2 /* VPShortModel.swift in Sources */,
|
||||
BF692AB72E06450C00A5C2DA /* VPRevolutionSelectedCell.swift in Sources */,
|
||||
1B056E7B2DDB37BA007EE38D /* VPGradientView.swift in Sources */,
|
||||
BF0FA7262DDC8F7600C9E5F2 /* VPCollectionView.swift in Sources */,
|
||||
BF5E75DB2DE5B8B700DE9DFE /* VPMarqueeView.swift in Sources */,
|
||||
@ -1554,6 +1565,7 @@
|
||||
BF0FA73B2DDED1C700C9E5F2 /* VPHomeListCell.swift in Sources */,
|
||||
BF0FA79F2DE1A29A00C9E5F2 /* VPCollectListCell.swift in Sources */,
|
||||
BF0FA7592DDF1C2800C9E5F2 /* VPPlayerProgressView.swift in Sources */,
|
||||
BF692AB52E0644B500A5C2DA /* VPRevolutionSelectedView.swift in Sources */,
|
||||
BFF5AFE02DEEC5AB0044227A /* VPPlayerVipBuyView.swift in Sources */,
|
||||
BFF5AFCA2DE97B7A0044227A /* VPWalletViewController.swift in Sources */,
|
||||
BFF5B26C2DF28FD50044227A /* VPStatAPI.swift in Sources */,
|
||||
|
@ -10,7 +10,7 @@ import UIKit
|
||||
class VPVideoAPI: NSObject {
|
||||
|
||||
///获取视频详情
|
||||
static func requestVideoDetail(shortPlayId: String, activityId: String? = nil, completer: ((_ model: VPVideoDetailModel?) -> Void)?) {
|
||||
static func requestVideoDetail(shortPlayId: String, activityId: String? = nil, revolution: VPShortModel.VideoRevolution? = nil, completer: ((_ model: VPVideoDetailModel?) -> Void)?) {
|
||||
var parameters: [String : Any] = [
|
||||
"short_play_id" : shortPlayId,
|
||||
"video_id" : "0"
|
||||
@ -20,6 +20,10 @@ class VPVideoAPI: NSObject {
|
||||
parameters["activity_id"] = activityId
|
||||
}
|
||||
|
||||
if let revolution = revolution?.rawValue {
|
||||
parameters["revolution"] = revolution
|
||||
}
|
||||
|
||||
var param = VPNetworkParameters(path: "/getVideoDetails")
|
||||
param.method = .get
|
||||
param.parameters = parameters
|
||||
|
@ -9,6 +9,8 @@ import UIKit
|
||||
|
||||
class VPLoginContentView: HWPanModalContentView {
|
||||
|
||||
var loginFinishBlock: (() -> Void)?
|
||||
|
||||
private lazy var bgView: UIImageView = {
|
||||
let imageView = UIImageView(image: UIImage(named: "bg_image_01"))
|
||||
return imageView
|
||||
@ -167,6 +169,7 @@ extension VPLoginContentView {
|
||||
VPHUD.dismiss()
|
||||
guard let self = self else { return }
|
||||
if isFinish {
|
||||
self.loginFinishBlock?()
|
||||
self.dismiss(animated: true) {
|
||||
|
||||
}
|
||||
|
@ -162,6 +162,11 @@ extension VPDetailPlayerViewController {
|
||||
self.viewModel.handleUnlock = { [weak self] in
|
||||
self?.unlockVideo()
|
||||
}
|
||||
|
||||
self.viewModel.updateDetailDataBlock = { [weak self] toIndexPath in
|
||||
guard let self = self else { return }
|
||||
self.requestDetailData(indexPath: self.viewModel.currentIndexPath)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -171,7 +176,7 @@ extension VPDetailPlayerViewController {
|
||||
let view = VPEpisodeView()
|
||||
view.dataArr = detailModel?.episodeList ?? []
|
||||
view.shortModel = detailModel?.shortPlayInfo
|
||||
view.currentIndex = self.currentIndexPath.row
|
||||
view.currentIndex = self.viewModel.currentIndexPath.row
|
||||
view.didSelectedIndex = { [weak self] (index) in
|
||||
self?.scrollToItem(indexPath: IndexPath(row: index, section: 0), animated: false)
|
||||
}
|
||||
@ -224,7 +229,7 @@ extension VPDetailPlayerViewController {
|
||||
view.videoId = videoInfo.short_play_video_id
|
||||
view.buyFinishBlock = { [weak self] in
|
||||
guard let self = self else { return }
|
||||
self.requestDetailData(indexPath: self.currentIndexPath)
|
||||
self.requestDetailData(indexPath: self.viewModel.currentIndexPath)
|
||||
}
|
||||
view.present(in: nil)
|
||||
}
|
||||
@ -343,7 +348,7 @@ extension VPDetailPlayerViewController {
|
||||
|
||||
|
||||
VPHUD.show(containerView: self.view)
|
||||
VPVideoAPI.requestVideoDetail(shortPlayId: shortPlayId, activityId: activityId) { [weak self] model in
|
||||
VPVideoAPI.requestVideoDetail(shortPlayId: shortPlayId, activityId: activityId, revolution: self.viewModel.revolution) { [weak self] model in
|
||||
VPHUD.dismiss()
|
||||
guard let self = self else { return }
|
||||
guard let model = model else { return }
|
||||
|
@ -52,8 +52,6 @@ class VPVideoPlayerViewController: VPViewController {
|
||||
|
||||
private(set) var dataArr: [Any] = []
|
||||
|
||||
private(set) var currentIndexPath = IndexPath(row: 0, section: 0)
|
||||
|
||||
///自动下一级
|
||||
var autoNextEpisode = true
|
||||
|
||||
@ -120,7 +118,7 @@ class VPVideoPlayerViewController: VPViewController {
|
||||
|
||||
self.viewModel.isPlaying = true
|
||||
|
||||
if getDataCount() - currentIndexPath.row <= 2 {
|
||||
if getDataCount() - viewModel.currentIndexPath.row <= 2 {
|
||||
self.loadMoreData()
|
||||
}
|
||||
|
||||
@ -144,7 +142,7 @@ class VPVideoPlayerViewController: VPViewController {
|
||||
func clearDataArr() {
|
||||
self.dataArr.removeAll()
|
||||
self.viewModel.currentPlayer = nil
|
||||
self.currentIndexPath = .init(row: 0, section: 0)
|
||||
viewModel.currentIndexPath = .init(row: 0, section: 0)
|
||||
self.collectionView.contentOffset = .init(x: 0, y: 0)
|
||||
self.collectionView.reloadData()
|
||||
}
|
||||
@ -176,7 +174,7 @@ class VPVideoPlayerViewController: VPViewController {
|
||||
func reloadData(completion: (() -> Void)? = nil) {
|
||||
CATransaction.setCompletionBlock { [weak self] in
|
||||
guard let self = self else { return }
|
||||
let cell = self.collectionView.cellForItem(at: self.currentIndexPath) as? VPVideoPlayerCell
|
||||
let cell = self.collectionView.cellForItem(at: viewModel.currentIndexPath) as? VPVideoPlayerCell
|
||||
self.viewModel.currentPlayer = cell
|
||||
|
||||
completion?()
|
||||
@ -190,7 +188,7 @@ class VPVideoPlayerViewController: VPViewController {
|
||||
CATransaction.setCompletionBlock { [weak self] in
|
||||
guard let self = self else { return }
|
||||
if !animated {
|
||||
if self.currentIndexPath != indexPath, indexPath.row < self.getDataCount() {
|
||||
if viewModel.currentIndexPath != indexPath, indexPath.row < self.getDataCount() {
|
||||
self.skip(indexPath: indexPath)
|
||||
} else {
|
||||
self.play()
|
||||
@ -315,8 +313,8 @@ extension VPVideoPlayerViewController: UICollectionViewDelegate, UICollectionVie
|
||||
}
|
||||
}
|
||||
|
||||
if self.viewModel.currentPlayer == nil, indexPath == currentIndexPath, let playerProtocol = cell as? VPPlayerProtocol {
|
||||
self.currentIndexPath = indexPath
|
||||
if self.viewModel.currentPlayer == nil, indexPath == viewModel.currentIndexPath, let playerProtocol = cell as? VPPlayerProtocol {
|
||||
viewModel.currentIndexPath = indexPath
|
||||
self.viewModel.currentPlayer = playerProtocol
|
||||
didChangeIndexPathForVisible()
|
||||
}
|
||||
@ -349,7 +347,7 @@ extension VPVideoPlayerViewController: UICollectionViewDelegate, UICollectionVie
|
||||
for indexPath in indexPaths {
|
||||
guard let cell = self.collectionView.cellForItem(at: indexPath) else { continue }
|
||||
if floor(offsetY) == floor(cell.frame.origin.y) {
|
||||
if self.currentIndexPath != indexPath {
|
||||
if viewModel.currentIndexPath != indexPath {
|
||||
self.skip(indexPath: indexPath)
|
||||
}
|
||||
}
|
||||
@ -357,7 +355,7 @@ extension VPVideoPlayerViewController: UICollectionViewDelegate, UICollectionVie
|
||||
}
|
||||
|
||||
private func skip(indexPath: IndexPath) {
|
||||
currentIndexPath = indexPath
|
||||
viewModel.currentIndexPath = indexPath
|
||||
guard let currentPlayer = self.collectionView.cellForItem(at: indexPath) as? VPPlayerProtocol else { return }
|
||||
self.viewModel.currentPlayer = currentPlayer
|
||||
// currentCell = self.collectionView.cellForItem(at: indexPath) as? BCListPlayerCell
|
||||
@ -381,7 +379,7 @@ extension VPVideoPlayerViewController {
|
||||
}
|
||||
|
||||
private func didChangeIndexPathForVisible() {
|
||||
self.delegate?.vp_playerListViewController?(self, didChangeIndexPathForVisible: self.currentIndexPath)
|
||||
self.delegate?.vp_playerListViewController?(self, didChangeIndexPathForVisible: viewModel.currentIndexPath)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -10,6 +10,32 @@ import SmartCodable
|
||||
|
||||
class VPShortModel: VPModel, SmartCodable {
|
||||
|
||||
enum VideoRevolution: String, SmartCaseDefaultable {
|
||||
case r_540 = "540"
|
||||
case r_720 = "720"
|
||||
case r_1080 = "1080"
|
||||
|
||||
var needLogin: Bool {
|
||||
if self == .r_720 {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
var needVip: Bool {
|
||||
if self == .r_1080 {
|
||||
return true
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
var toString: String {
|
||||
return "\(self.rawValue)P"
|
||||
}
|
||||
}
|
||||
|
||||
enum TagType: String, SmartCaseDefaultable {
|
||||
case hot = "hot"
|
||||
case new = "new"
|
||||
@ -39,6 +65,8 @@ class VPShortModel: VPModel, SmartCodable {
|
||||
var video_url: String?
|
||||
var updated_at: String?
|
||||
|
||||
var revolution: VideoRevolution?
|
||||
|
||||
@IgnoredKey
|
||||
var titleAttributedString: NSAttributedString?
|
||||
@IgnoredKey
|
||||
|
@ -14,6 +14,7 @@ class VPDetailPlayerControlView: VPVideoPlayerControlView {
|
||||
self.viewModel?.addObserver(self, forKeyPath: "rateModel", options: .new, context: nil)
|
||||
|
||||
rateButton.setTitle(self.viewModel?.rateModel.formatString(), for: .normal)
|
||||
revolutionButton.setNeedsUpdateConfiguration()
|
||||
}
|
||||
}
|
||||
|
||||
@ -30,6 +31,8 @@ class VPDetailPlayerControlView: VPVideoPlayerControlView {
|
||||
epView.setTitle("veloria_EP.".localizedReplace(text: videoInfo?.episode ?? "0"), for: .normal)
|
||||
lockView.isHidden = !(videoInfo?.is_lock ?? false)
|
||||
lockView.videoInfo = videoInfo
|
||||
|
||||
revolutionButton.setNeedsUpdateConfiguration()
|
||||
}
|
||||
}
|
||||
|
||||
@ -51,6 +54,15 @@ class VPDetailPlayerControlView: VPVideoPlayerControlView {
|
||||
}
|
||||
}
|
||||
|
||||
override var isCurrent: Bool {
|
||||
didSet {
|
||||
if !isCurrent {
|
||||
rateSelectedView.removeFromSuperview()
|
||||
revolutionSelectedView.removeFromSuperview()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//MARK: -------------- UI属性 --------------
|
||||
private lazy var bottomView: VPGradientView = {
|
||||
let view = VPGradientView()
|
||||
@ -104,6 +116,23 @@ class VPDetailPlayerControlView: VPVideoPlayerControlView {
|
||||
return button
|
||||
}()
|
||||
|
||||
///分辨率
|
||||
private lazy var revolutionButton: UIButton = {
|
||||
var config = UIButton.Configuration.plain()
|
||||
config.contentInsets = .init(top: 0, leading: 12, bottom: 0, trailing: 12)
|
||||
config.background.backgroundColor = .color949494(alpha: 0.4)
|
||||
|
||||
let button = UIButton(configuration: config)
|
||||
button.layer.cornerRadius = 15
|
||||
button.layer.masksToBounds = true
|
||||
button.configurationUpdateHandler = { [weak self] button in
|
||||
guard let self = self else { return }
|
||||
button.configuration?.attributedTitle = AttributedString.createAttributedString(string: self.viewModel?.revolution.toString ?? "", color: .colorFFFFFF(), font: .fontRegular(ofSize: 13))
|
||||
}
|
||||
button.addTarget(self, action: #selector(handleRevolutionButton), for: .touchUpInside)
|
||||
return button
|
||||
}()
|
||||
|
||||
private lazy var timeLabel: UILabel = {
|
||||
let label = UILabel()
|
||||
label.font = .fontRegular(ofSize: 12)
|
||||
@ -122,6 +151,16 @@ class VPDetailPlayerControlView: VPVideoPlayerControlView {
|
||||
return view
|
||||
}()
|
||||
|
||||
///分辨率选择
|
||||
private lazy var revolutionSelectedView: VPRevolutionSelectedView = {
|
||||
let view = VPRevolutionSelectedView()
|
||||
view.didSelected = { [weak self] revolution in
|
||||
guard let self = self else { return }
|
||||
self.viewModel?.selectedRevolution(revolution: revolution)
|
||||
}
|
||||
return view
|
||||
}()
|
||||
|
||||
private lazy var lockView: VPVideoLockView = {
|
||||
let view = VPVideoLockView()
|
||||
view.clickUnlockButton = { [weak self] in
|
||||
@ -176,6 +215,15 @@ extension VPDetailPlayerControlView {
|
||||
}
|
||||
}
|
||||
|
||||
@objc private func handleRevolutionButton() {
|
||||
addSubview(revolutionSelectedView)
|
||||
revolutionSelectedView.currentRevolution = self.viewModel?.revolution
|
||||
|
||||
revolutionSelectedView.snp.makeConstraints { make in
|
||||
make.edges.equalToSuperview()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension VPDetailPlayerControlView {
|
||||
@ -188,6 +236,7 @@ extension VPDetailPlayerControlView {
|
||||
addSubview(epBgView)
|
||||
epBgView.addSubview(epView)
|
||||
epBgView.addSubview(allEpView)
|
||||
addSubview(revolutionButton)
|
||||
addSubview(rateButton)
|
||||
addSubview(timeLabel)
|
||||
addSubview(lockView)
|
||||
@ -224,9 +273,14 @@ extension VPDetailPlayerControlView {
|
||||
make.right.equalToSuperview().offset(-10)
|
||||
}
|
||||
|
||||
revolutionButton.snp.makeConstraints { make in
|
||||
make.height.top.equalTo(epBgView)
|
||||
make.left.equalTo(epBgView.snp.right).offset(10)
|
||||
}
|
||||
|
||||
rateButton.snp.makeConstraints { make in
|
||||
make.right.equalToSuperview().offset(-15)
|
||||
make.left.equalTo(epBgView.snp.right).offset(10)
|
||||
make.left.equalTo(revolutionButton.snp.right).offset(10)
|
||||
make.height.top.equalTo(epBgView)
|
||||
make.width.equalTo(50)
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ class VPPlayerRechargeView: HWPanModalContentView {
|
||||
}
|
||||
|
||||
var buyFinishBlock: (() -> Void)?
|
||||
var vipBuyFinishBlock: (() -> Void)?
|
||||
|
||||
//MARK: UI属性
|
||||
private lazy var bgView: UIImageView = {
|
||||
@ -64,7 +65,12 @@ class VPPlayerRechargeView: HWPanModalContentView {
|
||||
private lazy var vipView: VPStoreVipBuyView = {
|
||||
let view = VPStoreVipBuyView()
|
||||
view.buyFinishBlock = { [weak self] in
|
||||
self?.buyFinishBlock?()
|
||||
if let vipBuyFinishBlock = self?.vipBuyFinishBlock {
|
||||
self?.vipBuyFinishBlock?()
|
||||
} else {
|
||||
self?.buyFinishBlock?()
|
||||
}
|
||||
|
||||
self?.dismiss(animated: true) {
|
||||
}
|
||||
}
|
||||
|
86
Veloria/Class/Player/View/VPRevolutionSelectedCell.swift
Normal file
86
Veloria/Class/Player/View/VPRevolutionSelectedCell.swift
Normal file
@ -0,0 +1,86 @@
|
||||
//
|
||||
// VPRevolutionSelectedCell.swift
|
||||
// Veloria
|
||||
//
|
||||
// Created by 湖南秦九 on 2025/6/21.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
class VPRevolutionSelectedCell: VPCollectionViewCell {
|
||||
|
||||
var videoRevolution: VPShortModel.VideoRevolution? {
|
||||
didSet {
|
||||
label.text = videoRevolution?.toString
|
||||
|
||||
if videoRevolution?.needLogin == true {
|
||||
markImageView.isHidden = false
|
||||
markImageView.image = UIImage(named: "mark_icon_01")
|
||||
} else if videoRevolution?.needVip == true {
|
||||
markImageView.isHidden = false
|
||||
markImageView.image = UIImage(named: "mark_icon_02")
|
||||
} else {
|
||||
markImageView.isHidden = true
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
var vp_isSelected: Bool = false {
|
||||
didSet {
|
||||
if vp_isSelected {
|
||||
contentView.vp_setGradientBorder()
|
||||
contentView.backgroundColor = .color1C2D2F(alpha: 0.6)
|
||||
|
||||
} else {
|
||||
contentView.vp_removeGradientBorder()
|
||||
contentView.backgroundColor = .color000000(alpha: 0.3)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private lazy var label: UILabel = {
|
||||
let label = UILabel()
|
||||
label.font = .fontRegular(ofSize: 14)
|
||||
label.textColor = .colorFFFFFF()
|
||||
return label
|
||||
}()
|
||||
|
||||
private lazy var markImageView: UIImageView = {
|
||||
let imageView = UIImageView()
|
||||
return imageView
|
||||
}()
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
vp_setupUI()
|
||||
}
|
||||
|
||||
@MainActor required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
extension VPRevolutionSelectedCell {
|
||||
|
||||
private func vp_setupUI() {
|
||||
contentView.layer.cornerRadius = 6
|
||||
contentView.layer.masksToBounds = false
|
||||
|
||||
|
||||
|
||||
contentView.addSubview(label)
|
||||
contentView.addSubview(markImageView)
|
||||
|
||||
label.snp.makeConstraints { make in
|
||||
make.center.equalToSuperview()
|
||||
}
|
||||
|
||||
markImageView.snp.makeConstraints { make in
|
||||
make.right.equalToSuperview()
|
||||
make.top.equalToSuperview().offset(-5)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
107
Veloria/Class/Player/View/VPRevolutionSelectedView.swift
Normal file
107
Veloria/Class/Player/View/VPRevolutionSelectedView.swift
Normal file
@ -0,0 +1,107 @@
|
||||
//
|
||||
// VPRevolutionSelectedView.swift
|
||||
// Veloria
|
||||
//
|
||||
// Created by 湖南秦九 on 2025/6/21.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
class VPRevolutionSelectedView: UIView {
|
||||
|
||||
var currentRevolution: VPShortModel.VideoRevolution? {
|
||||
didSet {
|
||||
collectionView.reloadData()
|
||||
}
|
||||
}
|
||||
|
||||
var didSelected: ((_ revolution: VPShortModel.VideoRevolution) -> Void)?
|
||||
|
||||
private lazy var dataArr: [VPShortModel.VideoRevolution] = {
|
||||
return [.r_540, .r_720, .r_1080]
|
||||
}()
|
||||
|
||||
private lazy var collectionViewLayout: UICollectionViewFlowLayout = {
|
||||
let layout = UICollectionViewFlowLayout()
|
||||
layout.scrollDirection = .horizontal
|
||||
layout.itemSize = .init(width: 100, height: 54)
|
||||
layout.minimumLineSpacing = 10
|
||||
layout.sectionInset = .init(top: 0, left: 15, bottom: 0, right: 15)
|
||||
return layout
|
||||
}()
|
||||
|
||||
private lazy var collectionView: VPCollectionView = {
|
||||
let collectionView = VPCollectionView(frame: .zero, collectionViewLayout: collectionViewLayout)
|
||||
collectionView.delegate = self
|
||||
collectionView.dataSource = self
|
||||
collectionView.register(VPRevolutionSelectedCell.self, forCellWithReuseIdentifier: "cell")
|
||||
collectionView.showsHorizontalScrollIndicator = false
|
||||
collectionView.layer.masksToBounds = false
|
||||
return collectionView
|
||||
}()
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
let tap = UITapGestureRecognizer(target: self, action: #selector(handleDismiss))
|
||||
tap.delegate = self
|
||||
self.addGestureRecognizer(tap)
|
||||
vp_setupUI()
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
@objc func handleDismiss() {
|
||||
self.removeFromSuperview()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
extension VPRevolutionSelectedView {
|
||||
|
||||
private func vp_setupUI() {
|
||||
addSubview(collectionView)
|
||||
|
||||
collectionView.snp.makeConstraints { make in
|
||||
make.left.right.equalToSuperview()
|
||||
make.bottom.equalToSuperview().offset(-(UIScreen.tabbarSafeBottomMargin + 85))
|
||||
make.height.equalTo(54)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//MARK: -------------- UICollectionViewDelegate UICollectionViewDataSource --------------
|
||||
extension VPRevolutionSelectedView: UICollectionViewDelegate, UICollectionViewDataSource {
|
||||
|
||||
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
|
||||
let videoRevolution = dataArr[indexPath.row]
|
||||
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! VPRevolutionSelectedCell
|
||||
cell.videoRevolution = videoRevolution
|
||||
cell.vp_isSelected = currentRevolution == videoRevolution
|
||||
return cell
|
||||
}
|
||||
|
||||
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
|
||||
return dataArr.count
|
||||
}
|
||||
|
||||
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
|
||||
let videoRevolution = dataArr[indexPath.row]
|
||||
self.didSelected?(videoRevolution)
|
||||
self.handleDismiss()
|
||||
}
|
||||
}
|
||||
|
||||
//MARK: -------------- UIGestureRecognizerDelegate --------------
|
||||
extension VPRevolutionSelectedView: UIGestureRecognizerDelegate {
|
||||
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
|
||||
if touch.view != self {
|
||||
return false
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
@ -11,6 +11,7 @@ class VPVideoPlayViewModel: NSObject {
|
||||
|
||||
@objc dynamic var isPlaying: Bool = true
|
||||
|
||||
var currentIndexPath = IndexPath(row: 0, section: 0)
|
||||
|
||||
var currentPlayer: VPPlayerProtocol? {
|
||||
didSet {
|
||||
@ -29,6 +30,9 @@ class VPVideoPlayViewModel: NSObject {
|
||||
}
|
||||
}
|
||||
|
||||
///当前分辨率
|
||||
lazy var revolution: VPShortModel.VideoRevolution = .r_540
|
||||
|
||||
///设置进度
|
||||
func seekToTime(toTime: Int) {
|
||||
self.currentPlayer?.seekToTime(toTime: toTime)
|
||||
@ -44,4 +48,46 @@ class VPVideoPlayViewModel: NSObject {
|
||||
var handleEpisode: (() -> Void)?
|
||||
|
||||
var handleUnlock: (() -> Void)?
|
||||
|
||||
///更新数据
|
||||
var updateDetailDataBlock: ((_ toIndexPath: IndexPath?) -> Void)?
|
||||
}
|
||||
|
||||
extension VPVideoPlayViewModel {
|
||||
///选择了新的分辨率
|
||||
func selectedRevolution(revolution: VPShortModel.VideoRevolution) {
|
||||
guard self.revolution != revolution else { return }
|
||||
let userInfo = VPLoginManager.manager.userInfo
|
||||
|
||||
if revolution.needLogin, userInfo?.is_tourist != false {
|
||||
|
||||
VPLoginManager.manager.openLogin { [weak self] in
|
||||
guard let self = self else { return }
|
||||
self.revolution = revolution
|
||||
self.updateDetailDataBlock?(self.currentIndexPath)
|
||||
}
|
||||
|
||||
} else if revolution.needVip, userInfo?.is_vip != true {
|
||||
guard let videoInfo = self.currentPlayer?.videoInfo else { return }
|
||||
|
||||
let view = VPPlayerRechargeView()
|
||||
view.shortPlayId = videoInfo.short_play_id
|
||||
view.videoId = videoInfo.short_play_video_id
|
||||
view.buyFinishBlock = { [weak self] in
|
||||
guard let self = self else { return }
|
||||
self.updateDetailDataBlock?(self.currentIndexPath)
|
||||
}
|
||||
view.vipBuyFinishBlock = { [weak self] in
|
||||
guard let self = self else { return }
|
||||
self.revolution = revolution
|
||||
self.updateDetailDataBlock?(self.currentIndexPath)
|
||||
}
|
||||
view.present(in: nil)
|
||||
} else {
|
||||
self.revolution = revolution
|
||||
self.updateDetailDataBlock?(self.currentIndexPath)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -8,6 +8,9 @@
|
||||
import UIKit
|
||||
|
||||
class VPStoreViewController: VPViewController {
|
||||
|
||||
///vip购买成功回调
|
||||
var vipBuyFinishBlock: (() -> Void)?
|
||||
|
||||
private lazy var scrollView: VPScrollView = {
|
||||
let scrollView = VPScrollView()
|
||||
@ -23,6 +26,10 @@ class VPStoreViewController: VPViewController {
|
||||
|
||||
private lazy var vipView: VPStoreVipBuyView = {
|
||||
let view = VPStoreVipBuyView()
|
||||
view.buyFinishBlock = { [weak self] in
|
||||
guard let self = self else { return }
|
||||
self.vipBuyFinishBlock?()
|
||||
}
|
||||
return view
|
||||
}()
|
||||
|
||||
|
@ -38,8 +38,9 @@ class VPLoginManager: NSObject {
|
||||
UserDefaults.vp_setObject(token, forKey: kVPLoginTokenDefaultsKey)
|
||||
}
|
||||
|
||||
func openLogin() {
|
||||
func openLogin(finishHandle: (() -> Void)? = nil) {
|
||||
let view = VPLoginContentView()
|
||||
view.loginFinishBlock = finishHandle
|
||||
view.present(in: nil)
|
||||
}
|
||||
|
||||
|
22
Veloria/Source/Assets.xcassets/icon/mark_icon_01.imageset/Contents.json
vendored
Normal file
22
Veloria/Source/Assets.xcassets/icon/mark_icon_01.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"filename" : "Group 79@2x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "Group 79@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
BIN
Veloria/Source/Assets.xcassets/icon/mark_icon_01.imageset/Group 79@2x.png
vendored
Normal file
BIN
Veloria/Source/Assets.xcassets/icon/mark_icon_01.imageset/Group 79@2x.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.2 KiB |
BIN
Veloria/Source/Assets.xcassets/icon/mark_icon_01.imageset/Group 79@3x.png
vendored
Normal file
BIN
Veloria/Source/Assets.xcassets/icon/mark_icon_01.imageset/Group 79@3x.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.7 KiB |
22
Veloria/Source/Assets.xcassets/icon/mark_icon_02.imageset/Contents.json
vendored
Normal file
22
Veloria/Source/Assets.xcassets/icon/mark_icon_02.imageset/Contents.json
vendored
Normal file
@ -0,0 +1,22 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"filename" : "Group 78@2x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "Group 78@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
BIN
Veloria/Source/Assets.xcassets/icon/mark_icon_02.imageset/Group 78@2x.png
vendored
Normal file
BIN
Veloria/Source/Assets.xcassets/icon/mark_icon_02.imageset/Group 78@2x.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.8 KiB |
BIN
Veloria/Source/Assets.xcassets/icon/mark_icon_02.imageset/Group 78@3x.png
vendored
Normal file
BIN
Veloria/Source/Assets.xcassets/icon/mark_icon_02.imageset/Group 78@3x.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.2 KiB |
Loading…
x
Reference in New Issue
Block a user