mirror of
https://github.com/danbee/persephone
synced 2025-03-04 08:39:11 +00:00
WIP: Big ReSwift refactor
This commit is contained in:
parent
89b26c4b8a
commit
5651276bd6
1
Cartfile
1
Cartfile
@ -2,3 +2,4 @@ github "SwiftyJSON/SwiftyJSON" ~> 4.0
|
|||||||
github "PromiseKit/Foundation" ~> 3.0
|
github "PromiseKit/Foundation" ~> 3.0
|
||||||
github "nhurden/MediaKeyTap"
|
github "nhurden/MediaKeyTap"
|
||||||
github "krzyzanowskim/CryptoSwift"
|
github "krzyzanowskim/CryptoSwift"
|
||||||
|
github "ReSwift/ReSwift" "mjarvis/swift-5.0"
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
github "PromiseKit/Foundation" "3.3.2"
|
github "PromiseKit/Foundation" "3.3.2"
|
||||||
github "SwiftyJSON/SwiftyJSON" "4.2.0"
|
github "ReSwift/ReSwift" "bc5943ad9493fc7fbad5200f690be538db8e86fb"
|
||||||
|
github "SwiftyJSON/SwiftyJSON" "4.3.0"
|
||||||
github "krzyzanowskim/CryptoSwift" "1.0.0"
|
github "krzyzanowskim/CryptoSwift" "1.0.0"
|
||||||
github "mxcl/PromiseKit" "6.8.4"
|
github "mxcl/PromiseKit" "6.8.4"
|
||||||
github "nhurden/MediaKeyTap" "2.2.1"
|
github "nhurden/MediaKeyTap" "2.2.1"
|
||||||
|
|||||||
@ -20,7 +20,7 @@
|
|||||||
E40F41F3221EDE27004B6CB8 /* Preferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = E40F41F2221EDE27004B6CB8 /* Preferences.swift */; };
|
E40F41F3221EDE27004B6CB8 /* Preferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = E40F41F2221EDE27004B6CB8 /* Preferences.swift */; };
|
||||||
E40FE71B221B904300A4223F /* NSEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = E40FE71A221B904300A4223F /* NSEvent.swift */; };
|
E40FE71B221B904300A4223F /* NSEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = E40FE71A221B904300A4223F /* NSEvent.swift */; };
|
||||||
E419E2872249B96600216A8C /* Song.swift in Sources */ = {isa = PBXBuildFile; fileRef = E419E2862249B96600216A8C /* Song.swift */; };
|
E419E2872249B96600216A8C /* Song.swift in Sources */ = {isa = PBXBuildFile; fileRef = E419E2862249B96600216A8C /* Song.swift */; };
|
||||||
E41B22C021FB6BBA00D544F6 /* libmpdclient.2.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = E41B22BF21FB6BBA00D544F6 /* libmpdclient.2.dylib */; settings = {ATTRIBUTES = (Required, ); }; };
|
E41B22C021FB6BBA00D544F6 /* libmpdclient.2.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = E41B22BF21FB6BBA00D544F6 /* libmpdclient.2.dylib */; };
|
||||||
E41B22C121FB6C3300D544F6 /* libmpdclient.2.dylib in Embed Libraries */ = {isa = PBXBuildFile; fileRef = E41B22BF21FB6BBA00D544F6 /* libmpdclient.2.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
E41B22C121FB6C3300D544F6 /* libmpdclient.2.dylib in Embed Libraries */ = {isa = PBXBuildFile; fileRef = E41B22BF21FB6BBA00D544F6 /* libmpdclient.2.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
||||||
E41B22C621FB932700D544F6 /* MPDClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = E41B22C521FB932700D544F6 /* MPDClient.swift */; };
|
E41B22C621FB932700D544F6 /* MPDClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = E41B22C521FB932700D544F6 /* MPDClient.swift */; };
|
||||||
E41E52FD223BF87300173814 /* MPDClient+Connection.swift in Sources */ = {isa = PBXBuildFile; fileRef = E41E52FC223BF87300173814 /* MPDClient+Connection.swift */; };
|
E41E52FD223BF87300173814 /* MPDClient+Connection.swift in Sources */ = {isa = PBXBuildFile; fileRef = E41E52FC223BF87300173814 /* MPDClient+Connection.swift */; };
|
||||||
@ -60,7 +60,6 @@
|
|||||||
E45E4FDB22515D87004B537F /* Brewfile in Resources */ = {isa = PBXBuildFile; fileRef = E45E4FD822515D87004B537F /* Brewfile */; };
|
E45E4FDB22515D87004B537F /* Brewfile in Resources */ = {isa = PBXBuildFile; fileRef = E45E4FD822515D87004B537F /* Brewfile */; };
|
||||||
E45E4FDC22515D87004B537F /* Cartfile in Resources */ = {isa = PBXBuildFile; fileRef = E45E4FD922515D87004B537F /* Cartfile */; };
|
E45E4FDC22515D87004B537F /* Cartfile in Resources */ = {isa = PBXBuildFile; fileRef = E45E4FD922515D87004B537F /* Cartfile */; };
|
||||||
E45E4FDF225168DA004B537F /* CryptoSwift.framework.dSYM in Resources */ = {isa = PBXBuildFile; fileRef = E45E4FDD225168DA004B537F /* CryptoSwift.framework.dSYM */; };
|
E45E4FDF225168DA004B537F /* CryptoSwift.framework.dSYM in Resources */ = {isa = PBXBuildFile; fileRef = E45E4FDD225168DA004B537F /* CryptoSwift.framework.dSYM */; };
|
||||||
E45E4FE0225168DA004B537F /* CryptoSwift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E45E4FDE225168DA004B537F /* CryptoSwift.framework */; };
|
|
||||||
E45E4FE122516953004B537F /* CryptoSwift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E45E4FDE225168DA004B537F /* CryptoSwift.framework */; };
|
E45E4FE122516953004B537F /* CryptoSwift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E45E4FDE225168DA004B537F /* CryptoSwift.framework */; };
|
||||||
E45E4FE222516953004B537F /* CryptoSwift.framework in Embed Libraries */ = {isa = PBXBuildFile; fileRef = E45E4FDE225168DA004B537F /* CryptoSwift.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
E45E4FE222516953004B537F /* CryptoSwift.framework in Embed Libraries */ = {isa = PBXBuildFile; fileRef = E45E4FDE225168DA004B537F /* CryptoSwift.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||||
E465049A21E94DF500A70F4C /* WindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E465049921E94DF500A70F4C /* WindowController.swift */; };
|
E465049A21E94DF500A70F4C /* WindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E465049921E94DF500A70F4C /* WindowController.swift */; };
|
||||||
@ -76,6 +75,19 @@
|
|||||||
E4A83BEF2221F8CF0098FED6 /* AlbumArtPrefsController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4A83BEE2221F8CF0098FED6 /* AlbumArtPrefsController.swift */; };
|
E4A83BEF2221F8CF0098FED6 /* AlbumArtPrefsController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4A83BEE2221F8CF0098FED6 /* AlbumArtPrefsController.swift */; };
|
||||||
E4A83BF12221FAA00098FED6 /* PreferencesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4A83BF02221FAA00098FED6 /* PreferencesViewController.swift */; };
|
E4A83BF12221FAA00098FED6 /* PreferencesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4A83BF02221FAA00098FED6 /* PreferencesViewController.swift */; };
|
||||||
E4A83BF4222207D50098FED6 /* AlbumArtService.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4A83BF3222207D50098FED6 /* AlbumArtService.swift */; };
|
E4A83BF4222207D50098FED6 /* AlbumArtService.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4A83BF3222207D50098FED6 /* AlbumArtService.swift */; };
|
||||||
|
E4B11B53226928F20075461B /* AppState.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4B11B52226928F20075461B /* AppState.swift */; };
|
||||||
|
E4B11B5A2269296C0075461B /* ReSwift.framework.dSYM in Resources */ = {isa = PBXBuildFile; fileRef = E4B11B582269296C0075461B /* ReSwift.framework.dSYM */; };
|
||||||
|
E4B11B5B226929730075461B /* ReSwift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E4B11B572269296C0075461B /* ReSwift.framework */; };
|
||||||
|
E4B11B5C226929730075461B /* ReSwift.framework in Embed Libraries */ = {isa = PBXBuildFile; fileRef = E4B11B572269296C0075461B /* ReSwift.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||||
|
E4B11B61226A4C000075461B /* PlayerReducer.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4B11B60226A4BFF0075461B /* PlayerReducer.swift */; };
|
||||||
|
E4B11B63226A4C510075461B /* AppReducer.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4B11B62226A4C510075461B /* AppReducer.swift */; };
|
||||||
|
E4B11B66226A4F830075461B /* PlayerState.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4B11B65226A4F830075461B /* PlayerState.swift */; };
|
||||||
|
E4B11B68226A4FA00075461B /* QueueState.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4B11B67226A4FA00075461B /* QueueState.swift */; };
|
||||||
|
E4B11B6A226A4FBC0075461B /* AlbumListState.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4B11B69226A4FBC0075461B /* AlbumListState.swift */; };
|
||||||
|
E4B11B6D226A5B180075461B /* UpdateQueueAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4B11B6C226A5B180075461B /* UpdateQueueAction.swift */; };
|
||||||
|
E4B11B6F226A5C7A0075461B /* UpdateStatusAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4B11B6E226A5C7A0075461B /* UpdateStatusAction.swift */; };
|
||||||
|
E4B11B71226A64E60075461B /* UpdateElapsedTimeAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4B11B70226A64E60075461B /* UpdateElapsedTimeAction.swift */; };
|
||||||
|
E4B11B73226A6C770075461B /* TrackTimer.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4B11B72226A6C770075461B /* TrackTimer.swift */; };
|
||||||
E4C8B53C22342005009A20F3 /* PreferencesWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4C8B53B22342005009A20F3 /* PreferencesWindowController.swift */; };
|
E4C8B53C22342005009A20F3 /* PreferencesWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4C8B53B22342005009A20F3 /* PreferencesWindowController.swift */; };
|
||||||
E4C8B53E22349002009A20F3 /* MPDIdle.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4C8B53D22349002009A20F3 /* MPDIdle.swift */; };
|
E4C8B53E22349002009A20F3 /* MPDIdle.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4C8B53D22349002009A20F3 /* MPDIdle.swift */; };
|
||||||
E4E8CC902204EC7F0024217A /* Delegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4E8CC8F2204EC7F0024217A /* Delegate.swift */; };
|
E4E8CC902204EC7F0024217A /* Delegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4E8CC8F2204EC7F0024217A /* Delegate.swift */; };
|
||||||
@ -113,6 +125,7 @@
|
|||||||
dstPath = "";
|
dstPath = "";
|
||||||
dstSubfolderSpec = 10;
|
dstSubfolderSpec = 10;
|
||||||
files = (
|
files = (
|
||||||
|
E4B11B5C226929730075461B /* ReSwift.framework in Embed Libraries */,
|
||||||
E41B22C121FB6C3300D544F6 /* libmpdclient.2.dylib in Embed Libraries */,
|
E41B22C121FB6C3300D544F6 /* libmpdclient.2.dylib in Embed Libraries */,
|
||||||
E450ADA42229E7E00091BED3 /* PMKFoundation.framework in Embed Libraries */,
|
E450ADA42229E7E00091BED3 /* PMKFoundation.framework in Embed Libraries */,
|
||||||
E421ACA4221F73C4008B2449 /* MediaKeyTap.framework in Embed Libraries */,
|
E421ACA4221F73C4008B2449 /* MediaKeyTap.framework in Embed Libraries */,
|
||||||
@ -242,6 +255,18 @@
|
|||||||
E4A83BEE2221F8CF0098FED6 /* AlbumArtPrefsController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlbumArtPrefsController.swift; sourceTree = "<group>"; };
|
E4A83BEE2221F8CF0098FED6 /* AlbumArtPrefsController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlbumArtPrefsController.swift; sourceTree = "<group>"; };
|
||||||
E4A83BF02221FAA00098FED6 /* PreferencesViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreferencesViewController.swift; sourceTree = "<group>"; };
|
E4A83BF02221FAA00098FED6 /* PreferencesViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreferencesViewController.swift; sourceTree = "<group>"; };
|
||||||
E4A83BF3222207D50098FED6 /* AlbumArtService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlbumArtService.swift; sourceTree = "<group>"; };
|
E4A83BF3222207D50098FED6 /* AlbumArtService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlbumArtService.swift; sourceTree = "<group>"; };
|
||||||
|
E4B11B52226928F20075461B /* AppState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppState.swift; sourceTree = "<group>"; };
|
||||||
|
E4B11B572269296C0075461B /* ReSwift.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ReSwift.framework; path = Carthage/Build/Mac/ReSwift.framework; sourceTree = "<group>"; };
|
||||||
|
E4B11B582269296C0075461B /* ReSwift.framework.dSYM */ = {isa = PBXFileReference; lastKnownFileType = wrapper.dsym; name = ReSwift.framework.dSYM; path = Carthage/Build/Mac/ReSwift.framework.dSYM; sourceTree = "<group>"; };
|
||||||
|
E4B11B60226A4BFF0075461B /* PlayerReducer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerReducer.swift; sourceTree = "<group>"; };
|
||||||
|
E4B11B62226A4C510075461B /* AppReducer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppReducer.swift; sourceTree = "<group>"; };
|
||||||
|
E4B11B65226A4F830075461B /* PlayerState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerState.swift; sourceTree = "<group>"; };
|
||||||
|
E4B11B67226A4FA00075461B /* QueueState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QueueState.swift; sourceTree = "<group>"; };
|
||||||
|
E4B11B69226A4FBC0075461B /* AlbumListState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlbumListState.swift; sourceTree = "<group>"; };
|
||||||
|
E4B11B6C226A5B180075461B /* UpdateQueueAction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UpdateQueueAction.swift; sourceTree = "<group>"; };
|
||||||
|
E4B11B6E226A5C7A0075461B /* UpdateStatusAction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UpdateStatusAction.swift; sourceTree = "<group>"; };
|
||||||
|
E4B11B70226A64E60075461B /* UpdateElapsedTimeAction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UpdateElapsedTimeAction.swift; sourceTree = "<group>"; };
|
||||||
|
E4B11B72226A6C770075461B /* TrackTimer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrackTimer.swift; sourceTree = "<group>"; };
|
||||||
E4C8B53B22342005009A20F3 /* PreferencesWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreferencesWindowController.swift; sourceTree = "<group>"; };
|
E4C8B53B22342005009A20F3 /* PreferencesWindowController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PreferencesWindowController.swift; sourceTree = "<group>"; };
|
||||||
E4C8B53D22349002009A20F3 /* MPDIdle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPDIdle.swift; sourceTree = "<group>"; };
|
E4C8B53D22349002009A20F3 /* MPDIdle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPDIdle.swift; sourceTree = "<group>"; };
|
||||||
E4E8CC8F2204EC7F0024217A /* Delegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Delegate.swift; sourceTree = "<group>"; };
|
E4E8CC8F2204EC7F0024217A /* Delegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Delegate.swift; sourceTree = "<group>"; };
|
||||||
@ -260,12 +285,12 @@
|
|||||||
isa = PBXFrameworksBuildPhase;
|
isa = PBXFrameworksBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
E45E4FE122516953004B537F /* CryptoSwift.framework in Frameworks */,
|
E4B11B5B226929730075461B /* ReSwift.framework in Frameworks */,
|
||||||
E41B22C021FB6BBA00D544F6 /* libmpdclient.2.dylib in Frameworks */,
|
E41B22C021FB6BBA00D544F6 /* libmpdclient.2.dylib in Frameworks */,
|
||||||
E421ACA3221F73C4008B2449 /* MediaKeyTap.framework in Frameworks */,
|
|
||||||
E450AD8622262AE60091BED3 /* SwiftyJSON.framework in Frameworks */,
|
|
||||||
E45E4FE0225168DA004B537F /* CryptoSwift.framework in Frameworks */,
|
|
||||||
E450ADA32229E7E00091BED3 /* PMKFoundation.framework in Frameworks */,
|
E450ADA32229E7E00091BED3 /* PMKFoundation.framework in Frameworks */,
|
||||||
|
E421ACA3221F73C4008B2449 /* MediaKeyTap.framework in Frameworks */,
|
||||||
|
E45E4FE122516953004B537F /* CryptoSwift.framework in Frameworks */,
|
||||||
|
E450AD8622262AE60091BED3 /* SwiftyJSON.framework in Frameworks */,
|
||||||
E450AD9222262C970091BED3 /* PromiseKit.framework in Frameworks */,
|
E450AD9222262C970091BED3 /* PromiseKit.framework in Frameworks */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
@ -316,6 +341,7 @@
|
|||||||
E407861A2110CE6E006887B1 /* Persephone */ = {
|
E407861A2110CE6E006887B1 /* Persephone */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
E4B11B6B226A5AF50075461B /* Actions */,
|
||||||
E407861B2110CE6E006887B1 /* AppDelegate.swift */,
|
E407861B2110CE6E006887B1 /* AppDelegate.swift */,
|
||||||
E407861F2110CE70006887B1 /* Assets.xcassets */,
|
E407861F2110CE70006887B1 /* Assets.xcassets */,
|
||||||
E4D1B597220BA3A20026F233 /* Controllers */,
|
E4D1B597220BA3A20026F233 /* Controllers */,
|
||||||
@ -330,8 +356,10 @@
|
|||||||
E40786252110CE70006887B1 /* Persephone.entitlements */,
|
E40786252110CE70006887B1 /* Persephone.entitlements */,
|
||||||
E450AD9E2229B9BC0091BED3 /* PersephoneBridgingHeader.h */,
|
E450AD9E2229B9BC0091BED3 /* PersephoneBridgingHeader.h */,
|
||||||
E4A83BEC2221F5DD0098FED6 /* Preferences */,
|
E4A83BEC2221F5DD0098FED6 /* Preferences */,
|
||||||
|
E4B11B5F226A4BED0075461B /* Reducers */,
|
||||||
E4D1B598220BA3C90026F233 /* Resources */,
|
E4D1B598220BA3C90026F233 /* Resources */,
|
||||||
E4A83BF2222207BE0098FED6 /* Services */,
|
E4A83BF2222207BE0098FED6 /* Services */,
|
||||||
|
E4B11B64226A4F460075461B /* State */,
|
||||||
E408D3C3220E138B0006D9BE /* Views */,
|
E408D3C3220E138B0006D9BE /* Views */,
|
||||||
);
|
);
|
||||||
path = Persephone;
|
path = Persephone;
|
||||||
@ -397,6 +425,8 @@
|
|||||||
E41B22BE21FB6B3300D544F6 /* Frameworks */ = {
|
E41B22BE21FB6B3300D544F6 /* Frameworks */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
E4B11B572269296C0075461B /* ReSwift.framework */,
|
||||||
|
E4B11B582269296C0075461B /* ReSwift.framework.dSYM */,
|
||||||
E45E4FDE225168DA004B537F /* CryptoSwift.framework */,
|
E45E4FDE225168DA004B537F /* CryptoSwift.framework */,
|
||||||
E45E4FDD225168DA004B537F /* CryptoSwift.framework.dSYM */,
|
E45E4FDD225168DA004B537F /* CryptoSwift.framework.dSYM */,
|
||||||
E450ADA02229E7C90091BED3 /* PMKFoundation.framework */,
|
E450ADA02229E7C90091BED3 /* PMKFoundation.framework */,
|
||||||
@ -531,6 +561,36 @@
|
|||||||
path = Services;
|
path = Services;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
E4B11B5F226A4BED0075461B /* Reducers */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
E4B11B60226A4BFF0075461B /* PlayerReducer.swift */,
|
||||||
|
E4B11B62226A4C510075461B /* AppReducer.swift */,
|
||||||
|
);
|
||||||
|
path = Reducers;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
E4B11B64226A4F460075461B /* State */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
E4B11B52226928F20075461B /* AppState.swift */,
|
||||||
|
E4B11B65226A4F830075461B /* PlayerState.swift */,
|
||||||
|
E4B11B67226A4FA00075461B /* QueueState.swift */,
|
||||||
|
E4B11B69226A4FBC0075461B /* AlbumListState.swift */,
|
||||||
|
);
|
||||||
|
path = State;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
E4B11B6B226A5AF50075461B /* Actions */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
E4B11B6C226A5B180075461B /* UpdateQueueAction.swift */,
|
||||||
|
E4B11B6E226A5C7A0075461B /* UpdateStatusAction.swift */,
|
||||||
|
E4B11B70226A64E60075461B /* UpdateElapsedTimeAction.swift */,
|
||||||
|
);
|
||||||
|
path = Actions;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
E4D1B594220BA2490026F233 /* Models */ = {
|
E4D1B594220BA2490026F233 /* Models */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@ -591,6 +651,7 @@
|
|||||||
E4F6B462221E125900ACF42A /* QueueItem.swift */,
|
E4F6B462221E125900ACF42A /* QueueItem.swift */,
|
||||||
E419E2862249B96600216A8C /* Song.swift */,
|
E419E2862249B96600216A8C /* Song.swift */,
|
||||||
E47E2FDC2220A6D100F747E6 /* Time.swift */,
|
E47E2FDC2220A6D100F747E6 /* Time.swift */,
|
||||||
|
E4B11B72226A6C770075461B /* TrackTimer.swift */,
|
||||||
);
|
);
|
||||||
path = Models;
|
path = Models;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -724,6 +785,7 @@
|
|||||||
E42A8F3C22176D6400A13ED9 /* README.md in Resources */,
|
E42A8F3C22176D6400A13ED9 /* README.md in Resources */,
|
||||||
E450AD8F22262C620091BED3 /* PromiseKit.framework.dSYM in Resources */,
|
E450AD8F22262C620091BED3 /* PromiseKit.framework.dSYM in Resources */,
|
||||||
E408D3CB220E341D0006D9BE /* AlbumViewItem.xib in Resources */,
|
E408D3CB220E341D0006D9BE /* AlbumViewItem.xib in Resources */,
|
||||||
|
E4B11B5A2269296C0075461B /* ReSwift.framework.dSYM in Resources */,
|
||||||
E40786232110CE70006887B1 /* Main.storyboard in Resources */,
|
E40786232110CE70006887B1 /* Main.storyboard in Resources */,
|
||||||
E450ADA12229E7C90091BED3 /* PMKFoundation.framework.dSYM in Resources */,
|
E450ADA12229E7C90091BED3 /* PMKFoundation.framework.dSYM in Resources */,
|
||||||
E47E2FCC2220573500F747E6 /* MediaKeyTap.framework.dSYM in Resources */,
|
E47E2FCC2220573500F747E6 /* MediaKeyTap.framework.dSYM in Resources */,
|
||||||
@ -775,10 +837,14 @@
|
|||||||
E4F6B467221E233200ACF42A /* AlbumDataSource.swift in Sources */,
|
E4F6B467221E233200ACF42A /* AlbumDataSource.swift in Sources */,
|
||||||
E408D3C2220E134F0006D9BE /* AlbumViewController.swift in Sources */,
|
E408D3C2220E134F0006D9BE /* AlbumViewController.swift in Sources */,
|
||||||
E40FE71B221B904300A4223F /* NSEvent.swift in Sources */,
|
E40FE71B221B904300A4223F /* NSEvent.swift in Sources */,
|
||||||
|
E4B11B6D226A5B180075461B /* UpdateQueueAction.swift in Sources */,
|
||||||
|
E4B11B68226A4FA00075461B /* QueueState.swift in Sources */,
|
||||||
E4928E0B2218D62A001D4BEA /* CGColor.swift in Sources */,
|
E4928E0B2218D62A001D4BEA /* CGColor.swift in Sources */,
|
||||||
E4C8B53E22349002009A20F3 /* MPDIdle.swift in Sources */,
|
E4C8B53E22349002009A20F3 /* MPDIdle.swift in Sources */,
|
||||||
|
E4B11B6F226A5C7A0075461B /* UpdateStatusAction.swift in Sources */,
|
||||||
E4F6B460221E119B00ACF42A /* QueueDataSource.swift in Sources */,
|
E4F6B460221E119B00ACF42A /* QueueDataSource.swift in Sources */,
|
||||||
E4C8B53C22342005009A20F3 /* PreferencesWindowController.swift in Sources */,
|
E4C8B53C22342005009A20F3 /* PreferencesWindowController.swift in Sources */,
|
||||||
|
E4B11B63226A4C510075461B /* AppReducer.swift in Sources */,
|
||||||
E41E5307223C019100173814 /* MPDClient+Status.swift in Sources */,
|
E41E5307223C019100173814 /* MPDClient+Status.swift in Sources */,
|
||||||
E41E5310223EF6CE00173814 /* AlbumArtService+Remote.swift in Sources */,
|
E41E5310223EF6CE00173814 /* AlbumArtService+Remote.swift in Sources */,
|
||||||
E41E530B223C033700173814 /* MPDClient+Album.swift in Sources */,
|
E41E530B223C033700173814 /* MPDClient+Album.swift in Sources */,
|
||||||
@ -795,7 +861,9 @@
|
|||||||
E4EB2379220F10B8008C70C0 /* MPDPair.swift in Sources */,
|
E4EB2379220F10B8008C70C0 /* MPDPair.swift in Sources */,
|
||||||
E4F6B463221E125900ACF42A /* QueueItem.swift in Sources */,
|
E4F6B463221E125900ACF42A /* QueueItem.swift in Sources */,
|
||||||
E4A83BF12221FAA00098FED6 /* PreferencesViewController.swift in Sources */,
|
E4A83BF12221FAA00098FED6 /* PreferencesViewController.swift in Sources */,
|
||||||
|
E4B11B61226A4C000075461B /* PlayerReducer.swift in Sources */,
|
||||||
E465049A21E94DF500A70F4C /* WindowController.swift in Sources */,
|
E465049A21E94DF500A70F4C /* WindowController.swift in Sources */,
|
||||||
|
E4B11B71226A64E60075461B /* UpdateElapsedTimeAction.swift in Sources */,
|
||||||
E41B22C621FB932700D544F6 /* MPDClient.swift in Sources */,
|
E41B22C621FB932700D544F6 /* MPDClient.swift in Sources */,
|
||||||
E40F41F3221EDE27004B6CB8 /* Preferences.swift in Sources */,
|
E40F41F3221EDE27004B6CB8 /* Preferences.swift in Sources */,
|
||||||
E47E2FDD2220A6D100F747E6 /* Time.swift in Sources */,
|
E47E2FDD2220A6D100F747E6 /* Time.swift in Sources */,
|
||||||
@ -803,6 +871,7 @@
|
|||||||
E439109822640213002982E9 /* SongNotifierService.swift in Sources */,
|
E439109822640213002982E9 /* SongNotifierService.swift in Sources */,
|
||||||
E407861C2110CE6E006887B1 /* AppDelegate.swift in Sources */,
|
E407861C2110CE6E006887B1 /* AppDelegate.swift in Sources */,
|
||||||
E41E5309223C020400173814 /* MPDClient+Command.swift in Sources */,
|
E41E5309223C020400173814 /* MPDClient+Command.swift in Sources */,
|
||||||
|
E4B11B73226A6C770075461B /* TrackTimer.swift in Sources */,
|
||||||
E47E2FE52220AA0700F747E6 /* AlbumViewLayout.swift in Sources */,
|
E47E2FE52220AA0700F747E6 /* AlbumViewLayout.swift in Sources */,
|
||||||
E41E52FF223BF95E00173814 /* MPDClient+Transport.swift in Sources */,
|
E41E52FF223BF95E00173814 /* MPDClient+Transport.swift in Sources */,
|
||||||
E47E2FD322205D2500F747E6 /* MainWindow.swift in Sources */,
|
E47E2FD322205D2500F747E6 /* MainWindow.swift in Sources */,
|
||||||
@ -813,13 +882,16 @@
|
|||||||
E4A83BF4222207D50098FED6 /* AlbumArtService.swift in Sources */,
|
E4A83BF4222207D50098FED6 /* AlbumArtService.swift in Sources */,
|
||||||
E47E2FD5222071FD00F747E6 /* AlbumViewItem.swift in Sources */,
|
E47E2FD5222071FD00F747E6 /* AlbumViewItem.swift in Sources */,
|
||||||
E408D3BE220E03EE0006D9BE /* RawRepresentable.swift in Sources */,
|
E408D3BE220E03EE0006D9BE /* RawRepresentable.swift in Sources */,
|
||||||
|
E4B11B66226A4F830075461B /* PlayerState.swift in Sources */,
|
||||||
E41E530E223EF4CF00173814 /* AlbumArtService+Caching.swift in Sources */,
|
E41E530E223EF4CF00173814 /* AlbumArtService+Caching.swift in Sources */,
|
||||||
E4E8CC922204F4B80024217A /* QueueViewController.swift in Sources */,
|
E4E8CC922204F4B80024217A /* QueueViewController.swift in Sources */,
|
||||||
E41E5312223EF74A00173814 /* AlbumArtService+Filesystem.swift in Sources */,
|
E41E5312223EF74A00173814 /* AlbumArtService+Filesystem.swift in Sources */,
|
||||||
E41E5301223BF99300173814 /* MPDClient+Queue.swift in Sources */,
|
E41E5301223BF99300173814 /* MPDClient+Queue.swift in Sources */,
|
||||||
E4EB237B220F7CF1008C70C0 /* MPDAlbum.swift in Sources */,
|
E4EB237B220F7CF1008C70C0 /* MPDAlbum.swift in Sources */,
|
||||||
E41E5303223BF9C300173814 /* MPDClient+Idle.swift in Sources */,
|
E41E5303223BF9C300173814 /* MPDClient+Idle.swift in Sources */,
|
||||||
|
E4B11B53226928F20075461B /* AppState.swift in Sources */,
|
||||||
E435E3E4221CD75D00184CFC /* NSImage.swift in Sources */,
|
E435E3E4221CD75D00184CFC /* NSImage.swift in Sources */,
|
||||||
|
E4B11B6A226A4FBC0075461B /* AlbumListState.swift in Sources */,
|
||||||
E41E5305223BFB0700173814 /* MPDClient+Error.swift in Sources */,
|
E41E5305223BFB0700173814 /* MPDClient+Error.swift in Sources */,
|
||||||
E435E3E2221CD4E200184CFC /* NSFont.swift in Sources */,
|
E435E3E2221CD4E200184CFC /* NSFont.swift in Sources */,
|
||||||
);
|
);
|
||||||
|
|||||||
13
Persephone/Actions/UpdateElapsedTimeAction.swift
Normal file
13
Persephone/Actions/UpdateElapsedTimeAction.swift
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
//
|
||||||
|
// UpdateElapsedTimeAction.swift
|
||||||
|
// Persephone
|
||||||
|
//
|
||||||
|
// Created by Daniel Barber on 2019/4/19.
|
||||||
|
// Copyright © 2019 Dan Barber. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import ReSwift
|
||||||
|
|
||||||
|
struct UpdateElapsedTimeAction: Action {
|
||||||
|
var elapsedTimeMs: UInt = 0
|
||||||
|
}
|
||||||
13
Persephone/Actions/UpdateQueueAction.swift
Normal file
13
Persephone/Actions/UpdateQueueAction.swift
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
//
|
||||||
|
// UpdateQueueAction.swift
|
||||||
|
// Persephone
|
||||||
|
//
|
||||||
|
// Created by Daniel Barber on 2019/4/19.
|
||||||
|
// Copyright © 2019 Dan Barber. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import ReSwift
|
||||||
|
|
||||||
|
struct UpdateQueueAction: Action {
|
||||||
|
var queue: [MPDClient.MPDSong]
|
||||||
|
}
|
||||||
13
Persephone/Actions/UpdateStatusAction.swift
Normal file
13
Persephone/Actions/UpdateStatusAction.swift
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
//
|
||||||
|
// UpdateStatusAction.swift
|
||||||
|
// Persephone
|
||||||
|
//
|
||||||
|
// Created by Daniel Barber on 2019/4/19.
|
||||||
|
// Copyright © 2019 Dan Barber. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import ReSwift
|
||||||
|
|
||||||
|
struct UpdateStatusAction: Action {
|
||||||
|
var status: MPDClient.MPDStatus
|
||||||
|
}
|
||||||
@ -7,6 +7,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
import Cocoa
|
import Cocoa
|
||||||
|
import ReSwift
|
||||||
import MediaKeyTap
|
import MediaKeyTap
|
||||||
|
|
||||||
@NSApplicationMain
|
@NSApplicationMain
|
||||||
@ -18,6 +19,10 @@ class AppDelegate: NSObject, NSApplicationDelegate, MediaKeyTapDelegate {
|
|||||||
withDelegate: NotificationsController()
|
withDelegate: NotificationsController()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
static let trackTimer = TrackTimer()
|
||||||
|
|
||||||
|
static let store = Store(reducer: appReducer, state: nil)
|
||||||
|
|
||||||
func applicationDidFinishLaunching(_ aNotification: Notification) {
|
func applicationDidFinishLaunching(_ aNotification: Notification) {
|
||||||
connect()
|
connect()
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// MPDClientNotificationHandler.swift
|
// NotificationsController.swift
|
||||||
// Persephone
|
// Persephone
|
||||||
//
|
//
|
||||||
// Created by Daniel Barber on 2019/2/02.
|
// Created by Daniel Barber on 2019/2/02.
|
||||||
@ -19,21 +19,23 @@ class NotificationsController: MPDClientDelegate {
|
|||||||
sendNotification(name: Notification.willDisconnect)
|
sendNotification(name: Notification.willDisconnect)
|
||||||
}
|
}
|
||||||
|
|
||||||
func didUpdateState(mpdClient: MPDClient, state: MPDClient.MPDStatus.State) {
|
func didUpdateStatus(mpdClient: MPDClient, status: MPDClient.MPDStatus) {
|
||||||
|
AppDelegate.store.dispatch(UpdateStatusAction(status: status))
|
||||||
sendNotification(
|
sendNotification(
|
||||||
name: Notification.stateChanged,
|
name: Notification.stateChanged,
|
||||||
userInfo: [Notification.stateKey: state]
|
userInfo: [Notification.stateKey: status.state]
|
||||||
|
)
|
||||||
|
sendNotification(
|
||||||
|
name: Notification.timeChanged,
|
||||||
|
userInfo: [
|
||||||
|
Notification.totalTimeKey: status.totalTime,
|
||||||
|
Notification.elapsedTimeMsKey: status.elapsedTimeMs
|
||||||
|
]
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func didUpdateTime(mpdClient: MPDClient, total: UInt, elapsedMs: UInt) {
|
func didUpdateTime(mpdClient: MPDClient, total: UInt, elapsedMs: UInt) {
|
||||||
sendNotification(
|
|
||||||
name: Notification.timeChanged,
|
|
||||||
userInfo: [
|
|
||||||
Notification.totalTimeKey: total,
|
|
||||||
Notification.elapsedTimeMsKey: elapsedMs
|
|
||||||
]
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func willStartDatabaseUpdate(mpdClient: MPDClient) {
|
func willStartDatabaseUpdate(mpdClient: MPDClient) {
|
||||||
@ -45,6 +47,7 @@ class NotificationsController: MPDClientDelegate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func didUpdateQueue(mpdClient: MPDClient, queue: [MPDClient.MPDSong]) {
|
func didUpdateQueue(mpdClient: MPDClient, queue: [MPDClient.MPDSong]) {
|
||||||
|
//AppDelegate.store.dispatch(UpdateQueueAction(queue: queue))
|
||||||
sendNotification(
|
sendNotification(
|
||||||
name: Notification.queueChanged,
|
name: Notification.queueChanged,
|
||||||
userInfo: [Notification.queueKey: queue]
|
userInfo: [Notification.queueKey: queue]
|
||||||
|
|||||||
@ -7,34 +7,23 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
import Cocoa
|
import Cocoa
|
||||||
|
import ReSwift
|
||||||
|
|
||||||
|
class WindowController: NSWindowController, StoreSubscriber {
|
||||||
|
typealias StoreSubscriberStateType = AppState
|
||||||
|
|
||||||
class WindowController: NSWindowController {
|
|
||||||
enum TransportAction: Int {
|
enum TransportAction: Int {
|
||||||
case prevTrack, playPause, stop, nextTrack
|
case prevTrack, playPause, stop, nextTrack
|
||||||
}
|
}
|
||||||
|
|
||||||
var state: MPDClient.MPDStatus.State?
|
var state: MPDClient.MPDStatus.State?
|
||||||
var totalTime: UInt?
|
|
||||||
var elapsedTimeMs: UInt?
|
|
||||||
var trackTimer: Timer?
|
var trackTimer: Timer?
|
||||||
|
|
||||||
override func windowDidLoad() {
|
override func windowDidLoad() {
|
||||||
super.windowDidLoad()
|
super.windowDidLoad()
|
||||||
window?.titleVisibility = .hidden
|
window?.titleVisibility = .hidden
|
||||||
|
|
||||||
NotificationCenter.default.addObserver(
|
AppDelegate.store.subscribe(self)
|
||||||
self,
|
|
||||||
selector: #selector(stateChanged(_:)),
|
|
||||||
name: Notification.stateChanged,
|
|
||||||
object: AppDelegate.mpdClient
|
|
||||||
)
|
|
||||||
|
|
||||||
NotificationCenter.default.addObserver(
|
|
||||||
self,
|
|
||||||
selector: #selector(timeChanged(_:)),
|
|
||||||
name: Notification.timeChanged,
|
|
||||||
object: AppDelegate.mpdClient
|
|
||||||
)
|
|
||||||
|
|
||||||
NotificationCenter.default.addObserver(
|
NotificationCenter.default.addObserver(
|
||||||
self,
|
self,
|
||||||
@ -54,6 +43,15 @@ class WindowController: NSWindowController {
|
|||||||
trackRemaining.font = .timerFont
|
trackRemaining.font = .timerFont
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func newState(state: WindowController.StoreSubscriberStateType) {
|
||||||
|
self.state = state.playerState.state
|
||||||
|
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
self.setTransportControlState(state.playerState)
|
||||||
|
self.setTrackProgressControls(state.playerState)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override func keyDown(with event: NSEvent) {
|
override func keyDown(with event: NSEvent) {
|
||||||
switch event.keyCode {
|
switch event.keyCode {
|
||||||
case NSEvent.keyCodeSpace:
|
case NSEvent.keyCodeSpace:
|
||||||
@ -63,17 +61,8 @@ class WindowController: NSWindowController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc func stateChanged(_ notification: Notification) {
|
func setTransportControlState(_ state: PlayerState) {
|
||||||
guard let state = notification.userInfo?[Notification.stateKey] as? MPDClient.MPDStatus.State
|
guard let state = state.state else { return }
|
||||||
else { return }
|
|
||||||
|
|
||||||
self.state = state
|
|
||||||
|
|
||||||
setTransportControlState()
|
|
||||||
}
|
|
||||||
|
|
||||||
func setTransportControlState() {
|
|
||||||
guard let state = state else { return }
|
|
||||||
|
|
||||||
transportControls.setEnabled(state.isOneOf([.playing, .paused]), forSegment: 0)
|
transportControls.setEnabled(state.isOneOf([.playing, .paused]), forSegment: 0)
|
||||||
transportControls.setEnabled(state.isOneOf([.playing, .paused, .stopped]), forSegment: 1)
|
transportControls.setEnabled(state.isOneOf([.playing, .paused, .stopped]), forSegment: 1)
|
||||||
@ -87,64 +76,37 @@ class WindowController: NSWindowController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc func timeChanged(_ notification: Notification) {
|
func setTrackProgressControls(_ playerState: PlayerState) {
|
||||||
guard let totalTime = notification.userInfo?[Notification.totalTimeKey] as? UInt,
|
guard let state = playerState.state,
|
||||||
let elapsedTimeMs = notification.userInfo?[Notification.elapsedTimeMsKey] as? UInt
|
let totalTime = playerState.totalTime,
|
||||||
|
let elapsedTimeMs = playerState.elapsedTimeMs
|
||||||
else { return }
|
else { return }
|
||||||
|
|
||||||
self.totalTime = totalTime
|
trackProgressBar.isEnabled = state.isOneOf([.playing, .paused])
|
||||||
self.elapsedTimeMs = elapsedTimeMs
|
|
||||||
|
|
||||||
setTrackProgressControls()
|
|
||||||
}
|
|
||||||
|
|
||||||
func setTrackProgressControls() {
|
|
||||||
guard let totalTime = totalTime,
|
|
||||||
let elapsedTimeMs = elapsedTimeMs
|
|
||||||
else { return }
|
|
||||||
|
|
||||||
trackProgressBar.isEnabled = [.playing, .paused].contains(state)
|
|
||||||
trackProgressBar.maxValue = Double(totalTime * 1000)
|
trackProgressBar.maxValue = Double(totalTime * 1000)
|
||||||
|
trackProgressBar.integerValue = Int(elapsedTimeMs)
|
||||||
|
|
||||||
if state == .playing {
|
setTimeElapsed(elapsedTimeMs)
|
||||||
trackTimer?.invalidate()
|
setTimeRemaining(elapsedTimeMs, totalTime * 1000)
|
||||||
|
|
||||||
trackTimer = Timer.scheduledTimer(
|
|
||||||
timeInterval: 0.25,
|
|
||||||
target: self,
|
|
||||||
selector: #selector(updateProgress(_:)),
|
|
||||||
userInfo: [
|
|
||||||
"startTime": CACurrentMediaTime(),
|
|
||||||
"startElapsed": Double(elapsedTimeMs) / 1000
|
|
||||||
],
|
|
||||||
repeats: true
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
trackTimer?.invalidate()
|
|
||||||
|
|
||||||
trackProgressBar.integerValue = Int(elapsedTimeMs)
|
|
||||||
setTimeElapsed()
|
|
||||||
setTimeRemaining()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@objc func updateProgress(_ timer: Timer) {
|
// func updateProgressState() {
|
||||||
let currentTime = CACurrentMediaTime()
|
// let currentTime = CACurrentMediaTime()
|
||||||
|
//
|
||||||
guard let userInfo = timer.userInfo as? Dictionary<String, Any>,
|
// guard let userInfo = timer.userInfo as? Dictionary<String, Any>,
|
||||||
let startTime = userInfo["startTime"] as? Double,
|
// let startTime = userInfo["startTime"] as? Double,
|
||||||
let startElapsed = userInfo["startElapsed"] as? Double
|
// let startElapsed = userInfo["startElapsed"] as? Double
|
||||||
else { return }
|
// else { return }
|
||||||
|
//
|
||||||
let timeDiff = currentTime - startTime
|
// let timeDiff = currentTime - startTime
|
||||||
let newElapsedTimeMs = (startElapsed + timeDiff) * 1000
|
// let newElapsedTimeMs = (startElapsed + timeDiff) * 1000
|
||||||
|
//
|
||||||
self.elapsedTimeMs = UInt(newElapsedTimeMs)
|
// self.elapsedTimeMs = UInt(newElapsedTimeMs)
|
||||||
trackProgressBar.integerValue = Int(newElapsedTimeMs)
|
// trackProgressBar.integerValue = Int(newElapsedTimeMs)
|
||||||
|
//
|
||||||
setTimeElapsed()
|
// setTimeElapsed()
|
||||||
setTimeRemaining()
|
// setTimeRemaining()
|
||||||
}
|
// }
|
||||||
|
|
||||||
@objc func startDatabaseUpdatingIndicator() {
|
@objc func startDatabaseUpdatingIndicator() {
|
||||||
databaseUpdatingIndicator.startAnimation(self)
|
databaseUpdatingIndicator.startAnimation(self)
|
||||||
@ -154,7 +116,7 @@ class WindowController: NSWindowController {
|
|||||||
databaseUpdatingIndicator.stopAnimation(self)
|
databaseUpdatingIndicator.stopAnimation(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
func setTimeElapsed() {
|
func setTimeElapsed(_ elapsedTimeMs: UInt?) {
|
||||||
guard let elapsedTimeMs = elapsedTimeMs else { return }
|
guard let elapsedTimeMs = elapsedTimeMs else { return }
|
||||||
|
|
||||||
let time = Time(timeInSeconds: Int(elapsedTimeMs) / 1000)
|
let time = Time(timeInSeconds: Int(elapsedTimeMs) / 1000)
|
||||||
@ -162,38 +124,40 @@ class WindowController: NSWindowController {
|
|||||||
trackProgress.stringValue = time.formattedTime
|
trackProgress.stringValue = time.formattedTime
|
||||||
}
|
}
|
||||||
|
|
||||||
func setTimeRemaining() {
|
func setTimeRemaining(_ elapsedTimeMs: UInt?, _ totalTime: UInt?) {
|
||||||
guard let elapsedTimeMs = elapsedTimeMs,
|
guard let elapsedTimeMs = elapsedTimeMs,
|
||||||
let totalTime = totalTime
|
let totalTime = totalTime
|
||||||
else { return }
|
else { return }
|
||||||
|
|
||||||
let time = Time(timeInSeconds: -(Int(totalTime) - Int(elapsedTimeMs) / 1000))
|
let time = Time(
|
||||||
|
timeInSeconds: -(Int(totalTime) - Int(elapsedTimeMs)) / 1000
|
||||||
|
)
|
||||||
|
|
||||||
trackRemaining.stringValue = time.formattedTime
|
trackRemaining.stringValue = time.formattedTime
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Refactor this using a gesture recognizer
|
// TODO: Refactor this using a gesture recognizer
|
||||||
@IBAction func changeTrackProgress(_ sender: NSSlider) {
|
// @IBAction func changeTrackProgress(_ sender: NSSlider) {
|
||||||
guard let event = NSApplication.shared.currentEvent else {
|
// guard let event = NSApplication.shared.currentEvent else {
|
||||||
return
|
// return
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
switch event.type {
|
// switch event.type {
|
||||||
case .leftMouseDown:
|
// case .leftMouseDown:
|
||||||
trackTimer?.invalidate()
|
// trackTimer?.invalidate()
|
||||||
case .leftMouseDragged:
|
// case .leftMouseDragged:
|
||||||
self.elapsedTimeMs = UInt(sender.integerValue)
|
// self.elapsedTimeMs = UInt(sender.integerValue)
|
||||||
|
//
|
||||||
setTimeElapsed()
|
// setTimeElapsed()
|
||||||
setTimeRemaining()
|
// setTimeRemaining()
|
||||||
case .leftMouseUp:
|
// case .leftMouseUp:
|
||||||
let seekTime = Float(sender.integerValue) / 1000
|
// let seekTime = Float(sender.integerValue) / 1000
|
||||||
|
//
|
||||||
AppDelegate.mpdClient.seekCurrentSong(timeInSeconds: seekTime)
|
// AppDelegate.mpdClient.seekCurrentSong(timeInSeconds: seekTime)
|
||||||
default:
|
// default:
|
||||||
break
|
// break
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
@IBAction func handleTransportControl(_ sender: NSSegmentedControl) {
|
@IBAction func handleTransportControl(_ sender: NSSegmentedControl) {
|
||||||
guard let transportAction = TransportAction(rawValue: sender.selectedSegment)
|
guard let transportAction = TransportAction(rawValue: sender.selectedSegment)
|
||||||
|
|||||||
@ -29,8 +29,7 @@ extension MPDClient {
|
|||||||
self.idle()
|
self.idle()
|
||||||
|
|
||||||
self.delegate?.didConnect(mpdClient: self)
|
self.delegate?.didConnect(mpdClient: self)
|
||||||
self.delegate?.didUpdateState(mpdClient: self, state: self.status!.state)
|
self.delegate?.didUpdateStatus(mpdClient: self, status: self.status!)
|
||||||
self.delegate?.didUpdateTime(mpdClient: self, total: self.status!.totalTime, elapsedMs: self.status!.elapsedTimeMs)
|
|
||||||
self.delegate?.didUpdateQueue(mpdClient: self, queue: self.queue)
|
self.delegate?.didUpdateQueue(mpdClient: self, queue: self.queue)
|
||||||
self.delegate?.didUpdateQueuePos(mpdClient: self, song: self.status!.song)
|
self.delegate?.didUpdateQueuePos(mpdClient: self, song: self.status!.song)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -43,9 +43,8 @@ extension MPDClient {
|
|||||||
self.fetchStatus()
|
self.fetchStatus()
|
||||||
|
|
||||||
if let status = self.status {
|
if let status = self.status {
|
||||||
|
self.delegate?.didUpdateStatus(mpdClient: self, status: status)
|
||||||
self.delegate?.didUpdateQueuePos(mpdClient: self, song: status.song)
|
self.delegate?.didUpdateQueuePos(mpdClient: self, song: status.song)
|
||||||
self.delegate?.didUpdateState(mpdClient: self, state: status.state)
|
|
||||||
self.delegate?.didUpdateTime(mpdClient: self, total: status.totalTime, elapsedMs: status.elapsedTimeMs)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if mpdIdle.contains(.update) {
|
if mpdIdle.contains(.update) {
|
||||||
|
|||||||
@ -12,8 +12,7 @@ protocol MPDClientDelegate {
|
|||||||
func didConnect(mpdClient: MPDClient)
|
func didConnect(mpdClient: MPDClient)
|
||||||
func willDisconnect(mpdClient: MPDClient)
|
func willDisconnect(mpdClient: MPDClient)
|
||||||
|
|
||||||
func didUpdateState(mpdClient: MPDClient, state: MPDClient.MPDStatus.State)
|
func didUpdateStatus(mpdClient: MPDClient, status: MPDClient.MPDStatus)
|
||||||
func didUpdateTime(mpdClient: MPDClient, total: UInt, elapsedMs: UInt)
|
|
||||||
|
|
||||||
func willStartDatabaseUpdate(mpdClient: MPDClient)
|
func willStartDatabaseUpdate(mpdClient: MPDClient)
|
||||||
func didFinishDatabaseUpdate(mpdClient: MPDClient)
|
func didFinishDatabaseUpdate(mpdClient: MPDClient)
|
||||||
|
|||||||
55
Persephone/Models/TrackTimer.swift
Normal file
55
Persephone/Models/TrackTimer.swift
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
//
|
||||||
|
// TrackTimer.swift
|
||||||
|
// Persephone
|
||||||
|
//
|
||||||
|
// Created by Daniel Barber on 2019/4/19.
|
||||||
|
// Copyright © 2019 Dan Barber. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Cocoa
|
||||||
|
|
||||||
|
class TrackTimer: NSObject {
|
||||||
|
var timer: Timer?
|
||||||
|
var startTime: CFTimeInterval = CACurrentMediaTime()
|
||||||
|
var startElapsed: Double = 0
|
||||||
|
|
||||||
|
func start(elapsedTimeMs: UInt?) {
|
||||||
|
print("Starting timer")
|
||||||
|
guard let elapsedTimeMs = elapsedTimeMs else { return }
|
||||||
|
print(elapsedTimeMs)
|
||||||
|
|
||||||
|
timer?.invalidate()
|
||||||
|
|
||||||
|
startTime = CACurrentMediaTime()
|
||||||
|
startElapsed = Double(elapsedTimeMs) / 1000
|
||||||
|
|
||||||
|
timer = Timer.scheduledTimer(
|
||||||
|
withTimeInterval: 0.25,
|
||||||
|
repeats: true
|
||||||
|
) { _ in
|
||||||
|
let currentTime = CACurrentMediaTime()
|
||||||
|
|
||||||
|
let timeDiff = currentTime - self.startTime
|
||||||
|
let newElapsedTimeMs = UInt((self.startElapsed + timeDiff) * 1000)
|
||||||
|
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
AppDelegate.store.dispatch(
|
||||||
|
UpdateElapsedTimeAction(elapsedTimeMs: newElapsedTimeMs)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func stop(elapsedTimeMs: UInt?) {
|
||||||
|
print("Stopping timer")
|
||||||
|
guard let elapsedTimeMs = elapsedTimeMs else { return }
|
||||||
|
|
||||||
|
timer?.invalidate()
|
||||||
|
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
AppDelegate.store.dispatch(
|
||||||
|
UpdateElapsedTimeAction(elapsedTimeMs: elapsedTimeMs)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
16
Persephone/Reducers/AppReducer.swift
Normal file
16
Persephone/Reducers/AppReducer.swift
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
//
|
||||||
|
// AppReducer.swift
|
||||||
|
// Persephone
|
||||||
|
//
|
||||||
|
// Created by Daniel Barber on 2019/4/19.
|
||||||
|
// Copyright © 2019 Dan Barber. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import ReSwift
|
||||||
|
|
||||||
|
func appReducer(action: Action, state: AppState?) -> AppState {
|
||||||
|
return AppState(
|
||||||
|
playerState: playerReducer(action: action, state: state?.playerState)
|
||||||
|
)
|
||||||
|
}
|
||||||
46
Persephone/Reducers/PlayerReducer.swift
Normal file
46
Persephone/Reducers/PlayerReducer.swift
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
//
|
||||||
|
// PlayerReducer.swift
|
||||||
|
// Persephone
|
||||||
|
//
|
||||||
|
// Created by Daniel Barber on 2019/4/19.
|
||||||
|
// Copyright © 2019 Dan Barber. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Cocoa
|
||||||
|
import ReSwift
|
||||||
|
|
||||||
|
func playerReducer(action: Action, state: PlayerState?) -> PlayerState {
|
||||||
|
var state = state ?? PlayerState()
|
||||||
|
|
||||||
|
switch action {
|
||||||
|
case let action as UpdateStatusAction:
|
||||||
|
state.status = action.status
|
||||||
|
state.state = action.status.state
|
||||||
|
state.totalTime = action.status.totalTime
|
||||||
|
state.elapsedTimeMs = action.status.elapsedTimeMs
|
||||||
|
|
||||||
|
if state.state == .playing {
|
||||||
|
AppDelegate.trackTimer.start(elapsedTimeMs: state.elapsedTimeMs)
|
||||||
|
} else {
|
||||||
|
AppDelegate.trackTimer.stop(elapsedTimeMs: state.elapsedTimeMs)
|
||||||
|
}
|
||||||
|
|
||||||
|
case let action as UpdateElapsedTimeAction:
|
||||||
|
state.elapsedTimeMs = action.elapsedTimeMs
|
||||||
|
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
return state
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateElapsedTime(_ timer: Timer) {
|
||||||
|
guard let userInfo = timer.userInfo as? Dictionary<String, Any>,
|
||||||
|
let elapsedTimeMs = userInfo["elapsedTimeMs"] as? UInt
|
||||||
|
else { return }
|
||||||
|
|
||||||
|
AppDelegate.store.dispatch(
|
||||||
|
UpdateElapsedTimeAction(elapsedTimeMs: elapsedTimeMs)
|
||||||
|
)
|
||||||
|
}
|
||||||
13
Persephone/State/AlbumListState.swift
Normal file
13
Persephone/State/AlbumListState.swift
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
//
|
||||||
|
// AlbumListState.swift
|
||||||
|
// Persephone
|
||||||
|
//
|
||||||
|
// Created by Daniel Barber on 2019/4/19.
|
||||||
|
// Copyright © 2019 Dan Barber. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import ReSwift
|
||||||
|
|
||||||
|
struct AlbumListState: StateType {
|
||||||
|
var albums: [Album] = []
|
||||||
|
}
|
||||||
15
Persephone/State/AppState.swift
Normal file
15
Persephone/State/AppState.swift
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
//
|
||||||
|
// AppState.swift
|
||||||
|
// Persephone
|
||||||
|
//
|
||||||
|
// Created by Daniel Barber on 2019/4/18.
|
||||||
|
// Copyright © 2019 Dan Barber. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import ReSwift
|
||||||
|
|
||||||
|
struct AppState: StateType {
|
||||||
|
var playerState = PlayerState()
|
||||||
|
// var queueState = QueueState()
|
||||||
|
// var albumListState = AlbumListState()
|
||||||
|
}
|
||||||
19
Persephone/State/PlayerState.swift
Normal file
19
Persephone/State/PlayerState.swift
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
//
|
||||||
|
// PlayerState.swift
|
||||||
|
// Persephone
|
||||||
|
//
|
||||||
|
// Created by Daniel Barber on 2019/4/19.
|
||||||
|
// Copyright © 2019 Dan Barber. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Cocoa
|
||||||
|
import ReSwift
|
||||||
|
|
||||||
|
struct PlayerState: StateType {
|
||||||
|
var status: MPDClient.MPDStatus?
|
||||||
|
|
||||||
|
var state: MPDClient.MPDStatus.State?
|
||||||
|
|
||||||
|
var totalTime: UInt?
|
||||||
|
var elapsedTimeMs: UInt?
|
||||||
|
}
|
||||||
14
Persephone/State/QueueState.swift
Normal file
14
Persephone/State/QueueState.swift
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
//
|
||||||
|
// QueueState.swift
|
||||||
|
// Persephone
|
||||||
|
//
|
||||||
|
// Created by Daniel Barber on 2019/4/19.
|
||||||
|
// Copyright © 2019 Dan Barber. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import ReSwift
|
||||||
|
|
||||||
|
struct QueueState: StateType {
|
||||||
|
var queue: [QueueItem] = []
|
||||||
|
var queuePos: Int = -1
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user