Filter module

dev
wenlei 10 months ago
parent ff497c2c87
commit 8f9479a7dc

@ -16,12 +16,12 @@ final class Application: NSObject {
var provider: IndieMusicAPI? var provider: IndieMusicAPI?
let navigator: Navigator let navigator: Navigator
let authManager: AuthManager let authManager: AuthManager
let launchADManager: LaunchADManager // let launchADManager: LaunchADManager
private override init() { private override init() {
authManager = AuthManager.shared authManager = AuthManager.shared
launchADManager = LaunchADManager.shared // launchADManager = LaunchADManager.shared
navigator = Navigator.default navigator = Navigator.default
super.init() super.init()
updateProvider() updateProvider()

@ -239,9 +239,9 @@ class Navigator {
private func show(target: UIViewController, sender: UIViewController?, transition: Transition) { private func show(target: UIViewController, sender: UIViewController?, transition: Transition) {
switch transition { switch transition {
case .root(in: let window): case .root(in: let window):
UIView.transition(with: window, duration: 0.5, options: .transitionFlipFromLeft, animations: { // UIView.transition(with: window, duration: 0, options: .curveEaseInOut, animations: {
window.rootViewController = target window.rootViewController = target
}, completion: nil) // }, completion: nil)
return return
case .custom: return case .custom: return
default: break default: break

@ -6,9 +6,9 @@
// //
import UIKit import UIKit
import XHLaunchAd //import XHLaunchAd
class LaunchADManager: NSObject, XHLaunchAdDelegate { class LaunchADManager: NSObject {
static let shared = LaunchADManager() static let shared = LaunchADManager()
@ -27,94 +27,94 @@ class LaunchADManager: NSObject, XHLaunchAdDelegate {
} }
func setupXHLaunchAd() { func setupXHLaunchAd() {
photoAD() // photoAD()
} }
func photoAD() { // func photoAD() {
XHLaunchAd.setLaunch(.launchScreen) // XHLaunchAd.setLaunch(.launchScreen)
XHLaunchAd.setWaitDataDuration(2) // XHLaunchAd.setWaitDataDuration(2)
//
//广 // //广
let imageAdconfiguration = XHLaunchImageAdConfiguration.init() // let imageAdconfiguration = XHLaunchImageAdConfiguration.init()
imageAdconfiguration.duration = 4 // imageAdconfiguration.duration = 4
imageAdconfiguration.frame = CGRect.init(x: 0, y: 0, width: BaseDimensions.screenWidth, height: BaseDimensions.screenHeight) // imageAdconfiguration.frame = CGRect.init(x: 0, y: 0, width: BaseDimensions.screenWidth, height: BaseDimensions.screenHeight)
// imageAdconfiguration.imageNameOrURLString = adModel.mediaUrl ?? "" //// imageAdconfiguration.imageNameOrURLString = adModel.mediaUrl ?? ""
//
//() // //()
//,XHLaunchAdImageCacheInBackground,, // //,XHLaunchAdImageCacheInBackground,,
imageAdconfiguration.imageOption = .cacheInBackground // imageAdconfiguration.imageOption = .cacheInBackground
imageAdconfiguration.contentMode = .scaleAspectFill // imageAdconfiguration.contentMode = .scaleAspectFill
// imageAdconfiguration.openModel = adModel.pointTo ?? "" //// imageAdconfiguration.openModel = adModel.pointTo ?? ""
//
//广 // //广
imageAdconfiguration.showFinishAnimate = .fadein // imageAdconfiguration.showFinishAnimate = .fadein
//广 // //广
imageAdconfiguration.showFinishAnimateTime = 0.4 // imageAdconfiguration.showFinishAnimateTime = 0.4
// // //
imageAdconfiguration.skipButtonType = .timeText // imageAdconfiguration.skipButtonType = .timeText
// imageAdconfiguration.customSkipView = self.skipButton() //// imageAdconfiguration.customSkipView = self.skipButton()
//,广 // //,广
imageAdconfiguration.showEnterForeground = false // imageAdconfiguration.showEnterForeground = false
//
// - "" () // // - "" ()
// if XHLaunchAd.checkImageInCache(with: URL.init(string: model.mediaUrl)) { // // if XHLaunchAd.checkImageInCache(with: URL.init(string: model.mediaUrl)) {
// //() // // //()
//// imageAdconfiguration.subViews = [self launchAdSubViews_alreadyView]; // //// imageAdconfiguration.subViews = [self launchAdSubViews_alreadyView];
// } // // }
//
//广 // //广
XHLaunchAd.imageAd(with: imageAdconfiguration, delegate: self) // XHLaunchAd.imageAd(with: imageAdconfiguration, delegate: self)
//
//
} // }
//
func skipButton() -> UIButton { // func skipButton() -> UIButton {
let skipButton = UIButton.init(frame: CGRect.init(x: BaseDimensions.screenWidth - 100, y: BaseDimensions.topHeight, width: 85, height: 30)) // let skipButton = UIButton.init(frame: CGRect.init(x: BaseDimensions.screenWidth - 100, y: BaseDimensions.topHeight, width: 85, height: 30))
skipButton.titleLabel?.font = UIFont.systemFont(ofSize: 14) // skipButton.titleLabel?.font = UIFont.systemFont(ofSize: 14)
skipButton.layer.cornerRadius = 5.0 // skipButton.layer.cornerRadius = 5.0
skipButton.layer.borderWidth = 1.5 // skipButton.layer.borderWidth = 1.5
skipButton.layer.borderColor = UIColor.lightGray.cgColor // skipButton.layer.borderColor = UIColor.lightGray.cgColor
skipButton.backgroundColor = .gray // skipButton.backgroundColor = .gray
skipButton.setTitleColor(.white, for: .normal) // skipButton.setTitleColor(.white, for: .normal)
skipButton.addTarget(self, action: #selector(skipAction), for: .touchUpInside) // skipButton.addTarget(self, action: #selector(skipAction), for: .touchUpInside)
skipButton.setTitle("跳过", for: .normal) // skipButton.setTitle("", for: .normal)
return skipButton // return skipButton
} // }
//
// @objc func skipButtonClick() { //// @objc func skipButtonClick() {
////
//// }
//
//
// ///
// @objc func skipAction() {
// XHLaunchAd.removeAnd(animated: true)
// }
//
// //
// func xhLaunchAd(_ launchAd: XHLaunchAd, clickAndOpenModel openModel: Any, click clickPoint: CGPoint) {
// /** openModel广广(configuration.openModel) */
//
//// let webVC = WebViewController.init(viewModel: nil, )
//// webVC.url = openModel as? String
//// MainRootVc?.children.first?.navigationController?.pushViewController(webVC, animated: true)
// }
//
//
// func xhLaunchAdShowFinish(_ launchAd: XHLaunchAd) {
//
//
//
// NotificationCenter.default.post(name: NSNotification.Name(rawValue: "notiShowAD"), object: nil, userInfo: nil)
//
// }
//
// func xhLaunchAd(_ launchAd: XHLaunchAd, customSkip customSkipView: UIView, duration: Int) {
// var button = self.skipButton()
// //
// button.setTitle("\(duration)", for: .normal)
// //
// } // }
///
@objc func skipAction() {
XHLaunchAd.removeAnd(animated: true)
}
//
func xhLaunchAd(_ launchAd: XHLaunchAd, clickAndOpenModel openModel: Any, click clickPoint: CGPoint) {
/** openModel广广(configuration.openModel) */
// let webVC = WebViewController.init(viewModel: nil, )
// webVC.url = openModel as? String
// MainRootVc?.children.first?.navigationController?.pushViewController(webVC, animated: true)
}
func xhLaunchAdShowFinish(_ launchAd: XHLaunchAd) {
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "notiShowAD"), object: nil, userInfo: nil)
}
func xhLaunchAd(_ launchAd: XHLaunchAd, customSkip customSkipView: UIView, duration: Int) {
var button = self.skipButton()
//
button.setTitle("\(duration)跳过", for: .normal)
}
} }

@ -72,6 +72,8 @@ struct SearchCategory: Codable {
let nameEn: String? let nameEn: String?
let image: String? let image: String?
let description: String? let description: String?
var isExpand: Bool?
} }

@ -91,7 +91,7 @@ class FilterViewController: ViewController {
output.modelSelected.drive { [weak self] sectionItem in output.modelSelected.drive { [weak self] sectionItem in
print(sectionItem) print(sectionItem)
// self?.navigator.dismiss(sender: self) self?.navigator.dismiss(sender: self)
}.disposed(by: rx.disposeBag) }.disposed(by: rx.disposeBag)
} }

@ -25,6 +25,15 @@ class FilterViewModel: ViewModel, ViewModelType {
let itemSelected = PublishSubject<Filter>() let itemSelected = PublishSubject<Filter>()
let items = BehaviorRelay<[FilterSection]>.init(value: []) let items = BehaviorRelay<[FilterSection]>.init(value: [])
var filter: BehaviorRelay<Filter?> = .init(value: nil)
init(filter: BehaviorRelay<Filter?>, provider: IndieMusicAPI) {
super.init(provider: provider)
self.filter = filter
}
func transform(input: Input) -> Output { func transform(input: Input) -> Output {
input.viewWillAppear.subscribe { _ in input.viewWillAppear.subscribe { _ in
@ -46,6 +55,10 @@ class FilterViewModel: ViewModel, ViewModelType {
let selection2 = FilterSection.journalNo(header: "期刊", items: journalNoList ?? []) let selection2 = FilterSection.journalNo(header: "期刊", items: journalNoList ?? [])
self.items.accept([selection0, selection1, selection2]) self.items.accept([selection0, selection1, selection2])
if let filter = self.filter.value {
self.selectItem(selectedFilter: filter)
}
} onError: { error in } onError: { error in
}.disposed(by: self.rx.disposeBag) }.disposed(by: self.rx.disposeBag)
@ -54,6 +67,17 @@ class FilterViewModel: ViewModel, ViewModelType {
input.modelSelected.drive { [weak self] selectedFilter in input.modelSelected.drive { [weak self] selectedFilter in
guard let self = self else { return } guard let self = self else { return }
selectItem(selectedFilter: selectedFilter)
}.disposed(by: rx.disposeBag)
return Output.init(items: items,
modelSelected: input.modelSelected)
}
func selectItem(selectedFilter: Filter) {
var updatedSections: [FilterSection] = [] var updatedSections: [FilterSection] = []
// section // section
@ -86,12 +110,9 @@ class FilterViewModel: ViewModel, ViewModelType {
self.items.accept(updatedSections) self.items.accept(updatedSections)
}.disposed(by: rx.disposeBag) self.filter.accept(selectedFilter)
return Output.init(items: items,
modelSelected: input.modelSelected)
} }

@ -452,16 +452,22 @@ class HomeFilterButton: UIControl {
}() }()
var isFiltered: Bool = false { var filter: Filter? {
didSet { didSet {
if let filter = filter {
imageView.image = UIImage.init(named: "home_drop_icon")
titleLabel.text = filter.name
layer.cornerRadius = 12
layer.borderColor = UIColor.black.cgColor
layer.borderWidth = 1
imageView.image = isFiltered ? UIImage.init(named: "home_drop_icon") : UIImage.init(named: "play_more_btn") } else {
imageView.image = UIImage.init(named: "play_more_btn")
titleLabel.text = "测试" layer.cornerRadius = 0
layer.cornerRadius = isFiltered ? 12 : 0
layer.borderColor = UIColor.black.cgColor layer.borderColor = UIColor.black.cgColor
layer.borderWidth = isFiltered ? 1 : 0 layer.borderWidth = 0
}
} }
} }
@ -485,7 +491,7 @@ class HomeFilterButton: UIControl {
if isFiltered { if filter != nil {
imageView.snp.remakeConstraints { make in imageView.snp.remakeConstraints { make in
make.right.equalTo(self).offset(-8) make.right.equalTo(self).offset(-8)
make.centerY.equalTo(self) make.centerY.equalTo(self)

@ -25,6 +25,9 @@ class HomeViewController: TableViewController {
var currentNavBarBgAlpha: CGFloat = 0 var currentNavBarBgAlpha: CGFloat = 0
let randomAudioTrackTrigger = PublishRelay<Void>.init()
weak var headerView: HomeSectionView?
override func viewDidLoad() { override func viewDidLoad() {
super.viewDidLoad() super.viewDidLoad()
@ -63,8 +66,8 @@ class HomeViewController: TableViewController {
override func makeUI() { override func makeUI() {
super.makeUI() super.makeUI()
let headerView = UIView.init(frame: CGRect.init(x: 0, y: 0, width: BaseDimensions.screenWidth, height: 120)) let headerView = UIView.init(frame: CGRect.init(x: 0, y: 0, width: BaseDimensions.screenWidth, height: 138))
homePagerView.frame = CGRect.init(x: 18, y: 0, width: BaseDimensions.screenWidth - 18 * 2, height: 120) homePagerView.frame = CGRect.init(x: 18, y: 18, width: BaseDimensions.screenWidth - 18 * 2, height: 120)
homePagerView.pagerView.dataSource = self homePagerView.pagerView.dataSource = self
homePagerView.pagerView.delegate = self homePagerView.pagerView.delegate = self
@ -86,7 +89,8 @@ class HomeViewController: TableViewController {
let input = HomeViewModel.Input.init(viewWillAppear: rx.viewWillAppear, let input = HomeViewModel.Input.init(viewWillAppear: rx.viewWillAppear,
headerRefresh: refresh, headerRefresh: refresh,
footerRefresh: footerRefreshTrigger, footerRefresh: footerRefreshTrigger,
selection: tableView.rx.itemSelected.asDriver()) selection: tableView.rx.itemSelected.asDriver(),
randomAudioTrackTrigger: randomAudioTrackTrigger)
let output = viewModel.transform(input: input) let output = viewModel.transform(input: input)
let dataSource = HomeViewController.dataSource { cell, item in let dataSource = HomeViewController.dataSource { cell, item in
@ -148,6 +152,34 @@ class HomeViewController: TableViewController {
}.disposed(by: rx.disposeBag) }.disposed(by: rx.disposeBag)
output.randomAudioTrack.subscribe { audioTrackArray in
guard let audioTrackArray = audioTrackArray.element,
let audioTrack = audioTrackArray.first else { return }
let playerViewModel = PlayerViewModel.init(track: audioTrack, provider: viewModel.provider)
self.navigator.show(segue: .player(viewModel: playerViewModel), sender: self, transition: .modal)
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
//
AudioManager.sharedInstance.setPlaylist(list: audioTrackArray)
AudioManager.sharedInstance.playTrack(track: audioTrack)
}
}.disposed(by: rx.disposeBag)
viewModel.filter.subscribe { filter in
guard let filter = filter.element else { return }
self.headerView?.filterButton.filter = filter
}.disposed(by: rx.disposeBag)
} }
override func viewDidLayoutSubviews() { override func viewDidLayoutSubviews() {
@ -269,25 +301,21 @@ extension HomeViewController {
} }
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
guard let viewModel = self.viewModel as? HomeViewModel else { return nil }
let header = HomeSectionView.init() let header = HomeSectionView.init()
self.headerView = header
self.headerView?.filterButton.filter = viewModel.filter.value
header.theFMButtonClosures = {[weak self] in header.theFMButtonClosures = {[weak self] in
guard let viewModel = self?.viewModel, self?.randomAudioTrackTrigger.accept(())
let track = AudioManager.sharedInstance.currentTrack else { return }
let playerViewModel = PlayerViewModel.init(track: track, provider: viewModel.provider)
self?.navigator.show(segue: .player(viewModel: playerViewModel), sender: self, transition: .modal)
} }
header.filterButtonClosures = {[weak self] in header.filterButtonClosures = {[weak self] in
header.filterButton.isFiltered.toggle()
guard let viewModel = self?.viewModel as? HomeViewModel, guard let viewModel = self?.viewModel as? HomeViewModel,
let navigator = self?.navigator else { return } let navigator = self?.navigator else { return }
let filterViewModel = FilterViewModel.init(provider: viewModel.provider) let filterViewModel = FilterViewModel.init(filter: viewModel.filter, provider: viewModel.provider)
// let filter = FilterViewController.init(viewModel: filterViewModel, navigator: navigator)
// self.present(filter, animated: true)
navigator.show(segue: .filter(viewModel: filterViewModel), sender: self, transition: .navigationPresent(type: .filter)) navigator.show(segue: .filter(viewModel: filterViewModel), sender: self, transition: .navigationPresent(type: .filter))
} }

@ -16,6 +16,7 @@ class HomeViewModel: ViewModel, ViewModelType {
let headerRefresh: Observable<Void> let headerRefresh: Observable<Void>
let footerRefresh: Observable<Void> let footerRefresh: Observable<Void>
let selection: Driver<IndexPath> let selection: Driver<IndexPath>
let randomAudioTrackTrigger: PublishRelay<Void>
} }
struct Output { struct Output {
@ -25,7 +26,7 @@ class HomeViewModel: ViewModel, ViewModelType {
let selection: Driver<IndexPath> let selection: Driver<IndexPath>
let itemSelected: PublishSubject<HomeSectionItem> let itemSelected: PublishSubject<HomeSectionItem>
let footerState: PublishRelay<RxMJRefreshFooterState> let footerState: PublishRelay<RxMJRefreshFooterState>
// let filterTrigger: Driver<Filter> let randomAudioTrack: PublishRelay<[AudioTrack]>
} }
@ -34,6 +35,9 @@ class HomeViewModel: ViewModel, ViewModelType {
let categoryId = BehaviorRelay<String>.init(value: "") let categoryId = BehaviorRelay<String>.init(value: "")
let journalNoRange = BehaviorRelay<String?>.init(value: nil) let journalNoRange = BehaviorRelay<String?>.init(value: nil)
let randomAudioTrack = PublishRelay<[AudioTrack]>.init()
let filter = BehaviorRelay<Filter?>.init(value: nil)
func transform(input: Input) -> Output { func transform(input: Input) -> Output {
let carouselItems = BehaviorRelay<[Carousel]>(value: []) let carouselItems = BehaviorRelay<[Carousel]>(value: [])
@ -106,15 +110,54 @@ class HomeViewModel: ViewModel, ViewModelType {
}.disposed(by: rx.disposeBag) }.disposed(by: rx.disposeBag)
input.randomAudioTrackTrigger.subscribe { _ in
self.requestRandomAudioTrack().subscribe { audioTrackArray in
self.randomAudioTrack.accept(audioTrackArray)
} onError: { error in
}.disposed(by: self.rx.disposeBag)
}.disposed(by: rx.disposeBag)
filter.subscribe { filter in
guard let filter = filter.element else { return }
self.page = 1
let categoryId = filter?.id
self.request(categoryId: filter?.id ?? nil, journalNoRange: filter?.id == "" ? filter?.name : nil, pageNum: self.page, pageSize: 10)
.subscribe { items in
let array = items.map { journal in
return HomeSectionItem.journalDetil(model: journal)
}
let section = HomeSectionModel.journal(title: "", items: array)
elements.accept([section])
} onError: { error in
print("筛选错误\(error)")
} .disposed(by: self.rx.disposeBag)
}.disposed(by: rx.disposeBag)
return Output.init(carouselItems: carouselItems, return Output.init(carouselItems: carouselItems,
items: elements, items: elements,
selection: input.selection, selection: input.selection,
itemSelected: itemSelected, itemSelected: itemSelected,
footerState: footerState) footerState: footerState,
randomAudioTrack: randomAudioTrack)
} }
func request(categoryId: String, func request(categoryId: String?,
journalNoRange: String?, journalNoRange: String?,
pageNum: Int, pageNum: Int,
pageSize: Int) -> Observable<[Journal]> { pageSize: Int) -> Observable<[Journal]> {
@ -131,4 +174,13 @@ class HomeViewModel: ViewModel, ViewModelType {
.trackError(error) .trackError(error)
} }
func requestRandomAudioTrack() -> Observable<[AudioTrack]> {
return self.provider.randomAudioTrack(limit: 30)
.trackActivity(loading)
.trackError(error)
}
} }

@ -121,7 +121,9 @@ class JournalDetailController: ViewController, UIScrollViewDelegate {
guard let viewModel = viewModel as? JournalDetailViewModel else { return } guard let viewModel = viewModel as? JournalDetailViewModel else { return }
let viewDidLoad = Observable.of(())
let input = JournalDetailViewModel.Input.init(viewWillAppear: rx.viewWillAppear, let input = JournalDetailViewModel.Input.init(viewWillAppear: rx.viewWillAppear,
viewDidLoad: viewDidLoad,
selection: collectionView.rx.itemSelected.asDriver(), selection: collectionView.rx.itemSelected.asDriver(),
notiPlayAudioTrack: NotificationCenter.default.rx.notification(.notiPlayAudioTrack)) notiPlayAudioTrack: NotificationCenter.default.rx.notification(.notiPlayAudioTrack))

@ -13,6 +13,7 @@ class JournalDetailViewModel: ViewModel, ViewModelType {
struct Input { struct Input {
let viewWillAppear: ControlEvent<Bool> let viewWillAppear: ControlEvent<Bool>
let viewDidLoad: Observable<Void>
let selection: Driver<IndexPath> let selection: Driver<IndexPath>
let notiPlayAudioTrack: Observable<Notification> let notiPlayAudioTrack: Observable<Notification>
@ -72,38 +73,56 @@ class JournalDetailViewModel: ViewModel, ViewModelType {
input.viewWillAppear.subscribe { (_) in input.viewWillAppear.subscribe { (_) in
guard let journalNo = self.journal.journalNo else { return }
self.requestMusic(journalNo: journalNo).subscribe { audioTrackArray in }.disposed(by: rx.disposeBag)
let audioArray = audioTrackArray.map { audioTrack in
return JournalItem.audioItem(model: audioTrack)
}
self.journal.trackCount = audioArray.count
isLike.accept(self.journal.haveCollect ?? false)
let journalArray = [JournalItem.journaItem(model: self.journal)]
let section = [JournalSection.audio(header: self.journal, items: audioArray),
JournalSection.journal(header: self.journal, items: journalArray)]
elements.accept(section) input.viewDidLoad.subscribe { (_) in
guard let journalNo = self.journal.journalNo, let journalID = self.journal.id else { return }
//
var audioSection: JournalSection?
var journalSection: JournalSection?
} onError: { error in // elements
let updateElements = {
var newSections: [JournalSection] = []
if let audio = audioSection {
newSections.append(audio) //
}
if let journal = journalSection {
newSections.append(journal)
}
elements.accept(newSections)
}
}.disposed(by: self.rx.disposeBag) //
self.requestMusic(journalNo: journalNo)
.subscribe(onNext: { audioTrackArray in
let audioArray = audioTrackArray.map { JournalItem.audioItem(model: $0) }
self.journal.trackCount = audioArray.count
isLike.accept(self.journal.haveCollect ?? false)
audioSection = JournalSection.audio(header: self.journal, items: audioArray)
updateElements()
}, onError: { error in
//
}).disposed(by: self.rx.disposeBag)
//
self.requestJournalRecommend(journalID: journalID)
.subscribe(onNext: { journals in
let journalArray = journals.map { JournalItem.journaItem(model: $0) }
journalSection = JournalSection.journal(header: nil, items: journalArray)
updateElements()
}, onError: { error in
//
}).disposed(by: self.rx.disposeBag)
}.disposed(by: rx.disposeBag) }.disposed(by: rx.disposeBag)
input.selection.drive { indexPath in input.selection.drive { indexPath in
let sectionItem = elements.value[indexPath.section].items[indexPath.row] let sectionItem = elements.value[indexPath.section].items[indexPath.row]
self.itemSelected.onNext(sectionItem) self.itemSelected.onNext(sectionItem)
@ -266,4 +285,11 @@ class JournalDetailViewModel: ViewModel, ViewModelType {
.trackError(error) .trackError(error)
} }
func requestJournalRecommend(journalID: String) -> Observable<[Journal]> {
self.provider.journalRecommend(journalID: journalID)
.trackActivity(loading)
.trackError(error)
}
} }

@ -11,24 +11,39 @@ import RxCocoa
import RxDataSources import RxDataSources
class MusicStyleViewController: ViewController { class MusicStyleViewController: ViewController {
let collectionView: UICollectionView = { lazy var collectionView: UICollectionView = {
let layout = UICollectionViewFlowLayout()
layout.minimumInteritemSpacing = 15
layout.minimumLineSpacing = 24
layout.sectionInset = UIEdgeInsets.init(top: 0, left: 18, bottom: 0, right: 18) let layout = UICollectionViewCompositionalLayout { (sectionIndex, environment) -> NSCollectionLayoutSection? in
let viewModel = self.viewModel as? JournalDetailViewModel
let doubleColumnItemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(0.5), heightDimension: .absolute(147))
let doubleColumnItem = NSCollectionLayoutItem(layoutSize: doubleColumnItemSize)
layout.itemSize = CGSize(width: (BaseDimensions.screenWidth - 18 * 2 - 15) / 2, height: 147) let doubleColumnGroup = NSCollectionLayoutGroup.horizontal(layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .estimated(100)), subitem: doubleColumnItem, count: 2)
doubleColumnGroup.interItemSpacing = .fixed(15)
doubleColumnGroup.contentInsets = NSDirectionalEdgeInsets(top: 0, leading: 18, bottom: 0, trailing: 18)
let collectionView = UICollectionView.init(frame: CGRect.zero, collectionViewLayout: layout) let doubleColumnSection = NSCollectionLayoutSection(group: doubleColumnGroup)
// doubleColumnSection.contentInsets = NSDirectionalEdgeInsets(top: 0, leading: 18, bottom: 0, trailing: 18)
let headerSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .estimated(viewModel?.headerHeight ?? 100))
let header = NSCollectionLayoutBoundarySupplementaryItem(layoutSize: headerSize, elementKind: UICollectionView.elementKindSectionHeader, alignment: .top)
doubleColumnSection.boundarySupplementaryItems = [header]
return doubleColumnSection
}
let collectionView = UICollectionView.init(frame: CGRect.zero, collectionViewLayout: layout)
collectionView.register(JournalViewCell.self, forCellWithReuseIdentifier: "JournalViewCell") collectionView.register(JournalViewCell.self, forCellWithReuseIdentifier: "JournalViewCell")
collectionView.register(MusicStyleHeaderView.self, forSupplementaryViewOfKind: "UICollectionElementKindSectionHeader", withReuseIdentifier: "MusicStyleHeaderView") collectionView.register(MusicStyleHeaderView.self, forSupplementaryViewOfKind: "UICollectionElementKindSectionHeader", withReuseIdentifier: "MusicStyleHeaderView")
if let layout = collectionView.collectionViewLayout as? UICollectionViewFlowLayout { collectionView.backgroundColor = .white
layout.headerReferenceSize = CGSize(width: collectionView.frame.width, height: 360) // header
}
return collectionView return collectionView
}() }()
@ -78,13 +93,11 @@ class MusicStyleViewController: ViewController {
switch refreshType.element { switch refreshType.element {
case .refresh: case .refresh:
self.headerRefreshTrigger.onNext(()) self.headerRefreshTrigger.onNext(())
case .loadMore where AuthManager.shared.token?.isValid == true: case .loadMore:
self.footerRefreshTrigger.onNext(()) self.footerRefreshTrigger.onNext(())
default: break default: break
} }
}.disposed(by: rx.disposeBag) }.disposed(by: rx.disposeBag)
@ -106,7 +119,35 @@ class MusicStyleViewController: ViewController {
let output = viewModel.transform(input: input) let output = viewModel.transform(input: input)
let dataSource = MusicStyleViewController.dataSource() let dataSource = RxCollectionViewSectionedReloadDataSource<MusicStyleSection>(
configureCell: { dataSource, collectionView, indexPath, item in
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "JournalViewCell", for: indexPath) as! JournalViewCell
cell.journal = item
return cell
},
configureSupplementaryView: { dataSource, collectionView, kind, indexPath in
guard kind == UICollectionView.elementKindSectionHeader else {
return UICollectionReusableView()
}
let section = dataSource[indexPath.section]
let resuableView = collectionView.dequeueReusableSupplementaryView(ofKind: "UICollectionElementKindSectionHeader", withReuseIdentifier: "MusicStyleHeaderView", for: indexPath) as! MusicStyleHeaderView
resuableView.searchCategory = section.header
resuableView.dropButtonTapObservable.subscribe { _ in
viewModel.isExpand.accept(!resuableView.isExpand)
viewModel.updateHeaderHeight(newHeight: viewModel.isExpand.value ? 506 + BaseDimensions.topHeight : 400 + BaseDimensions.topHeight)
}.disposed(by: self.rx.disposeBag)
return resuableView
}
)
output.items.bind(to: collectionView.rx.items(dataSource: dataSource)).disposed(by: rx.disposeBag) output.items.bind(to: collectionView.rx.items(dataSource: dataSource)).disposed(by: rx.disposeBag)
@ -122,18 +163,18 @@ class MusicStyleViewController: ViewController {
// _ = self.headerView.dropButton.rx.isSelected <-> viewModel.isExpand // _ = self.headerView.dropButton.rx.isSelected <-> viewModel.isExpand
viewModel.isExpand // viewModel.isExpand
.bind(to: self.headerView.dropButton.rx.isSelected) // .bind(to: self.headerView.dropButton.rx.isSelected)
.disposed(by: rx.disposeBag) // .disposed(by: rx.disposeBag)
//
viewModel.isExpand.subscribe { [weak self] isExpand in // viewModel.isExpand.subscribe { [weak self] isExpand in
//
print("dropButtonTrigger \(isExpand)") // print("dropButtonTrigger \(isExpand)")
self?.headerView.isExpand = isExpand // self?.headerView.isExpand = isExpand
self?.updateHeader() // self?.updateHeader()
//
} .disposed(by: rx.disposeBag) // } .disposed(by: rx.disposeBag)
//
} }
@ -163,44 +204,6 @@ class MusicStyleViewController: ViewController {
}
extension MusicStyleViewController: UICollectionViewDelegateFlowLayout {
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
// section header
let width = collectionView.bounds.width
headerView.frame = CGRect(x: 0, y: 0, width: width, height: 1000)
headerView.layoutIfNeeded()
let size = headerView.systemLayoutSizeFitting(CGSize(width: width, height: UIView.layoutFittingCompressedSize.height),
withHorizontalFittingPriority: .required,
verticalFittingPriority: .fittingSizeLevel)
return CGSize(width: collectionView.bounds.width, height: size.height)
}
static func dataSource() -> RxCollectionViewSectionedReloadDataSource<MusicStyleSection> {
return RxCollectionViewSectionedReloadDataSource<MusicStyleSection>(
configureCell: { dataSource, collectionView, indexPath, item in
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "JournalViewCell", for: indexPath) as! JournalViewCell
cell.journal = item
return cell
},
configureSupplementaryView: { dataSource, collectionView, kind, indexPath in
guard kind == UICollectionView.elementKindSectionHeader else {
return UICollectionReusableView()
}
let section = dataSource[indexPath.section]
let resuableView = collectionView.dequeueReusableSupplementaryView(ofKind: "UICollectionElementKindSectionHeader", withReuseIdentifier: "MusicStyleHeaderView", for: indexPath) as! MusicStyleHeaderView
resuableView.searchCategory = section.header
return resuableView
}
)
}
} }
@ -252,10 +255,12 @@ class MusicStyleHeaderView: UICollectionReusableView {
var dropButton: UIButton = { var dropButton: UIButton = {
let dropButton = UIButton.init() let dropButton = LayoutableButton.init()
dropButton.imageHorizontalAlignment = .right
dropButton.setTitle("展开", for: .normal) dropButton.setTitle("展开", for: .normal)
dropButton.setTitle("收起", for: .selected) dropButton.setTitle("收起", for: .selected)
dropButton.setTitleColor(.init(hex: 0x000000, alpha: 0.6), for: .normal) dropButton.setTitleColor(.secondaryText(), for: .normal)
dropButton.titleLabel?.font = UIFont.systemFont(ofSize: 15)
dropButton.setImage(UIImage.init(named: "journal_drop_down"), for: .normal) dropButton.setImage(UIImage.init(named: "journal_drop_down"), for: .normal)
dropButton.setImage(UIImage.init(named: "journal_drop_up"), for: .selected) dropButton.setImage(UIImage.init(named: "journal_drop_up"), for: .selected)
@ -265,37 +270,39 @@ class MusicStyleHeaderView: UICollectionReusableView {
var gradientLayer: CAGradientLayer = { var gradientLayerView: GradientLayerView = {
let gradientLayer = CAGradientLayer.init() let gradientLayerView = GradientLayerView.init(colors: [UIColor.init(hex: 0xFFFFFF, alpha: 0).cgColor,
gradientLayer.colors = [UIColor.init(hex: 0xFFFFFF, alpha: 0).cgColor, UIColor.init(hex: 0xFFFFFF, alpha: 0.8).cgColor], frame: .zero)
UIColor.init(hex: 0xFFFFFF, alpha: 0.8).cgColor] // gradientLayerView.backgroundColor = .red
gradientLayer.locations = [0.0, 0.9]
gradientLayer.startPoint = CGPoint.init(x: 0 , y: 0)
gradientLayer.endPoint = CGPoint.init(x: 0, y: 1)
return gradientLayer return gradientLayerView
}() }()
var isExpand = false { var isExpand = false {
didSet { didSet {
switch isExpand { switch isExpand {
case true: case true:
dropButton.isSelected = true dropButton.isSelected = true
contentLabel.numberOfLines = 0 contentLabel.numberOfLines = 0
gradientLayer.isHidden = true
gradientLayerView.isHidden = true
case false: case false:
dropButton.isSelected = false dropButton.isSelected = false
contentLabel.numberOfLines = 4 contentLabel.numberOfLines = 4
gradientLayer.isHidden = false
gradientLayerView.isHidden = false
} }
} }
} }
var dropButtonTapObservable: Observable<Void> {
return dropButton.rx.tap.asObservable()
}
var searchCategory: SearchCategory? { var searchCategory: SearchCategory? {
didSet { didSet {
guard let searchCategory = searchCategory else { return } guard let searchCategory = searchCategory else { return }
@ -308,6 +315,9 @@ class MusicStyleHeaderView: UICollectionReusableView {
contentLabel.text = searchCategory.description contentLabel.text = searchCategory.description
self.isExpand = searchCategory.isExpand ?? false
} }
} }
@ -316,6 +326,8 @@ class MusicStyleHeaderView: UICollectionReusableView {
super.init(frame: frame) super.init(frame: frame)
makeUI() makeUI()
backgroundColor = .red
} }
required init?(coder: NSCoder) { required init?(coder: NSCoder) {
@ -329,13 +341,9 @@ class MusicStyleHeaderView: UICollectionReusableView {
containerView.addSubview(styleLabel) containerView.addSubview(styleLabel)
containerView.addSubview(subStyleLabel) containerView.addSubview(subStyleLabel)
containerView.addSubview(contentLabel) containerView.addSubview(contentLabel)
containerView.addSubview(gradientLayerView)
containerView.addSubview(dropButton) containerView.addSubview(dropButton)
}
override func layoutSubviews() {
super.layoutSubviews()
titleImageView.snp.makeConstraints { make in titleImageView.snp.makeConstraints { make in
make.left.equalTo(self) make.left.equalTo(self)
@ -361,12 +369,16 @@ class MusicStyleHeaderView: UICollectionReusableView {
make.centerY.equalTo(styleLabel) make.centerY.equalTo(styleLabel)
} }
contentLabel.snp.makeConstraints { make in contentLabel.snp.remakeConstraints { make in
make.left.equalTo(containerView).offset(18) make.left.equalTo(containerView).offset(18)
make.right.equalTo(containerView).offset(-18) make.right.equalTo(containerView).offset(-18)
make.top.equalTo(styleLabel.snp.bottom).offset(15) make.top.equalTo(styleLabel.snp.bottom).offset(15)
} }
gradientLayerView.snp.remakeConstraints { make in
make.edges.equalTo(contentLabel)
}
dropButton.snp.remakeConstraints { make in dropButton.snp.remakeConstraints { make in
make.left.equalTo(containerView).offset(18) make.left.equalTo(containerView).offset(18)
make.top.equalTo(contentLabel.snp.bottom).offset(16) make.top.equalTo(contentLabel.snp.bottom).offset(16)
@ -374,7 +386,14 @@ class MusicStyleHeaderView: UICollectionReusableView {
} }
gradientLayer.frame = self.contentLabel.bounds
}
override func layoutSubviews() {
super.layoutSubviews()
} }

@ -26,9 +26,9 @@ class MusicStyleViewModel: ViewModel, ViewModelType {
let itemSelected = PublishSubject<MusicStyle>() let itemSelected = PublishSubject<MusicStyle>()
var headerHeight: CGFloat = 506 + BaseDimensions.topHeight
let isExpand = BehaviorRelay<Bool>.init(value: false) let isExpand = BehaviorRelay<Bool>.init(value: false)
var searchCategory: SearchCategory? var searchCategory: SearchCategory?
init(searchCategory: SearchCategory?, provider: IndieMusicAPI) { init(searchCategory: SearchCategory?, provider: IndieMusicAPI) {
self.searchCategory = searchCategory self.searchCategory = searchCategory
@ -89,6 +89,21 @@ class MusicStyleViewModel: ViewModel, ViewModelType {
// self.itemSelected.onNext(sectionItem) // self.itemSelected.onNext(sectionItem)
// }.disposed(by: rx.disposeBag) // }.disposed(by: rx.disposeBag)
isExpand.subscribe { isExpand in
var new = elements.value
if var header = new.first?.header {
header.isExpand = isExpand.element
if let items = new.first?.items {
new[0] = .init(header: header, items: items)
elements.accept(new)
}
}
}.disposed(by: rx.disposeBag)
let journal = PublishSubject<Journal>.init() let journal = PublishSubject<Journal>.init()
@ -108,4 +123,9 @@ class MusicStyleViewModel: ViewModel, ViewModelType {
.trackActivity(loading) .trackActivity(loading)
.trackError(error) .trackError(error)
} }
func updateHeaderHeight(newHeight: CGFloat) {
headerHeight = newHeight
}
} }

@ -103,10 +103,12 @@ class SearchResultsController: ViewController {
guard let viewModel = viewModel as? SearchResultsViewModel else { return } guard let viewModel = viewModel as? SearchResultsViewModel else { return }
let input = SearchResultsViewModel.Input.init(viewWillAppear: rx.viewWillAppear, let input = SearchResultsViewModel.Input.init(viewWillAppear: rx.viewWillAppear,
closeButtonTrigger: self.searchTopBar.cancelButton.rx.tap.asDriver(), closeButtonTrigger: self.searchTopBar.cancelButton.rx.tap.asDriver(),
searchText: searchTopBar.searchControl.textField.rx.text.asDriver(), searchText: searchTopBar.searchControl.textField.rx.text.asDriver(),
itemSelected: collectionView.rx.modelSelected(SearchResultsItem.self).asDriver(), modelSelected: collectionView.rx.modelSelected(SearchResultsItem.self).asDriver(),
searchType: searchType) searchType: searchType)
@ -127,6 +129,30 @@ class SearchResultsController: ViewController {
}.disposed(by: rx.disposeBag) }.disposed(by: rx.disposeBag)
output.modelSelected.drive { [weak self] searchResultsItem in
switch searchResultsItem {
case .single(let audioTrack):
let playerViewModel = PlayerViewModel.init(track: audioTrack, provider: viewModel.provider)
self?.navigator.show(segue: .player(viewModel: playerViewModel), sender: self, transition: .modal)
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
AudioManager.sharedInstance.setPlaylist(list: [audioTrack])
AudioManager.sharedInstance.playTrack(track: audioTrack)
}
case .journal(let journal):
let journalDetailViewModel = JournalDetailViewModel.init(journal: journal, provider: viewModel.provider)
self?.navigator.show(segue: .journalDetail(viewModel: journalDetailViewModel), sender: self)
}
}.disposed(by: rx.disposeBag)
} }
@ -201,21 +227,24 @@ extension SearchResultsController {
func createDoubleColumnSection() -> NSCollectionLayoutSection { func createDoubleColumnSection() -> NSCollectionLayoutSection {
let doubleColumnItemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(0.5), heightDimension: .absolute(147)) let doubleColumnItemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(0.5), heightDimension: .absolute(147))
let doubleColumnItem = NSCollectionLayoutItem(layoutSize: doubleColumnItemSize) let doubleColumnItem = NSCollectionLayoutItem(layoutSize: doubleColumnItemSize)
// doubleColumnItem.contentInsets = NSDirectionalEdgeInsets(top: 0, leading: 7.5, bottom: 0, trailing: 7.5)
let doubleColumnGroup = NSCollectionLayoutGroup.horizontal(layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .estimated(100)), subitem: doubleColumnItem, count: 2) let doubleColumnGroup = NSCollectionLayoutGroup.horizontal(layoutSize: NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .estimated(100)), subitem: doubleColumnItem, count: 2)
doubleColumnGroup.interItemSpacing = .fixed(10) doubleColumnGroup.interItemSpacing = .fixed(15)
doubleColumnGroup.contentInsets = NSDirectionalEdgeInsets(top: 0, leading: 18, bottom: 0, trailing: 18)
let doubleColumnSection = NSCollectionLayoutSection(group: doubleColumnGroup) let doubleColumnSection = NSCollectionLayoutSection(group: doubleColumnGroup)
doubleColumnSection.contentInsets = NSDirectionalEdgeInsets(top: 0, leading: 18, bottom: 0, trailing: 18)
return doubleColumnSection return doubleColumnSection
} }
} }
class SearchTopBar: UIView { class SearchTopBar: UIView {
let searchControl: SearchControl = { let searchControl: SearchControl = {
let searchControl = SearchControl.init() let searchControl = SearchControl.init()

@ -16,7 +16,7 @@ class SearchResultsViewModel: ViewModel, ViewModelType {
let viewWillAppear: ControlEvent<Bool> let viewWillAppear: ControlEvent<Bool>
let closeButtonTrigger: Driver<Void> let closeButtonTrigger: Driver<Void>
let searchText: Driver<String?> let searchText: Driver<String?>
let itemSelected: Driver<SearchResultsItem> let modelSelected: Driver<SearchResultsItem>
let searchType: BehaviorRelay<SearchType> let searchType: BehaviorRelay<SearchType>
} }
@ -24,7 +24,7 @@ class SearchResultsViewModel: ViewModel, ViewModelType {
struct Output { struct Output {
let items: BehaviorRelay<[SearchResultsSection]> let items: BehaviorRelay<[SearchResultsSection]>
let itemSelected: PublishSubject<SearchResultsItem> let modelSelected: Driver<SearchResultsItem>
} }
let items = BehaviorRelay<[SearchResultsSection]>.init(value: []) let items = BehaviorRelay<[SearchResultsSection]>.init(value: [])
@ -42,7 +42,9 @@ class SearchResultsViewModel: ViewModel, ViewModelType {
}.disposed(by: rx.disposeBag) }.disposed(by: rx.disposeBag)
input.searchText.drive { searchText in
input.searchText.debounce(.milliseconds(500))
.drive { searchText in
self.fetchSearchData(keyword: searchText ?? "") self.fetchSearchData(keyword: searchText ?? "")
.subscribe { searchResults in .subscribe { searchResults in
@ -68,6 +70,7 @@ class SearchResultsViewModel: ViewModel, ViewModelType {
input.searchType.subscribe { searchType in input.searchType.subscribe { searchType in
self.searchType.accept(searchType.element ?? .audio)
switch searchType.element { switch searchType.element {
case .audio: case .audio:
@ -88,31 +91,18 @@ class SearchResultsViewModel: ViewModel, ViewModelType {
self.items.accept([SearchResultsSection.single(title: "", items: self.audioTrackItems.value)]) self.items.accept([SearchResultsSection.single(title: "", items: self.audioTrackItems.value)])
case .journal: case .journal:
self.items.accept([SearchResultsSection.journal(title: "", items: self.journalItems.value)]) self.items.accept([SearchResultsSection.journal(title: "", items: self.journalItems.value)])
default: break
} }
}.disposed(by: rx.disposeBag) }.disposed(by: rx.disposeBag)
input.modelSelected.drive { searchResultsItem in
//
//
//
// let musicStyleItem = MusicStyle.init(title: "", subTitle: "123", backgroundImage: "")
// let musicStyleSection = MusicStyleSection.init(items: [musicStyleItem, musicStyleItem, musicStyleItem, musicStyleItem], header: "", headerSub: "Post Rock", content: "怀怀", isExpand: false)
//
//
// collectionViewItemstems.accept([musicStyleSection])
//
input.itemSelected.drive { indexPath in
// guard let sectionItem = self.collectionViewItemstems.value.first?.items[indexPath.row] else { return }
// self.collectionViewSelection.onNext(sectionItem)
}.disposed(by: rx.disposeBag) }.disposed(by: rx.disposeBag)
return Output.init(items: items, return Output.init(items: items,
itemSelected: itemSelected) modelSelected: input.modelSelected)
} }

@ -39,7 +39,7 @@ class SettingViewMdel: ViewModel, ViewModelType {
let timing = Setting.init(title: "定时关闭", detail: "", arrowIcon: "setting_arrow") let timing = Setting.init(title: "定时关闭", detail: "", arrowIcon: "setting_arrow")
let cache = Setting.init(title: "清理缓存", detail: "201.4MB", arrowIcon: "setting_arrow") let cache = Setting.init(title: "清理缓存", detail: "0.00MB", arrowIcon: "setting_arrow")
let permission = Setting.init(title: "个人信息与权限", detail: "", arrowIcon: "setting_arrow") let permission = Setting.init(title: "个人信息与权限", detail: "", arrowIcon: "setting_arrow")

@ -33,7 +33,7 @@ protocol IndieMusicAPI {
/// ///
func journalList(categoryId: String, journalNoRange: String?, pageNum: Int, pageSize: Int) -> Single<[Journal]> func journalList(categoryId: String?, journalNoRange: String?, pageNum: Int, pageSize: Int) -> Single<[Journal]>
/// ///
func journalMusic(journalNo: String) -> Single<[AudioTrack]> func journalMusic(journalNo: String) -> Single<[AudioTrack]>
@ -80,5 +80,8 @@ protocol IndieMusicAPI {
/// ///
func serach(keyword: String) -> Single<SearchResults> func serach(keyword: String) -> Single<SearchResults>
///
func randomAudioTrack(limit: Int) -> Single<[AudioTrack]>
} }

@ -51,6 +51,8 @@ enum APIConfig {
case searchCategory case searchCategory
case serach(String) case serach(String)
case randomAudioTrack(Int)
} }
extension APIConfig: TargetType { extension APIConfig: TargetType {
@ -125,12 +127,15 @@ extension APIConfig: TargetType {
case .serach(let keyword): case .serach(let keyword):
return "luoo-music/search/fuzzy/\(keyword)" return "luoo-music/search/fuzzy/\(keyword)"
case .randomAudioTrack(let limit):
return "luoo-music/song/random/\(limit)"
} }
} }
var method: Moya.Method { var method: Moya.Method {
switch self { switch self {
case .wechatAccessToken, .journalList, .journalMusic, .countryCode, .imageCheckCode, .getUserInfo, .carousel, .otherUserInfo, .single, .journal, .messageList, .collectSongList, .journalCollectList, .followingList, .followerList, .blackList, .commentList, .subCommentList, .filterMenu, .journalRecommend, .searchCategory, .serach: case .wechatAccessToken, .journalList, .journalMusic, .countryCode, .imageCheckCode, .getUserInfo, .carousel, .otherUserInfo, .single, .journal, .messageList, .collectSongList, .journalCollectList, .followingList, .followerList, .blackList, .commentList, .subCommentList, .filterMenu, .journalRecommend, .searchCategory, .serach, .randomAudioTrack:
return .get return .get
case .sendsms, .login, .autoLogin, .editAvatar, .like, .checkVersion, .logout: case .sendsms, .login, .autoLogin, .editAvatar, .like, .checkVersion, .logout:
return .post return .post
@ -144,7 +149,7 @@ extension APIConfig: TargetType {
var parameterEncoding: ParameterEncoding { var parameterEncoding: ParameterEncoding {
switch self { switch self {
case .wechatAccessToken, .journalList, .journalMusic, .countryCode, .sendsms, .imageCheckCode, .login, .getUserInfo, .carousel, .otherUserInfo, .single, .journal, .messageList, .like, .cancelLike, .collectSongList, .journalCollectList, .followingList, .followerList, .blackList, .commentList, .subCommentList, .filterMenu, .journalRecommend, .searchCategory, .serach: case .wechatAccessToken, .journalList, .journalMusic, .countryCode, .sendsms, .imageCheckCode, .login, .getUserInfo, .carousel, .otherUserInfo, .single, .journal, .messageList, .like, .cancelLike, .collectSongList, .journalCollectList, .followingList, .followerList, .blackList, .commentList, .subCommentList, .filterMenu, .journalRecommend, .searchCategory, .serach, .randomAudioTrack:
return URLEncoding.default return URLEncoding.default
case .autoLogin, .editUserInfo, .editAvatar, .checkVersion, .logout, .commentLike: case .autoLogin, .editUserInfo, .editAvatar, .checkVersion, .logout, .commentLike:
@ -156,7 +161,7 @@ extension APIConfig: TargetType {
var task: Task { var task: Task {
var parameters: [String: Any] = [:] var parameters: [String: Any] = [:]
switch self { switch self {
case .wechatAccessToken, .countryCode, .journalMusic, .imageCheckCode, .getUserInfo, .carousel, .otherUserInfo, .single, .journal, .messageList, .collectSongList, .journalCollectList, .followingList, .followerList, .blackList, .commentList, .subCommentList, .filterMenu, .journalRecommend, .searchCategory, .serach: case .wechatAccessToken, .countryCode, .journalMusic, .imageCheckCode, .getUserInfo, .carousel, .otherUserInfo, .single, .journal, .messageList, .collectSongList, .journalCollectList, .followingList, .followerList, .blackList, .commentList, .subCommentList, .filterMenu, .journalRecommend, .searchCategory, .serach, .randomAudioTrack:
return .requestPlain return .requestPlain
case .login(let dic), .journalList(let dic), .sendsms(let dic), .autoLogin(let dic), .editUserInfo(let dic), .like(let dic), .cancelLike(let dic), .logout(let dic), .checkVersion(let dic), .commentLike(_, let dic): case .login(let dic), .journalList(let dic), .sendsms(let dic), .autoLogin(let dic), .editUserInfo(let dic), .like(let dic), .cancelLike(let dic), .logout(let dic), .checkVersion(let dic), .commentLike(_, let dic):
@ -185,7 +190,7 @@ extension APIConfig: TargetType {
var headers : [String : String]? { var headers : [String : String]? {
switch self { switch self {
case .autoLogin, .getUserInfo, .journalList, .journalMusic, .otherUserInfo, .like, .cancelLike, .single, .journal, .collectSongList, .journalCollectList, .followingList, .messageList, .followerList, .blackList, .editUserInfo, .logout, .editAvatar, .commentList, .subCommentList, .commentLike, .filterMenu, .journalRecommend, .serach: case .autoLogin, .getUserInfo, .journalList, .journalMusic, .otherUserInfo, .like, .cancelLike, .single, .journal, .collectSongList, .journalCollectList, .followingList, .messageList, .followerList, .blackList, .editUserInfo, .logout, .editAvatar, .commentList, .subCommentList, .commentLike, .filterMenu, .journalRecommend, .serach, .randomAudioTrack:
return ["Authorization": AuthManager.shared.token?.basicToken ?? ""] return ["Authorization": AuthManager.shared.token?.basicToken ?? ""]
default: default:
return nil return nil

@ -145,15 +145,19 @@ extension RestApi {
} }
func journalList(categoryId: String, journalNoRange: String?, pageNum: Int, pageSize: Int) -> Single<[Journal]> { func journalList(categoryId: String?, journalNoRange: String?, pageNum: Int, pageSize: Int) -> Single<[Journal]> {
var dic = ["categoryId": categoryId, var dic = ["pageNum": pageNum,
"pageNum": pageNum,
"pageSize": pageSize "pageSize": pageSize
] as [String : Any] ] as [String : Any]
if let categoryId = categoryId {
dic["categoryId"] = categoryId
}
if let journalNoRange = journalNoRange { if let journalNoRange = journalNoRange {
dic["journalNoRange"] = journalNoRange dic["journalNoRange"] = journalNoRange
} }
print("筛选错误条件\(dic)")
return requestObject(.journalList(dic), with: "data.rows", type: [Journal].self) return requestObject(.journalList(dic), with: "data.rows", type: [Journal].self)
@ -263,4 +267,8 @@ extension RestApi {
} }
func randomAudioTrack(limit: Int) -> Single<[AudioTrack]> {
return requestObject(.randomAudioTrack(limit), with: "data", type: [AudioTrack].self)
}
} }

@ -20,7 +20,7 @@ target 'IndieMusic' do
pod 'WechatOpenSDK-XCFramework' pod 'WechatOpenSDK-XCFramework'
pod 'SwiftDate' pod 'SwiftDate'
pod 'DateToolsSwift' pod 'DateToolsSwift'
pod 'XHLaunchAd' # pod 'XHLaunchAd'
pod 'DZNEmptyDataSet' pod 'DZNEmptyDataSet'
pod 'SVProgressHUD',:git => 'https://github.com/Fidetro/SVProgressHUD.git' pod 'SVProgressHUD',:git => 'https://github.com/Fidetro/SVProgressHUD.git'
pod 'AttributedString' pod 'AttributedString'

Loading…
Cancel
Save