From 0de001ce1639112538362e90511c5e461d94fe6b Mon Sep 17 00:00:00 2001 From: Daniel Barber Date: Mon, 29 Apr 2019 08:31:44 -0400 Subject: [PATCH] Give the queue its own local state --- .../Controllers/AlbumViewController.swift | 28 +++++-------------- .../Controllers/NotificationsController.swift | 4 +-- .../Controllers/QueueViewController.swift | 9 ++---- Persephone/DataSources/AlbumDataSource.swift | 2 +- Persephone/DataSources/QueueDataSource.swift | 9 +++--- .../State/Actions/AlbumListActions.swift | 4 +-- Persephone/State/Actions/PlayerActions.swift | 8 +++--- Persephone/State/Actions/QueueActions.swift | 4 +++ Persephone/State/QueueState.swift | 5 +++- .../State/Reducers/AlbumListReducer.swift | 4 +-- Persephone/State/Reducers/PlayerReducer.swift | 20 ++++++++----- Persephone/State/Reducers/QueueReducer.swift | 5 +++- 12 files changed, 50 insertions(+), 52 deletions(-) diff --git a/Persephone/Controllers/AlbumViewController.swift b/Persephone/Controllers/AlbumViewController.swift index b3ab905..a5c73f9 100644 --- a/Persephone/Controllers/AlbumViewController.swift +++ b/Persephone/Controllers/AlbumViewController.swift @@ -28,15 +28,6 @@ class AlbumViewController: NSViewController, albumScrollView.postsBoundsChangedNotifications = true albumCollectionView.dataSource = dataSource - -// preferences.addObserver(self, forKeyPath: "mpdLibraryDir") -// preferences.addObserver(self, forKeyPath: "fetchMissingArtworkFromInternet") - } - - override func viewWillDisappear() { - super.viewWillDisappear() - - AppDelegate.store.unsubscribe(self) } override func viewWillLayout() { @@ -68,7 +59,7 @@ class AlbumViewController: NSViewController, case "mpdLibraryDir": albumCollectionView.reloadData() case "fetchMissingArtworkFromInternet": - AppDelegate.store.dispatch(ResetAlbumListCoverArt()) + AppDelegate.store.dispatch(ResetAlbumListCoverArtAction()) default: break } @@ -82,16 +73,11 @@ extension AlbumViewController: StoreSubscriber { typealias StoreSubscriberStateType = AlbumListState func newState(state: StoreSubscriberStateType) { - if dataSource.albums == [] { - dataSource.albums = state.albums - albumCollectionView.reloadData() - } else { - let oldAlbums = dataSource.albums - dataSource.albums = state.albums - albumCollectionView.animateItemChanges( - oldData: oldAlbums, - newData: dataSource.albums - ) - } + let oldAlbums = dataSource.albums + dataSource.albums = state.albums + albumCollectionView.animateItemChanges( + oldData: oldAlbums, + newData: dataSource.albums + ) } } diff --git a/Persephone/Controllers/NotificationsController.swift b/Persephone/Controllers/NotificationsController.swift index 85886ec..98e6c5a 100644 --- a/Persephone/Controllers/NotificationsController.swift +++ b/Persephone/Controllers/NotificationsController.swift @@ -30,13 +30,13 @@ class NotificationsController: MPDClientDelegate { func willStartDatabaseUpdate(mpdClient: MPDClient) { DispatchQueue.main.async { - AppDelegate.store.dispatch(StartedDatabaseUpdate()) + AppDelegate.store.dispatch(StartedDatabaseUpdateAction()) } } func didFinishDatabaseUpdate(mpdClient: MPDClient) { DispatchQueue.main.async { - AppDelegate.store.dispatch(FinishedDatabaseUpdate()) + AppDelegate.store.dispatch(FinishedDatabaseUpdateAction()) } } diff --git a/Persephone/Controllers/QueueViewController.swift b/Persephone/Controllers/QueueViewController.swift index 0e3a2ad..75484ae 100644 --- a/Persephone/Controllers/QueueViewController.swift +++ b/Persephone/Controllers/QueueViewController.swift @@ -27,12 +27,6 @@ class QueueViewController: NSViewController, queueView.columnAutoresizingStyle = .sequentialColumnAutoresizingStyle } - override func viewWillDisappear() { - super.viewWillDisappear() - - AppDelegate.store.unsubscribe(self) - } - override func keyDown(with event: NSEvent) { switch event.keyCode { case NSEvent.keyCodeSpace: @@ -128,7 +122,8 @@ extension QueueViewController: StoreSubscriber { typealias StoreSubscriberStateType = QueueState func newState(state: StoreSubscriberStateType) { - dataSource.setQueueIcon() + dataSource.queue = state.queue + dataSource.setQueueIcon(state) queueView.reloadData() } } diff --git a/Persephone/DataSources/AlbumDataSource.swift b/Persephone/DataSources/AlbumDataSource.swift index d3669ac..6702c54 100644 --- a/Persephone/DataSources/AlbumDataSource.swift +++ b/Persephone/DataSources/AlbumDataSource.swift @@ -33,7 +33,7 @@ class AlbumDataSource: NSObject, NSCollectionViewDataSource { .done { image in DispatchQueue.main.async { AppDelegate.store.dispatch( - UpdateCoverArt(coverArt: image, albumIndex: indexPath.item) + UpdateCoverArtAction(coverArt: image, albumIndex: indexPath.item) ) } } diff --git a/Persephone/DataSources/QueueDataSource.swift b/Persephone/DataSources/QueueDataSource.swift index 44d3b48..57b3c66 100644 --- a/Persephone/DataSources/QueueDataSource.swift +++ b/Persephone/DataSources/QueueDataSource.swift @@ -9,10 +9,11 @@ import Cocoa class QueueDataSource: NSObject, NSOutlineViewDataSource { + var queue: [QueueItem] = [] var queueIcon: NSImage? = nil - func setQueueIcon() { - switch AppDelegate.store.state.playerState.state { + func setQueueIcon(_ state: QueueState) { + switch state.state { case .playing?: queueIcon = .playIcon case .paused?: @@ -23,7 +24,7 @@ class QueueDataSource: NSObject, NSOutlineViewDataSource { } func outlineView(_ outlineView: NSOutlineView, numberOfChildrenOfItem item: Any?) -> Int { - return AppDelegate.store.state.queueState.queue.count + 1 + return queue.count + 1 } func outlineView(_ outlineView: NSOutlineView, isItemExpandable item: Any) -> Bool { @@ -32,7 +33,7 @@ class QueueDataSource: NSObject, NSOutlineViewDataSource { func outlineView(_ outlineView: NSOutlineView, child index: Int, ofItem item: Any?) -> Any { if index > 0 { - return AppDelegate.store.state.queueState.queue[index - 1] + return queue[index - 1] } else { return false } diff --git a/Persephone/State/Actions/AlbumListActions.swift b/Persephone/State/Actions/AlbumListActions.swift index 3de06f6..61218ef 100644 --- a/Persephone/State/Actions/AlbumListActions.swift +++ b/Persephone/State/Actions/AlbumListActions.swift @@ -9,9 +9,9 @@ import Cocoa import ReSwift -struct ResetAlbumListCoverArt: Action {} +struct ResetAlbumListCoverArtAction: Action {} -struct UpdateCoverArt: Action { +struct UpdateCoverArtAction: Action { var coverArt: NSImage? var albumIndex: Int } diff --git a/Persephone/State/Actions/PlayerActions.swift b/Persephone/State/Actions/PlayerActions.swift index ce4fe32..cc988fe 100644 --- a/Persephone/State/Actions/PlayerActions.swift +++ b/Persephone/State/Actions/PlayerActions.swift @@ -9,11 +9,11 @@ import Cocoa import ReSwift -struct UpdateCurrentCoverArt: Action { +struct UpdateCurrentCoverArtAction: Action { var coverArt: NSImage? } -struct UpdateCurrentSong: Action { +struct UpdateCurrentSongAction: Action { var currentSong: Song } @@ -25,6 +25,6 @@ struct UpdateStatusAction: Action { var status: MPDClient.MPDStatus } -struct StartedDatabaseUpdate: Action {} +struct StartedDatabaseUpdateAction: Action {} -struct FinishedDatabaseUpdate: Action {} +struct FinishedDatabaseUpdateAction: Action {} diff --git a/Persephone/State/Actions/QueueActions.swift b/Persephone/State/Actions/QueueActions.swift index 885b985..8558fc6 100644 --- a/Persephone/State/Actions/QueueActions.swift +++ b/Persephone/State/Actions/QueueActions.swift @@ -15,3 +15,7 @@ struct UpdateQueueAction: Action { struct UpdateQueuePosAction: Action { var queuePos: Int } + +struct UpdateQueuePlayerStateAction: Action { + var state: MPDClient.MPDStatus.State? +} diff --git a/Persephone/State/QueueState.swift b/Persephone/State/QueueState.swift index ef6acb6..d9b32a3 100644 --- a/Persephone/State/QueueState.swift +++ b/Persephone/State/QueueState.swift @@ -11,11 +11,14 @@ import ReSwift struct QueueState: StateType { var queue: [QueueItem] = [] var queuePos: Int = -1 + + var state: MPDClient.MPDStatus.State? } extension QueueState: Equatable { static func == (lhs: QueueState, rhs: QueueState) -> Bool { return (lhs.queue == rhs.queue) && - (lhs.queuePos == rhs.queuePos) + (lhs.queuePos == rhs.queuePos) && + (lhs.state == rhs.state) } } diff --git a/Persephone/State/Reducers/AlbumListReducer.swift b/Persephone/State/Reducers/AlbumListReducer.swift index ba542e5..33f5a1d 100644 --- a/Persephone/State/Reducers/AlbumListReducer.swift +++ b/Persephone/State/Reducers/AlbumListReducer.swift @@ -15,10 +15,10 @@ func albumListReducer(action: Action, state: AlbumListState?) -> AlbumListState case let action as UpdateAlbumListAction: state.albums = action.albums.map { Album(mpdAlbum: $0) } - case let action as UpdateCoverArt: + case let action as UpdateCoverArtAction: state.albums[action.albumIndex].coverArt = .loaded(action.coverArt) - case is ResetAlbumListCoverArt: + case is ResetAlbumListCoverArtAction: state.albums = AppDelegate.store.state.albumListState.albums.map { var album = $0 switch album.coverArt { diff --git a/Persephone/State/Reducers/PlayerReducer.swift b/Persephone/State/Reducers/PlayerReducer.swift index 3d36179..3072fa1 100644 --- a/Persephone/State/Reducers/PlayerReducer.swift +++ b/Persephone/State/Reducers/PlayerReducer.swift @@ -25,7 +25,13 @@ func playerReducer(action: Action, state: PlayerState?) -> PlayerState { AppDelegate.trackTimer.stop(elapsedTimeMs: state.elapsedTimeMs) } - case let action as UpdateCurrentSong: + DispatchQueue.main.async { + AppDelegate.store.dispatch( + UpdateQueuePlayerStateAction(state: state.state) + ) + } + + case let action as UpdateCurrentSongAction: state.currentSong = action.currentSong if let currentSong = state.currentSong { @@ -35,29 +41,29 @@ func playerReducer(action: Action, state: PlayerState?) -> PlayerState { .done() { image in DispatchQueue.main.async { if let image = image { - AppDelegate.store.dispatch(UpdateCurrentCoverArt(coverArt: image)) + AppDelegate.store.dispatch(UpdateCurrentCoverArtAction(coverArt: image)) } else { - AppDelegate.store.dispatch(UpdateCurrentCoverArt(coverArt: .defaultCoverArt)) + AppDelegate.store.dispatch(UpdateCurrentCoverArtAction(coverArt: .defaultCoverArt)) } } } .cauterize() } else { DispatchQueue.main.async { - AppDelegate.store.dispatch(UpdateCurrentCoverArt(coverArt: .defaultCoverArt)) + AppDelegate.store.dispatch(UpdateCurrentCoverArtAction(coverArt: .defaultCoverArt)) } } - case let action as UpdateCurrentCoverArt: + case let action as UpdateCurrentCoverArtAction: state.currentArtwork = action.coverArt case let action as UpdateElapsedTimeAction: state.elapsedTimeMs = action.elapsedTimeMs - case is StartedDatabaseUpdate: + case is StartedDatabaseUpdateAction: state.databaseUpdating = true - case is FinishedDatabaseUpdate: + case is FinishedDatabaseUpdateAction: state.databaseUpdating = false default: diff --git a/Persephone/State/Reducers/QueueReducer.swift b/Persephone/State/Reducers/QueueReducer.swift index f29ffc3..ceed68e 100644 --- a/Persephone/State/Reducers/QueueReducer.swift +++ b/Persephone/State/Reducers/QueueReducer.swift @@ -40,9 +40,12 @@ func queueReducer(action: Action, state: QueueState?) -> QueueState { DispatchQueue.main.async { AppDelegate.store.dispatch( - UpdateCurrentSong(currentSong: state.queue[newSongRowPos].song) + UpdateCurrentSongAction(currentSong: state.queue[newSongRowPos].song) ) } + + case let action as UpdateQueuePlayerStateAction: + state.state = action.state default: break