// // 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) ///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" override func viewDidLoad() { super.viewDidLoad() setTitle("Offline Songs") 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) } } override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) DispatchQueue.main.async { MP_DownloadManager.shared.delegate = self } reload() } //刷新列表 private func reload() { MPPositive_LoadCoreModel.shared.reloadLoadSongViewModel { [weak self] in guard let self = self else {return} tableView.showMessage(MPPositive_LoadCoreModel.shared.loadViewModels.count, title: "No Songs") numbersLabel.text = "\(MPPositive_LoadCoreModel.shared.loadViewModels.count) Songs" tableView.reloadData() } } private func configure() { 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() } } } //MARK: - tableView extension MPPositive_OfflineSongsViewController: UITableViewDataSource, UITableViewDelegate, UIViewControllerTransitioningDelegate, MP_DownloadManagerDelegate { func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return MPPositive_LoadCoreModel.shared.loadViewModels.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: MPPositive_SearchResultShowTableViewCellID, for: indexPath) as! MPPositive_SearchResultShowTableViewCell cell.loadViewModel = MPPositive_LoadCoreModel.shared.loadViewModels[indexPath.row] cell.moreBlock = { [weak self] in guard let self = self else {return} MPPositive_Debouncer.shared.call { let item = MPPositive_LoadCoreModel.shared.loadViewModels[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.removeBlock = { self.reload() } moreVC.disMissBlock = { MP_DownloadManager.shared.delegate = self 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", message: "Are you sure you want to delete the offline resources of this song?", preferredStyle: .alert) let cancel = UIAlertAction(title: "Cancel", style: .cancel) alertController.addAction(cancel) let sure = UIAlertAction(title: "Sure", style: .destructive) {(action) in guard let videoId = MPPositive_LoadCoreModel.shared.loadViewModels[indexPath.row].loadItem.videoId else {return} //确定删除 MP_DownloadManager.shared.deleteFileDocuments(videoId) { videoId in MP_HUD.progress("Loading...", delay: 0.5) { MP_HUD.text("Removed", delay: 1.0, completion: nil) tableView.reloadData() } } } 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", message: "Are you sure you want to cancel the download task of this song?", preferredStyle: .alert) let cancel = UIAlertAction(title: "Cancel", style: .cancel) alertController.addAction(cancel) let sure = UIAlertAction(title: "Sure", style: .destructive) {(action) in guard let videoId = MPPositive_LoadCoreModel.shared.loadViewModels[indexPath.row].loadItem.videoId else {return} //确定取消 MP_DownloadManager.shared.cancelDownloadTask(videoId) { videoId in MP_HUD.text("Canceled", delay: 1.0, completion: nil) tableView.reloadData() } } 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_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 MPPositive_LoadCoreModel.shared.loadViewModels.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 lodaViewModel = MPPositive_PlayerLoadViewModel(array, currentVideoId: MPPositive_LoadCoreModel.shared.loadViewModels[indexPath.row].loadItem.videoId ?? "") lodaViewModel.improveData(MPPositive_LoadCoreModel.shared.loadViewModels[indexPath.row].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) } //当进度更新时 func downloadProgressDidUpdate(for videoId: String, progress: CGFloat) { DispatchQueue.main.async { [weak self] in guard let self = self else {return} //根据VideoId获取当前列表中的下载的indexPath if let index = MPPositive_LoadCoreModel.shared.loadViewModels.firstIndex(where: {$0.loadItem.videoId == videoId}) { let indexPath = IndexPath(row: index, section: 0) //获取对应cell if let cell = tableView.cellForRow(at: indexPath) as? MPPositive_SearchResultShowTableViewCell { cell.setProgress(videoId) } } } } //下载结束后 func downloadResult(for videoId: String, result: Result) { DispatchQueue.main.async { [weak self] in guard let self = self else {return} switch result { case .success(let song): print("下载\(song.title ?? "")成功") case .failure(let error): //失败了,打印错误 print("下载报错,错误详情\(error)") MP_HUD.text("An error occurred while downloading. Please download again.", delay: 1.5, completion: nil) } //根据VideoId获取当前列表中的下载的indexPath if let index = MPPositive_LoadCoreModel.shared.loadViewModels.firstIndex(where: {$0.loadItem.videoId == videoId}) { let indexPath = IndexPath(row: index, section: 0) //获取对应cell if let cell = tableView.cellForRow(at: indexPath) as? MPPositive_SearchResultShowTableViewCell { cell.setProgress(videoId) } } } } }