Music_Player3/relax.offline.mp3.music/MP/MPPositive/Views/Home/MPPositive_PersonalisedRecommendationsTableViewCell.swift

367 lines
19 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_PersonalisedRecommendationsTableViewCell.swift
// relax.offline.mp3.music
//
// Created by Mr.Zhou on 2024/8/28.
//
import UIKit
import Lottie
class MPPositive_PersonalisedRecommendationsTableViewCell: UITableViewCell, UIViewControllerTransitioningDelegate {
////
private lazy var titleLabel:UILabel = createLabel(font: .systemFont(ofSize: 14*width), textColor: .init(hex: "#FFFFFF", alpha: 0.6), textAlignment: .left)
///
private lazy var subTitleLabel:UILabel = {
let label = createLabel(font: .systemFont(ofSize: 16*width, weight: .bold), textColor: .white, textAlignment: .left)
label.isUserInteractionEnabled = true
label.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(findRecommonedEvent(_ :))))
return label
}()
///Icon
private lazy var reloadlotView:LottieAnimationView = {
//View
let json = Bundle.main.path(forResource: "Reload_Animation", ofType: "json")
let animationView:LottieAnimationView = .init(filePath: json ?? "")
//
animationView.loopMode = .loop
//
animationView.contentMode = .scaleAspectFill
animationView.backgroundColor = .clear
return animationView
}()
///
enum PersonlShowType:Int {
case Singles = 0
case Lists = 1
case Artists = 2
///layout
var layout:UICollectionViewFlowLayout {
let layout = UICollectionViewFlowLayout()
switch self {
case .Singles:
layout.itemSize = .init(width: screen_Width*0.85, height: 70*width)
layout.sectionInset = .init(top: 10*width, left: 16*width, bottom: 0, right: 16*width)
layout.minimumLineSpacing = 0
layout.minimumInteritemSpacing = 0
layout.scrollDirection = .horizontal
case .Lists:
layout.sectionInset = .init(top: 15*width, left: 16*width, bottom: 0, right: 16*width)
layout.minimumLineSpacing = 8*width
layout.itemSize = .init(width: 109*width, height: 152*width)
layout.minimumInteritemSpacing = 0
layout.scrollDirection = .horizontal
case .Artists:
layout.sectionInset = .init(top: 15*width, left: 16*width, bottom: 0, right: 16*width)
layout.minimumLineSpacing = 8*width
layout.itemSize = .init(width: 94*width, height: 116*width)
layout.minimumInteritemSpacing = 0
layout.scrollDirection = .horizontal
}
return layout
}
}
//collectionView
private lazy var collectionView:UICollectionView = {
let collectionView:UICollectionView = .init(frame: .init(x: 0, y: 0, width: screen_Width, height: screen_Height), collectionViewLayout: showType.layout)
collectionView.showsVerticalScrollIndicator = false
collectionView.showsHorizontalScrollIndicator = false
collectionView.backgroundColor = .clear
collectionView.dataSource = self
collectionView.delegate = self
collectionView.register(MPPositive_HomeSingleCollectionViewCell.self, forCellWithReuseIdentifier: MPPositive_HomeSingleCollectionViewCellID)
collectionView.register(MPPositive_HomeListThirdCollectionViewCell.self, forCellWithReuseIdentifier: MPPositive_HomeListThirdCollectionViewCellID)
collectionView.register(MPPositive_HomeListFourthCollectionViewCell.self, forCellWithReuseIdentifier: MPPositive_HomeListFourthCollectionViewCellID)
return collectionView
}()
private let MPPositive_HomeSingleCollectionViewCellID = "MPPositive_HomeSingleCollectionViewCell"
private let MPPositive_HomeListThirdCollectionViewCellID = "MPPositive_HomeListThirdCollectionViewCell"
private let MPPositive_HomeListFourthCollectionViewCellID = "MPPositive_HomeListFourthCollectionViewCell"
var personlViewModel:MPPositive_PersonalListViewModel?{
didSet{
titleLabel.text = personlViewModel?.title
subTitleLabel.text = titleLabel.text == "Because you listen".localizableString() ? personlViewModel?.random?.title:personlViewModel?.random?.subtitle
reloadlotView.stop()
if let first = personlViewModel?.items.first, first.browseItem.itemType == .single {
showType = .Singles
}else {
//
if personlViewModel?.items.first?.browseItem.pageType == "MUSIC_PAGE_TYPE_ARTIST" {
showType = .Artists
}else {
showType = .Lists
}
}
}
}
var reloadRecommondBlock:((Int) -> Void)?
///
var showType:PersonlShowType = .Singles{
didSet{
collectionView.collectionViewLayout = showType.layout
collectionView.reloadData()
collectionView.scrollToItem(at: .init(row: 0, section: 0), at: .top, animated: false)
}
}
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
confirgue()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
}
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
//
private func confirgue() {
selectionStyle = .none
backgroundColor = .clear
contentView.backgroundColor = .clear
//UI
contentView.addSubview(titleLabel)
titleLabel.snp.makeConstraints { make in
make.left.equalToSuperview().offset(16*width)
make.top.equalTo(8*width)
}
contentView.addSubview(subTitleLabel)
subTitleLabel.snp.makeConstraints { make in
make.left.equalTo(titleLabel)
make.top.equalTo(titleLabel.snp.bottom).offset(6*width)
make.width.equalToSuperview().multipliedBy(0.6)
}
let reloadView = createReloadView()
contentView.addSubview(reloadView)
reloadView.snp.makeConstraints { make in
make.top.equalToSuperview().offset(10*width)
make.right.equalToSuperview().offset(-16*width)
make.width.equalTo(85*width)
make.height.equalTo(35*width)
}
contentView.addSubview(collectionView)
collectionView.snp.makeConstraints { make in
make.top.equalTo(subTitleLabel.snp.bottom).offset(5*width)
make.left.right.equalToSuperview()
make.bottom.equalToSuperview().offset(-30*width)
}
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
//View
private func createReloadView() -> UIView {
let view:UIView = .init(frame: .init(x: 0, y: 0, width: 60*width, height: 32*width))
view.backgroundColor = .init(hex: "#FFFFFF", alpha: 0.1)
view.layer.masksToBounds = true
view.layer.cornerRadius = 8*width
view.addSubview(reloadlotView)
reloadlotView.snp.makeConstraints { make in
make.width.height.equalTo(20*width)
make.centerY.equalToSuperview()
make.left.equalToSuperview().offset(10*width)
}
reloadlotView.stop()
//Label
let label = createLabel("Refresh", font: .systemFont(ofSize: 12*width), textColor: .white, textAlignment: .center)
view.addSubview(label)
label.snp.makeConstraints { make in
make.centerY.equalToSuperview()
make.left.equalTo(reloadlotView.snp.right).offset(4*width)
}
view.isUserInteractionEnabled = true
view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(reloadRecommonedEvent(_ :))))
return view
}
//
@objc private func reloadRecommonedEvent(_ sender:UITapGestureRecognizer) {
reloadlotView.play()
//
if titleLabel.text == "Because you listen".localizableString() {
reloadRecommondBlock?(1)
}else {
reloadRecommondBlock?(2)
}
}
//
@objc private func findRecommonedEvent(_ sender:UITapGestureRecognizer) {
guard let item = (self.personlViewModel?.random?.recently) else {
return
}
switch showType {
case.Singles:
///
MPPositive_Debouncer.shared.call {
[weak self] in
guard let self = self else {return}
guard MP_NetWorkManager.shared.netWorkStatu == .reachable else {
playOfflineSongs()
return
}
MP_AnalyticsManager.shared.home_b_module_clickAction(titleLabel.text ?? "")
MP_AnalyticsManager.shared.song_clickAction("Home")
//
MP_PlayerManager.shared.loadPlayer = nil
//
NotificationCenter.notificationKey.post(notificationName: .pup_player_vc)
MP_AnalyticsManager.shared.player_b_impAction()
//next
MP_NetWorkManager.shared.requestNextList(item.playListID ?? "", videoId: item.videoId ?? "", clickTrackingParams: ""){ [weak self] listSongs in
guard let self = self else {return}
//playerloadViewModel
let lodaViewModel = MPPositive_PlayerLoadViewModel(listSongs, currentVideoId: item.videoId ?? "")
lodaViewModel.improveData(item.videoId ?? "")
//
MP_PlayerManager.shared.setPlayType(.normal)
MP_PlayerManager.shared.loadPlayer = lodaViewModel
MP_AnalyticsManager.shared.player_b_listAction()
}
}
default:
//
MP_AnalyticsManager.shared.search_from_actionAction("Home")
let resultVC = MPPositive_SearchResultShowViewController(item.subtitle ?? "", isShowAd: true)
self.parentController()?.navigationController?.pushViewController(resultVC, animated: false)
}
}
//tableViewCell
override func systemLayoutSizeFitting(_ targetSize: CGSize, withHorizontalFittingPriority horizontalFittingPriority: UILayoutPriority, verticalFittingPriority: UILayoutPriority) -> CGSize {
let size = super.systemLayoutSizeFitting(targetSize, withHorizontalFittingPriority: horizontalFittingPriority, verticalFittingPriority: verticalFittingPriority)
collectionView.layoutIfNeeded()
switch showType {
case .Singles:
let height = showType.layout.itemSize.height*3 + showType.layout.sectionInset.top + 10
return CGSize(width: size.width, height: size.height + height)
default:
let height = showType.layout.itemSize.height + showType.layout.sectionInset.top + showType.layout.sectionInset.bottom
return CGSize(width: size.width, height: size.height + height)
}
}
}
//MARK: - collectionView
extension MPPositive_PersonalisedRecommendationsTableViewCell:UICollectionViewDataSource, UICollectionViewDelegate {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return personlViewModel?.items.count ?? 0
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
switch showType {
case .Singles:
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: MPPositive_HomeSingleCollectionViewCellID, for: indexPath) as! MPPositive_HomeSingleCollectionViewCell
cell.itemViewModel = personlViewModel?.items[indexPath.row]
cell.moreBlock = {
[weak self] in
guard let self = self, let itemView = (self.personlViewModel?.items[indexPath.row]) else {return}
MPPositive_Debouncer.shared.call {
MPPositive_ModalType = .MoreOperations
let moreVC = MPPositive_MoreSongOperationsViewController(itemView)
moreVC.disMissBlock = {
DispatchQueue.main.async {
collectionView.reloadData()
}
}
moreVC.transitioningDelegate = self
moreVC.modalPresentationStyle = .custom
self.parentController()?.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.personlViewModel?.items[indexPath.row].browseItem.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)
collectionView.reloadData()
}
}
}
alertController.addAction(sure)
self.parentController()?.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.personlViewModel?.items[indexPath.row].browseItem.videoId) else {return}
//
MP_DownloadManager.shared.cancelDownloadTask(videoId) { videoId in
MP_HUD.text("Cancel".localizableString(), delay: 1.0, completion: nil)
collectionView.reloadData()
}
}
alertController.addAction(sure)
self.parentController()?.present(alertController, animated: true)
}
return cell
case .Lists:
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: MPPositive_HomeListThirdCollectionViewCellID, for: indexPath) as! MPPositive_HomeListThirdCollectionViewCell
cell.itemViewModel = personlViewModel?.items[indexPath.row]
return cell
default:
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: MPPositive_HomeListFourthCollectionViewCellID, for: indexPath) as! MPPositive_HomeListFourthCollectionViewCell
cell.itemViewModel = personlViewModel?.items[indexPath.row]
return cell
}
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
guard let item = (self.personlViewModel?.items[indexPath.row]) else {
return
}
switch showType {
case.Singles:
///
MPPositive_Debouncer.shared.call {
[weak self] in
guard let self = self else {return}
guard MP_NetWorkManager.shared.netWorkStatu == .reachable else {
playOfflineSongs()
return
}
MP_AnalyticsManager.shared.home_b_module_clickAction(item.browseItem.pageType ?? "")
MP_AnalyticsManager.shared.song_clickAction("Home")
//
MP_PlayerManager.shared.loadPlayer = nil
//
NotificationCenter.notificationKey.post(notificationName: .pup_player_vc)
MP_AnalyticsManager.shared.player_b_impAction()
//next
MP_NetWorkManager.shared.requestNextList(item.browseItem.playListId ?? "", videoId: item.browseItem.videoId ?? "", clickTrackingParams: item.browseItem.clickTrackingParams){ [weak self] listSongs in
guard let self = self else {return}
//playerloadViewModel
let lodaViewModel = MPPositive_PlayerLoadViewModel(listSongs, currentVideoId: item.browseItem.videoId ?? "")
lodaViewModel.improveData(item.browseItem.videoId ?? "")
//
MP_PlayerManager.shared.setPlayType(.normal)
MP_PlayerManager.shared.loadPlayer = lodaViewModel
MP_AnalyticsManager.shared.player_b_listAction()
}
}
case .Lists:
//
let listVC = MPPositive_ListShowViewController(item.browseItem.browseId ?? "", params: "", title: item.title ?? "", subtitle: item.subtitle ?? "", clickTrackingParams: item.browseItem.clickTrackingParams ?? "")
self.parentController()?.navigationController?.pushViewController(listVC, animated: true)
case .Artists:
let artistVC = MPPositive_ArtistShowViewController(item.browseItem.artistId ?? "", clickTrackingParams: item.browseItem.clickTrackingParams ?? "")
self.parentController()?.navigationController?.pushViewController(artistVC, animated: true)
}
}
func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController? {
return MPPositive_PresentationController(presentedViewController: presented, presenting: presenting)
}
}