|
|
|
@ -13,69 +13,13 @@ import ETNavBarTransparent
|
|
|
|
|
import SVProgressHUD
|
|
|
|
|
import RxOptional
|
|
|
|
|
|
|
|
|
|
class JournalDetailController: TableViewController {
|
|
|
|
|
let journalCollapsibleHeaderView: JournalCollapsibleHeaderView = {
|
|
|
|
|
let journalCollapsibleHeaderView = JournalCollapsibleHeaderView.init()
|
|
|
|
|
|
|
|
|
|
class JournalDetailController: ViewController, UIScrollViewDelegate {
|
|
|
|
|
|
|
|
|
|
lazy var collectionView: UICollectionView = {
|
|
|
|
|
|
|
|
|
|
let layout = UICollectionViewCompositionalLayout { (sectionIndex, environment) -> NSCollectionLayoutSection? in
|
|
|
|
|
let viewModel = self.viewModel as? JournalDetailViewModel
|
|
|
|
|
if sectionIndex == 0 {
|
|
|
|
|
let singleColumnItemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .estimated(100))
|
|
|
|
|
let singleColumnItem = NSCollectionLayoutItem(layoutSize: singleColumnItemSize)
|
|
|
|
|
// singleColumnItem.contentInsets = NSDirectionalEdgeInsets(top: 0, leading: 18, bottom: 0, trailing: 18)
|
|
|
|
|
|
|
|
|
|
let singleColumnGroup = NSCollectionLayoutGroup.horizontal(layoutSize: singleColumnItemSize, subitems: [singleColumnItem])
|
|
|
|
|
|
|
|
|
|
let singleColumnSection = NSCollectionLayoutSection(group: singleColumnGroup)
|
|
|
|
|
|
|
|
|
|
// 创建header
|
|
|
|
|
let headerSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .estimated(viewModel?.headerHeight ?? 100))
|
|
|
|
|
let header = NSCollectionLayoutBoundarySupplementaryItem(layoutSize: headerSize, elementKind: UICollectionView.elementKindSectionHeader, alignment: .top)
|
|
|
|
|
singleColumnSection.boundarySupplementaryItems = [header]
|
|
|
|
|
// singleColumnSection.contentInsets = NSDirectionalEdgeInsets(top: 0, leading: 18, bottom: 0, trailing: 18)
|
|
|
|
|
|
|
|
|
|
return singleColumnSection
|
|
|
|
|
} else {
|
|
|
|
|
let doubleColumnItemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(0.5), heightDimension: .absolute(147))
|
|
|
|
|
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)
|
|
|
|
|
doubleColumnGroup.interItemSpacing = .fixed(10)
|
|
|
|
|
|
|
|
|
|
let doubleColumnSection = NSCollectionLayoutSection(group: doubleColumnGroup)
|
|
|
|
|
|
|
|
|
|
let headerSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .estimated(44))
|
|
|
|
|
let header = NSCollectionLayoutBoundarySupplementaryItem(layoutSize: headerSize, elementKind: UICollectionView.elementKindSectionHeader, alignment: .top)
|
|
|
|
|
doubleColumnSection.boundarySupplementaryItems = [header]
|
|
|
|
|
|
|
|
|
|
doubleColumnSection.contentInsets = NSDirectionalEdgeInsets(top: 0, leading: 18, bottom: 0, trailing: 18)
|
|
|
|
|
doubleColumnSection.interGroupSpacing = 24
|
|
|
|
|
|
|
|
|
|
return doubleColumnSection
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let collectionView = UICollectionView.init(frame: CGRect.zero, collectionViewLayout: layout)
|
|
|
|
|
collectionView.register(JournalViewCell.self, forCellWithReuseIdentifier: "JournalViewCell")
|
|
|
|
|
collectionView.register(JournalAudioViewCell.self, forCellWithReuseIdentifier: "JournalAudioViewCell")
|
|
|
|
|
|
|
|
|
|
collectionView.register(JournalAudioHeaderView.self, forSupplementaryViewOfKind: "UICollectionElementKindSectionHeader", withReuseIdentifier: "JournalAudioHeaderView")
|
|
|
|
|
collectionView.register(JournalDetailHeaderView.self, forSupplementaryViewOfKind: "UICollectionElementKindSectionHeader", withReuseIdentifier: "JournalDetailHeaderView")
|
|
|
|
|
|
|
|
|
|
collectionView.backgroundColor = .white
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return collectionView
|
|
|
|
|
return journalCollapsibleHeaderView
|
|
|
|
|
}()
|
|
|
|
|
|
|
|
|
|
weak var audioHeaderView: JournalAudioHeaderView?
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var commentToolView: CommentToolView = {
|
|
|
|
|
let commentToolView = CommentToolView.init()
|
|
|
|
|
|
|
|
|
@ -83,15 +27,13 @@ class JournalDetailController: ViewController, UIScrollViewDelegate {
|
|
|
|
|
}()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
override func viewDidLoad() {
|
|
|
|
|
super.viewDidLoad()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
override func viewWillAppear(_ animated: Bool) {
|
|
|
|
|
super.viewWillAppear(animated)
|
|
|
|
|
|
|
|
|
@ -102,18 +44,24 @@ class JournalDetailController: ViewController, UIScrollViewDelegate {
|
|
|
|
|
super.viewWillDisappear(animated)
|
|
|
|
|
|
|
|
|
|
navBarBgAlpha = 1
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
override func makeUI() {
|
|
|
|
|
super.makeUI()
|
|
|
|
|
|
|
|
|
|
collectionView.rx.setDelegate(self).disposed(by: rx.disposeBag)
|
|
|
|
|
|
|
|
|
|
view.addSubview(commentToolView)
|
|
|
|
|
view.addSubview(collectionView)
|
|
|
|
|
|
|
|
|
|
// updateText(text: "")
|
|
|
|
|
tableView.tableHeaderView = journalCollapsibleHeaderView
|
|
|
|
|
tableView.tableFooterView = UIView()
|
|
|
|
|
|
|
|
|
|
tableView.register(JournalAudioViewCell.self, forCellReuseIdentifier: "JournalAudioViewCell")
|
|
|
|
|
tableView.register(JournalContainerViewCell.self, forCellReuseIdentifier: "JournalContainerViewCell")
|
|
|
|
|
|
|
|
|
|
tableView.register(JournalAudioSectionView.self, forHeaderFooterViewReuseIdentifier: "JournalAudioSectionView")
|
|
|
|
|
tableView.register(JournalDetailSectionView.self, forHeaderFooterViewReuseIdentifier: "JournalDetailSectionView")
|
|
|
|
|
|
|
|
|
|
tableView.mj_header = nil
|
|
|
|
|
tableView.mj_footer = nil
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -125,169 +73,66 @@ class JournalDetailController: ViewController, UIScrollViewDelegate {
|
|
|
|
|
let viewDidLoad = Observable.of(())
|
|
|
|
|
let input = JournalDetailViewModel.Input.init(viewWillAppear: rx.viewWillAppear,
|
|
|
|
|
viewDidLoad: viewDidLoad,
|
|
|
|
|
selection: collectionView.rx.itemSelected.asDriver(),
|
|
|
|
|
modelSelected: tableView.rx.modelSelected(JournalItem.self).asDriver(),
|
|
|
|
|
notiPlayAudioTrack: NotificationCenter.default.rx.notification(.notiPlayAudioTrack))
|
|
|
|
|
|
|
|
|
|
// dropButtonTrigger: headerView.dropButton.rx.tap.asDriver(),
|
|
|
|
|
// playButtonTrigger: headerView.playButton.rx.tap.asDriver(),
|
|
|
|
|
// shareButtonTrigger: headerView.playButton.rx.tap.asDriver())//TODO
|
|
|
|
|
|
|
|
|
|
let output = viewModel.transform(input: input)
|
|
|
|
|
|
|
|
|
|
let dataSource = RxCollectionViewSectionedReloadDataSource<JournalSection>(
|
|
|
|
|
configureCell: { dataSource, collectionView, indexPath, item in
|
|
|
|
|
let dataSource = RxTableViewSectionedReloadDataSource<JournalSection>(
|
|
|
|
|
configureCell: { dataSource, tableView, indexPath, item in
|
|
|
|
|
|
|
|
|
|
switch dataSource[indexPath] {
|
|
|
|
|
case .audioItem(let audioTrack):
|
|
|
|
|
let cell: JournalAudioViewCell = collectionView.dequeueReusableCell(withReuseIdentifier: "JournalAudioViewCell", for: indexPath) as! JournalAudioViewCell
|
|
|
|
|
|
|
|
|
|
let cell: JournalAudioViewCell = tableView.dequeueReusableCell(withIdentifier: "JournalAudioViewCell", for: indexPath) as! JournalAudioViewCell
|
|
|
|
|
cell.audioTrack = audioTrack
|
|
|
|
|
cell.buttonTapCallback = { [weak self] audioTrack in
|
|
|
|
|
viewModel.item.accept(audioTrack)
|
|
|
|
|
let audioMoreActionViewModel = AudioMoreActionViewModel.init(audioTrack: viewModel.item, provider: viewModel.provider)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
self?.navigator.show(segue: .audioMore(viewModel: audioMoreActionViewModel), sender: self, transition: .navigationPresent(type: .audioMore))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return cell
|
|
|
|
|
case .journaItem(let journalDetail):
|
|
|
|
|
let cell: JournalViewCell = collectionView.dequeueReusableCell(withReuseIdentifier: "JournalViewCell", for: indexPath) as! JournalViewCell
|
|
|
|
|
|
|
|
|
|
cell.journal = journalDetail
|
|
|
|
|
|
|
|
|
|
return cell
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
configureSupplementaryView: { [weak self] dataSource, collectionView, kind, indexPath in
|
|
|
|
|
guard kind == UICollectionView.elementKindSectionHeader, let self = self else {
|
|
|
|
|
return UICollectionReusableView()
|
|
|
|
|
}
|
|
|
|
|
if indexPath.section == 0 {
|
|
|
|
|
let resuableView: JournalAudioHeaderView = collectionView.dequeueReusableSupplementaryView(ofKind: "UICollectionElementKindSectionHeader", withReuseIdentifier: "JournalAudioHeaderView", for: indexPath) as! JournalAudioHeaderView
|
|
|
|
|
self.audioHeaderView = resuableView
|
|
|
|
|
|
|
|
|
|
let section = dataSource.sectionModels.first.value
|
|
|
|
|
resuableView.journal = section?.header
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
resuableView.saveButton.rx.tap.subscribe { [weak self] _ in
|
|
|
|
|
guard let self = self else { return }
|
|
|
|
|
|
|
|
|
|
resuableView.titleImageView.image?.saveImageToPhotoLibrary()
|
|
|
|
|
.subscribe(onNext: { _ in
|
|
|
|
|
SVProgressHUD.showText(withStatus: "保存成功")
|
|
|
|
|
|
|
|
|
|
}, onError: { error in
|
|
|
|
|
|
|
|
|
|
}).disposed(by: self.rx.disposeBag)
|
|
|
|
|
|
|
|
|
|
}.disposed(by: self.rx.disposeBag)
|
|
|
|
|
|
|
|
|
|
case .journaItem(let journals):
|
|
|
|
|
let cell: JournalContainerViewCell = tableView.dequeueReusableCell(withIdentifier: "JournalContainerViewCell", for: indexPath) as! JournalContainerViewCell
|
|
|
|
|
|
|
|
|
|
let dataSource = JournalContainerViewCell.dataSource()
|
|
|
|
|
let header = SearchCategory.init(id: nil, nameCh: nil, nameEn: nil, image: nil, description: nil)
|
|
|
|
|
let sections = [MusicStyleSection.init(header: header, items: journals)]
|
|
|
|
|
|
|
|
|
|
resuableView.dropButtonTapObservable.subscribe { _ in
|
|
|
|
|
|
|
|
|
|
viewModel.isExpand.accept(!resuableView.isExpand)
|
|
|
|
|
viewModel.updateHeaderHeight(newHeight: viewModel.isExpand.value ? 506 + BaseDimensions.topHeight : 400 + BaseDimensions.topHeight)
|
|
|
|
|
|
|
|
|
|
// resuableView.isExpand = viewModel.isExpand.value
|
|
|
|
|
}.disposed(by: self.rx.disposeBag)
|
|
|
|
|
let items = Driver.just(sections)
|
|
|
|
|
items.drive(cell.collectionView.rx.items(dataSource: dataSource)).disposed(by: self.rx.disposeBag)
|
|
|
|
|
|
|
|
|
|
resuableView.playButtonTapObservable.subscribe { _ in
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let audioModels: [AudioTrack] = output.items.value.flatMap { section -> [JournalItem] in
|
|
|
|
|
switch section {
|
|
|
|
|
case .audio(_, let items):
|
|
|
|
|
return items
|
|
|
|
|
default:
|
|
|
|
|
return []
|
|
|
|
|
}
|
|
|
|
|
}.compactMap { item -> AudioTrack? in
|
|
|
|
|
if case let .audioItem(model) = item {
|
|
|
|
|
return model
|
|
|
|
|
} else {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
cell.onItemSelect = { [weak self] journal in
|
|
|
|
|
guard AuthManager.shared.token?.isValid == true else {
|
|
|
|
|
let loginViewModel = LoginViewModel.init(provider: viewModel.provider)
|
|
|
|
|
self?.navigator.show(segue: .login(viewModel: loginViewModel), sender: self)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
guard let track = audioModels.first else { return }
|
|
|
|
|
|
|
|
|
|
let value = BehaviorRelay<Journal>.init(value: journal)
|
|
|
|
|
let journalDetailViewModel = JournalDetailViewModel.init(journal: value, provider: viewModel.provider)
|
|
|
|
|
|
|
|
|
|
let playerViewModel = PlayerViewModel.init(track: track, provider: viewModel.provider)
|
|
|
|
|
self.navigator.show(segue: .player(viewModel: playerViewModel), sender: self, transition: .modal)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
|
|
|
|
|
// 这里放置延迟执行的代码
|
|
|
|
|
AudioManager.sharedInstance.setPlaylist(list: audioModels)
|
|
|
|
|
AudioManager.sharedInstance.playTrack(track: track)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}.disposed(by: self.rx.disposeBag)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// resuableView.downLoadButtonTapObservable
|
|
|
|
|
// .bind(to: viewModel.downloadButtonTapped)
|
|
|
|
|
// .disposed(by: self.rx.disposeBag)
|
|
|
|
|
//
|
|
|
|
|
// resuableView.likeButtonTapObservable
|
|
|
|
|
// .bind(to: viewModel.likeButtonTapped)
|
|
|
|
|
// .disposed(by: self.rx.disposeBag)
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
// resuableView.shareButtonTapObservable
|
|
|
|
|
// .bind(to: viewModel.shareButtonTrigger)
|
|
|
|
|
// .disposed(by: self.rx.disposeBag)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
resuableView.downLoadButtonTapObservable.subscribe { _ in
|
|
|
|
|
viewModel.downloadButtonTapped.onNext(())
|
|
|
|
|
|
|
|
|
|
}.disposed(by: self.rx.disposeBag)
|
|
|
|
|
resuableView.likeButtonTapObservable.subscribe { _ in
|
|
|
|
|
print("likeButtonTapObservable")
|
|
|
|
|
viewModel.likeButtonTapped.onNext(())
|
|
|
|
|
|
|
|
|
|
}.disposed(by: self.rx.disposeBag)
|
|
|
|
|
|
|
|
|
|
resuableView.shareButtonTapObservable.subscribe { _ in
|
|
|
|
|
viewModel.shareButtonTrigger.onNext(())
|
|
|
|
|
self?.navigator.show(segue: .journalDetail(viewModel: journalDetailViewModel), sender: self)
|
|
|
|
|
|
|
|
|
|
}.disposed(by: self.rx.disposeBag)
|
|
|
|
|
}
|
|
|
|
|
return cell
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return resuableView
|
|
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
let resuableView = collectionView.dequeueReusableSupplementaryView(ofKind: "UICollectionElementKindSectionHeader", withReuseIdentifier: "JournalDetailHeaderView", for: indexPath) as! JournalDetailHeaderView
|
|
|
|
|
|
|
|
|
|
return resuableView
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
output.items.bind(to: collectionView.rx.items(dataSource: dataSource)).disposed(by: rx.disposeBag)
|
|
|
|
|
|
|
|
|
|
input.selection.drive { indexPath in
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}.disposed(by: rx.disposeBag)
|
|
|
|
|
|
|
|
|
|
output.items.bind(to: tableView.rx.items(dataSource: dataSource)).disposed(by: rx.disposeBag)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
output.itemSelected.subscribe { [weak self] sectionItem in
|
|
|
|
|
output.modelSelected.drive {[weak self] journalItem in
|
|
|
|
|
|
|
|
|
|
switch sectionItem {
|
|
|
|
|
switch journalItem {
|
|
|
|
|
case .audioItem(let track):
|
|
|
|
|
let audioModels: [AudioTrack] = output.items.value.flatMap { section -> [JournalItem] in
|
|
|
|
|
switch section {
|
|
|
|
|
case .audio(_, let items):
|
|
|
|
|
case .audioSection(header: nil, items: let items):
|
|
|
|
|
return items
|
|
|
|
|
default:
|
|
|
|
|
return []
|
|
|
|
@ -299,82 +144,78 @@ class JournalDetailController: ViewController, UIScrollViewDelegate {
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let playerViewModel = PlayerViewModel.init(track: track, provider: viewModel.provider)
|
|
|
|
|
self?.navigator.show(segue: .player(viewModel: playerViewModel), sender: self, transition: .modal)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
|
|
|
|
|
// 这里放置延迟执行的代码
|
|
|
|
|
AudioManager.sharedInstance.setPlaylist(list: audioModels)
|
|
|
|
|
AudioManager.sharedInstance.playTrack(track: track)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case .journaItem(let journal):
|
|
|
|
|
case .journaItem(let journal): break
|
|
|
|
|
|
|
|
|
|
guard AuthManager.shared.token?.isValid == true else {
|
|
|
|
|
let loginViewModel = LoginViewModel.init(provider: viewModel.provider)
|
|
|
|
|
self?.navigator.show(segue: .login(viewModel: loginViewModel), sender: self)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let journalDetailViewModel = JournalDetailViewModel.init(journal: journal, provider: viewModel.provider)
|
|
|
|
|
|
|
|
|
|
self?.navigator.show(segue: .journalDetail(viewModel: journalDetailViewModel), sender: self)
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}.disposed(by: rx.disposeBag)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
output.toShare.subscribe { [weak self] _ in
|
|
|
|
|
|
|
|
|
|
let share = ShareActionViewModel.init(audioTrack: nil, journal: viewModel.journal, provider: viewModel.provider)
|
|
|
|
|
let share = ShareActionViewModel.init(audioTrack: nil, journal: viewModel.journal.value, provider: viewModel.provider)
|
|
|
|
|
self?.navigator.show(segue: .share(viewModel: share), sender: self, transition: .navigationPresent(type: .share))
|
|
|
|
|
|
|
|
|
|
}.disposed(by: rx.disposeBag)
|
|
|
|
|
|
|
|
|
|
output.isLike.subscribe { [weak self] isLike in
|
|
|
|
|
guard let self = self else { return }
|
|
|
|
|
self.audioHeaderView?.journalAudioSectionView.likeButton.isSelected = isLike
|
|
|
|
|
|
|
|
|
|
}.disposed(by: rx.disposeBag)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
output.journalDetail.subscribe { [weak self] journal in
|
|
|
|
|
|
|
|
|
|
output.journal.subscribe { [weak self] journal in
|
|
|
|
|
guard let self = self else { return }
|
|
|
|
|
self.commentToolView.commentCountButton.commentCountLabel.text = "\(journal)"
|
|
|
|
|
} onError: { error in
|
|
|
|
|
self.journalCollapsibleHeaderView.journal = journal
|
|
|
|
|
|
|
|
|
|
}.disposed(by: rx.disposeBag)
|
|
|
|
|
self.updateHeader()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if let header: JournalAudioSectionView = tableView.headerView(forSection: 0) as? JournalAudioSectionView {
|
|
|
|
|
|
|
|
|
|
print("有header")
|
|
|
|
|
|
|
|
|
|
header.likeButton.isSelected = journal.haveCollect ?? false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}.disposed(by: rx.disposeBag)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
commentToolView.containerView.rx.tapGesture().when(.recognized)
|
|
|
|
|
.subscribe { [weak self] tap in
|
|
|
|
|
guard let self = self else { return }
|
|
|
|
|
|
|
|
|
|
let commentViewModel = CommentViewModel.init(journal: viewModel.journal, provider: viewModel.provider)
|
|
|
|
|
|
|
|
|
|
let commentViewModel = CommentViewModel.init(journal: viewModel.journal.value, provider: viewModel.provider)
|
|
|
|
|
|
|
|
|
|
self.navigator.show(segue: .comment(viewModel: commentViewModel), sender: self)
|
|
|
|
|
|
|
|
|
|
}.disposed(by: rx.disposeBag)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
journalCollapsibleHeaderView.dropButton.rx.tap.subscribe { _ in
|
|
|
|
|
self.journalCollapsibleHeaderView.isExpand.toggle()
|
|
|
|
|
|
|
|
|
|
self.updateHeader()
|
|
|
|
|
|
|
|
|
|
}.disposed(by: rx.disposeBag)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
override func viewDidLayoutSubviews() {
|
|
|
|
@ -388,26 +229,494 @@ class JournalDetailController: ViewController, UIScrollViewDelegate {
|
|
|
|
|
make.height.equalTo(BaseDimensions.bottomHeight + 48)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
collectionView.snp.makeConstraints { make in
|
|
|
|
|
tableView.snp.remakeConstraints { make in
|
|
|
|
|
make.left.equalTo(view)
|
|
|
|
|
make.right.equalTo(view)
|
|
|
|
|
make.bottom.equalTo(commentToolView.snp.top)
|
|
|
|
|
make.top.equalTo(view).offset(-BaseDimensions.topHeight)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func updateHeader() {
|
|
|
|
|
guard let headerView = tableView.tableHeaderView as? JournalCollapsibleHeaderView else { return }
|
|
|
|
|
|
|
|
|
|
let width = tableView.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)
|
|
|
|
|
|
|
|
|
|
print("header size: \(size.height)")
|
|
|
|
|
|
|
|
|
|
if headerView.frame.size.height != size.height {
|
|
|
|
|
headerView.frame.size.height = size.height
|
|
|
|
|
tableView.tableHeaderView = headerView
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
extension JournalDetailController {
|
|
|
|
|
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
|
|
|
|
|
guard let viewModel = viewModel as? JournalDetailViewModel else { return nil }
|
|
|
|
|
|
|
|
|
|
extension JournalDetailController: UICollectionViewDelegateFlowLayout {
|
|
|
|
|
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
|
|
|
|
|
// 根据section和内容计算并返回实际的header大小
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
switch section {
|
|
|
|
|
case 0:
|
|
|
|
|
let headerView = JournalAudioSectionView.init(reuseIdentifier: "JournalAudioSectionView")
|
|
|
|
|
headerView.countLabel.text = "共\(tableView.numberOfRows(inSection: 0))首"
|
|
|
|
|
headerView.likeButton.isSelected = viewModel.journal.value.haveCollect ?? false
|
|
|
|
|
|
|
|
|
|
headerView.downloadButton.rx.tap.subscribe { _ in
|
|
|
|
|
|
|
|
|
|
}.disposed(by: rx.disposeBag)
|
|
|
|
|
|
|
|
|
|
headerView.likeButton.rx.tap.subscribe { _ in
|
|
|
|
|
viewModel.likeButtonTapped.accept(())
|
|
|
|
|
}.disposed(by: rx.disposeBag)
|
|
|
|
|
|
|
|
|
|
headerView.shareButton.rx.tap.subscribe { _ in
|
|
|
|
|
viewModel.shareButtonTrigger.accept(())
|
|
|
|
|
}.disposed(by: rx.disposeBag)
|
|
|
|
|
|
|
|
|
|
return headerView
|
|
|
|
|
|
|
|
|
|
case 1:
|
|
|
|
|
let headerView = JournalDetailSectionView.init(reuseIdentifier: "JournalDetailSectionView")
|
|
|
|
|
return headerView
|
|
|
|
|
default:
|
|
|
|
|
return nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return CGSize(width: collectionView.frame.width, height: 100)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
|
|
|
|
|
// 返回你的header视图的高度
|
|
|
|
|
return 44
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//class JournalDetailController: ViewController, UIScrollViewDelegate {
|
|
|
|
|
//
|
|
|
|
|
// lazy var collectionView: UICollectionView = {
|
|
|
|
|
//
|
|
|
|
|
// let layout = UICollectionViewCompositionalLayout { (sectionIndex, environment) -> NSCollectionLayoutSection? in
|
|
|
|
|
// let viewModel = self.viewModel as? JournalDetailViewModel
|
|
|
|
|
////
|
|
|
|
|
//// case collapsible(journal: Journal)
|
|
|
|
|
//// case audioSection(header: AudioSection, items: [JournalItem])
|
|
|
|
|
//// case journalSection(header: String, items: [JournalItem])
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
// if sectionIndex == 0 {
|
|
|
|
|
// let singleColumnItemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .estimated(100))
|
|
|
|
|
// let singleColumnItem = NSCollectionLayoutItem(layoutSize: singleColumnItemSize)
|
|
|
|
|
//
|
|
|
|
|
// let singleColumnGroup = NSCollectionLayoutGroup.horizontal(layoutSize: singleColumnItemSize, subitems: [singleColumnItem])
|
|
|
|
|
//
|
|
|
|
|
// let singleColumnSection = NSCollectionLayoutSection(group: singleColumnGroup)
|
|
|
|
|
//
|
|
|
|
|
// // 创建header
|
|
|
|
|
// let headerSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .estimated(viewModel?.headerHeight ?? 100))
|
|
|
|
|
// let header = NSCollectionLayoutBoundarySupplementaryItem(layoutSize: headerSize, elementKind: UICollectionView.elementKindSectionHeader, alignment: .top)
|
|
|
|
|
// singleColumnSection.boundarySupplementaryItems = [header]
|
|
|
|
|
//
|
|
|
|
|
// return singleColumnSection
|
|
|
|
|
// } else if sectionIndex == 1 {
|
|
|
|
|
// let singleColumnItemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .estimated(100))
|
|
|
|
|
// let singleColumnItem = NSCollectionLayoutItem(layoutSize: singleColumnItemSize)
|
|
|
|
|
//
|
|
|
|
|
// let singleColumnGroup = NSCollectionLayoutGroup.horizontal(layoutSize: singleColumnItemSize, subitems: [singleColumnItem])
|
|
|
|
|
//
|
|
|
|
|
// let singleColumnSection = NSCollectionLayoutSection(group: singleColumnGroup)
|
|
|
|
|
//
|
|
|
|
|
// // 创建header
|
|
|
|
|
// let headerSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .estimated(100))
|
|
|
|
|
// let header = NSCollectionLayoutBoundarySupplementaryItem(layoutSize: headerSize, elementKind: UICollectionView.elementKindSectionHeader, alignment: .top)
|
|
|
|
|
// singleColumnSection.boundarySupplementaryItems = [header]
|
|
|
|
|
//
|
|
|
|
|
// return singleColumnSection
|
|
|
|
|
//
|
|
|
|
|
// } else {
|
|
|
|
|
// let doubleColumnItemSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(0.5), heightDimension: .absolute(147))
|
|
|
|
|
// 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)
|
|
|
|
|
// doubleColumnGroup.interItemSpacing = .fixed(10)
|
|
|
|
|
//
|
|
|
|
|
// let doubleColumnSection = NSCollectionLayoutSection(group: doubleColumnGroup)
|
|
|
|
|
//
|
|
|
|
|
// let headerSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0), heightDimension: .estimated(44))
|
|
|
|
|
// let header = NSCollectionLayoutBoundarySupplementaryItem(layoutSize: headerSize, elementKind: UICollectionView.elementKindSectionHeader, alignment: .top)
|
|
|
|
|
// doubleColumnSection.boundarySupplementaryItems = [header]
|
|
|
|
|
//
|
|
|
|
|
// doubleColumnSection.contentInsets = NSDirectionalEdgeInsets(top: 0, leading: 18, bottom: 0, trailing: 18)
|
|
|
|
|
// doubleColumnSection.interGroupSpacing = 24
|
|
|
|
|
//
|
|
|
|
|
// return doubleColumnSection
|
|
|
|
|
//
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// let collectionView = UICollectionView.init(frame: CGRect.zero, collectionViewLayout: layout)
|
|
|
|
|
//
|
|
|
|
|
// collectionView.register(JournalCollapsibleViewCell.self, forCellWithReuseIdentifier: "JournalCollapsibleViewCell")
|
|
|
|
|
// collectionView.register(JournalAudioSectionViewCell.self, forCellWithReuseIdentifier: "JournalAudioSectionViewCell")
|
|
|
|
|
// collectionView.register(JournalDetailSectionViewCell.self, forCellWithReuseIdentifier: "JournalDetailSectionViewCell")
|
|
|
|
|
// collectionView.register(JournalViewCell.self, forCellWithReuseIdentifier: "JournalViewCell")
|
|
|
|
|
// collectionView.register(JournalAudioViewCell.self, forCellWithReuseIdentifier: "JournalAudioViewCell")
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
// collectionView.backgroundColor = .white
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
// return collectionView
|
|
|
|
|
// }()
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
// var commentToolView: CommentToolView = {
|
|
|
|
|
// let commentToolView = CommentToolView.init()
|
|
|
|
|
//
|
|
|
|
|
// return commentToolView
|
|
|
|
|
// }()
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
// override func viewDidLoad() {
|
|
|
|
|
// super.viewDidLoad()
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// override func viewWillAppear(_ animated: Bool) {
|
|
|
|
|
// super.viewWillAppear(animated)
|
|
|
|
|
//
|
|
|
|
|
// navBarBgAlpha = 0
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// override func viewWillDisappear(_ animated: Bool) {
|
|
|
|
|
// super.viewWillDisappear(animated)
|
|
|
|
|
//
|
|
|
|
|
// navBarBgAlpha = 1
|
|
|
|
|
//
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// override func makeUI() {
|
|
|
|
|
// super.makeUI()
|
|
|
|
|
//
|
|
|
|
|
// collectionView.rx.setDelegate(self).disposed(by: rx.disposeBag)
|
|
|
|
|
//
|
|
|
|
|
// view.addSubview(commentToolView)
|
|
|
|
|
// view.addSubview(collectionView)
|
|
|
|
|
//
|
|
|
|
|
//// updateText(text: "")
|
|
|
|
|
//
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// override func bindViewModel() {
|
|
|
|
|
// super.bindViewModel()
|
|
|
|
|
//
|
|
|
|
|
// guard let viewModel = viewModel as? JournalDetailViewModel else { return }
|
|
|
|
|
//
|
|
|
|
|
// let viewDidLoad = Observable.of(())
|
|
|
|
|
// let input = JournalDetailViewModel.Input.init(viewWillAppear: rx.viewWillAppear,
|
|
|
|
|
// viewDidLoad: viewDidLoad,
|
|
|
|
|
// selection: collectionView.rx.itemSelected.asDriver(),
|
|
|
|
|
// notiPlayAudioTrack: NotificationCenter.default.rx.notification(.notiPlayAudioTrack))
|
|
|
|
|
//
|
|
|
|
|
//// dropButtonTrigger: headerView.dropButton.rx.tap.asDriver(),
|
|
|
|
|
//// playButtonTrigger: headerView.playButton.rx.tap.asDriver(),
|
|
|
|
|
//// shareButtonTrigger: headerView.playButton.rx.tap.asDriver())//TODO
|
|
|
|
|
//
|
|
|
|
|
// let output = viewModel.transform(input: input)
|
|
|
|
|
//
|
|
|
|
|
// let dataSource = RxCollectionViewSectionedReloadDataSource<JournalSection>(
|
|
|
|
|
// configureCell: { dataSource, collectionView, indexPath, item in
|
|
|
|
|
// switch dataSource[indexPath] {
|
|
|
|
|
// case .audioItem(let audioTrack):
|
|
|
|
|
// let cell: JournalAudioViewCell = collectionView.dequeueReusableCell(withReuseIdentifier: "JournalAudioViewCell", for: indexPath) as! JournalAudioViewCell
|
|
|
|
|
//
|
|
|
|
|
// cell.audioTrack = audioTrack
|
|
|
|
|
// cell.buttonTapCallback = { [weak self] audioTrack in
|
|
|
|
|
// viewModel.item.accept(audioTrack)
|
|
|
|
|
// let audioMoreActionViewModel = AudioMoreActionViewModel.init(audioTrack: viewModel.item, provider: viewModel.provider)
|
|
|
|
|
//
|
|
|
|
|
// self?.navigator.show(segue: .audioMore(viewModel: audioMoreActionViewModel), sender: self, transition: .navigationPresent(type: .audioMore))
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// return cell
|
|
|
|
|
// case .journaItem(let journalDetail):
|
|
|
|
|
// let cell: JournalViewCell = collectionView.dequeueReusableCell(withReuseIdentifier: "JournalViewCell", for: indexPath) as! JournalViewCell
|
|
|
|
|
//
|
|
|
|
|
// cell.journal = journalDetail
|
|
|
|
|
//
|
|
|
|
|
// return cell
|
|
|
|
|
//
|
|
|
|
|
// }
|
|
|
|
|
// },
|
|
|
|
|
// configureSupplementaryView: { [weak self] dataSource, collectionView, kind, indexPath in
|
|
|
|
|
// guard kind == UICollectionView.elementKindSectionHeader, let self = self else {
|
|
|
|
|
// return UICollectionReusableView()
|
|
|
|
|
// }
|
|
|
|
|
// if indexPath.section == 0 {
|
|
|
|
|
// let resuableView: JournalAudioHeaderView = collectionView.dequeueReusableSupplementaryView(ofKind: "UICollectionElementKindSectionHeader", withReuseIdentifier: "JournalAudioHeaderView", for: indexPath) as! JournalAudioHeaderView
|
|
|
|
|
// self.audioHeaderView = resuableView
|
|
|
|
|
//
|
|
|
|
|
// let section = dataSource.sectionModels.first.value
|
|
|
|
|
// resuableView.journal = section?.header
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
// resuableView.saveButton.rx.tap.subscribe { [weak self] _ in
|
|
|
|
|
// guard let self = self else { return }
|
|
|
|
|
//
|
|
|
|
|
// resuableView.titleImageView.image?.saveImageToPhotoLibrary()
|
|
|
|
|
// .subscribe(onNext: { _ in
|
|
|
|
|
// SVProgressHUD.showText(withStatus: "保存成功")
|
|
|
|
|
//
|
|
|
|
|
// }, onError: { error in
|
|
|
|
|
//
|
|
|
|
|
// }).disposed(by: self.rx.disposeBag)
|
|
|
|
|
//
|
|
|
|
|
// }.disposed(by: self.rx.disposeBag)
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
// resuableView.dropButtonTapObservable.subscribe { _ in
|
|
|
|
|
//
|
|
|
|
|
// viewModel.isExpand.accept(!resuableView.isExpand)
|
|
|
|
|
// viewModel.updateHeaderHeight(newHeight: viewModel.isExpand.value ? 506 + BaseDimensions.topHeight : 400 + BaseDimensions.topHeight)
|
|
|
|
|
//
|
|
|
|
|
//// resuableView.isExpand = viewModel.isExpand.value
|
|
|
|
|
// }.disposed(by: self.rx.disposeBag)
|
|
|
|
|
//
|
|
|
|
|
// resuableView.playButtonTapObservable.subscribe { _ in
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
// let audioModels: [AudioTrack] = output.items.value.flatMap { section -> [JournalItem] in
|
|
|
|
|
// switch section {
|
|
|
|
|
// case .audio(_, let items):
|
|
|
|
|
// return items
|
|
|
|
|
// default:
|
|
|
|
|
// return []
|
|
|
|
|
// }
|
|
|
|
|
// }.compactMap { item -> AudioTrack? in
|
|
|
|
|
// if case let .audioItem(model) = item {
|
|
|
|
|
// return model
|
|
|
|
|
// } else {
|
|
|
|
|
// return nil
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// guard let track = audioModels.first else { return }
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
// let playerViewModel = PlayerViewModel.init(track: track, provider: viewModel.provider)
|
|
|
|
|
// self.navigator.show(segue: .player(viewModel: playerViewModel), sender: self, transition: .modal)
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
// DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
|
|
|
|
|
// // 这里放置延迟执行的代码
|
|
|
|
|
// AudioManager.sharedInstance.setPlaylist(list: audioModels)
|
|
|
|
|
// AudioManager.sharedInstance.playTrack(track: track)
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// }.disposed(by: self.rx.disposeBag)
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
//// resuableView.downLoadButtonTapObservable
|
|
|
|
|
//// .bind(to: viewModel.downloadButtonTapped)
|
|
|
|
|
//// .disposed(by: self.rx.disposeBag)
|
|
|
|
|
////
|
|
|
|
|
//// resuableView.likeButtonTapObservable
|
|
|
|
|
//// .bind(to: viewModel.likeButtonTapped)
|
|
|
|
|
//// .disposed(by: self.rx.disposeBag)
|
|
|
|
|
////
|
|
|
|
|
////
|
|
|
|
|
//// resuableView.shareButtonTapObservable
|
|
|
|
|
//// .bind(to: viewModel.shareButtonTrigger)
|
|
|
|
|
//// .disposed(by: self.rx.disposeBag)
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
// resuableView.downLoadButtonTapObservable.subscribe { _ in
|
|
|
|
|
// viewModel.downloadButtonTapped.onNext(())
|
|
|
|
|
//
|
|
|
|
|
// }.disposed(by: self.rx.disposeBag)
|
|
|
|
|
// resuableView.likeButtonTapObservable.subscribe { _ in
|
|
|
|
|
// print("likeButtonTapObservable")
|
|
|
|
|
// viewModel.likeButtonTapped.onNext(())
|
|
|
|
|
//
|
|
|
|
|
// }.disposed(by: self.rx.disposeBag)
|
|
|
|
|
//
|
|
|
|
|
// resuableView.shareButtonTapObservable.subscribe { _ in
|
|
|
|
|
// viewModel.shareButtonTrigger.onNext(())
|
|
|
|
|
//
|
|
|
|
|
// }.disposed(by: self.rx.disposeBag)
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
// return resuableView
|
|
|
|
|
//
|
|
|
|
|
// } else {
|
|
|
|
|
// let resuableView = collectionView.dequeueReusableSupplementaryView(ofKind: "UICollectionElementKindSectionHeader", withReuseIdentifier: "JournalDetailHeaderView", for: indexPath) as! JournalDetailHeaderView
|
|
|
|
|
//
|
|
|
|
|
// return resuableView
|
|
|
|
|
//
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
// )
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
// output.items.bind(to: collectionView.rx.items(dataSource: dataSource)).disposed(by: rx.disposeBag)
|
|
|
|
|
//
|
|
|
|
|
// input.selection.drive { indexPath in
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
// }.disposed(by: rx.disposeBag)
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
// output.itemSelected.subscribe { [weak self] sectionItem in
|
|
|
|
|
//
|
|
|
|
|
// switch sectionItem {
|
|
|
|
|
// case .audioItem(let track):
|
|
|
|
|
// let audioModels: [AudioTrack] = output.items.value.flatMap { section -> [JournalItem] in
|
|
|
|
|
// switch section {
|
|
|
|
|
// case .audio(_, let items):
|
|
|
|
|
// return items
|
|
|
|
|
// default:
|
|
|
|
|
// return []
|
|
|
|
|
// }
|
|
|
|
|
// }.compactMap { item -> AudioTrack? in
|
|
|
|
|
// if case let .audioItem(model) = item {
|
|
|
|
|
// return model
|
|
|
|
|
// } else {
|
|
|
|
|
// return nil
|
|
|
|
|
// }
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
// let playerViewModel = PlayerViewModel.init(track: track, provider: viewModel.provider)
|
|
|
|
|
// self?.navigator.show(segue: .player(viewModel: playerViewModel), sender: self, transition: .modal)
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
// DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
|
|
|
|
|
// // 这里放置延迟执行的代码
|
|
|
|
|
// AudioManager.sharedInstance.setPlaylist(list: audioModels)
|
|
|
|
|
// AudioManager.sharedInstance.playTrack(track: track)
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
// case .journaItem(let journal):
|
|
|
|
|
//
|
|
|
|
|
// guard AuthManager.shared.token?.isValid == true else {
|
|
|
|
|
// let loginViewModel = LoginViewModel.init(provider: viewModel.provider)
|
|
|
|
|
// self?.navigator.show(segue: .login(viewModel: loginViewModel), sender: self)
|
|
|
|
|
// return
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// let journalDetailViewModel = JournalDetailViewModel.init(journal: journal, provider: viewModel.provider)
|
|
|
|
|
//
|
|
|
|
|
// self?.navigator.show(segue: .journalDetail(viewModel: journalDetailViewModel), sender: self)
|
|
|
|
|
//
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
// }.disposed(by: rx.disposeBag)
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
// output.toShare.subscribe { [weak self] _ in
|
|
|
|
|
//
|
|
|
|
|
// let share = ShareActionViewModel.init(audioTrack: nil, journal: viewModel.journal, provider: viewModel.provider)
|
|
|
|
|
// self?.navigator.show(segue: .share(viewModel: share), sender: self, transition: .navigationPresent(type: .share))
|
|
|
|
|
//
|
|
|
|
|
// }.disposed(by: rx.disposeBag)
|
|
|
|
|
//
|
|
|
|
|
// output.isLike.subscribe { [weak self] isLike in
|
|
|
|
|
// guard let self = self else { return }
|
|
|
|
|
// self.audioHeaderView?.journalAudioSectionView.likeButton.isSelected = isLike
|
|
|
|
|
// }.disposed(by: rx.disposeBag)
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
// output.journalDetail.subscribe { [weak self] journal in
|
|
|
|
|
// guard let self = self else { return }
|
|
|
|
|
// self.commentToolView.commentCountButton.commentCountLabel.text = "\(journal)"
|
|
|
|
|
// } onError: { error in
|
|
|
|
|
//
|
|
|
|
|
// }.disposed(by: rx.disposeBag)
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
// commentToolView.containerView.rx.tapGesture().when(.recognized)
|
|
|
|
|
// .subscribe { [weak self] tap in
|
|
|
|
|
// guard let self = self else { return }
|
|
|
|
|
//
|
|
|
|
|
// let commentViewModel = CommentViewModel.init(journal: viewModel.journal, provider: viewModel.provider)
|
|
|
|
|
//
|
|
|
|
|
// self.navigator.show(segue: .comment(viewModel: commentViewModel), sender: self)
|
|
|
|
|
//
|
|
|
|
|
// }.disposed(by: rx.disposeBag)
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
// override func viewDidLayoutSubviews() {
|
|
|
|
|
// super.viewDidLayoutSubviews()
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
// commentToolView.snp.makeConstraints { make in
|
|
|
|
|
// make.left.equalTo(view)
|
|
|
|
|
// make.right.equalTo(view)
|
|
|
|
|
// make.bottom.equalTo(view)
|
|
|
|
|
// make.height.equalTo(BaseDimensions.bottomHeight + 48)
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
// collectionView.snp.makeConstraints { make in
|
|
|
|
|
// make.left.equalTo(view)
|
|
|
|
|
// make.right.equalTo(view)
|
|
|
|
|
// make.bottom.equalTo(commentToolView.snp.top)
|
|
|
|
|
// make.top.equalTo(view).offset(-BaseDimensions.topHeight)
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
// }
|
|
|
|
|
//
|
|
|
|
|
//}
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
//extension JournalDetailController: UICollectionViewDelegateFlowLayout {
|
|
|
|
|
// func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
|
|
|
|
|
// // 根据section和内容计算并返回实际的header大小
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
//
|
|
|
|
|
// return CGSize(width: collectionView.frame.width, height: 100)
|
|
|
|
|
// }
|
|
|
|
|
//}
|
|
|
|
|