diff --git a/MoviaBox/Class/Login/Controller/SPLoginViewController.swift b/MoviaBox/Class/Login/Controller/SPLoginViewController.swift index 4825c54..969d911 100644 --- a/MoviaBox/Class/Login/Controller/SPLoginViewController.swift +++ b/MoviaBox/Class/Login/Controller/SPLoginViewController.swift @@ -29,13 +29,13 @@ class SPLoginViewController: SPViewController { }() private lazy var faceBookButton: UIButton = { - let button = createButton(title: "Login with Facebook", titleColor: .colorFFFFFF(), icon: UIImage(named: "facebook_icon_01"), background: .color0866FF()) + let button = createButton(title: "movia_login_title_facebook".localized, titleColor: .colorFFFFFF(), icon: UIImage(named: "facebook_icon_01"), background: .color0866FF()) button.addTarget(self, action: #selector(handleFaceBookButton), for: .touchUpInside) return button }() private lazy var appleButton: UIButton = { - let button = createButton(title: "Login with Apple", titleColor: .color333333(), icon: UIImage(named: "apple_icon_01"), background: .colorFFFFFF()) + let button = createButton(title: "movia_login_title_apple".localized, titleColor: .color333333(), icon: UIImage(named: "apple_icon_01"), background: .colorFFFFFF()) button.addTarget(self, action: #selector(handleAppleButton), for: .touchUpInside) return button }() diff --git a/MoviaBox/Class/Mine/Controller/SPMineViewController.swift b/MoviaBox/Class/Mine/Controller/SPMineViewController.swift index 41abbf7..d4970bd 100644 --- a/MoviaBox/Class/Mine/Controller/SPMineViewController.swift +++ b/MoviaBox/Class/Mine/Controller/SPMineViewController.swift @@ -11,7 +11,7 @@ class SPMineViewController: SPViewController { private lazy var dataArr: [SPMineItem] = { let arr = [ -// SPMineItem(type: .language, iconImage: UIImage(named: "language_icon_01"), title: "movia_profile_Language".localized), + SPMineItem(type: .language, iconImage: UIImage(named: "language_icon_01"), title: "movia_profile_Language".localized), SPMineItem(type: .feedBack, iconImage: UIImage(named: "feed_back_icon_01"), title: "movia_profile_Feedback".localized), SPMineItem(type: .privacyPolicy, iconImage: UIImage(named: "privacy_policy_icon_01"), title: "movia_profile_Privacy_Policy".localized), SPMineItem(type: .userAgreement, iconImage: UIImage(named: "user_agreement_icon_01"), title: "movia_profile_User_Agreement".localized), diff --git a/MoviaBox/Class/Player/Controller/SPPlayerDetailViewController.swift b/MoviaBox/Class/Player/Controller/SPPlayerDetailViewController.swift index 5b83d37..3cebd73 100644 --- a/MoviaBox/Class/Player/Controller/SPPlayerDetailViewController.swift +++ b/MoviaBox/Class/Player/Controller/SPPlayerDetailViewController.swift @@ -139,7 +139,7 @@ class SPPlayerDetailViewController: SPPlayerListViewController { // uploadPlayTime() // } } - /* + override func handleBack() { guard isShowRecommand else { super.handleBack() @@ -167,7 +167,7 @@ class SPPlayerDetailViewController: SPPlayerListViewController { private func _handleBack() { super.handleBack() } - */ + } extension SPPlayerDetailViewController { @@ -391,17 +391,10 @@ extension SPPlayerDetailViewController { self.viewModel.currentPlayer?.seekToTime(toTime: (videoInfo.play_seconds ?? 0) / 1000) } } else { - self.scrollToItem(indexPath: .init(row: 0, section: 0), animated: false) { [weak self] in - guard let self = self else { return } - self.play() - } + self.scrollToItem(indexPath: .init(row: 0, section: 0), animated: false) } - } else { - self.scrollToItem(indexPath: .init(row: 0, section: 0), animated: false) { [weak self] in - guard let self = self else { return } - self.play() - } + self.scrollToItem(indexPath: .init(row: 0, section: 0), animated: false) } } diff --git a/MoviaBox/Class/Player/View/SPPlayerControlView.swift b/MoviaBox/Class/Player/View/SPPlayerControlView.swift index 28e20fa..15c6344 100644 --- a/MoviaBox/Class/Player/View/SPPlayerControlView.swift +++ b/MoviaBox/Class/Player/View/SPPlayerControlView.swift @@ -39,6 +39,13 @@ class SPPlayerControlView: UIView { } } + ///加载中状态 + var isLoading = false { + didSet { + progressView.isLoading = isLoading + } + } + var durationTime: Int = 0 var currentTime: Int = 0 diff --git a/MoviaBox/Class/Player/View/SPPlayerDetailRecommandView.swift b/MoviaBox/Class/Player/View/SPPlayerDetailRecommandView.swift index 8ce4b71..952553c 100644 --- a/MoviaBox/Class/Player/View/SPPlayerDetailRecommandView.swift +++ b/MoviaBox/Class/Player/View/SPPlayerDetailRecommandView.swift @@ -82,7 +82,7 @@ class SPPlayerDetailRecommandView: HWPanModalContentView { //MARK: HWPanModalPresentable override func longFormHeight() -> PanModalHeight { - return PanModalHeightMake(.content, 540) + return PanModalHeightMake(.content, 540 + kSPTabbarSafeBottomMargin) } override func showDragIndicator() -> Bool { diff --git a/MoviaBox/Class/Player/View/SPPlayerListCell.swift b/MoviaBox/Class/Player/View/SPPlayerListCell.swift index fdf5839..88ed9d1 100644 --- a/MoviaBox/Class/Player/View/SPPlayerListCell.swift +++ b/MoviaBox/Class/Player/View/SPPlayerListCell.swift @@ -70,14 +70,6 @@ class SPPlayerListCell: SPCollectionViewCell, SPPlayerProtocol { self.controlView.progress = 0 self.coverImageView.isHidden = false -// if let model = model as? SPShortModel { -// self.controlView.model = model -// coverImageView.sp_setImage(url: model.image_url) -// } else if let model = model as? SPVideoDetailModel { -// self.controlView.model = model.shortPlayInfo -// coverImageView.sp_setImage(url: model.shortPlayInfo?.image_url) -// } - } } @@ -210,4 +202,12 @@ extension SPPlayerListCell: SPPlayerDelegate { } } + func sp_player(_ player: SPPlayer, loadStateDidChange state: SPPlayer.LoadState) { + if state == .prepare || state == .stalled { + self.controlView.isLoading = true + } else { + self.controlView.isLoading = false + } + } + } diff --git a/MoviaBox/Class/Player/View/SPPlayerProgressView.swift b/MoviaBox/Class/Player/View/SPPlayerProgressView.swift index 9f5a95e..501e31b 100644 --- a/MoviaBox/Class/Player/View/SPPlayerProgressView.swift +++ b/MoviaBox/Class/Player/View/SPPlayerProgressView.swift @@ -32,17 +32,39 @@ class SPPlayerProgressView: UIView { ///滑动进度 private var panProgress: CGFloat = 0 - var progressColor: UIColor = .color3D4556() + var progressColor: UIColor = .color3D4556() { + didSet { + self.backgroundColor = progressColor + } + } var currentProgress: UIColor = .colorFFFFFF() var lineWidth: CGFloat = 2 + ///加载中状态 + var isLoading = false { + didSet { + if isLoading { + if gradientTimer == nil { + gradientTimer = Timer.scheduledTimer(timeInterval: 0.05, target: YYWeakProxy(target: self), selector: #selector(handleGradientTimer), userInfo: nil, repeats: true) + } + } else { + gradientTimer?.invalidate() + gradientTimer = nil + } + } + } + ///是否在滑动中 private var isPaning: Bool = false + private var gradientTimer: Timer? + + private var gradientValue: CGFloat = 0 + override init(frame: CGRect) { super.init(frame: frame) - self.backgroundColor = .clear + self.backgroundColor = progressColor let pan = UIPanGestureRecognizer(target: self, action: #selector(handlePanGesture(sender:))) self.addGestureRecognizer(pan) @@ -50,6 +72,7 @@ class SPPlayerProgressView: UIView { let tap = UITapGestureRecognizer(target: self, action: #selector(handleTapGesture(sender:))) self.addGestureRecognizer(tap) + } required init?(coder: NSCoder) { @@ -62,28 +85,59 @@ class SPPlayerProgressView: UIView { setNeedsDisplay() } + @objc private func handleGradientTimer() { + gradientValue += 0.1 + if gradientValue > 1 { + gradientValue = 0 + } + setNeedsDisplay() + } + override func draw(_ rect: CGRect) { super.draw(rect) guard let context = UIGraphicsGetCurrentContext() else { return } let width = rect.width let height = rect.height - var progress = self.progress - if self.isPaning { - progress = self.panProgress + if isLoading, !isPaning { + // 定义颜色空间 + let colorSpace = CGColorSpaceCreateDeviceRGB() + let colors: [CGColor] = [ + UIColor.clear.cgColor, + UIColor.white.cgColor, + UIColor.clear.cgColor + ] + let locations: [CGFloat] = [0.0, gradientValue, 1.0] + + guard let gradient = CGGradient(colorsSpace: colorSpace, colors: colors as CFArray, locations: locations) else { + return + } + + // 定义渐变的起点和终点 + let startPoint = CGPoint(x: rect.minX, y: rect.minY) + let endPoint = CGPoint(x: rect.maxX, y: rect.maxY) + // 绘制渐变 + context.drawLinearGradient(gradient, start: startPoint, end: endPoint, options: []) + } else { + var progress = self.progress + if self.isPaning { + progress = self.panProgress + } + + ///绘制进度 + let progressPath = UIBezierPath(roundedRect: CGRect(x: 0, y: height - lineWidth, width: width, height: lineWidth), cornerRadius: lineWidth / 2) + context.addPath(progressPath.cgPath) + context.setFillColor(progressColor.cgColor) + context.fillPath() + + ///绘制当前进度 + let currentPath = UIBezierPath(roundedRect: CGRect(x: 0, y: height - lineWidth, width: width * progress, height: lineWidth), cornerRadius: lineWidth / 2) + context.addPath(currentPath.cgPath) + context.setFillColor(currentProgress.cgColor) + context.fillPath() } - ///绘制进度 - let progressPath = UIBezierPath(roundedRect: CGRect(x: 0, y: height - lineWidth, width: width, height: lineWidth), cornerRadius: lineWidth / 2) - context.addPath(progressPath.cgPath) - context.setFillColor(progressColor.cgColor) - context.fillPath() - - ///绘制当前进度 - let currentPath = UIBezierPath(roundedRect: CGRect(x: 0, y: height - lineWidth, width: width * progress, height: lineWidth), cornerRadius: lineWidth / 2) - context.addPath(currentPath.cgPath) - context.setFillColor(currentProgress.cgColor) - context.fillPath() + } } diff --git a/MoviaBox/Libs/Player/SPPlayer.swift b/MoviaBox/Libs/Player/SPPlayer.swift index 664570b..2353e7f 100644 --- a/MoviaBox/Libs/Player/SPPlayer.swift +++ b/MoviaBox/Libs/Player/SPPlayer.swift @@ -18,6 +18,9 @@ import ZFPlayer ///播放状态变化 @objc optional func sp_player(_ player: SPPlayer, playStateDidChanged state: SPPlayer.PlayState) + ///加载状态发生变化 + @objc optional func sp_player(_ player: SPPlayer, loadStateDidChange state: SPPlayer.LoadState) + ///播放时间发生变化 @objc optional func sp_playTimeChanged(_ player: SPPlayer, currentTime: Int, duration: Int) @@ -41,10 +44,19 @@ class SPPlayer: NSObject { case stopped } + @objc enum LoadState: Int { + case unknown + case prepare + case playable + case playthroughOK + case stalled + } + weak var delegate: SPPlayerDelegate? private(set) lazy var isPlaying = false private(set) lazy var playState: PlayState = .unknown + private(set) lazy var loadState: LoadState = .unknown /** 是否添加息屏监控 @@ -228,18 +240,25 @@ extension SPPlayer { } else if loadState == .playable, isPlaying, self.player.playState != .playStatePlaying { self.start() } -// switch loadState { -// case .prepare: -// spLog(message: "加载状态====准备完成") -// case .playable: -// spLog(message: "加载状态====可播放") -// case .playthroughOK: -// spLog(message: "加载状态====将自动播放") -// case .stalled: -// spLog(message: "加载状态====如果已启动,将自动暂停") -// default: -// break -// } + + switch loadState { + case .prepare: + self.loadState = .prepare +// spLog(message: "加载状态====准备加载") + case .playable: + self.loadState = .playable +// spLog(message: "加载状态====可播放") + case .playthroughOK: + self.loadState = .playthroughOK +// spLog(message: "加载状态====将自动播放") + case .stalled: + self.loadState = .stalled +// spLog(message: "加载状态====如果已启动,将自动暂停") + default: + self.loadState = .unknown + break + } + self.delegate?.sp_player?(self, loadStateDidChange: self.loadState) } //错误信息 diff --git a/MoviaBox/Source/en.lproj/Localizable.strings b/MoviaBox/Source/en.lproj/Localizable.strings index bcf37cb..baf09c6 100644 --- a/MoviaBox/Source/en.lproj/Localizable.strings +++ b/MoviaBox/Source/en.lproj/Localizable.strings @@ -101,6 +101,8 @@ "movia_open_notification_info" = "Stay informed with popular recommendations and latest updates!"; "movia_top_today" = "Top Today"; "movia_play_now" = "Play Now"; +"movia_login_title_facebook" = "Sign in with FaceBook"; +"movia_login_title_apple" = "Sign in with Apple"; "movia_iap_error_toast_01" = "Invalid in-app purchase";