diff --git a/Persephone.xcodeproj/project.pbxproj b/Persephone.xcodeproj/project.pbxproj index 7c43ecb..541758e 100644 --- a/Persephone.xcodeproj/project.pbxproj +++ b/Persephone.xcodeproj/project.pbxproj @@ -99,6 +99,7 @@ E4B11BAD2274F2E80075461B /* UpdateAlbumArt.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4B11BAC2274F2E80075461B /* UpdateAlbumArt.swift */; }; E4B11BB02274F71A0075461B /* EnumEquatable.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4B11BAF2274F71A0075461B /* EnumEquatable.swift */; }; E4B11BB22274F9520075461B /* ResetAlbumListArt.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4B11BB12274F9520075461B /* ResetAlbumListArt.swift */; }; + E4B11BB42275002D0075461B /* UpdateMPDDatabase.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4B11BB32275002D0075461B /* UpdateMPDDatabase.swift */; }; E4C8B53C22342005009A20F3 /* PreferencesWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4C8B53B22342005009A20F3 /* PreferencesWindowController.swift */; }; E4C8B53E22349002009A20F3 /* MPDIdle.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4C8B53D22349002009A20F3 /* MPDIdle.swift */; }; E4E8CC902204EC7F0024217A /* Delegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4E8CC8F2204EC7F0024217A /* Delegate.swift */; }; @@ -289,6 +290,7 @@ E4B11BAC2274F2E80075461B /* UpdateAlbumArt.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UpdateAlbumArt.swift; sourceTree = ""; }; E4B11BAF2274F71A0075461B /* EnumEquatable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EnumEquatable.swift; sourceTree = ""; }; E4B11BB12274F9520075461B /* ResetAlbumListArt.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResetAlbumListArt.swift; sourceTree = ""; }; + E4B11BB32275002D0075461B /* UpdateMPDDatabase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UpdateMPDDatabase.swift; sourceTree = ""; }; E4C8B53B22342005009A20F3 /* PreferencesWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreferencesWindowController.swift; sourceTree = ""; }; E4C8B53D22349002009A20F3 /* MPDIdle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPDIdle.swift; sourceTree = ""; }; E4E8CC8F2204EC7F0024217A /* Delegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Delegate.swift; sourceTree = ""; }; @@ -619,6 +621,7 @@ E4B11B6E226A5C7A0075461B /* UpdateStatusAction.swift */, E4B11BAC2274F2E80075461B /* UpdateAlbumArt.swift */, E4B11BB12274F9520075461B /* ResetAlbumListArt.swift */, + E4B11BB32275002D0075461B /* UpdateMPDDatabase.swift */, ); path = Actions; sourceTree = ""; @@ -886,6 +889,7 @@ E4928E0B2218D62A001D4BEA /* CGColor.swift in Sources */, E4C8B53E22349002009A20F3 /* MPDIdle.swift in Sources */, E4B11BAD2274F2E80075461B /* UpdateAlbumArt.swift in Sources */, + E4B11BB42275002D0075461B /* UpdateMPDDatabase.swift in Sources */, E4B11B6F226A5C7A0075461B /* UpdateStatusAction.swift in Sources */, E4F6B460221E119B00ACF42A /* QueueDataSource.swift in Sources */, E4C8B53C22342005009A20F3 /* PreferencesWindowController.swift in Sources */, diff --git a/Persephone/Actions/UpdateMPDDatabase.swift b/Persephone/Actions/UpdateMPDDatabase.swift new file mode 100644 index 0000000..3a5510a --- /dev/null +++ b/Persephone/Actions/UpdateMPDDatabase.swift @@ -0,0 +1,13 @@ +// +// UpdateMPDDatabase.swift +// Persephone +// +// Created by Daniel Barber on 2019/4/27. +// Copyright © 2019 Dan Barber. All rights reserved. +// + +import ReSwift + +struct StartedDatabaseUpdate: Action {} + +struct FinishedDatabaseUpdate: Action {} diff --git a/Persephone/AppDelegate.swift b/Persephone/AppDelegate.swift index 267dda2..f38b32b 100644 --- a/Persephone/AppDelegate.swift +++ b/Persephone/AppDelegate.swift @@ -11,7 +11,10 @@ import ReSwift import MediaKeyTap @NSApplicationMain -class AppDelegate: NSObject, NSApplicationDelegate, MediaKeyTapDelegate { +class AppDelegate: NSObject, NSApplicationDelegate, MediaKeyTapDelegate, StoreSubscriber { + + typealias StoreSubscriberStateType = PlayerState + var preferences = Preferences() var mediaKeyTap: MediaKeyTap? @@ -32,12 +35,11 @@ class AppDelegate: NSObject, NSApplicationDelegate, MediaKeyTapDelegate { mediaKeyTap = MediaKeyTap(delegate: self) mediaKeyTap?.start() - NotificationCenter.default.addObserver( - self, - selector: #selector(enableUpdateDatabaseMenuItem), - name: Notification.databaseUpdateFinished, - object: AppDelegate.mpdClient - ) + AppDelegate.store.subscribe(self) { + (subscription: Subscription) -> Subscription in + + subscription.select { state in state.playerState } + } } func applicationWillTerminate(_ aNotification: Notification) { @@ -82,12 +84,11 @@ class AppDelegate: NSObject, NSApplicationDelegate, MediaKeyTapDelegate { } @IBAction func updateDatabase(_ sender: NSMenuItem) { - sender.isEnabled = false AppDelegate.mpdClient.updateDatabase() } - @objc func enableUpdateDatabaseMenuItem() { - updateDatabaseMenuItem?.isEnabled = true + func newState(state: PlayerState) { + updateDatabaseMenuItem.isEnabled = !state.databaseUpdating } @IBOutlet weak var updateDatabaseMenuItem: NSMenuItem! diff --git a/Persephone/Controllers/NotificationsController.swift b/Persephone/Controllers/NotificationsController.swift index a747f76..85886ec 100644 --- a/Persephone/Controllers/NotificationsController.swift +++ b/Persephone/Controllers/NotificationsController.swift @@ -29,11 +29,15 @@ class NotificationsController: MPDClientDelegate { } func willStartDatabaseUpdate(mpdClient: MPDClient) { - sendNotification(name: Notification.databaseUpdateStarted) + DispatchQueue.main.async { + AppDelegate.store.dispatch(StartedDatabaseUpdate()) + } } func didFinishDatabaseUpdate(mpdClient: MPDClient) { - sendNotification(name: Notification.databaseUpdateFinished) + DispatchQueue.main.async { + AppDelegate.store.dispatch(FinishedDatabaseUpdate()) + } } func didUpdateQueue(mpdClient: MPDClient, queue: [MPDClient.MPDSong]) { @@ -52,10 +56,6 @@ class NotificationsController: MPDClientDelegate { DispatchQueue.main.async { AppDelegate.store.dispatch(UpdateAlbumListAction(albums: albums)) } - sendNotification( - name: Notification.loadedAlbums, - userInfo: [Notification.albumsKey: albums] - ) } private func sendNotification(name: Notification.Name, userInfo: [AnyHashable : Any] = [:]) { diff --git a/Persephone/Controllers/WindowController.swift b/Persephone/Controllers/WindowController.swift index c990b8d..7059ed9 100644 --- a/Persephone/Controllers/WindowController.swift +++ b/Persephone/Controllers/WindowController.swift @@ -29,20 +29,6 @@ class WindowController: NSWindowController, StoreSubscriber { subscription.select { state in state.playerState } } - NotificationCenter.default.addObserver( - self, - selector: #selector(startDatabaseUpdatingIndicator), - name: Notification.databaseUpdateStarted, - object: AppDelegate.mpdClient - ) - - NotificationCenter.default.addObserver( - self, - selector: #selector(stopDatabaseUpdatingIndicator), - name: Notification.databaseUpdateFinished, - object: AppDelegate.mpdClient - ) - trackProgress.font = .timerFont trackRemaining.font = .timerFont } @@ -53,6 +39,7 @@ class WindowController: NSWindowController, StoreSubscriber { DispatchQueue.main.async { self.setTransportControlState(state) self.setTrackProgressControls(state) + self.setDatabaseUpdatingIndicator(state) } } @@ -94,11 +81,19 @@ class WindowController: NSWindowController, StoreSubscriber { setTimeRemaining(elapsedTimeMs, totalTime * 1000) } - @objc func startDatabaseUpdatingIndicator() { + func setDatabaseUpdatingIndicator(_ playerState: PlayerState) { + if playerState.databaseUpdating { + startDatabaseUpdatingIndicator() + } else { + stopDatabaseUpdatingIndicator() + } + } + + func startDatabaseUpdatingIndicator() { databaseUpdatingIndicator.startAnimation(self) } - @objc func stopDatabaseUpdatingIndicator() { + func stopDatabaseUpdatingIndicator() { databaseUpdatingIndicator.stopAnimation(self) } diff --git a/Persephone/Extensions/CGColor.swift b/Persephone/Extensions/CGColor.swift index 17fe822..b6281e6 100644 --- a/Persephone/Extensions/CGColor.swift +++ b/Persephone/Extensions/CGColor.swift @@ -9,6 +9,6 @@ import Cocoa extension CGColor { - static let albumBorderColorLight = NSColor.black.withAlphaComponent(0.1).cgColor - static let albumBorderColorDark = NSColor.white.withAlphaComponent(0.1).cgColor + static let albumBorderColorLight = NSColor.black.withAlphaComponent(0.15).cgColor + static let albumBorderColorDark = NSColor.white.withAlphaComponent(0.15).cgColor } diff --git a/Persephone/Reducers/PlayerReducer.swift b/Persephone/Reducers/PlayerReducer.swift index c31609d..1f0b4da 100644 --- a/Persephone/Reducers/PlayerReducer.swift +++ b/Persephone/Reducers/PlayerReducer.swift @@ -28,6 +28,12 @@ func playerReducer(action: Action, state: PlayerState?) -> PlayerState { case let action as UpdateElapsedTimeAction: state.elapsedTimeMs = action.elapsedTimeMs + case is StartedDatabaseUpdate: + state.databaseUpdating = true + + case is FinishedDatabaseUpdate: + state.databaseUpdating = false + default: break } diff --git a/Persephone/State/PlayerState.swift b/Persephone/State/PlayerState.swift index 6a32e2f..de5bdc2 100644 --- a/Persephone/State/PlayerState.swift +++ b/Persephone/State/PlayerState.swift @@ -16,12 +16,15 @@ struct PlayerState: StateType { var totalTime: UInt? var elapsedTimeMs: UInt? + + var databaseUpdating: Bool = false } extension PlayerState: Equatable { static func == (lhs: PlayerState, rhs: PlayerState) -> Bool { return (lhs.state == rhs.state) && (lhs.totalTime == rhs.totalTime) && - (lhs.elapsedTimeMs == rhs.elapsedTimeMs) + (lhs.elapsedTimeMs == rhs.elapsedTimeMs) && + (lhs.databaseUpdating == rhs.databaseUpdating) } }