Music_Player3/relax.offline.mp3.music/MP/MPPositive/Views/Player/MPPositive_PlayerCoverView.swift

371 lines
18 KiB
Swift
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// MPPositive_PlayerCoverView.swift
// MusicPlayer
// Created by Mr.Zhou on 2024/5/8.
import UIKit
import DownloadButton
//BView(View)
class MPPositive_PlayerCoverView: UIView, PKDownloadButtonDelegate {
///
lazy var coverImageView:UIImageView = {
let imageView = UIImageView()
imageView.image = placeholderImage
imageView.contentMode = .scaleAspectFill
imageView.layer.masksToBounds = true
imageView.layer.cornerRadius = 16*width
return imageView
}()
///
lazy var titleLabel:UILabel = createLabel("Loading", font: .systemFont(ofSize: 22*width, weight: .regular), textColor: .init(hex: "#FFFFFF", alpha: 0.85), textAlignment: .left)
///
lazy var subtitleLabel:UILabel = createLabel("Loading", font: .systemFont(ofSize: 12*width, weight: .regular), textColor: .init(hex: "#EEEEEE", alpha: 0.6), textAlignment: .left)
///
lazy var collectionSongBtn:UIButton = {
let btn = UIButton()
btn.setBackgroundImage(UIImage(named: "List_UnCollection'logo"), for: .normal)
btn.setBackgroundImage(UIImage(named: "List_Collectioned'logo"), for: .selected)
btn.addTarget(self, action: #selector(collectionSwitchClick(_ :)), for: .touchUpInside)
return btn
}()
///
lazy var downloadButton:PKDownloadButton = {
let btn:PKDownloadButton = .init()
//
btn.startDownloadButton.cleanDefaultAppearance()
btn.startDownloadButton.setBackgroundImage(UIImage(named: "Song_Unload'logo"), for: .normal)
//
btn.downloadedButton.setBackgroundImage(UIImage(named: "Song_Loaded'logo"), for: .normal)
btn.downloadedButton.isUserInteractionEnabled = false
btn.downloadedButton.setAttributedTitle(nil, for: .normal)
//
btn.stopDownloadButton.stopButton.setImage(UIImage(named: "download"), for: .normal)
btn.stopDownloadButton.isUserInteractionEnabled = false
btn.stopDownloadButton.tintColor = UIColor(hex: "#80F988")
btn.stopDownloadButton.stopButtonWidth = 2
btn.stopDownloadButton.filledLineWidth = 3*width
btn.stopDownloadButton.filledLineStyleOuter = true
//
btn.pendingView.tintColor = UIColor(hex: "#80F988")
btn.pendingView.radius = 12*width
btn.pendingView.emptyLineRadians = 2*width
btn.pendingView.spinTime = 3
btn.delegate = self
return btn
}()
///View
lazy var sliderView:MPPositive_PlayerSilder = {
let sliderView:MPPositive_PlayerSilder = .init(frame: .init(x: 0, y: 0, width: 335*width, height: 6*width))
sliderView.addTarget(self, action: #selector(seekProgressClick(_:forEvent:)), for: .valueChanged)
sliderView.addTarget(self, action: #selector(seekProgressClick(_:forEvent:)), for: .touchDown)
sliderView.addTarget(self, action: #selector(seekProgressClick(_:forEvent:)), for: .touchUpInside)
return sliderView
}()
///View
lazy var progressView:UIProgressView = {
let progressView:UIProgressView = .init()
progressView.isUserInteractionEnabled = true
progressView.progressTintColor = .init(hex: "#FFFFFF", alpha: 0.3)
progressView.trackTintColor = .clear
progressView.progress = 0
return progressView
}()
///Label
lazy var durationLabel:UILabel = createLabel("00:00" ,font: .systemFont(ofSize: 12*width, weight: .medium), textColor: .init(hex: "#FFFFFF", alpha: 0.85), textAlignment: .left)
///Label
lazy var maxTimesLabel:UILabel = createLabel("00:00" ,font: .systemFont(ofSize: 12*width, weight: .medium), textColor: .init(hex: "#FFFFFF", alpha: 0.6), textAlignment: .right)
///View
private lazy var maskNotReachableView:UIView = {
let maskView = UIView()
maskView.backgroundColor = .init(hex: "#000000", alpha: 0.7)
maskView.layer.masksToBounds = true
maskView.layer.cornerRadius = 16*width
//icon
let iconImageView:UIImageView = .init(image: .init(named: "NoNetReache'log"))
maskView.addSubview(iconImageView)
iconImageView.snp.makeConstraints { make in
make.centerX.equalToSuperview()
make.centerY.equalToSuperview().multipliedBy(0.8)
make.width.equalTo(52*width)
make.height.equalTo(42*width)
}
//label
let noticeLabel:UILabel = createLabel("Weak connection. Please check your network", font: .systemFont(ofSize: 18, weight: .medium), textColor: .white, textAlignment: .center, lines: 0)
maskView.addSubview(noticeLabel)
noticeLabel.snp.makeConstraints { make in
make.top.equalTo(iconImageView.snp.bottom).offset(20*width)
make.centerX.equalToSuperview()
make.width.equalToSuperview().multipliedBy(0.7)
}
return maskView
}()
override init(frame: CGRect) {
super.init(frame: frame)
backgroundColor = .clear
configure()
//
NotificationCenter.notificationKey.add(observer: self, selector: #selector(netWorkNotReachableAction(_:)), notificationName: .net_switch_notReachable)
NotificationCenter.notificationKey.add(observer: self, selector: #selector(netWorkReachableAction(_:)), notificationName: .net_switch_reachable)
}
required init?(coder: NSCoder) {
super.init(coder: coder)
}
//
public func restoreDownloadProgress() {
guard let currentVideo = MP_PlayerManager.shared.loadPlayer?.currentVideo else {
return
}
//video
if let progress = MP_DownloadManager.shared.getProgress(for: currentVideo.song.videoId) {
DispatchQueue.main.async {
[weak self] in
guard let self = self else {return}
//URL
downloadButton.state = .downloading
downloadButton.isUserInteractionEnabled = false
//
downloadButton.stopDownloadButton.progress = progress
}
}else {
//,
downloadButton.state = (MPPositive_DownloadItemModel.fetch(.init(format: "videoId == %@", currentVideo.song.videoId ?? "")).count != 0) ? .downloaded:.startDownload
downloadButton.isUserInteractionEnabled = true
}
}
deinit {
NotificationCenter.default.removeObserver(self)
}
//
private func configure() {
//
addSubview(coverImageView)
coverImageView.snp.makeConstraints { make in
make.width.equalTo(335*width)
make.height.equalTo(330*width)
make.centerX.equalToSuperview()
make.top.equalToSuperview().offset(12*width)
}
addSubview(maskNotReachableView)
maskNotReachableView.snp.makeConstraints { make in
make.left.right.top.bottom.equalTo(coverImageView)
}
maskNotReachableView.isHidden = (MP_NetWorkManager.shared.netWorkStatu == .reachable)
//
addSubview(titleLabel)
titleLabel.snp.makeConstraints { make in
make.left.equalTo(coverImageView.snp.left)
make.top.equalTo(coverImageView.snp.bottom).offset(36*width)
make.right.equalTo(coverImageView.snp.right).offset(-100*width)
}
addSubview(subtitleLabel)
subtitleLabel.snp.makeConstraints { make in
make.left.right.equalTo(titleLabel)
make.top.equalTo(titleLabel.snp.bottom).offset(6*width)
}
//
addSubview(downloadButton)
downloadButton.snp.makeConstraints { make in
make.right.equalTo(coverImageView.snp.right).offset(-12*width)
make.top.equalTo(coverImageView.snp.bottom).offset(47*width)
make.width.height.equalTo(24*width)
}
addSubview(collectionSongBtn)
collectionSongBtn.snp.makeConstraints { make in
make.right.equalTo(downloadButton.snp.left).offset(-20*width)
make.centerY.equalTo(downloadButton.snp.centerY)
make.width.height.equalTo(24*width)
}
addSubview(progressView)
progressView.snp.makeConstraints { make in
make.top.equalTo(subtitleLabel.snp.bottom).offset(25*width)
make.centerX.equalToSuperview()
make.width.equalTo(335*width)
make.height.equalTo(6*width)
}
//label
addSubview(sliderView)
sliderView.snp.makeConstraints { make in
make.left.right.top.bottom.equalTo(progressView)
}
addSubview(durationLabel)
durationLabel.snp.makeConstraints { make in
make.left.equalTo(sliderView.snp.left)
make.top.equalTo(sliderView.snp.bottom).offset(5*width)
}
addSubview(maxTimesLabel)
maxTimesLabel.snp.makeConstraints { make in
make.right.equalTo(sliderView.snp.right)
make.top.equalTo(sliderView.snp.bottom).offset(5*width)
}
//
restoreDownloadProgress()
}
//
@objc private func netWorkNotReachableAction(_ sender:Notification) {
DispatchQueue.main.async {
[weak self] in
guard let self = self else {return}
maskNotReachableView.isHidden = false
}
}
//
@objc private func netWorkReachableAction(_ sender:Notification) {
DispatchQueue.main.async {
[weak self] in
guard let self = self else {return}
maskNotReachableView.isHidden = true
}
}
//
@objc private func seekProgressClick(_ sender: UISlider, forEvent event: UIEvent) {
//touchEvent
let touchEvent = event.allTouches?.first
//
switch touchEvent?.phase {
case .began://
//
MP_PlayerManager.shared.setEditPorgressStatu()
case .moved://
break
case .ended://
let value = sender.value
//
MP_PlayerManager.shared.setEditProgressEnd(value)
default:
break
}
}
//
@objc private func collectionSwitchClick(_ sender:UIButton) {
getUserNotificationCenter()
guard MP_NetWorkManager.shared.netWorkStatu == .reachable else {
MP_HUD.text("Weak connection.", delay: 2.0, completion: nil)
return
}
if self.collectionSongBtn.isSelected == true{
self.collectionSongBtn.isSelected = false
if MP_PlayerManager.shared.loadPlayer.currentVideo != nil{
MPPositive_CollectionSongModel.fetch(.init(format: "videoId == %@", MP_PlayerManager.shared.loadPlayer.currentVideo.song.videoId)).forEach { i in
if i.videoId == MP_PlayerManager.shared.loadPlayer.currentVideo.song.videoId{
MPPositive_CollectionSongModel.delete(i)
}
}
MP_PlayerManager.shared.loadPlayer.currentVideo.reloadCollectionAndDownLoad()
MPPositive_LoadCoreModel.shared.reloadCollectionSongViewModel(nil)
MP_AnalyticsManager.shared.player_b_unlove_clickAction(MP_PlayerManager.shared.loadPlayer.currentVideo?.song.videoId ?? "", videoname: MP_PlayerManager.shared.loadPlayer.currentVideo?.song.title ?? "", artistname: MP_PlayerManager.shared.loadPlayer.currentVideo?.song.shortBylineText ?? "")
}
}else{
self.collectionSongBtn.isSelected = true
if MP_PlayerManager.shared.loadPlayer.currentVideo != nil{
let item = MPPositive_CollectionSongModel.create()
item.title = MP_PlayerManager.shared.loadPlayer.currentVideo.title
item.videoId = MP_PlayerManager.shared.loadPlayer.currentVideo.song.videoId
item.subtitle = MP_PlayerManager.shared.loadPlayer.currentVideo.subtitle
item.coverImage = MP_PlayerManager.shared.loadPlayer.currentVideo.coverUrl
item.lyricsID = MP_PlayerManager.shared.loadPlayer.currentVideo.song.lyricsID
item.relatedID = MP_PlayerManager.shared.loadPlayer.currentVideo.song.relatedID
MPPositive_CollectionSongModel.save()
MP_PlayerManager.shared.loadPlayer.currentVideo.reloadCollectionAndDownLoad()
MPPositive_LoadCoreModel.shared.reloadCollectionSongViewModel(nil)
MP_AnalyticsManager.shared.player_b_love_clickAction(MP_PlayerManager.shared.loadPlayer.currentVideo?.song.videoId ?? "", videoname: MP_PlayerManager.shared.loadPlayer.currentVideo?.song.title ?? "", artistname: MP_PlayerManager.shared.loadPlayer.currentVideo?.song.shortBylineText ?? "")
}
}
}
//
func downloadButtonTapped(_ downloadButton: PKDownloadButton!, currentState state: PKDownloadButtonState) {
getUserNotificationCenter()
guard MP_NetWorkManager.shared.netWorkStatu == .reachable else {
MP_HUD.text("Weak connection.", delay: 2.0, completion: nil)
return
}
guard MP_PlayerManager.shared.loadPlayer?.currentVideo != nil, MP_PlayerManager.shared.loadPlayer?.currentVideo?.isDlownd == false else {
return
}
//
switch state {
case .startDownload: //
//
downloadButton.state = .pending
//
downloadButton.isUserInteractionEnabled = false
//
guard let currentVideo = MP_PlayerManager.shared.loadPlayer?.currentVideo, let videoURL = currentVideo.resourcePlayerURL else {
MP_HUD.text("An error occurred while downloading. Please download again.", delay: 1.0) {
downloadButton.state = .startDownload
downloadButton.isUserInteractionEnabled = true
}
return
}
MP_AnalyticsManager.shared.player_b_download_clickAction(currentVideo.song.videoId, videoname: currentVideo.song.title ?? "", artistname: currentVideo.song.shortBylineText ?? "")
//
MP_DownloadManager.shared.downloadVideo(from: videoURL, song: currentVideo.song) { [weak self] progress in
guard let self = self, currentVideo.song.videoId == MP_PlayerManager.shared.loadPlayer.currentVideo.song.videoId else {
//
downloadButton.state = (MP_PlayerManager.shared.loadPlayer.currentVideo?.isDlownd ?? false) ? .downloaded:.startDownload
downloadButton.isUserInteractionEnabled = !(MP_PlayerManager.shared.loadPlayer.currentVideo?.isDlownd ?? false)
return
}
downloadButton.state = .downloading
downloadButton.stopDownloadButton.progress = progress
} completion: { [weak self] result in
guard let self = self else {return}
//
switch result {
case .success(let song):
//
let item = MPPositive_DownloadItemModel.create()
item.coverImage = song.coverUrls!.last
item.reviewImage = song.reviewUrls!.last
item.title = song.title
item.longBylineText = song.longBylineText
item.lengthText = song.lengthText
item.shortBylineText = song.shortBylineText
item.lyrics = song.lyrics
item.lyricsID = song.lyricsID
item.videoId = song.videoId
item.relatedID = song.relatedID
MPPositive_DownloadItemModel.save()
DispatchQueue.main.async {
//线
if song.videoId == MP_PlayerManager.shared.loadPlayer?.currentVideo?.song.videoId {
//
MP_PlayerManager.shared.loadPlayer.currentVideo.reloadCollectionAndDownLoad()
}else {
//
}
print("完成了对\(song.title ?? "")的下载")
//
downloadButton.state = .downloaded
downloadButton.isUserInteractionEnabled = false
//
MPPositive_LoadCoreModel.shared.reloadLoadSongViewModel(nil)
MP_AnalyticsManager.shared.player_b_downloadsuccess_actionAction(item.videoId, videoname: item.title ?? "", artistname: item.shortBylineText ?? "")
}
case .failure(let error):
//
print("下载报错,错误详情\(error)")
DispatchQueue.main.async {
//
downloadButton.state = .startDownload
downloadButton.isUserInteractionEnabled = true
}
MP_HUD.text("An error occurred while downloading. Please download again.", delay: 1.5, completion: nil)
}
}
case .pending://
break
case .downloading:
break
case .downloaded:
break
@unknown default:
break
}
}
}