Skip to content

Commit

Permalink
Merge pull request #1250 from wakmusic/1230-auto-scroll-to-current-so…
Browse files Browse the repository at this point in the history
…ng-when-music-detail-to-playlist

🔀 :: (#1230) 노래 상세에서 재생목록 접근 시 재생목록 자동 스크롤
  • Loading branch information
baekteun authored Aug 28, 2024
2 parents 916fcd2 + 1815797 commit e50f0d2
Show file tree
Hide file tree
Showing 8 changed files with 56 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,25 @@ import Foundation
import RxSwift

public protocol PlayListPresenterGlobalStateProtocol {
var presentPlayListObservable: Observable<Void> { get }
var presentPlayListObservable: Observable<String?> { get }

func presentPlayList(currentSongID: String?)
func presentPlayList()
}

public final class PlayListPresenterGlobalState: PlayListPresenterGlobalStateProtocol {
private let presentPlayListSubject = PublishSubject<Void>()
public var presentPlayListObservable: Observable<Void> {
private let presentPlayListSubject = PublishSubject<String?>()
public var presentPlayListObservable: Observable<String?> {
presentPlayListSubject
}

public init() {}

public func presentPlayList(currentSongID: String?) {
presentPlayListSubject.onNext(currentSongID)
}

public func presentPlayList() {
presentPlayListSubject.onNext(())
presentPlayList(currentSongID: nil)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -122,9 +122,13 @@ private extension MainContainerViewController {
)

playlistPresenterGlobalState.presentPlayListObservable
.bind { [navigationController, playlistFactory] _ in
.bind { [navigationController, playlistFactory] currentSongID in
guard let playlistFactory else { return }
let playlistViewController = playlistFactory.makeViewController()
let playlistViewController = if let currentSongID {
playlistFactory.makeViewController(currentSongID: currentSongID)
} else {
playlistFactory.makeViewController()
}
playlistViewController.modalPresentationStyle = .overFullScreen
navigationController?.topViewController?.present(playlistViewController, animated: true)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,8 @@ final class DummyTextPopupFactory: TextPopupFactory {
}

final class DummyPlaylistPresenterGlobalState: PlayListPresenterGlobalStateProtocol {
var presentPlayListObservable: RxSwift.Observable<Void> { .empty() }
var presentPlayListObservable: RxSwift.Observable<String?> { .empty() }
func presentPlayList(currentSongID: String?) {}
func presentPlayList() {}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ final class MusicDetailReactor: Reactor {
case credit(id: String)
case lyricsHighlighting(model: LyricHighlightingRequiredModel)
case musicPick(id: String)
case playlist
case playlist(id: String)
case dismiss
case textPopup(text: String, completion: () -> Void)
case signin
Expand Down Expand Up @@ -414,7 +414,7 @@ private extension MusicDetailReactor {
guard let song = currentState.selectedSong else { return .empty() }
let log = Log.clickPlaylistButton(id: song.videoID)
LogManager.analytics(log)
return navigateMutation(navigate: .playlist)
return navigateMutation(navigate: .playlist(id: song.videoID))
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,8 @@ final class MusicDetailViewController: BaseReactorViewController<MusicDetailReac
owner.navigateLyricsHighlighing(model: model)
case let .musicPick(id):
owner.presentMusicPick(id: id)
case .playlist:
owner.presentPlaylist()
case let .playlist(id):
owner.presentPlaylist(id: id)
case let .textPopup(text, completion):
owner.presentTextPopup(text: text, completion: completion)
case .signin:
Expand Down Expand Up @@ -240,9 +240,9 @@ private extension MusicDetailViewController {
self.present(viewController, animated: true)
}

func presentPlaylist() {
func presentPlaylist(id: String) {
self.dismiss(animated: true) { [playlistPresenterGlobalState] in
playlistPresenterGlobalState.presentPlayList()
playlistPresenterGlobalState.presentPlayList(currentSongID: id)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ import UIKit

public protocol PlaylistFactory {
func makeViewController() -> UIViewController
func makeViewController(currentSongID: String) -> UIViewController
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,20 @@ public final class PlaylistComponent: Component<PlaylistDependency>, PlaylistFac
public func makeViewController() -> UIViewController {
let viewModel = PlaylistViewModel()
let viewController = PlaylistViewController(
currentSongID: nil,
viewModel: viewModel,
containSongsFactory: dependency.containSongsFactory,
songDetailPresenter: dependency.songDetailPresenter,
textPopupFactory: dependency.textPopupFactory,
signInFactory: dependency.signInFactory
)
return viewController
}

public func makeViewController(currentSongID: String) -> UIViewController {
let viewModel = PlaylistViewModel()
let viewController = PlaylistViewController(
currentSongID: currentSongID,
viewModel: viewModel,
containSongsFactory: dependency.containSongsFactory,
songDetailPresenter: dependency.songDetailPresenter,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,17 @@ public final class PlaylistViewController: UIViewController, SongCartViewType {
)
lazy var output = self.viewModel.transform(from: input)

private let currentSongID: String?

init(
currentSongID: String?,
viewModel: PlaylistViewModel,
containSongsFactory: ContainSongsFactory,
songDetailPresenter: any SongDetailPresentable,
textPopupFactory: any TextPopupFactory,
signInFactory: any SignInFactory
) {
self.currentSongID = currentSongID
self.containSongsFactory = containSongsFactory
self.songDetailPresenter = songDetailPresenter
self.signInFactory = signInFactory
Expand Down Expand Up @@ -178,6 +182,20 @@ private extension PlaylistViewController {

output.playlists
.map { [PlayListSectionModel.init(model: 0, items: $0)] }
.do(afterNext: { [currentSongID, tableView = playlistView.playlistTableView] playListSectionModel in
guard let currentSongID else { return }
guard
let sectionIndex = playListSectionModel.firstIndex(where: { model in
model.items.contains(where: { $0.id == currentSongID })
}),
let itemIndex = playListSectionModel[safe: sectionIndex]?.items
.firstIndex(where: { $0.id == currentSongID })
else { return }
let index = IndexPath(row: itemIndex, section: sectionIndex)
DispatchQueue.main.async {
tableView.scrollToRow(at: index, at: .middle, animated: false)
}
})
.bind(to: playlistView.playlistTableView.rx.items(dataSource: createDatasources(output: output)))
.disposed(by: disposeBag)

Expand Down

0 comments on commit e50f0d2

Please sign in to comment.