Music_Player3/relax.offline.mp3.music/MP/MPPositive/ViewControllers/Search(搜索页)/MPPositive_SearchResultShowViewController.swift

338 lines
14 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_SearchResultShowViewController.swift
// MusicPlayer
//
// Created by Mr.Zhou on 2024/5/12.
//
import UIKit
///
class MPPositive_SearchResultShowViewController: MPPositive_BaseViewController, UIViewControllerTransitioningDelegate {
//MARK: - View
//textField
private lazy var searchTextField:UITextField = {
let textField = UITextField()
textField.delegate = self
textField.font = .systemFont(ofSize: 14*width, weight: .regular)
textField.textColor = .white
//
let attributedText = NSAttributedString(string: "Search songs,artists,playlists", attributes: [.font:UIFont.systemFont(ofSize: 14*width, weight: .regular), .foregroundColor:UIColor(hex: "#666666")])
textField.attributedPlaceholder = attributedText
return textField
}()
//
private lazy var deleteBtn:UIButton = {
let btn:UIButton = .init()
btn.setBackgroundImage(UIImage(named: "Search_Delete'logo"), for: .normal)
btn.addTarget(self, action: #selector(deleteTextClick(_ :)), for: .touchUpInside)
return btn
}()
//cancel
private lazy var cancelBtn:UIButton = {
let btn:UIButton = .init()
btn.setTitle("Cancel", for: .normal)
btn.setTitleColor(.init(hex: "#FFFFFF", alpha: 0.85), for: .normal)
btn.titleLabel?.font = .systemFont(ofSize: 14*width, weight: .regular)
btn.addTarget(self, action: #selector(backPopClick(_ :)), for: .touchUpInside)
return btn
}()
//
private var debounceTimer: Timer?
//
private var suggestionList:MPPositive_SearchSuggestionItemListModel!{
didSet{
DispatchQueue.main.async {
[weak self] in
guard let self = self else {return}
if suggestionList != nil {
//
suggestionView.isHidden = false
suggestionView.suggestions = suggestionList.attributedTexts
MP_AnalyticsManager.shared.search_sug_showAction()
}else {
suggestionView.isHidden = true
suggestionView.suggestions = nil
}
}
}
}
//
private var searchText:String?
//MARK: - View
private lazy var suggestionView:MPPositive_SearchSuggestionsView = .init(frame: .zero)
//MARK: - View
private lazy var resultsShowView:MPPositive_SearchResultsShowView = .init(frame: .zero)
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
}
init(_ text:String) {
super.init(nibName: nil, bundle: nil)
searchTextField.text = text
searchText = text
resultsShowView.loadModel = .init(text)
MP_AnalyticsManager.shared.search_sug_clickAction(text)
}
required init?(coder: NSCoder) {
super.init(coder: coder)
}
deinit {
debounceTimer?.invalidate()
debounceTimer = nil
}
override func viewDidLoad() {
super.viewDidLoad()
setTitle("Result")
setPopBtn()
configure()
suggestionView.selectedTextBlock = {
[weak self] (text) in
guard let self = self else {return}
searchText = text
searchTextField.text = text
resultsShowView.loadModel = .init(text)
MP_AnalyticsManager.shared.search_sug_clickAction(text)
suggestionView.isHidden = true
}
resultsShowView.scrollBlock = {
[weak self] in
self?.view?.endEditing(true)
}
resultsShowView.chooseItemBlock = {
[weak self] (item) in
guard let self = self else {return}
switch item.item.itemType {
case .artist:
//
let artistVC = MPPositive_ArtistShowViewController(item.item.browseId ?? "")
navigationController?.pushViewController(artistVC, animated: true)
case .list:
//
let listVC = MPPositive_ListShowViewController(item.item.browseId ?? "", params: "", title: item.title ?? "", subtitle: item.subtitle ?? "")
navigationController?.pushViewController(listVC, animated: true)
case .single:
MPPositive_Debouncer.shared.call {
[weak self] in
guard let self = self else {return}
guard MP_NetWorkManager.shared.netWorkStatu == .reachable else {
MP_HUD.text("Weak connection.", delay: 2.0, completion: nil)
return
}
//
MP_PlayerManager.shared.loadPlayer = nil
///
//
NotificationCenter.notificationKey.post(notificationName: .pup_player_vc)
MP_AnalyticsManager.shared.player_b_impAction()
//next
MP_NetWorkManager.shared.requestNextList(item.item.playListId ?? "", videoId: item.item.videoId ?? ""){ [weak self] listSongs in
guard let self = self else {return}
//playerloadViewModel
let lodaViewModel = MPPositive_PlayerLoadViewModel(listSongs, currentVideoId: item.item.videoId ?? "")
lodaViewModel.improveData(item.item.videoId ?? "")
//
MP_PlayerManager.shared.setPlayType(.normal)
MP_PlayerManager.shared.loadPlayer = lodaViewModel
MP_AnalyticsManager.shared.player_b_listAction()
// NotificationCenter.notificationKey.post(notificationName: .pup_player_vc)
}
}
case .none:
break
}
}
resultsShowView.moreBlock = {
[weak self] (itemView) in
guard let self = self else {return}
MPPositive_Debouncer.shared.call {
MPPositive_ModalType = .MoreOperations
let moreVC = MPPositive_MoreSongOperationsViewController(itemView)
moreVC.disMissBlock = {
self.resultsShowView.segmentView.reloadData()
}
moreVC.transitioningDelegate = self
moreVC.modalPresentationStyle = .custom
self.present(moreVC, animated: true)
}
}
resultsShowView.cancelBlock = {
[weak self] (itemView, tableView) 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 = itemView.item.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)
}
resultsShowView.deleteBlock = {
[weak self] (itemView, tableView) 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 = itemView.item.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)
}
errorBlock = {
[weak self] in
MP_HUD.hideNow()
self?.resultsShowView.isHidden = false
self?.resultsShowView.emptyImageView.isHidden = false
}
}
func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController? {
return MPPositive_PresentationController(presentedViewController: presented, presenting: presenting)
}
private func configure() {
//
let searchView = createSearchView()
navView.addSubview(searchView)
searchView.snp.makeConstraints { make in
make.width.equalTo(275*width)
make.height.equalTo(40*width)
make.centerY.equalToSuperview()
make.left.equalToSuperview().offset(18*width)
}
navView.addSubview(cancelBtn)
cancelBtn.snp.makeConstraints { make in
make.right.equalToSuperview().offset(-18*width)
make.centerY.equalToSuperview()
}
//suggestionView
view.addSubview(suggestionView)
suggestionView.snp.makeConstraints { make in
make.left.right.bottom.equalToSuperview()
make.top.equalTo(navView.snp.bottom)
}
suggestionView.isHidden = true
//resultsShowView
view.addSubview(resultsShowView)
resultsShowView.snp.makeConstraints { make in
make.left.right.bottom.equalToSuperview()
make.top.equalTo(navView.snp.bottom)
}
resultsShowView.isHidden = true
}
//
private func createSearchView() -> UIView{
let searchView:UIView = UIView()
searchView.backgroundColor = .init(hex: "#000000")
searchView.isUserInteractionEnabled = true
searchView.layer.masksToBounds = true
searchView.layer.cornerRadius = 20*width
//icon
let iconImageView = UIImageView(image: .init(named: "Search_ICON'logo"))
searchView.addSubview(iconImageView)
iconImageView.snp.makeConstraints { make in
make.height.width.equalTo(24*width)
make.left.equalToSuperview().offset(8*width)
make.centerY.equalToSuperview()
}
searchView.addSubview(deleteBtn)
deleteBtn.snp.makeConstraints { make in
make.height.width.equalTo(24*width)
make.right.equalToSuperview().offset(-12*width)
make.centerY.equalToSuperview()
}
//textField
searchView.addSubview(searchTextField)
searchTextField.snp.makeConstraints { make in
make.top.bottom.equalToSuperview()
make.left.equalTo(iconImageView.snp.right).offset(14*width)
make.right.equalTo(deleteBtn.snp.left).offset(-12*width)
}
return searchView
}
//
@objc private func deleteTextClick(_ sender:UIButton) {
//View
searchTextField.text = ""
searchText = ""
suggestionView.suggestions = nil
resultsShowView.loadModel = nil
}
//
@objc private func backPopClick(_ sender:UIButton) {
navigationController?.popViewController(animated: true)
}
}
//MARK: - UITextFieldDelegate
extension MPPositive_SearchResultShowViewController:UITextFieldDelegate {
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
let text = (textField.text! as NSString).replacingCharacters(in: range, with: string)
guard text.count <= 30 else {
return false
}
//,View
resultsShowView.isHidden = true
if text.isEmpty {
self.suggestionList = nil
cancelDebounceTimer()
}else {
//
loadSearchSuggestions(text)
}
return true
}
//
private func cancelDebounceTimer() {
debounceTimer?.invalidate()
debounceTimer = nil
}
//
private func loadSearchSuggestions(_ text:String) {
cancelDebounceTimer()
//0.5
debounceTimer = Timer.scheduledTimer(withTimeInterval: 0.5, repeats: false) { [weak self] _ in
self?.searchText = text
self?.fetchSearchSuggestions(text)
}
}
//
private func fetchSearchSuggestions(_ text:String) {
MP_NetWorkManager.shared.requestSearchSuggestions(text) { [weak self] (result) in
self?.suggestionList = .init(self?.searchText ?? "", suggestions: result)
}
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
//textField
if let text = textField.text, text.isEmpty != true {
self.searchText = text
//
resultsShowView.loadModel = .init(text)
MP_AnalyticsManager.shared.search_sug_clickAction(text)
suggestionView.isHidden = true
//
view.endEditing(true)
return true
}else {
return false
}
}
}