Skip to content

Commit

Permalink
✨ :: 최신음악 화면 추가 6t
Browse files Browse the repository at this point in the history
  • Loading branch information
KangTaeHoon committed Nov 16, 2023
1 parent f5b2da2 commit 855666f
Show file tree
Hide file tree
Showing 5 changed files with 120 additions and 19 deletions.
4 changes: 4 additions & 0 deletions Projects/App/Sources/Application/NeedleGenerated.swift
Original file line number Diff line number Diff line change
Expand Up @@ -767,6 +767,9 @@ private class NewSongsContentDependency93a05f20fa300c5bbec3Provider: NewSongsCon
var fetchNewSongsUseCase: any FetchNewSongsUseCase {
return appComponent.fetchNewSongsUseCase
}
var fetchChartUpdateTimeUseCase: any FetchChartUpdateTimeUseCase {
return appComponent.fetchChartUpdateTimeUseCase
}
var containSongsComponent: ContainSongsComponent {
return appComponent.containSongsComponent
}
Expand Down Expand Up @@ -1169,6 +1172,7 @@ extension ProfilePopComponent: Registration {
extension NewSongsContentComponent: Registration {
public func registerItems() {
keyPathToName[\NewSongsContentDependency.fetchNewSongsUseCase] = "fetchNewSongsUseCase-any FetchNewSongsUseCase"
keyPathToName[\NewSongsContentDependency.fetchChartUpdateTimeUseCase] = "fetchChartUpdateTimeUseCase-any FetchChartUpdateTimeUseCase"
keyPathToName[\NewSongsContentDependency.containSongsComponent] = "containSongsComponent-ContainSongsComponent"
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import DataMappingModule

public protocol NewSongsContentDependency: Dependency {
var fetchNewSongsUseCase: any FetchNewSongsUseCase { get }
var fetchChartUpdateTimeUseCase: any FetchChartUpdateTimeUseCase { get }
var containSongsComponent: ContainSongsComponent { get }
}

Expand All @@ -21,9 +22,10 @@ public final class NewSongsContentComponent: Component<NewSongsContentDependency
return NewSongsContentViewController.viewController(
viewModel: .init(
type: type,
fetchNewSongsUseCase: dependency.fetchNewSongsUseCase
)
,containSongsComponent: dependency.containSongsComponent
fetchNewSongsUseCase: dependency.fetchNewSongsUseCase,
fetchChartUpdateTimeUseCase: dependency.fetchChartUpdateTimeUseCase
),
containSongsComponent: dependency.containSongsComponent
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import DomainModule
public class NewSongsContentViewController: UIViewController, ViewControllerFromStoryBoard, SongCartViewType {
@IBOutlet weak var tableView: UITableView!
@IBOutlet weak var activityIncidator: NVActivityIndicatorView!

var viewModel: NewSongsContentViewModel!
fileprivate lazy var input = NewSongsContentViewModel.Input()
fileprivate lazy var output = viewModel.transform(from: input)
Expand Down Expand Up @@ -103,7 +103,8 @@ extension NewSongsContentViewController {
withIdentifier: "NewSongsCell",
for: indexPath
) as? NewSongsCell else {
return UITableViewCell() }
return UITableViewCell()
}
cell.update(model: model)
return cell
}
Expand Down Expand Up @@ -134,9 +135,10 @@ extension NewSongsContentViewController {
.subscribe()
.disposed(by: disposeBag)

output.groupPlaySongs
.subscribe(onNext: { songs in
PlayState.shared.loadAndAppendSongsToPlaylist(songs)
output.updateTime
.filter { !$0.isEmpty }
.subscribe(onNext: { [weak self] _ in
self?.tableView.reloadData()
})
.disposed(by: disposeBag)
}
Expand All @@ -163,13 +165,21 @@ extension NewSongsContentViewController: UITableViewDelegate {
}

public func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 80
return 80 + 22
}

public func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let base = UIView(frame: CGRect(x: 0, y: 0, width: APP_WIDTH(), height: 88+22))

let view = PlayButtonGroupView(frame: CGRect(x: 0, y: 0, width: APP_WIDTH(), height: 80))
view.delegate = self
return view
base.addSubview(view)

let time = ChartUpdateTimeView(frame: CGRect(x: 0, y: view.frame.height, width: APP_WIDTH(), height: 22))
time.setUpdateTime(updateTime: self.output.updateTime.value)
base.addSubview(time)

return base
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,18 @@ public final class NewSongsContentViewModel: ViewModelType {
public let type: NewSongGroupType
private let disposeBag = DisposeBag()
private let fetchNewSongsUseCase: FetchNewSongsUseCase

private let fetchChartUpdateTimeUseCase: FetchChartUpdateTimeUseCase

deinit { DEBUG_LOG("\(Self.self) Deinit") }

public init(
type: NewSongGroupType,
fetchNewSongsUseCase: FetchNewSongsUseCase
fetchNewSongsUseCase: FetchNewSongsUseCase,
fetchChartUpdateTimeUseCase: FetchChartUpdateTimeUseCase
) {
self.type = type
self.fetchNewSongsUseCase = fetchNewSongsUseCase
self.fetchChartUpdateTimeUseCase = fetchChartUpdateTimeUseCase
}

public struct Input {
Expand All @@ -42,14 +45,26 @@ public final class NewSongsContentViewModel: ViewModelType {
var updateTime: BehaviorRelay<String> = BehaviorRelay(value: "")
let indexOfSelectedSongs: BehaviorRelay<[Int]> = BehaviorRelay(value: [])
let songEntityOfSelectedSongs: BehaviorRelay<[SongEntity]> = BehaviorRelay(value: [])
let groupPlaySongs: PublishSubject<[SongEntity]> = PublishSubject()
var canLoadMore: BehaviorRelay<Bool> = BehaviorRelay(value: true)
}

public func transform(from input: Input) -> Output {
let output = Output()

let refresh = Observable.combineLatest(output.dataSource, input.pageID) { (dataSource, pageID) -> [NewSongsEntity] in
let chartUpdateTime = self.fetchChartUpdateTimeUseCase
.execute(type: .total)
.catchAndReturn("팬치들 미안해요 ㅠㅠ 잠시만 기다려주세요") // 이스터에그 🥰
.asObservable()

chartUpdateTime
.take(1)
.bind(to: output.updateTime)
.disposed(by: disposeBag)

let refresh = Observable.combineLatest(
output.dataSource,
input.pageID
) { (dataSource, pageID) -> [NewSongsEntity] in
return pageID == 1 ? [] : dataSource
}

Expand All @@ -59,8 +74,8 @@ public final class NewSongsContentViewModel: ViewModelType {
input.pageID
.flatMap { (pageID) -> Single<[NewSongsEntity]> in
return fetchNewSongsUseCase
.execute(type: type, page: pageID, limit: 100)
.catchAndReturn([])
.execute(type: type, page: pageID, limit: 100)
.catchAndReturn([])
}
.asObservable()
.do(onNext: { (model) in
Expand All @@ -76,8 +91,13 @@ public final class NewSongsContentViewModel: ViewModelType {
.disposed(by: disposeBag)

input.refreshPulled
.map { _ in 1 }
.bind(to: input.pageID)
.do(onNext: { _ in
input.pageID.accept(1)
})
.flatMap{ _ -> Observable<String> in
return chartUpdateTime
}
.bind(to: output.updateTime)
.disposed(by: disposeBag)

input.songTapped
Expand Down Expand Up @@ -166,7 +186,9 @@ public final class NewSongsContentViewModel: ViewModelType {
return dataSource.shuffled()
}
}
.bind(to: output.groupPlaySongs)
.subscribe(onNext: { (songs) in
PlayState.shared.loadAndAppendSongsToPlaylist(songs)
})
.disposed(by: disposeBag)

return output
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
//
// PlayButtonForNewSongsView.swift
// CommonFeature
//
// Created by KTH on 2023/11/16.
// Copyright © 2023 yongbeomkwak. All rights reserved.
//

import UIKit
import DesignSystem
import RxRelay
import RxSwift
import SnapKit
import Then

public final class ChartUpdateTimeView: UIView {
private let updateTimeLabel = UILabel().then {
$0.font = DesignSystemFontFamily.Pretendard.light.font(size: 12)
$0.textColor = DesignSystemAsset.GrayColor.gray600.color
}
private let updateTimeImageView = UIImageView().then {
$0.image = DesignSystemAsset.Chart.check.image
}

public override init(frame: CGRect) {
super.init(frame: frame)
self.setupView()
}

required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.setupView()
}

public func setUpdateTime(updateTime: String) {
let attributedString = NSMutableAttributedString(string: updateTime)
attributedString.addAttributes([.font: DesignSystemFontFamily.Pretendard.light.font(size: 12),
.foregroundColor: DesignSystemAsset.GrayColor.gray600.color,
.kern: -0.5],
range: NSRange(location: 0, length: attributedString.string.count))
updateTimeLabel.attributedText = attributedString
}
}

extension ChartUpdateTimeView {
private func setupView() {
self.backgroundColor = DesignSystemAsset.GrayColor.gray100.color

[updateTimeImageView, updateTimeLabel].forEach { self.addSubview($0) }

updateTimeImageView.snp.makeConstraints {
$0.top.equalTo(1)
$0.width.height.equalTo(16)
$0.leading.equalTo(20)
}

updateTimeLabel.snp.makeConstraints {
$0.top.equalTo(0)
$0.height.equalTo(18)
$0.leading.equalTo(updateTimeImageView.snp.trailing).offset(2)
}
}
}

0 comments on commit 855666f

Please sign in to comment.