Music_Player3/relax.offline.mp3.music/MP/MPPositive/ViewControllers/Center(个人曲库页)/MPPositive_OfflineSongsViewController.swift
2024-08-16 18:41:40 +08:00

349 lines
16 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_OfflineSongsViewController.swift
// MusicPlayer
//
// Created by Mr.Zhou on 2024/5/28.
//
import UIKit
class MPPositive_OfflineSongsViewController: MPPositive_BaseViewController {
///广View
fileprivate lazy var adContainerView:UIView = {
let adContainerView:UIView = .init(frame: .init(x: 0, y: 0, width: screen_Width, height: 300*width))
adContainerView.backgroundColor = .clear
return adContainerView
}()
private lazy var numbersLabel:UILabel = createLabel(font: .systemFont(ofSize: 18*width, weight: .regular), textColor: .white, textAlignment: .left)
//
private lazy var rightBtn:UIButton = {
let btn:UIButton = .init(frame: .init(x: 0, y: 0, width: 24*width, height: 24*width))
btn.setBackgroundImage(UIImage(named: "Change Sort'logo"), for: .normal)
btn.addTarget(self, action: #selector(sortTypeClick(_ :)), for: .touchUpInside)
return btn
}()
///
private lazy var searchBtn:UIButton = {
let btn = UIButton()
btn.setBackgroundImage(UIImage(named: "Center_Search'logo"), for: .normal)
btn.addTarget(self, action: #selector(searchActionShowClick(_ :)), for: .touchUpInside)
return btn
}()
//View
private lazy var searchShowView:MPPositive_CenterListSearchView = .init(frame: .init(x: 0, y: 0, width: screen_Width, height: 30*width))
///tableView
private lazy var tableView:UITableView = {
let tableView = UITableView(frame: .init(x: 0, y: 0, width: screen_Width, height: screen_Height), style: .plain)
if #available(iOS 15.0, *) {
tableView.sectionHeaderTopPadding = 0
}
tableView.backgroundColor = .clear
tableView.separatorStyle = .none
tableView.estimatedRowHeight = 200
tableView.rowHeight = UITableView.automaticDimension
tableView.dataSource = self
tableView.delegate = self
tableView.register(MPPositive_SearchResultShowTableViewCell.self, forCellReuseIdentifier: MPPositive_SearchResultShowTableViewCellID)
tableView.contentInset = .init(top: 0, left: 0, bottom: 70*width, right: 0)
return tableView
}()
private let MPPositive_SearchResultShowTableViewCellID = "MPPositive_SearchResultShowTableViewCell"
//
private var isSearchStyle:Bool = false
//
private var offlines:[MPPositive_DownloadViewModel] = []
//
private var searchSongs:[MPPositive_DownloadViewModel] = []
//
private var showSongs:[MPPositive_DownloadViewModel] = []
//
private var sortType:Int{
get{
if let type = UserDefaults.standard.object(forKey: "Offline_Songs_SortType") as? Int {
return type
}else {
return 0
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
setTitle("Offline Songs".localizableString())
setPopBtn()
configure()
MP_AdMobManager.shared.layoutLibraryNativeAd(in: adContainerView, index: 1)
MP_AdMobManager.shared.onLibraryNativeAdBlock = {
[weak adContainerView] in
guard let adContainerView = adContainerView else {return}
MP_AdMobManager.shared.layoutLibraryNativeAd(in: adContainerView, index: 1)
}
searchShowView.cancelBlock = {
[weak self] in
guard let self = self else {return}
cancelSearchAction()
}
searchShowView.textBlock = {
[weak self] (text) in
guard let self = self else {return}
isSearchStyle = true
//
reloadSearch(text)
}
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
reload()
}
//
private func reload() {
MPPositive_LoadCoreModel.shared.reloadLoadSongViewModel {
[weak self] in
guard let self = self else {return}
offlines = MPPositive_LoadCoreModel.shared.loadViewModels
tableView.showMessage(offlines.count, title: "No Songs")
numbersLabel.text = "\(offlines.count) \("Songs".localizableString())"
isSearchStyle ? reloadSearch(self.searchShowView.textField.text ?? ""):reloadShow()
}
}
//
private func reloadShow() {
tableView.showMessage(offlines.count, title: "No Songs")
switch sortType {
case 0://
showSongs = offlines.sorted(by: { item1, item2 in
if let date1 = item1.loadItem.addTime, let date2 = item2.loadItem.addTime {
return date1 > date2
}else {
return false
}
})
default://
showSongs = offlines.sorted(by: { item1, item2 in
if let date1 = item1.loadItem.addTime, let date2 = item2.loadItem.addTime {
return date1 < date2
}else {
return true
}
})
}
tableView.reloadData()
}
//
private func reloadSearch(_ text:String) {
if text.isEmpty {
//
searchSongs = offlines
}else {
//
searchSongs = offlines.filter({($0.title ?? "").contains(text) || ($0.subtitle ?? "").contains(text)})
}
tableView.reloadSections(.init(integer: 0), with: .automatic)
}
private func configure() {
navView.addSubview(rightBtn)
rightBtn.snp.makeConstraints { make in
make.width.height.equalTo(24*width)
make.centerY.equalToSuperview()
make.right.equalToSuperview().offset(-16*width)
}
navView.addSubview(searchBtn)
searchBtn.snp.makeConstraints { make in
make.right.equalTo(rightBtn.snp.left).offset(-10*width)
make.width.height.equalTo(24*width)
make.centerY.equalTo(rightBtn)
}
navView.addSubview(searchShowView)
searchShowView.snp.makeConstraints { make in
make.height.equalTo(40*width)
make.left.equalTo(popBtn.snp.right).offset(5*width)
make.right.equalTo(rightBtn)
make.centerY.equalTo(searchBtn)
}
searchShowView.alpha = 0
searchShowView.isHidden = true
searchShowView.isUserInteractionEnabled = false
view.addSubview(adContainerView)
adContainerView.snp.makeConstraints { make in
make.left.right.equalToSuperview()
make.top.equalTo(navView.snp.bottom)
make.height.equalTo(0)
}
view.addSubview(numbersLabel)
numbersLabel.snp.makeConstraints { make in
make.left.equalToSuperview().offset(18*width)
make.top.equalTo(adContainerView.snp.bottom).offset(32*width)
}
view.addSubview(tableView)
tableView.snp.makeConstraints { make in
make.top.equalTo(numbersLabel.snp.bottom).offset(18*width)
make.left.right.bottom.equalToSuperview()
}
}
//
@objc private func sortTypeClick(_ sender:UIButton) {
view.endEditing(true)
//
cancelSearchAction()
MPPositive_ModalType = .SortType
let sortVC = MPPositive_SortTypeViewController(sortType)
sortVC.chooseBlock = {
[weak self] (type) in
guard let self = self else {return}
UserDefaults.standard.set(type, forKey: "Offline_Songs_SortType")
reloadShow()
}
sortVC.transitioningDelegate = self
sortVC.modalPresentationStyle = .custom
present(sortVC, animated: true)
}
//
@objc private func searchActionShowClick(_ sender:UIButton) {
//
UIView.animate(withDuration: 0.2) {
[weak self] in
guard let self = self else {return}
searchShowView.isHidden = false
//searchView
searchShowView.alpha = 1
searchBtn.isUserInteractionEnabled = false
} completion: { [weak self] statu in
guard let self = self else {return}
searchShowView.isUserInteractionEnabled = true
}
}
//
private func cancelSearchAction() {
UIView.animate(withDuration: 0.2) {
[weak self] in
guard let self = self else {return}
searchShowView.isUserInteractionEnabled = false
searchShowView.alpha = 0
isSearchStyle = false
} completion: { [weak self] statu in
guard let self = self else {return}
searchShowView.isHidden = true
searchBtn.isUserInteractionEnabled = true
reloadShow()
}
}
}
//MARK: - tableView
extension MPPositive_OfflineSongsViewController: UITableViewDataSource, UITableViewDelegate, UIViewControllerTransitioningDelegate{
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return isSearchStyle ? searchSongs.count:showSongs.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: MPPositive_SearchResultShowTableViewCellID, for: indexPath) as! MPPositive_SearchResultShowTableViewCell
if isSearchStyle {
cell.loadViewModel = searchSongs[indexPath.row]
}else {
cell.loadViewModel = showSongs[indexPath.row]
}
cell.moreBlock = {
[weak self] in
guard let self = self else {return}
MPPositive_Debouncer.shared.call {
let item = self.isSearchStyle ? self.searchSongs[indexPath.row]:self.showSongs[indexPath.row]
let song = MPPositive_SongItemModel()
song.coverUrls = [item.loadItem.coverImage]
song.reviewUrls = [item.loadItem.reviewImage]
song.title = item.loadItem.title
song.longBylineText = item.loadItem.longBylineText
song.lengthText = item.loadItem.lengthText
song.shortBylineText = item.loadItem.shortBylineText
song.lyrics = item.loadItem.lyrics
song.lyricsID = item.loadItem.lyricsID
song.videoId = item.loadItem.videoId
song.relatedID = item.loadItem.relatedID
MPPositive_ModalType = .MoreOperations
let moreVC = MPPositive_MoreSongOperationsViewController(song)
moreVC.disMissBlock = {
self.reload()
}
moreVC.transitioningDelegate = self
moreVC.modalPresentationStyle = .custom
self.present(moreVC, animated: true)
}
}
cell.deleteBlock = {
[weak self] in
guard let self = self else {return}
//
let alertController = UIAlertController(title: "Delete This Song".localizableString(), message: "Are you sure you want to delete the offline resources of this song?".localizableString(), preferredStyle: .alert)
let cancel = UIAlertAction(title: "Cancel".localizableString(), style: .cancel)
alertController.addAction(cancel)
let sure = UIAlertAction(title: "Confirm".localizableString(), style: .destructive) {(action) in
guard let videoId = self.isSearchStyle ? self.searchSongs[indexPath.row].loadItem.videoId:self.showSongs[indexPath.row].loadItem.videoId else {return}
//
MP_DownloadManager.shared.deleteFileDocuments(videoId) { videoId in
MP_HUD.progress("Loading...".localizableString(), delay: 0.5) {
MP_HUD.text("Removed".localizableString(), delay: 1.0, completion: nil)
self.reload()
}
}
}
alertController.addAction(sure)
present(alertController, animated: true)
}
cell.cancelBlock = {
[weak self] in
guard let self = self else {return}
//
let alertController = UIAlertController(title: "Cancel Song Download Task".localizableString(), message: "Are you sure you want to cancel the download task of this song?".localizableString(), preferredStyle: .alert)
let cancel = UIAlertAction(title: "Cancel".localizableString(), style: .cancel)
alertController.addAction(cancel)
let sure = UIAlertAction(title: "Confirm".localizableString(), style: .destructive) {(action) in
guard let videoId = self.isSearchStyle ? self.searchSongs[indexPath.row].loadItem.videoId:self.showSongs[indexPath.row].loadItem.videoId else {return}
//
MP_DownloadManager.shared.cancelDownloadTask(videoId) { videoId in
MP_HUD.text("Cancel".localizableString(), delay: 1.0, completion: nil)
self.reload()
}
}
alertController.addAction(sure)
present(alertController, animated: true)
}
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
MPPositive_Debouncer.shared.call {
[weak self] in
guard let self = self else {return}
MP_AnalyticsManager.shared.song_clickAction("Offline Song")
//
MP_PlayerManager.shared.loadPlayer = nil
//
NotificationCenter.notificationKey.post(notificationName: .pup_player_vc)
MP_AnalyticsManager.shared.player_b_impAction()
//
var array:[MPPositive_SongItemModel] = []
for (index, song) in offlines.enumerated() {
let item = MPPositive_SongItemModel()
item.index = index
item.coverUrls = [song.loadItem.coverImage]
item.reviewUrls = [song.loadItem.reviewImage]
item.title = song.loadItem.title
item.longBylineText = song.loadItem.longBylineText
item.lengthText = song.loadItem.lengthText
item.shortBylineText = song.loadItem.shortBylineText
item.lyricsID = song.loadItem.lyricsID
item.lyrics = song.loadItem.lyrics
item.videoId = song.loadItem.videoId
item.relatedID = song.loadItem.relatedID
array.append(item)
}
let currentVideo = isSearchStyle ? searchSongs[indexPath.row]:showSongs[indexPath.row]
let lodaViewModel = MPPositive_PlayerLoadViewModel(array, currentVideoId: currentVideo.loadItem.videoId ?? "")
lodaViewModel.improveData(currentVideo.loadItem.videoId ?? "")
//
MP_PlayerManager.shared.setPlayType(.normal)
MP_PlayerManager.shared.loadPlayer = lodaViewModel
MP_AnalyticsManager.shared.player_b_listAction()
// NotificationCenter.notificationKey.post(notificationName: .pup_player_vc)
}
}
func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController? {
return MPPositive_PresentationController(presentedViewController: presented, presenting: presenting)
}
}