Skip to content

Commit

Permalink
Merge pull request #504 from wakmusic/494-refactoring-artist
Browse files Browse the repository at this point in the history
๐Ÿ”€ :: (#494) ์•„ํ‹ฐ์ŠคํŠธ ํŽ˜์ด์ง€ ๋ฆฌํŒฉํ† ๋ง
  • Loading branch information
KangTaeHoon authored Apr 26, 2024
2 parents 8f3c0db + 3eecf88 commit e120318
Show file tree
Hide file tree
Showing 6 changed files with 161 additions and 188 deletions.
194 changes: 97 additions & 97 deletions Projects/App/Sources/Application/NeedleGenerated.swift

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,6 @@ public final class ArtistReactor: Reactor {
switch action {
case .viewDidLoad:
return viewDidLoad()

default:
return .empty()
}
}

Expand Down Expand Up @@ -64,7 +61,7 @@ private extension ArtistReactor {
// Waterfall Grid UI๊ฐ€ ๊ธฐ๋ณธ์ ์œผ๋กœ ์™ผ์ชฝ๋ถ€ํ„ฐ ์Œ“์ด๊ฒŒ ๋˜๊ธฐ์— ์ฒซ๋ฒˆ์งธ Cell์„ hide ์‹œํ‚ต๋‹ˆ๋‹ค
if newArtistList.count == 1 {
let hiddenItem: ArtistListEntity = self.makeHiddenArtistEntity()
newArtistList.append(hiddenItem)
newArtistList.insert(hiddenItem, at: 0)
} else {
newArtistList.swapAt(0, 1)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ class ArtistDetailHeaderViewController: UIViewController, ViewControllerFromStor
@IBOutlet weak var introDescriptionLabel: UILabel!

var disposeBag: DisposeBag = DisposeBag()
var isBack: Bool = false

deinit {
DEBUG_LOG("\(Self.self) Deinit")
Expand Down Expand Up @@ -93,8 +92,8 @@ extension ArtistDetailHeaderViewController {
)

self.artistNameLabelHeight.constant =
(availableWidth >= artistNameWidth) ? 36 :
ceil(artistNameAttributedString.height(containerWidth: availableWidth))
(availableWidth >= artistNameWidth) ? 36 :
ceil(artistNameAttributedString.height(containerWidth: availableWidth))

self.artistNameLabel.attributedText = artistNameAttributedString

Expand Down Expand Up @@ -144,51 +143,37 @@ extension ArtistDetailHeaderViewController {
)
self.view.layoutIfNeeded()
}
}

private func bind() {
private extension ArtistDetailHeaderViewController {
func bind() {
let mergeObservable = Observable.merge(
descriptionFrontButton.rx.tap.map { _ in () },
descriptionBackButton.rx.tap.map { _ in () }
)

mergeObservable
.subscribe(onNext: { [weak self] _ in
guard let `self` = self else { return }
self.flip()
}).disposed(by: disposeBag)
.bind(with: self) { owner, _ in
owner.flipArtistIntro()
}
.disposed(by: disposeBag)
}

private func flip() {
if self.isBack {
self.isBack = false
self.descriptionFrontView.isHidden = self.isBack
self.descriptionBackView.isHidden = !self.descriptionFrontView.isHidden

UIView.transition(
with: self.descriptionView,
duration: 0.3,
options: .transitionFlipFromLeft,
animations: nil,
completion: { _ in
}
)
} else {
self.isBack = true
self.descriptionFrontView.isHidden = self.isBack
self.descriptionBackView.isHidden = !self.descriptionFrontView.isHidden

UIView.transition(
with: self.descriptionView,
duration: 0.3,
options: .transitionFlipFromRight,
animations: nil,
completion: { _ in
}
)
}
func flipArtistIntro() {
descriptionFrontView.isHidden = descriptionFrontView.isHidden ? false : true
descriptionBackView.isHidden = !descriptionFrontView.isHidden

UIView.transition(
with: descriptionView,
duration: 0.3,
options: descriptionFrontView.isHidden ? .transitionFlipFromRight : .transitionFlipFromLeft,
animations: nil,
completion: { _ in
}
)
}

private func configureUI() {
func configureUI() {
descriptionFrontButton.setImage(DesignSystemAsset.Artist.documentOff.image, for: .normal)
descriptionBackButton.setImage(DesignSystemAsset.Artist.documentOn.image, for: .normal)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public class ArtistMusicContentViewController: BaseViewController, ViewControlle
var containSongsComponent: ContainSongsComponent!

private var viewModel: ArtistMusicContentViewModel!
lazy var input = ArtistMusicContentViewModel.Input(pageID: BehaviorRelay(value: 1))
lazy var input = ArtistMusicContentViewModel.Input()
lazy var output = viewModel.transform(from: input)
var disposeBag = DisposeBag()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,30 +31,26 @@ public final class ArtistMusicContentViewModel: ViewModelType {
}

public struct Input {
var pageID: BehaviorRelay<Int>
var songTapped: PublishSubject<Int> = PublishSubject()
var allSongSelected: PublishSubject<Bool> = PublishSubject()
let pageID: BehaviorRelay<Int> = BehaviorRelay(value: 1)
let songTapped: PublishSubject<Int> = PublishSubject()
let allSongSelected: PublishSubject<Bool> = PublishSubject()
}

public struct Output {
var canLoadMore: BehaviorRelay<Bool>
var dataSource: BehaviorRelay<[ArtistSongListEntity]>
let indexOfSelectedSongs: BehaviorRelay<[Int]>
let songEntityOfSelectedSongs: BehaviorRelay<[SongEntity]>
let canLoadMore: BehaviorRelay<Bool> = BehaviorRelay(value: true)
let dataSource: BehaviorRelay<[ArtistSongListEntity]> = BehaviorRelay(value: [])
let indexOfSelectedSongs: BehaviorRelay<[Int]> = BehaviorRelay(value: [])
let songEntityOfSelectedSongs: BehaviorRelay<[SongEntity]> = BehaviorRelay(value: [])
}

public func transform(from input: Input) -> Output {
let output = Output()
let ID: String = model?.artistId ?? ""
let type: ArtistSongSortType = self.type
let fetchArtistSongListUseCase: FetchArtistSongListUseCase = self.fetchArtistSongListUseCase

let dataSource: BehaviorRelay<[ArtistSongListEntity]> = BehaviorRelay(value: [])
let canLoadMore: BehaviorRelay<Bool> = BehaviorRelay(value: true)
let indexOfSelectedSongs: BehaviorRelay<[Int]> = BehaviorRelay(value: [])
let songEntityOfSelectedSongs: BehaviorRelay<[SongEntity]> = BehaviorRelay(value: [])

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

Expand All @@ -67,19 +63,19 @@ public final class ArtistMusicContentViewModel: ViewModelType {
.asObservable()
.do(onNext: { model in
let loadMore: Bool = model.count < 30 ? false : true
canLoadMore.accept(loadMore)
output.canLoadMore.accept(loadMore)
// DEBUG_LOG("page: \(input.pageID.value) called, count: \(model.count), nextPage exist: \(loadMore)")
}, onError: { _ in
canLoadMore.accept(false)
output.canLoadMore.accept(false)
})
.withLatestFrom(refresh, resultSelector: { newModels, datasources -> [ArtistSongListEntity] in
return datasources + newModels
})
.bind(to: dataSource)
.bind(to: output.dataSource)
.disposed(by: disposeBag)

input.songTapped
.withLatestFrom(indexOfSelectedSongs, resultSelector: { index, selectedSongs -> [Int] in
.withLatestFrom(output.indexOfSelectedSongs, resultSelector: { index, selectedSongs -> [Int] in
if selectedSongs.contains(index) {
guard let removeTargetIndex = selectedSongs.firstIndex(where: { $0 == index })
else { return selectedSongs }
Expand All @@ -92,25 +88,25 @@ public final class ArtistMusicContentViewModel: ViewModelType {
}
})
.map { $0.sorted { $0 < $1 } }
.bind(to: indexOfSelectedSongs)
.bind(to: output.indexOfSelectedSongs)
.disposed(by: disposeBag)

input.allSongSelected
.withLatestFrom(dataSource) { ($0, $1) }
.withLatestFrom(output.dataSource) { ($0, $1) }
.map { flag, dataSource -> [Int] in
return flag ? Array(0 ..< dataSource.count) : []
}
.bind(to: indexOfSelectedSongs)
.bind(to: output.indexOfSelectedSongs)
.disposed(by: disposeBag)

Utility.PreferenceManager.$startPage
.skip(1)
.map { _ in [] }
.bind(to: indexOfSelectedSongs)
.bind(to: output.indexOfSelectedSongs)
.disposed(by: disposeBag)

indexOfSelectedSongs
.withLatestFrom(dataSource) { ($0, $1) }
output.indexOfSelectedSongs
.withLatestFrom(output.dataSource) { ($0, $1) }
.map { selectedSongs, dataSource in
var newModel = dataSource
newModel.indices.forEach { newModel[$0].isSelected = false }
Expand All @@ -120,11 +116,11 @@ public final class ArtistMusicContentViewModel: ViewModelType {
}
return newModel
}
.bind(to: dataSource)
.bind(to: output.dataSource)
.disposed(by: disposeBag)

indexOfSelectedSongs
.withLatestFrom(dataSource) { ($0, $1) }
output.indexOfSelectedSongs
.withLatestFrom(output.dataSource) { ($0, $1) }
.map { indexOfSelectedSongs, dataSource in
return indexOfSelectedSongs.map {
SongEntity(
Expand All @@ -139,14 +135,9 @@ public final class ArtistMusicContentViewModel: ViewModelType {
)
}
}
.bind(to: songEntityOfSelectedSongs)
.bind(to: output.songEntityOfSelectedSongs)
.disposed(by: disposeBag)

return Output(
canLoadMore: canLoadMore,
dataSource: dataSource,
indexOfSelectedSongs: indexOfSelectedSongs,
songEntityOfSelectedSongs: songEntityOfSelectedSongs
)
return output
}
}
32 changes: 16 additions & 16 deletions Projects/Features/ArtistFeature/Tests/ArtistReactorTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ final class ArtistReactorTests: XCTestCase {
sut = nil
}

func test_when_viewDidLoad_action_and_artist_count_is_1_then_append_hidden_item() {
func test_when_viewDidLoad_action_and_artist_count_is_1_then_insert_zero_index_hidden_item() {
// Given
let dummyArtistList = [makeTwoDummyArtistList().first!]
fetchArtistListUseCase.handler = {
Expand All @@ -32,8 +32,8 @@ final class ArtistReactorTests: XCTestCase {
// Then
XCTAssertEqual(fetchArtistListUseCase.callCount, 1)
XCTAssertEqual(sut.currentState.artistList[0], dummyArtistList.first)
XCTAssertEqual(sut.currentState.artistList[1].artistId, "")
XCTAssertEqual(sut.currentState.artistList[1].isHiddenItem, true)
XCTAssertEqual(sut.currentState.artistList[0].artistId, "")
XCTAssertEqual(sut.currentState.artistList[0].isHiddenItem, true)
}

func test_when_viewDidLoad_action_and_artist_count_greater_than_2_then_swap_index_0_and_1() {
Expand All @@ -59,20 +59,20 @@ final class ArtistReactorTests: XCTestCase {
private func makeTwoDummyArtistList() -> [ArtistListEntity] {
[
ArtistListEntity(
artistId: "1",
name: "name",
short: "short",
group: "group",
title: "title",
description: "description",
color: [["ffffff"]],
youtube: "https://youtube.com",
twitch: "twitch",
instagram: "insta",
imageRoundVersion: 1,
imageSquareVersion: 1,
artistId: "",
name: "",
short: "",
group: "",
title: "",
description: "",
color: [],
youtube: "",
twitch: "",
instagram: "",
imageRoundVersion: 0,
imageSquareVersion: 0,
graduated: false,
isHiddenItem: false
isHiddenItem: true
),
ArtistListEntity(
artistId: "2",
Expand Down

0 comments on commit e120318

Please sign in to comment.