1
1
mirror of https://github.com/danbee/persephone synced 2025-03-04 08:39:11 +00:00

Compare commits

..

No commits in common. "7d0c50a8b71fcc25ae3adee08a8ab4347e2b7b80" and "95319d93594ac130dd6a80bae62bd735e4d35334" have entirely different histories.

70 changed files with 397 additions and 883 deletions

View File

@ -35,17 +35,12 @@
E41EA46C221636AF0068EF46 /* GeneralPrefsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E41EA46B221636AF0068EF46 /* GeneralPrefsViewController.swift */; };
E4235640228623D2001216D6 /* QueueSongTitleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E423563F228623D2001216D6 /* QueueSongTitleView.swift */; };
E42410B62241B956005ED6DF /* MPDClient+Database.swift in Sources */ = {isa = PBXBuildFile; fileRef = E42410B52241B956005ED6DF /* MPDClient+Database.swift */; };
E42A4D4F22E20D7D001C6CAD /* MPDTag.swift in Sources */ = {isa = PBXBuildFile; fileRef = E42A4D4E22E20D7D001C6CAD /* MPDTag.swift */; };
E42A4D5122E2167E001C6CAD /* MPDClient+Songs.swift in Sources */ = {isa = PBXBuildFile; fileRef = E42A4D5022E2167E001C6CAD /* MPDClient+Songs.swift */; };
E42A8F3B22176D6400A13ED9 /* LICENSE.md in Resources */ = {isa = PBXBuildFile; fileRef = E42A8F3922176D6400A13ED9 /* LICENSE.md */; };
E42A8F3C22176D6400A13ED9 /* README.md in Resources */ = {isa = PBXBuildFile; fileRef = E42A8F3A22176D6400A13ED9 /* README.md */; };
E435E3E2221CD4E200184CFC /* NSFont.swift in Sources */ = {isa = PBXBuildFile; fileRef = E435E3E1221CD4E200184CFC /* NSFont.swift */; };
E435E3E4221CD75D00184CFC /* NSImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = E435E3E3221CD75D00184CFC /* NSImage.swift */; };
E439109822640213002982E9 /* SongNotifierService.swift in Sources */ = {isa = PBXBuildFile; fileRef = E439109722640213002982E9 /* SongNotifierService.swift */; };
E43AC1F122C68E6A001E483C /* NSPasteboardItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = E43AC1F022C68E6A001E483C /* NSPasteboardItem.swift */; };
E43AC1F522C6A4F4001E483C /* DraggedAlbum.swift in Sources */ = {isa = PBXBuildFile; fileRef = E43AC1F422C6A4F4001E483C /* DraggedAlbum.swift */; };
E43AC1F622C6AD0B001E483C /* AlbumViewController+NSCollectionViewDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = E43AC1F222C6A439001E483C /* AlbumViewController+NSCollectionViewDelegate.swift */; };
E43AC1F822C7065A001E483C /* AlbumCoverButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = E43AC1F722C7065A001E483C /* AlbumCoverButton.swift */; };
E43B67AA22909793007DCF55 /* AlbumDetailView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E43B67A822909793007DCF55 /* AlbumDetailView.swift */; };
E43B67AB22909793007DCF55 /* AlbumDetailView.xib in Resources */ = {isa = PBXBuildFile; fileRef = E43B67A922909793007DCF55 /* AlbumDetailView.xib */; };
E43B67AD229194CD007DCF55 /* AlbumTracksDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = E43B67AC229194CD007DCF55 /* AlbumTracksDataSource.swift */; };
@ -54,7 +49,6 @@
E440519C227BAF2E0090CD6F /* UIActions.swift in Sources */ = {isa = PBXBuildFile; fileRef = E440519B227BAF2E0090CD6F /* UIActions.swift */; };
E440519E227BB0720090CD6F /* UIReducer.swift in Sources */ = {isa = PBXBuildFile; fileRef = E440519D227BB0720090CD6F /* UIReducer.swift */; };
E44051A0227BB0AB0090CD6F /* UIState.swift in Sources */ = {isa = PBXBuildFile; fileRef = E440519F227BB0AB0090CD6F /* UIState.swift */; };
E442CCCD2347E73C00004E0C /* Artist.swift in Sources */ = {isa = PBXBuildFile; fileRef = E442CCCC2347E73C00004E0C /* Artist.swift */; };
E450AD7E222620A10091BED3 /* Album.swift in Sources */ = {isa = PBXBuildFile; fileRef = E450AD7D222620A10091BED3 /* Album.swift */; };
E450AD9522262DF10091BED3 /* CoverArtQueue.swift in Sources */ = {isa = PBXBuildFile; fileRef = E450AD9422262DF10091BED3 /* CoverArtQueue.swift */; };
E451E36B22BD214D008BE9B2 /* DraggedSongType.swift in Sources */ = {isa = PBXBuildFile; fileRef = E451E36A22BD214D008BE9B2 /* DraggedSongType.swift */; };
@ -68,13 +62,13 @@
E47E2FD122205C4600F747E6 /* MainSplitViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E47E2FD022205C4600F747E6 /* MainSplitViewController.swift */; };
E47E2FD322205D2500F747E6 /* MainWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = E47E2FD222205D2500F747E6 /* MainWindow.swift */; };
E47E2FD5222071FD00F747E6 /* AlbumViewItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = E47E2FD4222071FD00F747E6 /* AlbumViewItem.swift */; };
E47E2FD72220720300F747E6 /* AlbumItemView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E47E2FD62220720300F747E6 /* AlbumItemView.swift */; };
E47E2FDD2220A6D100F747E6 /* Time.swift in Sources */ = {isa = PBXBuildFile; fileRef = E47E2FDC2220A6D100F747E6 /* Time.swift */; };
E47E2FE52220AA0700F747E6 /* FlexibleGridViewLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = E47E2FE42220AA0700F747E6 /* FlexibleGridViewLayout.swift */; };
E47E2FE52220AA0700F747E6 /* AlbumViewLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = E47E2FE42220AA0700F747E6 /* AlbumViewLayout.swift */; };
E489E39922B85D0400CA8CBD /* NSPasteboard.swift in Sources */ = {isa = PBXBuildFile; fileRef = E489E39822B85D0400CA8CBD /* NSPasteboard.swift */; };
E489E39D22B9CF0000CA8CBD /* NSView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E489E39C22B9CF0000CA8CBD /* NSView.swift */; };
E489E3A422B9D31800CA8CBD /* DraggedSongView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E489E3A222B9D31800CA8CBD /* DraggedSongView.swift */; };
E489E3A522B9D31800CA8CBD /* DraggedSongView.xib in Resources */ = {isa = PBXBuildFile; fileRef = E489E3A322B9D31800CA8CBD /* DraggedSongView.xib */; };
E48E92D7235113DF00A5E1BB /* Metadata.swift in Sources */ = {isa = PBXBuildFile; fileRef = E48E92D6235113DF00A5E1BB /* Metadata.swift */; };
E4928E0B2218D62A001D4BEA /* CGColor.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4928E0A2218D62A001D4BEA /* CGColor.swift */; };
E49A5482233E580800EED353 /* PromiseKit in Frameworks */ = {isa = PBXBuildFile; productRef = E49A5481233E580800EED353 /* PromiseKit */; };
E49A5485233E5ADC00EED353 /* Differ in Frameworks */ = {isa = PBXBuildFile; productRef = E49A5484233E5ADC00EED353 /* Differ */; };
@ -104,7 +98,6 @@
E4B11BC02275EE150075461B /* QueueActions.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4B11BBF2275EE150075461B /* QueueActions.swift */; };
E4B11BC22275EE410075461B /* AlbumListActions.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4B11BC12275EE410075461B /* AlbumListActions.swift */; };
E4B5AE7E22F4C49600CCEC65 /* MPDServerDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4B5AE7D22F4C49600CCEC65 /* MPDServerDelegate.swift */; };
E4BBD2F323357C0700702C16 /* ArtistListState.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4BBD2F223357C0700702C16 /* ArtistListState.swift */; };
E4C8B53C22342005009A20F3 /* PreferencesWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4C8B53B22342005009A20F3 /* PreferencesWindowController.swift */; };
E4C8B53E22349002009A20F3 /* MPDIdle.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4C8B53D22349002009A20F3 /* MPDIdle.swift */; };
E4D3BFA622B419C000C56F48 /* QueueViewController+NSOutlineViewDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4D3BFA522B419C000C56F48 /* QueueViewController+NSOutlineViewDelegate.swift */; };
@ -115,9 +108,6 @@
E4E96D13233E630800AFD36F /* PMKFoundation in Frameworks */ = {isa = PBXBuildFile; productRef = E4E96D12233E630800AFD36F /* PMKFoundation */; };
E4EB2379220F10B8008C70C0 /* MPDPair.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4EB2378220F10B8008C70C0 /* MPDPair.swift */; };
E4EB237B220F7CF1008C70C0 /* MPDAlbum.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4EB237A220F7CF1008C70C0 /* MPDAlbum.swift */; };
E4F26F7723411AE300D45FF9 /* ArtistListActions.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4F26F7623411AE300D45FF9 /* ArtistListActions.swift */; };
E4F26F7923411B1500D45FF9 /* ArtistReducer.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4F26F7823411B1500D45FF9 /* ArtistReducer.swift */; };
E4F26F7B23411D5400D45FF9 /* MPDClient+Artist.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4F26F7A23411D5400D45FF9 /* MPDClient+Artist.swift */; };
E4F6B460221E119B00ACF42A /* QueueDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4F6B45F221E119B00ACF42A /* QueueDataSource.swift */; };
E4F6B463221E125900ACF42A /* QueueItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4F6B462221E125900ACF42A /* QueueItem.swift */; };
E4F6B467221E233200ACF42A /* AlbumDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4F6B466221E233200ACF42A /* AlbumDataSource.swift */; };
@ -240,17 +230,12 @@
E41EA46B221636AF0068EF46 /* GeneralPrefsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GeneralPrefsViewController.swift; sourceTree = "<group>"; };
E423563F228623D2001216D6 /* QueueSongTitleView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QueueSongTitleView.swift; sourceTree = "<group>"; };
E42410B52241B956005ED6DF /* MPDClient+Database.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MPDClient+Database.swift"; sourceTree = "<group>"; };
E42A4D4E22E20D7D001C6CAD /* MPDTag.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPDTag.swift; sourceTree = "<group>"; };
E42A4D5022E2167E001C6CAD /* MPDClient+Songs.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MPDClient+Songs.swift"; sourceTree = "<group>"; };
E42A8F3922176D6400A13ED9 /* LICENSE.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = LICENSE.md; sourceTree = "<group>"; };
E42A8F3A22176D6400A13ED9 /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
E435E3E1221CD4E200184CFC /* NSFont.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSFont.swift; sourceTree = "<group>"; };
E435E3E3221CD75D00184CFC /* NSImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSImage.swift; sourceTree = "<group>"; };
E439109722640213002982E9 /* SongNotifierService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SongNotifierService.swift; sourceTree = "<group>"; };
E43AC1F022C68E6A001E483C /* NSPasteboardItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSPasteboardItem.swift; sourceTree = "<group>"; };
E43AC1F222C6A439001E483C /* AlbumViewController+NSCollectionViewDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AlbumViewController+NSCollectionViewDelegate.swift"; sourceTree = "<group>"; };
E43AC1F422C6A4F4001E483C /* DraggedAlbum.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DraggedAlbum.swift; sourceTree = "<group>"; };
E43AC1F722C7065A001E483C /* AlbumCoverButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlbumCoverButton.swift; sourceTree = "<group>"; };
E43B67A822909793007DCF55 /* AlbumDetailView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlbumDetailView.swift; sourceTree = "<group>"; };
E43B67A922909793007DCF55 /* AlbumDetailView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = AlbumDetailView.xib; sourceTree = "<group>"; };
E43B67AC229194CD007DCF55 /* AlbumTracksDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlbumTracksDataSource.swift; sourceTree = "<group>"; };
@ -259,7 +244,6 @@
E440519B227BAF2E0090CD6F /* UIActions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIActions.swift; sourceTree = "<group>"; };
E440519D227BB0720090CD6F /* UIReducer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIReducer.swift; sourceTree = "<group>"; };
E440519F227BB0AB0090CD6F /* UIState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIState.swift; sourceTree = "<group>"; };
E442CCCC2347E73C00004E0C /* Artist.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Artist.swift; sourceTree = "<group>"; };
E450AD7D222620A10091BED3 /* Album.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Album.swift; sourceTree = "<group>"; };
E450AD9422262DF10091BED3 /* CoverArtQueue.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoverArtQueue.swift; sourceTree = "<group>"; };
E450AD9E2229B9BC0091BED3 /* PersephoneBridgingHeader.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PersephoneBridgingHeader.h; sourceTree = "<group>"; };
@ -273,13 +257,13 @@
E47E2FD022205C4600F747E6 /* MainSplitViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainSplitViewController.swift; sourceTree = "<group>"; };
E47E2FD222205D2500F747E6 /* MainWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainWindow.swift; sourceTree = "<group>"; };
E47E2FD4222071FD00F747E6 /* AlbumViewItem.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AlbumViewItem.swift; sourceTree = "<group>"; };
E47E2FD62220720300F747E6 /* AlbumItemView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AlbumItemView.swift; sourceTree = "<group>"; };
E47E2FDC2220A6D100F747E6 /* Time.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Time.swift; sourceTree = "<group>"; };
E47E2FE42220AA0700F747E6 /* FlexibleGridViewLayout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FlexibleGridViewLayout.swift; sourceTree = "<group>"; };
E47E2FE42220AA0700F747E6 /* AlbumViewLayout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AlbumViewLayout.swift; sourceTree = "<group>"; };
E489E39822B85D0400CA8CBD /* NSPasteboard.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSPasteboard.swift; sourceTree = "<group>"; };
E489E39C22B9CF0000CA8CBD /* NSView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSView.swift; sourceTree = "<group>"; };
E489E3A222B9D31800CA8CBD /* DraggedSongView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DraggedSongView.swift; sourceTree = "<group>"; };
E489E3A322B9D31800CA8CBD /* DraggedSongView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = DraggedSongView.xib; sourceTree = "<group>"; };
E48E92D6235113DF00A5E1BB /* Metadata.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Metadata.swift; sourceTree = "<group>"; };
E4928E0A2218D62A001D4BEA /* CGColor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CGColor.swift; sourceTree = "<group>"; };
E4A3A6A022A457B600EA2C40 /* AlbumDetailSongListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlbumDetailSongListView.swift; sourceTree = "<group>"; };
E4A642D922090CBE00067D21 /* MPDStatus.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPDStatus.swift; sourceTree = "<group>"; };
@ -302,7 +286,6 @@
E4B11BBF2275EE150075461B /* QueueActions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QueueActions.swift; sourceTree = "<group>"; };
E4B11BC12275EE410075461B /* AlbumListActions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlbumListActions.swift; sourceTree = "<group>"; };
E4B5AE7D22F4C49600CCEC65 /* MPDServerDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPDServerDelegate.swift; sourceTree = "<group>"; };
E4BBD2F223357C0700702C16 /* ArtistListState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArtistListState.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>"; };
E4D3BFA522B419C000C56F48 /* QueueViewController+NSOutlineViewDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "QueueViewController+NSOutlineViewDelegate.swift"; sourceTree = "<group>"; };
@ -312,9 +295,6 @@
E4E8CC9922075D370024217A /* MPDSong.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPDSong.swift; sourceTree = "<group>"; };
E4EB2378220F10B8008C70C0 /* MPDPair.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPDPair.swift; sourceTree = "<group>"; };
E4EB237A220F7CF1008C70C0 /* MPDAlbum.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPDAlbum.swift; sourceTree = "<group>"; };
E4F26F7623411AE300D45FF9 /* ArtistListActions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArtistListActions.swift; sourceTree = "<group>"; };
E4F26F7823411B1500D45FF9 /* ArtistReducer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ArtistReducer.swift; sourceTree = "<group>"; };
E4F26F7A23411D5400D45FF9 /* MPDClient+Artist.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MPDClient+Artist.swift"; sourceTree = "<group>"; };
E4F6B45F221E119B00ACF42A /* QueueDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QueueDataSource.swift; sourceTree = "<group>"; };
E4F6B462221E125900ACF42A /* QueueItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QueueItem.swift; sourceTree = "<group>"; };
E4F6B466221E233200ACF42A /* AlbumDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlbumDataSource.swift; sourceTree = "<group>"; };
@ -385,19 +365,25 @@
E407861A2110CE6E006887B1 /* Persephone */ = {
isa = PBXGroup;
children = (
E44051932278765A0090CD6F /* App.swift */,
E407861B2110CE6E006887B1 /* AppDelegate.swift */,
E44051932278765A0090CD6F /* App.swift */,
E407861F2110CE70006887B1 /* Assets.xcassets */,
E442CCC42347D5B900004E0C /* Components */,
E4D1B597220BA3A20026F233 /* Controllers */,
E4F6B45E221E117600ACF42A /* DataSources */,
E408D3B7220DE8CC0006D9BE /* Extensions */,
E41B22C721FB966C00D544F6 /* include */,
E40786242110CE70006887B1 /* Info.plist */,
E47E2FE32220AA0700F747E6 /* Layouts */,
E4F6B461221E124700ACF42A /* Models */,
E4A642DB220912FA00067D21 /* MPDClient */,
E450AD8922262B420091BED3 /* Operations */,
E40786252110CE70006887B1 /* Persephone.entitlements */,
E450AD9E2229B9BC0091BED3 /* PersephoneBridgingHeader.h */,
E4A83BEC2221F5DD0098FED6 /* Preferences */,
E4D1B598220BA3C90026F233 /* Resources */,
E4A83BF2222207BE0098FED6 /* Services */,
E4B11B64226A4F460075461B /* State */,
E408D3C3220E138B0006D9BE /* Views */,
);
path = Persephone;
sourceTree = "<group>";
@ -440,14 +426,12 @@
isa = PBXGroup;
children = (
E41E530A223C033700173814 /* MPDClient+Album.swift */,
E4F26F7A23411D5400D45FF9 /* MPDClient+Artist.swift */,
E41E5308223C020400173814 /* MPDClient+Command.swift */,
E41E52FC223BF87300173814 /* MPDClient+Connection.swift */,
E42410B52241B956005ED6DF /* MPDClient+Database.swift */,
E41E5304223BFB0700173814 /* MPDClient+Error.swift */,
E41E5302223BF9C300173814 /* MPDClient+Idle.swift */,
E41E5300223BF99300173814 /* MPDClient+Queue.swift */,
E42A4D5022E2167E001C6CAD /* MPDClient+Songs.swift */,
E41E5306223C019100173814 /* MPDClient+Status.swift */,
E41E52FE223BF95E00173814 /* MPDClient+Transport.swift */,
E408D3BD220E03EE0006D9BE /* RawRepresentable.swift */,
@ -455,6 +439,21 @@
path = Extensions;
sourceTree = "<group>";
};
E408D3C3220E138B0006D9BE /* Views */ = {
isa = PBXGroup;
children = (
E4A3A6A022A457B600EA2C40 /* AlbumDetailSongListView.swift */,
E45878372296173C00586A1C /* AlbumDetailSongRowView.swift */,
E47E2FD62220720300F747E6 /* AlbumItemView.swift */,
E4B11BB7227538FA0075461B /* CurrentCoverArtView.swift */,
E489E3A222B9D31800CA8CBD /* DraggedSongView.swift */,
E47E2FD222205D2500F747E6 /* MainWindow.swift */,
E423563F228623D2001216D6 /* QueueSongTitleView.swift */,
E4120D6B22AD8139004CB1F8 /* QueueView.swift */,
);
path = Views;
sourceTree = "<group>";
};
E41B22BE21FB6B3300D544F6 /* Frameworks */ = {
isa = PBXGroup;
children = (
@ -524,91 +523,6 @@
path = Extensions;
sourceTree = "<group>";
};
E442CCC42347D5B900004E0C /* Components */ = {
isa = PBXGroup;
children = (
E442CCCB2347D77A00004E0C /* Browser */,
E4A83BEC2221F5DD0098FED6 /* Preferences */,
E442CCC62347D5E700004E0C /* Queue */,
E442CCC92347D6FD00004E0C /* Shared */,
E442CCC52347D5CA00004E0C /* Window */,
);
path = Components;
sourceTree = "<group>";
};
E442CCC52347D5CA00004E0C /* Window */ = {
isa = PBXGroup;
children = (
E40786212110CE70006887B1 /* Main.storyboard */,
E47E2FD022205C4600F747E6 /* MainSplitViewController.swift */,
E47E2FD222205D2500F747E6 /* MainWindow.swift */,
E465049921E94DF500A70F4C /* WindowController.swift */,
);
path = Window;
sourceTree = "<group>";
};
E442CCC62347D5E700004E0C /* Queue */ = {
isa = PBXGroup;
children = (
E4B11BB7227538FA0075461B /* CurrentCoverArtView.swift */,
E4F6B45F221E119B00ACF42A /* QueueDataSource.swift */,
E423563F228623D2001216D6 /* QueueSongTitleView.swift */,
E4120D6B22AD8139004CB1F8 /* QueueView.swift */,
E4E8CC912204F4B80024217A /* QueueViewController.swift */,
E4D3BFA522B419C000C56F48 /* QueueViewController+NSOutlineViewDelegate.swift */,
);
path = Queue;
sourceTree = "<group>";
};
E442CCC72347D62F00004E0C /* Album Browser */ = {
isa = PBXGroup;
children = (
E408D3C9220E341D0006D9BE /* AlbumViewItem.xib */,
E43AC1F722C7065A001E483C /* AlbumCoverButton.swift */,
E4F6B466221E233200ACF42A /* AlbumDataSource.swift */,
E408D3C1220E134F0006D9BE /* AlbumViewController.swift */,
E43AC1F222C6A439001E483C /* AlbumViewController+NSCollectionViewDelegate.swift */,
E47E2FD4222071FD00F747E6 /* AlbumViewItem.swift */,
);
path = "Album Browser";
sourceTree = "<group>";
};
E442CCC82347D65300004E0C /* Album Detail */ = {
isa = PBXGroup;
children = (
E43B67A922909793007DCF55 /* AlbumDetailView.xib */,
E4A3A6A022A457B600EA2C40 /* AlbumDetailSongListView.swift */,
E45878372296173C00586A1C /* AlbumDetailSongRowView.swift */,
E43B67A822909793007DCF55 /* AlbumDetailView.swift */,
E4E7A6AC22AAAF98006D566C /* AlbumDetailView+NSTableViewDelegate.swift */,
E43B67AC229194CD007DCF55 /* AlbumTracksDataSource.swift */,
);
path = "Album Detail";
sourceTree = "<group>";
};
E442CCC92347D6FD00004E0C /* Shared */ = {
isa = PBXGroup;
children = (
E4E13C2C2350D8CB00092A6E /* Layouts */,
E408D3B7220DE8CC0006D9BE /* Extensions */,
E489E3A222B9D31800CA8CBD /* DraggedSongView.swift */,
E489E3A322B9D31800CA8CBD /* DraggedSongView.xib */,
E4405191227644340090CD6F /* MPDServerController.swift */,
E4B5AE7D22F4C49600CCEC65 /* MPDServerDelegate.swift */,
E4B11BB52275374B0075461B /* UserNotificationsController.swift */,
);
path = Shared;
sourceTree = "<group>";
};
E442CCCB2347D77A00004E0C /* Browser */ = {
isa = PBXGroup;
children = (
E442CCC82347D65300004E0C /* Album Detail */,
E442CCC72347D62F00004E0C /* Album Browser */,
);
path = Browser;
sourceTree = "<group>";
};
E450AD8922262B420091BED3 /* Operations */ = {
isa = PBXGroup;
children = (
@ -617,6 +531,14 @@
path = Operations;
sourceTree = "<group>";
};
E47E2FE32220AA0700F747E6 /* Layouts */ = {
isa = PBXGroup;
children = (
E47E2FE42220AA0700F747E6 /* AlbumViewLayout.swift */,
);
path = Layouts;
sourceTree = "<group>";
};
E4A642DB220912FA00067D21 /* MPDClient */ = {
isa = PBXGroup;
children = (
@ -629,6 +551,14 @@
sourceTree = "<group>";
};
E4A83BEC2221F5DD0098FED6 /* Preferences */ = {
isa = PBXGroup;
children = (
E4A83BED2221F5E60098FED6 /* Controllers */,
);
path = Preferences;
sourceTree = "<group>";
};
E4A83BED2221F5E60098FED6 /* Controllers */ = {
isa = PBXGroup;
children = (
E4A83BEE2221F8CF0098FED6 /* CoverArtPrefsController.swift */,
@ -636,15 +566,15 @@
E4A83BF02221FAA00098FED6 /* PreferencesViewController.swift */,
E4C8B53B22342005009A20F3 /* PreferencesWindowController.swift */,
);
path = Preferences;
path = Controllers;
sourceTree = "<group>";
};
E4A83BF2222207BE0098FED6 /* Services */ = {
isa = PBXGroup;
children = (
E41E530C223EF4BA00173814 /* Extensions */,
E4A83BF3222207D50098FED6 /* CoverArtService.swift */,
E439109722640213002982E9 /* SongNotifierService.swift */,
E41E530C223EF4BA00173814 /* Extensions */,
);
path = Services;
sourceTree = "<group>";
@ -652,12 +582,11 @@
E4B11B5F226A4BED0075461B /* Reducers */ = {
isa = PBXGroup;
children = (
E4B11B78226D346B0075461B /* AlbumListReducer.swift */,
E4B11B62226A4C510075461B /* AppReducer.swift */,
E4F26F7823411B1500D45FF9 /* ArtistReducer.swift */,
E4B11B60226A4BFF0075461B /* PlayerReducer.swift */,
E4FF718F227601B400D4C412 /* PreferencesReducer.swift */,
E4B11B62226A4C510075461B /* AppReducer.swift */,
E4B11B74226CC4D30075461B /* QueueReducer.swift */,
E4B11B78226D346B0075461B /* AlbumListReducer.swift */,
E4FF718F227601B400D4C412 /* PreferencesReducer.swift */,
E440519D227BB0720090CD6F /* UIReducer.swift */,
);
path = Reducers;
@ -668,13 +597,12 @@
children = (
E4B11B6B226A5AF50075461B /* Actions */,
E4B11B5F226A4BED0075461B /* Reducers */,
E4B11B69226A4FBC0075461B /* AlbumListState.swift */,
E4B11B52226928F20075461B /* AppState.swift */,
E4BBD2F223357C0700702C16 /* ArtistListState.swift */,
E4B11B65226A4F830075461B /* PlayerState.swift */,
E4FF718D2276010E00D4C412 /* PreferencesState.swift */,
E4B11B67226A4FA00075461B /* QueueState.swift */,
E440519F227BB0AB0090CD6F /* UIState.swift */,
E4B11B65226A4F830075461B /* PlayerState.swift */,
E4B11B67226A4FA00075461B /* QueueState.swift */,
E4B11B69226A4FBC0075461B /* AlbumListState.swift */,
E4FF718D2276010E00D4C412 /* PreferencesState.swift */,
);
path = State;
sourceTree = "<group>";
@ -683,10 +611,9 @@
isa = PBXGroup;
children = (
E4B11BC12275EE410075461B /* AlbumListActions.swift */,
E4F26F7623411AE300D45FF9 /* ArtistListActions.swift */,
E4B11BBD2275EDAA0075461B /* PlayerActions.swift */,
E4FF71912276029000D4C412 /* PreferencesActions.swift */,
E4B11BBF2275EE150075461B /* QueueActions.swift */,
E4FF71912276029000D4C412 /* PreferencesActions.swift */,
E440519B227BAF2E0090CD6F /* UIActions.swift */,
);
path = Actions;
@ -701,7 +628,6 @@
E4EB2378220F10B8008C70C0 /* MPDPair.swift */,
E4E8CC9922075D370024217A /* MPDSong.swift */,
E4A642D922090CBE00067D21 /* MPDStatus.swift */,
E42A4D4E22E20D7D001C6CAD /* MPDTag.swift */,
);
path = Models;
sourceTree = "<group>";
@ -714,29 +640,57 @@
path = Protocols;
sourceTree = "<group>";
};
E4E13C2C2350D8CB00092A6E /* Layouts */ = {
E4D1B597220BA3A20026F233 /* Controllers */ = {
isa = PBXGroup;
children = (
E47E2FE42220AA0700F747E6 /* FlexibleGridViewLayout.swift */,
E43B67A822909793007DCF55 /* AlbumDetailView.swift */,
E4E7A6AC22AAAF98006D566C /* AlbumDetailView+NSTableViewDelegate.swift */,
E408D3C1220E134F0006D9BE /* AlbumViewController.swift */,
E47E2FD4222071FD00F747E6 /* AlbumViewItem.swift */,
E47E2FD022205C4600F747E6 /* MainSplitViewController.swift */,
E4405191227644340090CD6F /* MPDServerController.swift */,
E4B5AE7D22F4C49600CCEC65 /* MPDServerDelegate.swift */,
E4E8CC912204F4B80024217A /* QueueViewController.swift */,
E4D3BFA522B419C000C56F48 /* QueueViewController+NSOutlineViewDelegate.swift */,
E4B11BB52275374B0075461B /* UserNotificationsController.swift */,
E465049921E94DF500A70F4C /* WindowController.swift */,
);
path = Layouts;
path = Controllers;
sourceTree = "<group>";
};
E4D1B598220BA3C90026F233 /* Resources */ = {
isa = PBXGroup;
children = (
E43B67A922909793007DCF55 /* AlbumDetailView.xib */,
E408D3C9220E341D0006D9BE /* AlbumViewItem.xib */,
E489E3A322B9D31800CA8CBD /* DraggedSongView.xib */,
E40786212110CE70006887B1 /* Main.storyboard */,
);
path = Resources;
sourceTree = "<group>";
};
E4F6B45E221E117600ACF42A /* DataSources */ = {
isa = PBXGroup;
children = (
E4F6B466221E233200ACF42A /* AlbumDataSource.swift */,
E4F6B45F221E119B00ACF42A /* QueueDataSource.swift */,
E43B67AC229194CD007DCF55 /* AlbumTracksDataSource.swift */,
);
path = DataSources;
sourceTree = "<group>";
};
E4F6B461221E124700ACF42A /* Models */ = {
isa = PBXGroup;
children = (
E450AD7D222620A10091BED3 /* Album.swift */,
E442CCCC2347E73C00004E0C /* Artist.swift */,
E43AC1F422C6A4F4001E483C /* DraggedAlbum.swift */,
E451E36C22BD23DB008BE9B2 /* DraggedSong.swift */,
E451E36A22BD214D008BE9B2 /* DraggedSongType.swift */,
E4B11BA82274EDE30075461B /* Loading.swift */,
E4FF71932276043A00D4C412 /* MPDServer.swift */,
E4F6B462221E125900ACF42A /* QueueItem.swift */,
E419E2862249B96600216A8C /* Song.swift */,
E47E2FDC2220A6D100F747E6 /* Time.swift */,
E4B11B72226A6C770075461B /* TrackTimer.swift */,
E48E92D6235113DF00A5E1BB /* Metadata.swift */,
E451E36A22BD214D008BE9B2 /* DraggedSongType.swift */,
E451E36C22BD23DB008BE9B2 /* DraggedSong.swift */,
);
path = Models;
sourceTree = "<group>";
@ -934,11 +888,8 @@
E4F6B467221E233200ACF42A /* AlbumDataSource.swift in Sources */,
E4B11BA92274EDE30075461B /* Loading.swift in Sources */,
E408D3C2220E134F0006D9BE /* AlbumViewController.swift in Sources */,
E42A4D4F22E20D7D001C6CAD /* MPDTag.swift in Sources */,
E43AC1F522C6A4F4001E483C /* DraggedAlbum.swift in Sources */,
E40FE71B221B904300A4223F /* NSEvent.swift in Sources */,
E4B11BB62275374B0075461B /* UserNotificationsController.swift in Sources */,
E43AC1F622C6AD0B001E483C /* AlbumViewController+NSCollectionViewDelegate.swift in Sources */,
E4B11B68226A4FA00075461B /* QueueState.swift in Sources */,
E4928E0B2218D62A001D4BEA /* CGColor.swift in Sources */,
E4D3BFA622B419C000C56F48 /* QueueViewController+NSOutlineViewDelegate.swift in Sources */,
@ -949,20 +900,18 @@
E4B11B63226A4C510075461B /* AppReducer.swift in Sources */,
E41E5307223C019100173814 /* MPDClient+Status.swift in Sources */,
E41E5310223EF6CE00173814 /* CoverArtService+Remote.swift in Sources */,
E442CCCD2347E73C00004E0C /* Artist.swift in Sources */,
E48E92D7235113DF00A5E1BB /* Metadata.swift in Sources */,
E41E530B223C033700173814 /* MPDClient+Album.swift in Sources */,
E42410B62241B956005ED6DF /* MPDClient+Database.swift in Sources */,
E4235640228623D2001216D6 /* QueueSongTitleView.swift in Sources */,
E451E36E22BD2501008BE9B2 /* DraggedSong.swift in Sources */,
E4A642DA22090CBE00067D21 /* MPDStatus.swift in Sources */,
E4B11BC02275EE150075461B /* QueueActions.swift in Sources */,
E47E2FD72220720300F747E6 /* AlbumItemView.swift in Sources */,
E450AD9522262DF10091BED3 /* CoverArtQueue.swift in Sources */,
E43B67AD229194CD007DCF55 /* AlbumTracksDataSource.swift in Sources */,
E41E52FD223BF87300173814 /* MPDClient+Connection.swift in Sources */,
E450AD7E222620A10091BED3 /* Album.swift in Sources */,
E408D3B6220DD8970006D9BE /* Notification.swift in Sources */,
E43AC1F822C7065A001E483C /* AlbumCoverButton.swift in Sources */,
E45962C62241A78500FC1A1E /* MPDCommand.swift in Sources */,
E408D3B9220DE98F0006D9BE /* NSUserInterfaceItemIdentifier.swift in Sources */,
E4EB2379220F10B8008C70C0 /* MPDPair.swift in Sources */,
@ -974,7 +923,6 @@
E4F6B463221E125900ACF42A /* QueueItem.swift in Sources */,
E4A83BF12221FAA00098FED6 /* PreferencesViewController.swift in Sources */,
E4B11BC22275EE410075461B /* AlbumListActions.swift in Sources */,
E4F26F7B23411D5400D45FF9 /* MPDClient+Artist.swift in Sources */,
E4B11B61226A4C000075461B /* PlayerReducer.swift in Sources */,
E4FF71922276029000D4C412 /* PreferencesActions.swift in Sources */,
E489E39922B85D0400CA8CBD /* NSPasteboard.swift in Sources */,
@ -984,18 +932,16 @@
E47E2FDD2220A6D100F747E6 /* Time.swift in Sources */,
E419E2872249B96600216A8C /* Song.swift in Sources */,
E451E36B22BD214D008BE9B2 /* DraggedSongType.swift in Sources */,
E4BBD2F323357C0700702C16 /* ArtistListState.swift in Sources */,
E44051A0227BB0AB0090CD6F /* UIState.swift in Sources */,
E4FF718E2276010E00D4C412 /* PreferencesState.swift in Sources */,
E439109822640213002982E9 /* SongNotifierService.swift in Sources */,
E407861C2110CE6E006887B1 /* AppDelegate.swift in Sources */,
E4B11B75226CC4D30075461B /* QueueReducer.swift in Sources */,
E41E5309223C020400173814 /* MPDClient+Command.swift in Sources */,
E4F26F7923411B1500D45FF9 /* ArtistReducer.swift in Sources */,
E4B11B73226A6C770075461B /* TrackTimer.swift in Sources */,
E44051942278765A0090CD6F /* App.swift in Sources */,
E4B11B79226D346B0075461B /* AlbumListReducer.swift in Sources */,
E47E2FE52220AA0700F747E6 /* FlexibleGridViewLayout.swift in Sources */,
E47E2FE52220AA0700F747E6 /* AlbumViewLayout.swift in Sources */,
E41E52FF223BF95E00173814 /* MPDClient+Transport.swift in Sources */,
E47E2FD322205D2500F747E6 /* MainWindow.swift in Sources */,
E47E2FD122205C4600F747E6 /* MainSplitViewController.swift in Sources */,
@ -1010,7 +956,6 @@
E408D3BE220E03EE0006D9BE /* RawRepresentable.swift in Sources */,
E4B11B66226A4F830075461B /* PlayerState.swift in Sources */,
E4B11BBE2275EDAA0075461B /* PlayerActions.swift in Sources */,
E4F26F7723411AE300D45FF9 /* ArtistListActions.swift in Sources */,
E4FF71942276043A00D4C412 /* MPDServer.swift in Sources */,
E41E530E223EF4CF00173814 /* CoverArtService+Caching.swift in Sources */,
E4E8CC922204F4B80024217A /* QueueViewController.swift in Sources */,
@ -1027,7 +972,6 @@
E41E5305223BFB0700173814 /* MPDClient+Error.swift in Sources */,
E435E3E2221CD4E200184CFC /* NSFont.swift in Sources */,
E489E39D22B9CF0000CA8CBD /* NSView.swift in Sources */,
E42A4D5122E2167E001C6CAD /* MPDClient+Songs.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -1198,7 +1142,10 @@
COMBINE_HIDPI_IMAGES = YES;
DEVELOPMENT_TEAM = BDEE7ZBFZ3;
ENABLE_HARDENED_RUNTIME = YES;
FRAMEWORK_SEARCH_PATHS = "$(inherited)";
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Carthage/Build/Mac",
);
INFOPLIST_FILE = Persephone/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
@ -1226,7 +1173,10 @@
COMBINE_HIDPI_IMAGES = YES;
DEVELOPMENT_TEAM = BDEE7ZBFZ3;
ENABLE_HARDENED_RUNTIME = YES;
FRAMEWORK_SEARCH_PATHS = "$(inherited)";
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Carthage/Build/Mac",
);
INFOPLIST_FILE = Persephone/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",

View File

@ -15,5 +15,5 @@ struct App {
static let userNotificationsController = UserNotificationsController()
static let mpdServerController = MPDServerController()
static let mpdServerDelegate = MPDServerDelegate()
static var mpdClient: MPDClient!
static let mpdClient = MPDClient(withDelegate: mpdServerDelegate)
}

View File

@ -39,13 +39,10 @@ class AppDelegate: NSObject,
func connectToMPDServer() {
let mpdServer = App.store.state.preferencesState.mpdServer
App.mpdClient = MPDClient(
App.mpdClient.connect(
host: mpdServer.hostOrDefault,
port: mpdServer.portOrDefault,
withDelegate: App.mpdServerDelegate
port: mpdServer.portOrDefault
)
App.mpdClient.connect()
}
func instantiateControllers() {

View File

@ -1,43 +0,0 @@
//
// AlbumCoverButton.swift
// Persephone
//
// Created by Daniel Barber on 2019/6/28.
// Copyright © 2019 Dan Barber. All rights reserved.
//
import AppKit
class AlbumCoverButton: NSButton {
var dragging = false
var deltaX: CGFloat = 0
var deltaY: CGFloat = 0
override func mouseDown(with event: NSEvent) {
nextResponder?.mouseDown(with: event)
}
override func mouseDragged(with event: NSEvent) {
deltaX = deltaX + event.deltaX
deltaY = deltaY + event.deltaY
if (deltaX > 5 || deltaX < -5 || deltaY > 5 || deltaY < -5) {
dragging = true
}
nextResponder?.mouseDragged(with: event)
}
override func mouseUp(with event: NSEvent) {
deltaX = 0
deltaY = 0
if dragging {
dragging = false
nextResponder?.mouseUp(with: event)
} else {
super.mouseDown(with: event)
super.mouseUp(with: event)
}
}
}

View File

@ -1,32 +0,0 @@
//
// AlbumViewController+NSCollectionViewDelegate.swift
// Persephone
//
// Created by Daniel Barber on 2019/6/28.
// Copyright © 2019 Dan Barber. All rights reserved.
//
import AppKit
extension AlbumViewController: NSCollectionViewDelegate {
func registerForDragAndDrop(_ collectionView: NSCollectionView) {
collectionView.registerForDraggedTypes([.albumPasteboardType])
collectionView.setDraggingSourceOperationMask(.copy, forLocal: true)
}
func collectionView(_ collectionView: NSCollectionView, pasteboardWriterForItemAt indexPath: IndexPath) -> NSPasteboardWriting? {
let album = dataSource.albums[indexPath.item]
return NSPasteboardItem(
draggedAlbum: DraggedAlbum(
title: album.title,
artist: album.artist
),
ofType: .albumPasteboardType
)
}
func collectionView(_ collectionView: NSCollectionView, canDragItemsAt indexPaths: Set<IndexPath>, with event: NSEvent) -> Bool {
return true
}
}

View File

@ -1,90 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14868" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14868"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="AlbumViewItem" customModule="Persephone" customModuleProvider="target">
<connections>
<outlet property="albumArtist" destination="5Uu-j1-qyT" id="2Et-tX-InT"/>
<outlet property="albumCoverBox" destination="oat-Vd-t1v" id="aDy-tW-PFO"/>
<outlet property="albumCoverView" destination="juD-33-Glf" id="zPG-vz-USc"/>
<outlet property="albumTitle" destination="KEh-NL-c2W" id="SI3-hm-H2B"/>
<outlet property="view" destination="Hz6-mo-xeY" id="v7W-XA-Emc"/>
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<customView identifier="albumViewItem" id="Hz6-mo-xeY">
<rect key="frame" x="0.0" y="0.0" width="158" height="192"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<subviews>
<box boxType="custom" borderType="none" cornerRadius="4" title="Box" translatesAutoresizingMaskIntoConstraints="NO" id="oat-Vd-t1v">
<rect key="frame" x="5" y="49" width="148" height="138"/>
<view key="contentView" wantsLayer="YES" id="h1X-3X-S5v">
<rect key="frame" x="0.0" y="0.0" width="148" height="138"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="juD-33-Glf" customClass="AlbumCoverButton" customModule="Persephone" customModuleProvider="target">
<rect key="frame" x="5" y="5" width="138" height="128"/>
<shadow key="shadow" blurRadius="4">
<size key="offset" width="0.0" height="2"/>
<color key="color" white="0.0" alpha="0.34603323063380281" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</shadow>
<buttonCell key="cell" type="square" bezelStyle="shadowlessSquare" image="defaultCoverArt" imagePosition="only" alignment="center" lineBreakMode="truncatingTail" refusesFirstResponder="YES" state="on" transparent="YES" imageScaling="proportionallyUpOrDown" inset="2" id="t8A-Hz-L38">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="showAlbumDetail:" target="-2" id="A4Q-gb-B45"/>
</connections>
</button>
</subviews>
<constraints>
<constraint firstItem="juD-33-Glf" firstAttribute="top" secondItem="h1X-3X-S5v" secondAttribute="top" constant="5" id="aa9-xp-ssN"/>
<constraint firstAttribute="bottom" secondItem="juD-33-Glf" secondAttribute="bottom" constant="5" id="chP-h2-dVN"/>
<constraint firstItem="juD-33-Glf" firstAttribute="leading" secondItem="h1X-3X-S5v" secondAttribute="leading" constant="5" id="wpA-lb-lHS"/>
<constraint firstAttribute="trailing" secondItem="juD-33-Glf" secondAttribute="trailing" constant="5" id="z1e-o3-Xt0"/>
</constraints>
</view>
</box>
<textField identifier="albumTitle" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="KEh-NL-c2W">
<rect key="frame" x="8" y="28" width="142" height="17"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" title="Label" id="pDs-0t-e1j">
<font key="font" metaFont="system"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField identifier="albumArtist" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="5Uu-j1-qyT">
<rect key="frame" x="8" y="10" width="142" height="16"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" title="Label" id="yZn-e9-zyP">
<font key="font" metaFont="system"/>
<color key="textColor" name="secondaryLabelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
</subviews>
<constraints>
<constraint firstItem="5Uu-j1-qyT" firstAttribute="trailing" secondItem="KEh-NL-c2W" secondAttribute="trailing" id="64z-uz-4nY"/>
<constraint firstAttribute="bottom" secondItem="KEh-NL-c2W" secondAttribute="bottom" constant="28" id="8Kg-1r-wNp"/>
<constraint firstAttribute="bottom" secondItem="oat-Vd-t1v" secondAttribute="bottom" constant="49" id="9be-hX-hie"/>
<constraint firstItem="oat-Vd-t1v" firstAttribute="top" secondItem="Hz6-mo-xeY" secondAttribute="top" constant="5" id="HYh-A2-m7g"/>
<constraint firstItem="5Uu-j1-qyT" firstAttribute="leading" secondItem="KEh-NL-c2W" secondAttribute="leading" id="MUo-0i-fX9"/>
<constraint firstItem="oat-Vd-t1v" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="5" id="PHC-uH-EH6"/>
<constraint firstAttribute="bottom" secondItem="5Uu-j1-qyT" secondAttribute="bottom" constant="10" id="gci-4h-pDZ"/>
<constraint firstItem="KEh-NL-c2W" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="10" id="hG2-cb-UqL"/>
<constraint firstAttribute="trailing" secondItem="oat-Vd-t1v" secondAttribute="trailing" constant="5" id="nD3-RG-rfr"/>
<constraint firstItem="KEh-NL-c2W" firstAttribute="top" secondItem="oat-Vd-t1v" secondAttribute="bottom" constant="4" id="rOI-E8-Odh"/>
<constraint firstItem="KEh-NL-c2W" firstAttribute="centerX" secondItem="Hz6-mo-xeY" secondAttribute="centerX" id="ubc-MA-g7H"/>
</constraints>
<point key="canvasLocation" x="-20" y="112"/>
</customView>
<collectionViewItem id="Qgu-aI-55A" customClass="AlbumViewItem" customModule="Persephone" customModuleProvider="target"/>
</objects>
<resources>
<image name="defaultCoverArt" width="128" height="128"/>
</resources>
</document>

View File

@ -1,14 +0,0 @@
//
// Notification.swift
// Persephone
//
// Created by Daniel Barber on 2019/2/08.
// Copyright © 2019 Dan Barber. All rights reserved.
//
import Foundation
extension Notification.Name {
static let didConnect = Notification.Name("MPDClientDidConnect")
static let willDisconnect = Notification.Name("MPDClientWillDisconnect")
}

View File

@ -17,7 +17,7 @@ class AlbumDetailView: NSViewController {
@IBOutlet var albumTracksView: NSTableView!
@IBOutlet var albumTitle: NSTextField!
@IBOutlet var albumMetadata: NSTextFieldCell!
@IBOutlet var albumArtist: NSTextField!
@IBOutlet var albumCoverView: NSImageView!
override func viewDidLoad() {
@ -41,10 +41,8 @@ class AlbumDetailView: NSViewController {
getAlbumSongs(for: album)
let date = album.metadata?.date ?? ""
albumTitle.stringValue = album.title
albumMetadata.stringValue = "\(album.artist) · \(date)"
albumArtist.stringValue = album.artist
switch album.coverArt {
case .loaded(let coverArt):
@ -60,7 +58,7 @@ class AlbumDetailView: NSViewController {
dataSource.albumSongs = []
albumTracksView.reloadData()
albumTitle.stringValue = ""
albumMetadata.stringValue = ""
albumArtist.stringValue = ""
albumCoverView.image = .defaultCoverArt
App.store.dispatch(SetSelectedSong(selectedSong: nil))

View File

@ -11,9 +11,12 @@ import ReSwift
import Differ
class AlbumViewController: NSViewController,
NSCollectionViewDelegate,
NSCollectionViewDelegateFlowLayout {
let paddingWidth: CGFloat = 40
let gutterWidth: CGFloat = 20
var dataSource = AlbumDataSource()
let layout = FlexibleGridViewLayout(coder: NSCoder())
override func viewDidLoad() {
super.viewDidLoad()
@ -22,16 +25,9 @@ class AlbumViewController: NSViewController,
$0.select { $0.albumListState }
}
NotificationCenter.default.addObserver(self, selector: #selector(didConnect), name: .didConnect, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(willDisconnect), name: .willDisconnect, object: nil)
albumScrollView.postsBoundsChangedNotifications = true
albumCollectionView.dataSource = dataSource
layout?.extraHeight = 44
albumCollectionView.collectionViewLayout = layout
registerForDragAndDrop(albumCollectionView)
}
deinit {
@ -41,7 +37,7 @@ class AlbumViewController: NSViewController,
override func viewWillLayout() {
super.viewWillLayout()
if let layout = albumCollectionView.collectionViewLayout as? FlexibleGridViewLayout {
if let layout = albumCollectionView.collectionViewLayout as? AlbumViewLayout {
layout.saveScrollPosition()
}
@ -51,22 +47,12 @@ class AlbumViewController: NSViewController,
override func viewDidLayout() {
super.viewDidLayout()
guard let layout = albumCollectionView.collectionViewLayout as? FlexibleGridViewLayout
guard let layout = albumCollectionView.collectionViewLayout as? AlbumViewLayout
else { return }
layout.setScrollPosition()
}
@objc func didConnect() {
App.mpdClient.fetchAllAlbums()
}
@objc func willDisconnect() {
DispatchQueue.main.async {
App.store.dispatch(UpdateAlbumListAction(albums: []))
}
}
@IBOutlet var albumScrollView: NSScrollView!
@IBOutlet var albumCollectionView: NSCollectionView!
}
@ -76,7 +62,7 @@ extension AlbumViewController: StoreSubscriber {
func newState(state: StoreSubscriberStateType) {
let oldAlbums = dataSource.albums
dataSource.albums = state.albums
albumCollectionView.animateItemChanges(

View File

@ -12,23 +12,12 @@ class AlbumViewItem: NSCollectionViewItem {
var observer: NSKeyValueObservation?
var album: Album?
override var isSelected: Bool {
didSet {
albumCoverBox.layer?.borderWidth = isSelected ? 5 : 0
}
}
override func viewDidLoad() {
super.viewDidLoad()
albumCoverView.wantsLayer = true
albumCoverView.layer?.cornerRadius = 3
albumCoverView.layer?.borderWidth = 1
albumCoverBox.wantsLayer = true
albumCoverBox.layer?.cornerRadius = 5
albumCoverBox.layer?.borderWidth = 0
setAppearance()
if #available(OSX 10.14, *) {
@ -63,10 +52,8 @@ class AlbumViewItem: NSCollectionViewItem {
[.darkAqua, .aqua]) == .darkAqua
albumCoverView.layer?.borderColor = darkMode ? .albumBorderColorDark : .albumBorderColorLight
albumCoverBox.layer?.borderColor = NSColor.controlAccentColor.cgColor
} else {
albumCoverView.layer?.borderColor = .albumBorderColorLight
albumCoverBox.layer?.borderColor = NSColor.selectedControlColor.cgColor
}
}
@ -78,13 +65,12 @@ class AlbumViewItem: NSCollectionViewItem {
AlbumDetailView.popover.contentViewController = AlbumDetailView.shared
AlbumDetailView.popover.behavior = .transient
AlbumDetailView.popover.show(
relativeTo: albumCoverView.bounds,
of: albumCoverView,
relativeTo: sender.bounds,
of: sender,
preferredEdge: .maxY
)
}
@IBOutlet var albumCoverBox: NSBox!
@IBOutlet var albumCoverView: NSButton!
@IBOutlet var albumTitle: NSTextField!
@IBOutlet var albumArtist: NSTextField!

View File

@ -11,9 +11,9 @@ import ReSwift
class MPDServerController {
init() {
// App.store.subscribe(self) {
// $0.select { $0.preferencesState.mpdServer }
// }
App.store.subscribe(self) {
$0.select { $0.preferencesState.mpdServer }
}
}
}
@ -22,6 +22,9 @@ extension MPDServerController: StoreSubscriber {
func newState(state: MPDServer) {
App.mpdClient.disconnect()
App.mpdClient.connect()
App.mpdClient.connect(
host: state.hostOrDefault,
port: state.portOrDefault
)
}
}

View File

@ -9,12 +9,12 @@
import Foundation
class MPDServerDelegate: MPDClientDelegate {
func didConnect(mpdClient: MPDClient) {
NotificationCenter.default.post(name: .didConnect, object: nil)
}
func didConnect(mpdClient: MPDClient) {}
func willDisconnect(mpdClient: MPDClient) {
NotificationCenter.default.post(name: .willDisconnect, object: nil)
DispatchQueue.main.async {
App.store.dispatch(UpdateAlbumListAction(albums: []))
}
}
func didUpdateStatus(mpdClient: MPDClient, status: MPDClient.MPDStatus) {
@ -52,10 +52,4 @@ class MPDServerDelegate: MPDClientDelegate {
App.store.dispatch(UpdateAlbumListAction(albums: albums))
}
}
func didLoadArtists(mpdClient: MPDClient, artists: [String]) {
DispatchQueue.main.async {
App.store.dispatch(UpdateArtistListAction(artists: artists))
}
}
}

View File

@ -22,19 +22,12 @@ class QueueViewController: NSViewController {
$0.select { $0.queueState }
}
NotificationCenter.default.addObserver(self, selector: #selector(didConnect), name: .didConnect, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(willDisconnect), name: .willDisconnect, object: nil)
queueView.dataSource = dataSource
queueView.columnAutoresizingStyle = .sequentialColumnAutoresizingStyle
queueView.registerForDraggedTypes([.songPasteboardType, .albumPasteboardType])
queueView.registerForDraggedTypes([.songPasteboardType])
queueView.draggingDestinationFeedbackStyle = .regular
}
deinit {
App.store.unsubscribe(self)
}
override func keyDown(with event: NSEvent) {
switch event.keyCode {
case NSEvent.keyCodeSpace:
@ -50,17 +43,6 @@ class QueueViewController: NSViewController {
}
}
@objc func didConnect() {
App.mpdClient.fetchQueue()
}
@objc func willDisconnect() {
DispatchQueue.main.async {
App.store.dispatch(UpdateQueuePosAction(queuePos: -1))
App.store.dispatch(UpdateQueueAction(queue: []))
}
}
@IBAction func playTrack(_ sender: Any) {
let queuePos = queueView.selectedRow - 1

View File

@ -27,8 +27,6 @@ class WindowController: NSWindowController {
@IBOutlet var shuffleState: NSButton!
@IBOutlet var repeatState: NSButton!
@IBOutlet var browseViewControls: NSSegmentedControl!
override func windowDidLoad() {
super.windowDidLoad()
window?.titleVisibility = .hidden
@ -161,6 +159,7 @@ class WindowController: NSWindowController {
@IBAction func handleRepeatButton(_ sender: NSButton) {
App.mpdClient.setRepeatState(repeatState: sender.state == .on)
}
}
extension WindowController: NSWindowDelegate {
@ -180,7 +179,7 @@ extension WindowController: NSWindowDelegate {
extension WindowController: StoreSubscriber {
typealias StoreSubscriberStateType = (playerState: PlayerState, uiState: UIState)
func newState(state: StoreSubscriberStateType) {
func newState(state: (playerState: PlayerState, uiState: UIState)) {
DispatchQueue.main.async {
self.setTransportControlState(state.playerState)
self.setShuffleRepeatState(state.playerState)

View File

@ -28,15 +28,6 @@ class AlbumDataSource: NSObject, NSCollectionViewDataSource {
App.mpdClient.getAlbumFirstSong(for: albums[indexPath.item].mpdAlbum) { mpdSong in
guard let mpdSong = mpdSong else { return }
DispatchQueue.main.async {
App.store.dispatch(
UpdateAlbumMetaData(
metadata: Metadata(date: mpdSong.date),
albumIndex: indexPath.item
)
)
}
CoverArtService(song: Song(mpdSong: mpdSong))
.fetchCoverArt()
.done { image in

View File

@ -57,68 +57,47 @@ class QueueDataSource: NSObject, NSOutlineViewDataSource {
var newQueuePos = index - 1
guard newQueuePos >= 0,
let draggingTypes = info.draggingPasteboard.types
let draggingTypes = info.draggingPasteboard.types,
draggingTypes.contains(.songPasteboardType),
let pasteboardItem = info.draggingPasteboard.pasteboardItems?.first,
let draggedSong = pasteboardItem.draggedSong(forType: .songPasteboardType)
else { return [] }
if draggingTypes.contains(.songPasteboardType) {
guard let pasteboardItem = info.draggingPasteboard.pasteboardItems?.first,
let draggedSong = pasteboardItem.draggedSong(forType: .songPasteboardType)
switch draggedSong.type {
case let .queueItem(queuePos):
if newQueuePos > queuePos { newQueuePos -= 1 }
guard queuePos != newQueuePos
else { return [] }
switch draggedSong.type {
case let .queueItem(queuePos):
if newQueuePos > queuePos { newQueuePos -= 1 }
guard queuePos != newQueuePos
else { return [] }
return .move
case .albumSongItem:
return .copy
}
} else if draggingTypes.contains(.albumPasteboardType) {
return .move
case .albumSongItem:
return .copy
}
return []
}
func outlineView(_ outlineView: NSOutlineView, acceptDrop info: NSDraggingInfo, item: Any?, childIndex index: Int) -> Bool {
var newQueuePos = index - 1
guard let draggingTypes = info.draggingPasteboard.types
guard let draggingTypes = info.draggingPasteboard.types,
draggingTypes.contains(.songPasteboardType),
let data = info.draggingPasteboard.data(forType: .songPasteboardType),
let draggedSong = try? PropertyListDecoder().decode(DraggedSong.self, from: data)
else { return false }
if draggingTypes.contains(.songPasteboardType) {
guard let data = info.draggingPasteboard.data(forType: .songPasteboardType),
let draggedSong = try? PropertyListDecoder().decode(DraggedSong.self, from: data)
switch draggedSong.type {
case let .queueItem(queuePos):
if newQueuePos > queuePos { newQueuePos -= 1 }
guard queuePos != newQueuePos
else { return false }
switch draggedSong.type {
case let .queueItem(queuePos):
if newQueuePos > queuePos { newQueuePos -= 1 }
guard queuePos != newQueuePos
else { return false }
App.mpdClient.moveSongInQueue(at: queuePos, to: newQueuePos)
return true
case let .albumSongItem(uri):
App.mpdClient.addSongToQueue(songUri: uri, at: newQueuePos)
return true
}
} else if draggingTypes.contains(.albumPasteboardType) {
guard let data = info.draggingPasteboard.data(forType: .albumPasteboardType),
let draggedAlbum = try? PropertyListDecoder().decode(DraggedAlbum.self, from: data)
else { return false }
let mpdAlbum = MPDClient.MPDAlbum(title: draggedAlbum.title, artist: draggedAlbum.artist)
App.mpdClient.addAlbumToQueue(album: mpdAlbum, at: newQueuePos)
App.mpdClient.moveSongInQueue(at: queuePos, to: newQueuePos)
return true
case let .albumSongItem(uri):
App.mpdClient.addSongToQueue(songUri: uri, at: newQueuePos)
return true
}
return false
}
func outlineView(_ outlineView: NSOutlineView, draggingSession session: NSDraggingSession, willBeginAt screenPoint: NSPoint, forItems draggedItems: [Any]) {
@ -146,4 +125,5 @@ class QueueDataSource: NSObject, NSOutlineViewDataSource {
}
}
}
}

View File

@ -9,6 +9,5 @@
import AppKit
extension NSPasteboard.PasteboardType {
static let songPasteboardType = NSPasteboard.PasteboardType("me.danbarber.persephone.song")
static let albumPasteboardType = NSPasteboard.PasteboardType("me.danbarber.persephone.album")
static let songPasteboardType = NSPasteboard.PasteboardType("me.danbarber.persephone")
}

View File

@ -14,23 +14,12 @@ extension NSPasteboardItem {
self.setDraggedSong(draggedSong, forType: type)
}
convenience init(draggedAlbum: DraggedAlbum, ofType type: NSPasteboard.PasteboardType) {
self.init()
self.setDraggedAlbum(draggedAlbum, forType: type)
}
func setDraggedSong(_ draggedSong: DraggedSong, forType type: NSPasteboard.PasteboardType) {
let data = try! PropertyListEncoder().encode(draggedSong)
setData(data, forType: type)
}
func setDraggedAlbum(_ draggedAlbum: DraggedAlbum, forType type: NSPasteboard.PasteboardType) {
let data = try! PropertyListEncoder().encode(draggedAlbum)
setData(data, forType: type)
}
func draggedSong(forType type: NSPasteboard.PasteboardType) -> DraggedSong? {
guard let itemData = data(forType: type)
else { return nil }

View File

@ -17,12 +17,9 @@ extension NSUserInterfaceItemIdentifier {
static let queueSongTitle = NSUserInterfaceItemIdentifier("songTitleCell")
static let albumViewItem = NSUserInterfaceItemIdentifier("AlbumViewItem")
static let artistViewItem = NSUserInterfaceItemIdentifier("ArtistViewItem")
static let discNumber = NSUserInterfaceItemIdentifier("discNumberCell")
static let trackNumber = NSUserInterfaceItemIdentifier("trackNumberCell")
static let songTitle = NSUserInterfaceItemIdentifier("songTitleCell")
static let songDuration = NSUserInterfaceItemIdentifier("songDurationCell")
static let artistListName = NSUserInterfaceItemIdentifier("artistCell")
}

View File

@ -0,0 +1,29 @@
//
// Notification.swift
// Persephone
//
// Created by Daniel Barber on 2019/2/08.
// Copyright © 2019 Dan Barber. All rights reserved.
//
import Foundation
extension Notification {
static let didConnect = Name("MPDClientDidConnect")
static let willDisconnect = Name("MPDClientWillDisconnect")
static let stateChanged = Name("MPDClientStateChanged")
static let timeChanged = Name("MPDClientTimeChanged")
static let databaseUpdateStarted = Name("MPDClientDatabaseUpdateStarted")
static let databaseUpdateFinished = Name("MPDClientDatabaseUpdateFinished")
static let queueChanged = Name("MPDClientQueueChanged")
static let queuePosChanged = Name("MPDClientQueuePosChanged")
static let loadedAlbums = Name("MPDClientLoadedAlbums")
static let stateKey = "state"
static let queueKey = "queue"
static let queuePosKey = "song"
static let albumsKey = "albums"
static let totalTimeKey = "totalTime"
static let elapsedTimeMsKey = "elapsedTimeMs"
}

View File

@ -8,21 +8,21 @@
import AppKit
class FlexibleGridViewLayout: NSCollectionViewFlowLayout {
let maxItemWidth: CGFloat = 200
var extraHeight: CGFloat = 0
class AlbumViewLayout: NSCollectionViewFlowLayout {
let maxItemWidth: CGFloat = 180
let albumInfoHeight: CGFloat = 39
var scrollPosition: CGFloat = 0
required init?(coder aDecoder: NSCoder) {
super.init()
minimumLineSpacing = 0
minimumInteritemSpacing = 0
minimumLineSpacing = 20
minimumInteritemSpacing = 20
sectionInset = NSEdgeInsets(
top: 10,
left: 30,
bottom: 50,
right: 30
top: 20,
left: 40,
bottom: 60,
right: 40
)
}
@ -43,7 +43,7 @@ class FlexibleGridViewLayout: NSCollectionViewFlowLayout {
divider = divider + 1
} while itemWidth > maxItemWidth
let itemHeight = itemWidth + extraHeight
let itemHeight = itemWidth + albumInfoHeight
itemSize = NSSize(width: itemWidth, height: itemHeight)
}

View File

@ -101,7 +101,16 @@ extension MPDClient {
func albumSongs(for album: MPDAlbum, callback: ([MPDSong]) -> Void) {
guard isConnected else { return }
let songs = searchSongs([MPDTag.album: album.title, MPDTag.artist: album.artist])
var songs: [MPDSong] = []
mpd_search_db_songs(self.connection, true)
mpd_search_add_tag_constraint(self.connection, MPD_OPERATOR_DEFAULT, MPD_TAG_ALBUM, album.title)
mpd_search_add_tag_constraint(self.connection, MPD_OPERATOR_DEFAULT, MPD_TAG_ALBUM_ARTIST, album.artist)
mpd_search_commit(self.connection)
while let song = mpd_recv_song(self.connection) {
songs.append(MPDSong(song))
}
callback(songs)
}

View File

@ -1,38 +0,0 @@
//
// MPDClient+Artist.swift
// Persephone
//
// Created by Daniel Barber on 2019/9/29.
// Copyright © 2019 Dan Barber. All rights reserved.
//
import Foundation
import mpdclient
extension MPDClient {
func fetchAllArtists() {
enqueueCommand(command: .fetchAllArtists)
}
func allArtists() {
var artists: [String] = []
mpd_search_db_tags(self.connection, MPD_TAG_ALBUM_ARTIST)
mpd_search_commit(self.connection)
while let pair = mpd_recv_pair(self.connection) {
let pair = MPDPair(pair)
switch pair.name {
case "AlbumArtist":
artists.append(pair.value)
default:
break
}
mpd_return_pair(self.connection, pair.pair)
}
self.delegate?.didLoadArtists(mpdClient: self, artists: artists)
}
}

View File

@ -81,16 +81,6 @@ extension MPDClient {
else { return }
sendAddSongToQueue(uri: songUri, at: queuePos)
case .addAlbumToQueue:
guard let album = userData["album"] as? MPDAlbum,
let queuePos = userData["queuePos"] as? Int
else { return }
sendAddAlbumToQueue(album: album, at: queuePos)
// Artist commands
case .fetchAllArtists:
allArtists()
// Album commands
case .fetchAllAlbums:
allAlbums()
@ -111,7 +101,6 @@ extension MPDClient {
albumSongs(for: album, callback: callback)
}
}
func enqueueCommand(

View File

@ -10,8 +10,8 @@ import Foundation
import mpdclient
extension MPDClient {
func makeConnectionOperation(host: String, port: Int) -> BlockOperation {
BlockOperation { [unowned self] in
func connect(host: String, port: Int) {
commandQueue.addOperation { [unowned self] in
guard let connection = mpd_connection_new(host, UInt32(port), 10000),
mpd_connection_get_error(connection) == MPD_ERROR_SUCCESS
else { return }
@ -24,17 +24,17 @@ extension MPDClient {
self.connection = connection
self.status = MPDStatus(status)
self.fetchQueue()
self.fetchAllAlbums()
self.idle()
self.delegate?.didConnect(mpdClient: self)
self.delegate?.didUpdateStatus(mpdClient: self, status: self.status!)
self.idle()
self.delegate?.didUpdateQueue(mpdClient: self, queue: self.queue)
self.delegate?.didUpdateQueuePos(mpdClient: self, song: self.status!.song)
}
}
func connect() {
commandQueue.addOperation(connectionOperation)
}
func disconnect() {
guard isConnected else { return }

View File

@ -11,7 +11,7 @@ import mpdclient
extension MPDClient {
func fetchQueue() {
enqueueCommand(command: .fetchQueue)
sendCommand(command: .fetchQueue)
}
func clearQueue() {
@ -38,10 +38,6 @@ extension MPDClient {
enqueueCommand(command: .addSongToQueue, userData: ["uri": songUri, "queuePos": queuePos])
}
func addAlbumToQueue(album: MPDAlbum, at queuePos: Int) {
enqueueCommand(command: .addAlbumToQueue, userData: ["album": album, "queuePos": queuePos])
}
func sendPlayTrack(at queuePos: Int) {
mpd_run_play_pos(self.connection, UInt32(queuePos))
}
@ -54,8 +50,6 @@ extension MPDClient {
let song = MPDSong(mpdSong)
self.queue.append(song)
}
self.delegate?.didUpdateQueue(mpdClient: self, queue: self.queue)
}
func sendClearQueue() {
@ -86,16 +80,4 @@ extension MPDClient {
func sendAddSongToQueue(uri: String, at queuePos: Int) {
mpd_run_add_id_to(self.connection, uri, UInt32(queuePos))
}
func sendAddAlbumToQueue(album: MPDAlbum, at queuePos: Int) {
let songs = searchSongs([MPDTag.album: album.title, MPDTag.artist: album.artist])
var insertPos = UInt32(queuePos)
for song in songs {
mpd_run_add_id_to(self.connection, song.uri, insertPos)
insertPos += 1
}
}
}

View File

@ -1,28 +0,0 @@
//
// MPDClient+Songs.swift
// Persephone
//
// Created by Daniel Barber on 2019/7/19.
// Copyright © 2019 Dan Barber. All rights reserved.
//
import Foundation
import mpdclient
extension MPDClient {
func searchSongs(_ terms: [MPDClient.MPDTag: String]) -> [MPDSong] {
var songs: [MPDSong] = []
mpd_search_db_songs(self.connection, true)
for (tag, term) in terms {
mpd_search_add_tag_constraint(self.connection, MPD_OPERATOR_DEFAULT, tag.mpdTag(), term)
}
mpd_search_commit(self.connection)
while let song = mpd_recv_song(self.connection) {
songs.append(MPDSong(song))
}
return songs
}
}

View File

@ -10,8 +10,6 @@ import Foundation
import mpdclient
class MPDClient {
var connectionOperation: BlockOperation!
var delegate: MPDClientDelegate?
var connection: OpaquePointer?
@ -22,9 +20,8 @@ class MPDClient {
let commandQueue = OperationQueue()
init(host: String, port: Int, withDelegate delegate: MPDClientDelegate?) {
init(withDelegate delegate: MPDClientDelegate?) {
commandQueue.maxConcurrentOperationCount = 1
self.delegate = delegate
self.connectionOperation = makeConnectionOperation(host: host, port: port)
}
}

View File

@ -35,10 +35,6 @@ extension MPDClient {
case removeSong
case moveSongInQueue
case addSongToQueue
case addAlbumToQueue
// Artist commands
case fetchAllArtists
// Album commands
case fetchAllAlbums

View File

@ -12,6 +12,26 @@ import mpdclient
extension MPDClient {
class MPDSong {
let song: OpaquePointer
enum TagType: Int {
case unknown = -1
case artist, album, albumArtist, title, track, name,
genre, date, composer, performer, comment, disc
case musicBrainzArtistId
case musicBrainzAlbumId
case musicBrainzAlbumArtistId
case musicBrainzTrackId
case musicBrainzReleaseTrackId
case originalDate
case artistSort
case albumArtistSort
case albumSort
case tagCount
}
init(_ song: OpaquePointer) {
self.song = song
@ -48,12 +68,10 @@ extension MPDClient {
}
}
var date: String {
return getTag(.date)
}
func getTag(_ tagType: TagType) -> String {
let mpdTagType = mpd_tag_type(rawValue: Int32(tagType.rawValue))
func getTag(_ tagType: MPDTag) -> String {
guard let tag = mpd_song_get_tag(song, tagType.mpdTag(), 0)
guard let tag = mpd_song_get_tag(song, mpdTagType, 0)
else { return "" }
return String(cString: tag)

View File

@ -1,36 +0,0 @@
//
// MPDTag.swift
// Persephone
//
// Created by Daniel Barber on 2019/7/19.
// Copyright © 2019 Dan Barber. All rights reserved.
//
import Foundation
import mpdclient
extension MPDClient {
enum MPDTag: Int {
case unknown = -1
case artist, album, albumArtist, title, track, name,
genre, date, composer, performer, comment, disc
case musicBrainzArtistId
case musicBrainzAlbumId
case musicBrainzAlbumArtistId
case musicBrainzTrackId
case musicBrainzReleaseTrackId
case originalDate
case artistSort
case albumArtistSort
case albumSort
case tagCount
func mpdTag() -> mpd_tag_type {
return mpd_tag_type(rawValue: Int32(self.rawValue))
}
}
}

View File

@ -21,6 +21,4 @@ protocol MPDClientDelegate {
func didUpdateQueuePos(mpdClient: MPDClient, song: Int)
func didLoadAlbums(mpdClient: MPDClient, albums: [MPDClient.MPDAlbum])
func didLoadArtists(mpdClient: MPDClient, artists: [String])
}

View File

@ -12,7 +12,6 @@ import CryptoSwift
struct Album {
var mpdAlbum: MPDClient.MPDAlbum
var coverArt: Loading<NSImage?> = .notLoaded
var metadata: Metadata?
init(mpdAlbum: MPDClient.MPDAlbum) {
self.mpdAlbum = mpdAlbum

View File

@ -1,24 +0,0 @@
//
// Artist.swift
// Persephone
//
// Created by Daniel Barber on 2019/10/04.
// Copyright © 2019 Dan Barber. All rights reserved.
//
import AppKit
struct Artist {
var name: String
var image: Loading<NSImage?> = .notLoaded
init(name: String) {
self.name = name
}
}
extension Artist: Equatable {
static func == (lhs: Artist, rhs: Artist) -> Bool {
return (lhs.name == rhs.name)
}
}

View File

@ -1,19 +0,0 @@
//
// DraggedAlbum.swift
// Persephone
//
// Created by Daniel Barber on 2019/6/28.
// Copyright © 2019 Dan Barber. All rights reserved.
//
import AppKit
import CryptoSwift
struct DraggedAlbum: Codable {
var title: String
var artist: String
var hash: String {
return "\(title) - \(artist)".sha1()
}
}

View File

@ -1,13 +0,0 @@
//
// Metadata.swift
// Persephone
//
// Created by Daniel Barber on 2019/10/11.
// Copyright © 2019 Dan Barber. All rights reserved.
//
import Foundation
struct Metadata {
var date: String?
}

View File

@ -18,6 +18,7 @@ class GeneralPrefsViewController: NSViewController {
}
if let mpdPort = App.store.state.preferencesState.mpdServer.port {
print(mpdPort)
mpdPortField.stringValue = "\(mpdPort)"
}

View File

@ -1,15 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14868" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14868"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14490.70"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="AlbumDetailView" customModule="Persephone" customModuleProvider="target">
<connections>
<outlet property="albumArtist" destination="4Jx-I5-Nkv" id="mct-x3-yYC"/>
<outlet property="albumCoverView" destination="FWd-vZ-5CT" id="aHh-Bz-XQW"/>
<outlet property="albumMetadata" destination="ztJ-4E-qvI" id="YGK-TG-RPt"/>
<outlet property="albumTitle" destination="m2v-pR-e9v" id="M5i-u6-Nev"/>
<outlet property="albumTracksView" destination="ehr-qh-87Q" id="fSa-Di-CqI"/>
<outlet property="view" destination="Hz6-mo-xeY" id="0bl-1N-x8E"/>
@ -17,12 +17,12 @@
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<customView wantsLayer="YES" id="Hz6-mo-xeY">
<customView id="Hz6-mo-xeY">
<rect key="frame" x="0.0" y="0.0" width="823" height="568"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<subviews>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="m2v-pR-e9v">
<rect key="frame" x="357" y="515" width="448" height="28"/>
<rect key="frame" x="357" y="514" width="448" height="29"/>
<constraints>
<constraint firstAttribute="width" constant="444" id="erC-QS-9hc"/>
</constraints>
@ -33,8 +33,8 @@
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="4Jx-I5-Nkv">
<rect key="frame" x="357" y="488" width="448" height="19"/>
<textFieldCell key="cell" title="Metadata" id="ztJ-4E-qvI">
<rect key="frame" x="357" y="487" width="448" height="19"/>
<textFieldCell key="cell" title="Artist Name" id="ztJ-4E-qvI">
<font key="font" metaFont="system" size="16"/>
<color key="textColor" name="secondaryLabelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
@ -47,20 +47,30 @@
<constraint firstAttribute="width" constant="300" id="8XY-bQ-C7X"/>
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="300" id="cyo-wr-hV8"/>
</constraints>
<shadow key="shadow" blurRadius="4">
<size key="offset" width="0.0" height="-2"/>
<color key="color" white="0.0" alpha="0.34795884683098594" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</shadow>
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyUpOrDown" image="defaultCoverArt" id="scE-kj-gex"/>
</imageView>
<button verticalHuggingPriority="750" imageHugsTitle="YES" translatesAutoresizingMaskIntoConstraints="NO" id="jMU-bv-TNF">
<rect key="frame" x="31" y="184" width="119" height="35"/>
<constraints>
<constraint firstAttribute="height" constant="33" id="2uQ-mC-4QY"/>
<constraint firstAttribute="width" constant="119" id="h2n-ZB-Ufr"/>
</constraints>
<buttonCell key="cell" type="smallSquare" title="Play Album" bezelStyle="smallSquare" image="playButton" imagePosition="left" alignment="center" lineBreakMode="truncatingTail" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="Rtg-Zd-JYc">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="playAlbum:" target="-2" id="LTw-Lg-yH2"/>
</connections>
</button>
<scrollView horizontalCompressionResistancePriority="250" borderType="none" autohidesScrollers="YES" horizontalLineScroll="19" horizontalPageScroll="10" verticalLineScroll="19" verticalPageScroll="10" hasHorizontalScroller="NO" horizontalScrollElasticity="none" translatesAutoresizingMaskIntoConstraints="NO" id="BOb-Lr-10M">
<rect key="frame" x="359" y="33" width="444" height="426"/>
<rect key="frame" x="359" y="33" width="444" height="425"/>
<clipView key="contentView" drawsBackground="NO" copiesOnScroll="NO" id="9QN-UB-b4l">
<rect key="frame" x="0.0" y="0.0" width="444" height="426"/>
<rect key="frame" x="0.0" y="0.0" width="444" height="425"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<tableView verticalHuggingPriority="750" allowsExpansionToolTips="YES" columnAutoresizingStyle="none" columnSelection="YES" multipleSelection="NO" autosaveColumns="NO" rowSizeStyle="automatic" viewBased="YES" id="ehr-qh-87Q" customClass="AlbumDetailSongListView" customModule="Persephone" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="444" height="426"/>
<rect key="frame" x="0.0" y="0.0" width="444" height="425"/>
<autoresizingMask key="autoresizingMask"/>
<size key="intercellSpacing" width="3" height="2"/>
<color key="backgroundColor" red="0.11764705882352941" green="0.11764705882352941" blue="0.11764705882352941" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
@ -84,7 +94,7 @@
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="6eU-Jx-HDR">
<rect key="frame" x="0.0" y="1" width="40" height="16"/>
<rect key="frame" x="0.0" y="0.0" width="40" height="17"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" alignment="left" title="1." id="Z5y-oS-Qm8">
<font key="font" metaFont="system"/>
<color key="textColor" name="secondaryLabelColor" catalog="System" colorSpace="catalog"/>
@ -106,7 +116,7 @@
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="nwx-zY-r5o">
<rect key="frame" x="0.0" y="1" width="441" height="16"/>
<rect key="frame" x="0.0" y="0.0" width="441" height="17"/>
<constraints>
<constraint firstAttribute="width" constant="437" id="irN-AG-Pcj"/>
</constraints>
@ -145,7 +155,7 @@
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="R8t-bV-9LI">
<rect key="frame" x="0.0" y="1" width="353" height="16"/>
<rect key="frame" x="0.0" y="0.0" width="353" height="17"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" alignment="left" title="My Song Title" id="Sdi-jJ-EOM">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
@ -182,7 +192,7 @@
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="pCr-f1-wNs">
<rect key="frame" x="0.0" y="1" width="42" height="16"/>
<rect key="frame" x="0.0" y="0.0" width="42" height="17"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" alignment="right" title="0:00" id="Qe2-WO-eXr">
<font key="font" metaFont="system"/>
<color key="textColor" name="secondaryLabelColor" catalog="System" colorSpace="catalog"/>
@ -219,36 +229,22 @@
<autoresizingMask key="autoresizingMask"/>
</scroller>
</scrollView>
<button verticalHuggingPriority="750" imageHugsTitle="YES" translatesAutoresizingMaskIntoConstraints="NO" id="jMU-bv-TNF">
<rect key="frame" x="31" y="184" width="119" height="35"/>
<constraints>
<constraint firstAttribute="height" constant="33" id="2uQ-mC-4QY"/>
<constraint firstAttribute="width" constant="119" id="h2n-ZB-Ufr"/>
</constraints>
<buttonCell key="cell" type="smallSquare" title="Play Album" bezelStyle="smallSquare" image="playButton" imagePosition="left" alignment="center" lineBreakMode="truncatingTail" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="Rtg-Zd-JYc">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="systemMedium" size="13"/>
</buttonCell>
<connections>
<action selector="playAlbum:" target="-2" id="LTw-Lg-yH2"/>
</connections>
</button>
</subviews>
<constraints>
<constraint firstItem="BOb-Lr-10M" firstAttribute="top" secondItem="4Jx-I5-Nkv" secondAttribute="bottom" constant="29" id="1ty-6R-dGL"/>
<constraint firstItem="FWd-vZ-5CT" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" constant="31" id="694-aS-G4N"/>
<constraint firstItem="jMU-bv-TNF" firstAttribute="leading" secondItem="FWd-vZ-5CT" secondAttribute="leading" id="AwZ-M4-fep"/>
<constraint firstItem="BOb-Lr-10M" firstAttribute="leading" secondItem="4Jx-I5-Nkv" secondAttribute="leading" id="GEK-R3-Sw6"/>
<constraint firstItem="BOb-Lr-10M" firstAttribute="top" secondItem="4Jx-I5-Nkv" secondAttribute="bottom" constant="29" id="K5g-Kd-iHK"/>
<constraint firstAttribute="bottom" secondItem="BOb-Lr-10M" secondAttribute="bottom" constant="33" id="MZ6-81-2qe"/>
<constraint firstItem="4Jx-I5-Nkv" firstAttribute="leading" secondItem="m2v-pR-e9v" secondAttribute="leading" id="NaJ-VT-uln"/>
<constraint firstAttribute="bottom" secondItem="BOb-Lr-10M" secondAttribute="bottom" constant="33" id="Q1M-yZ-LHD"/>
<constraint firstItem="FWd-vZ-5CT" firstAttribute="top" secondItem="Hz6-mo-xeY" secondAttribute="top" constant="25" id="QA9-xn-fzY"/>
<constraint firstItem="m2v-pR-e9v" firstAttribute="top" secondItem="FWd-vZ-5CT" secondAttribute="top" id="bqi-HD-KZW"/>
<constraint firstItem="jMU-bv-TNF" firstAttribute="top" secondItem="FWd-vZ-5CT" secondAttribute="bottom" constant="25" id="dd1-6b-TEN"/>
<constraint firstItem="4Jx-I5-Nkv" firstAttribute="trailing" secondItem="m2v-pR-e9v" secondAttribute="trailing" id="dmh-TC-Ncr"/>
<constraint firstItem="m2v-pR-e9v" firstAttribute="leading" secondItem="FWd-vZ-5CT" secondAttribute="trailing" constant="28" id="icS-vq-PkK"/>
<constraint firstItem="4Jx-I5-Nkv" firstAttribute="top" secondItem="m2v-pR-e9v" secondAttribute="bottom" constant="8" symbolic="YES" id="nTZ-Ew-sDQ"/>
<constraint firstItem="BOb-Lr-10M" firstAttribute="leading" secondItem="4Jx-I5-Nkv" secondAttribute="leading" id="pXJ-Jl-uAG"/>
<constraint firstAttribute="trailing" secondItem="m2v-pR-e9v" secondAttribute="trailing" constant="20" symbolic="YES" id="qyi-X9-6B9"/>
<constraint firstItem="BOb-Lr-10M" firstAttribute="trailing" secondItem="4Jx-I5-Nkv" secondAttribute="trailing" id="zOM-i7-cog"/>
<constraint firstItem="BOb-Lr-10M" firstAttribute="trailing" secondItem="4Jx-I5-Nkv" secondAttribute="trailing" id="sPx-cY-MeX"/>
</constraints>
<point key="canvasLocation" x="262.5" y="121"/>
</customView>

View File

@ -0,0 +1,81 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14490.70"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="AlbumViewItem" customModule="Persephone" customModuleProvider="target">
<connections>
<outlet property="albumArtist" destination="5Uu-j1-qyT" id="2Et-tX-InT"/>
<outlet property="albumCoverView" destination="Kfb-8f-ean" id="CXx-gB-gz8"/>
<outlet property="albumTitle" destination="KEh-NL-c2W" id="SI3-hm-H2B"/>
<outlet property="imageView" destination="Kfb-8f-ean" id="Ur0-hX-wJm"/>
<outlet property="view" destination="Hz6-mo-xeY" id="v7W-XA-Emc"/>
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<customView id="Hz6-mo-xeY" customClass="AlbumItemView" customModule="Persephone" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="128" height="167"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<subviews>
<textField identifier="albumTitle" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="KEh-NL-c2W">
<rect key="frame" x="-2" y="18" width="132" height="17"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" title="Label" id="pDs-0t-e1j">
<font key="font" metaFont="system"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<textField identifier="albumArtist" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="5Uu-j1-qyT">
<rect key="frame" x="-2" y="0.0" width="132" height="17"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" title="Label" id="yZn-e9-zyP">
<font key="font" metaFont="system"/>
<color key="textColor" name="secondaryLabelColor" catalog="System" colorSpace="catalog"/>
<color key="backgroundColor" name="textBackgroundColor" catalog="System" colorSpace="catalog"/>
</textFieldCell>
</textField>
<imageView identifier="albumArtwork" horizontalHuggingPriority="750" verticalHuggingPriority="750" placeholderIntrinsicWidth="128" placeholderIntrinsicHeight="128" translatesAutoresizingMaskIntoConstraints="NO" id="Kfb-8f-ean">
<rect key="frame" x="0.0" y="39" width="128" height="128"/>
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyUpOrDown" image="defaultCoverArt" id="FsA-JX-BFh"/>
</imageView>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="x5e-56-uVO" userLabel="Album Detail Button">
<rect key="frame" x="0.0" y="39" width="128" height="128"/>
<buttonCell key="cell" type="square" bezelStyle="shadowlessSquare" alignment="center" lineBreakMode="truncatingTail" state="on" imageScaling="proportionallyDown" inset="2" id="MTh-fn-aCH">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
<font key="font" metaFont="system"/>
</buttonCell>
<connections>
<action selector="showAlbumDetail:" target="-2" id="nO1-4H-LHS"/>
</connections>
</button>
</subviews>
<constraints>
<constraint firstItem="x5e-56-uVO" firstAttribute="leading" secondItem="Kfb-8f-ean" secondAttribute="leading" id="1Hi-Uk-rkL"/>
<constraint firstItem="5Uu-j1-qyT" firstAttribute="trailing" secondItem="KEh-NL-c2W" secondAttribute="trailing" id="64z-uz-4nY"/>
<constraint firstAttribute="bottom" secondItem="KEh-NL-c2W" secondAttribute="bottom" constant="18" id="8Kg-1r-wNp"/>
<constraint firstItem="x5e-56-uVO" firstAttribute="trailing" secondItem="Kfb-8f-ean" secondAttribute="trailing" id="BYd-Fg-DVb"/>
<constraint firstItem="Kfb-8f-ean" firstAttribute="leading" secondItem="Hz6-mo-xeY" secondAttribute="leading" id="JMi-4i-dgs"/>
<constraint firstAttribute="trailing" secondItem="Kfb-8f-ean" secondAttribute="trailing" id="KQC-Wz-Bsg"/>
<constraint firstItem="5Uu-j1-qyT" firstAttribute="leading" secondItem="KEh-NL-c2W" secondAttribute="leading" id="MUo-0i-fX9"/>
<constraint firstItem="Kfb-8f-ean" firstAttribute="top" secondItem="Hz6-mo-xeY" secondAttribute="top" id="Qbk-jx-zAi"/>
<constraint firstItem="KEh-NL-c2W" firstAttribute="trailing" secondItem="Kfb-8f-ean" secondAttribute="trailing" id="U0w-G4-ggX"/>
<constraint firstItem="KEh-NL-c2W" firstAttribute="leading" secondItem="Kfb-8f-ean" secondAttribute="leading" id="V8r-Rc-Dx7"/>
<constraint firstAttribute="bottom" secondItem="5Uu-j1-qyT" secondAttribute="bottom" id="gci-4h-pDZ"/>
<constraint firstItem="x5e-56-uVO" firstAttribute="top" secondItem="Kfb-8f-ean" secondAttribute="top" id="hw2-ik-6VW"/>
<constraint firstItem="x5e-56-uVO" firstAttribute="bottom" secondItem="Kfb-8f-ean" secondAttribute="bottom" id="iVQ-Vn-dSV"/>
<constraint firstAttribute="bottom" secondItem="Kfb-8f-ean" secondAttribute="bottom" constant="39" id="sid-zJ-YMA"/>
</constraints>
<connections>
<outlet property="imageView" destination="Kfb-8f-ean" id="T7Z-En-dU3"/>
</connections>
<point key="canvasLocation" x="-22" y="125.5"/>
</customView>
<collectionViewItem id="Qgu-aI-55A" customClass="AlbumViewItem" customModule="Persephone" customModuleProvider="target"/>
</objects>
<resources>
<image name="defaultCoverArt" width="128" height="128"/>
</resources>
</document>

View File

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="14868" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" initialViewController="B8D-0N-5wS">
<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" initialViewController="B8D-0N-5wS">
<dependencies>
<deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14868"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14490.70"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
@ -187,7 +187,7 @@
<customObject id="YLy-65-1bz" customClass="NSFontManager"/>
<customObject id="Ady-hI-5gd" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="-183" y="-242"/>
<point key="canvasLocation" x="81" y="-332"/>
</scene>
<!--Window Controller-->
<scene sceneID="R2V-B0-nI4">
@ -341,7 +341,7 @@
<splitViewController id="fnD-7K-pHK" customClass="MainSplitViewController" customModule="Persephone" customModuleProvider="target" sceneMemberID="viewController">
<splitViewItems>
<splitViewItem holdingPriority="255" behavior="contentList" id="CWo-v7-gd2"/>
<splitViewItem id="Mdr-U0-Vci"/>
<splitViewItem id="y8g-4F-czS"/>
</splitViewItems>
<splitView key="splitView" dividerStyle="thin" vertical="YES" id="g34-ef-XN0">
<rect key="frame" x="0.0" y="0.0" width="450" height="300"/>
@ -353,12 +353,12 @@
<connections>
<outlet property="splitView" destination="g34-ef-XN0" id="YEc-LL-DoS"/>
<segue destination="KIP-rq-4dM" kind="relationship" relationship="splitItems" id="Vmb-hY-d12"/>
<segue destination="SjO-VS-1bb" kind="relationship" relationship="splitItems" id="peC-gL-WJ1"/>
<segue destination="gPn-fP-LFc" kind="relationship" relationship="splitItems" id="zKs-UD-ltC"/>
</connections>
</splitViewController>
<customObject id="Dag-kO-ps3" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="886" y="182"/>
<point key="canvasLocation" x="74" y="873"/>
</scene>
<!--Window Controller-->
<scene sceneID="Rpk-bo-5kf">
@ -378,7 +378,7 @@
</windowController>
<customObject id="0sd-8B-etN" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="346" y="-242"/>
<point key="canvasLocation" x="915" y="-155"/>
</scene>
<!--General-->
<scene sceneID="5er-B6-hoB">
@ -405,7 +405,7 @@
</tabViewController>
<customObject id="XtF-QO-9W0" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="870" y="-242"/>
<point key="canvasLocation" x="916" y="236"/>
</scene>
<!--Cover Art-->
<scene sceneID="pQx-0G-WVt">
@ -416,7 +416,7 @@
<autoresizingMask key="autoresizingMask"/>
<subviews>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="zZn-Rm-e1f">
<rect key="frame" x="53" y="129" width="104" height="16"/>
<rect key="frame" x="53" y="130" width="104" height="17"/>
<textFieldCell key="cell" lineBreakMode="clipping" title="Music Directory:" id="sPn-V6-CfK">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
@ -424,7 +424,7 @@
</textFieldCell>
</textField>
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="gDk-ca-eOa">
<rect key="frame" x="162" y="125" width="288" height="21"/>
<rect key="frame" x="162" y="126" width="288" height="22"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" placeholderString="~/Music" drawsBackground="YES" id="7WZ-b7-GUs">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
@ -435,7 +435,7 @@
</connections>
</textField>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="pRL-MG-1Be">
<rect key="frame" x="160" y="94" width="264" height="18"/>
<rect key="frame" x="160" y="95" width="264" height="18"/>
<buttonCell key="cell" type="check" title="Fetch missing artwork from MusicBrainz" bezelStyle="regularSquare" imagePosition="left" inset="2" id="LpD-Ew-HMd">
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
<font key="font" metaFont="system"/>
@ -445,7 +445,7 @@
</connections>
</button>
<button verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="z1g-nP-ksw">
<rect key="frame" x="160" y="63" width="264" height="18"/>
<rect key="frame" x="160" y="64" width="264" height="18"/>
<constraints>
<constraint firstAttribute="width" constant="260" id="gK0-aW-CJy"/>
</constraints>
@ -455,7 +455,7 @@
</buttonCell>
</button>
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="xgS-Kg-8KR">
<rect key="frame" x="162" y="26" width="144" height="21"/>
<rect key="frame" x="162" y="26" width="144" height="22"/>
<constraints>
<constraint firstAttribute="width" constant="144" id="DSX-th-Wn1"/>
</constraints>
@ -466,7 +466,7 @@
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="SmH-w6-5QI">
<rect key="frame" x="37" y="30" width="119" height="16"/>
<rect key="frame" x="37" y="30" width="119" height="17"/>
<textFieldCell key="cell" lineBreakMode="clipping" enabled="NO" alignment="right" title="Cover art filename:" id="b4u-u7-iWD">
<font key="font" metaFont="system"/>
<color key="textColor" name="secondaryLabelColor" catalog="System" colorSpace="catalog"/>
@ -498,57 +498,7 @@
</viewController>
<customObject id="KzD-E3-lpA" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="1459" y="-242"/>
</scene>
<!--View Controller-->
<scene sceneID="VvW-vT-alQ">
<objects>
<customObject id="MSG-y7-cKU" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
<viewController id="SjO-VS-1bb" sceneMemberID="viewController">
<view key="view" id="BRY-0R-F3u">
<rect key="frame" x="0.0" y="0.0" width="478" height="558"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<tabView type="noTabsNoBorder" initialItem="XgS-cX-SDH" translatesAutoresizingMaskIntoConstraints="NO" id="ARv-cj-xlz">
<rect key="frame" x="0.0" y="0.0" width="478" height="558"/>
<font key="font" metaFont="system"/>
<tabViewItems>
<tabViewItem label="Albums" identifier="" id="XgS-cX-SDH">
<view key="view" id="hB7-hN-SbB">
<rect key="frame" x="0.0" y="0.0" width="478" height="558"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<containerView translatesAutoresizingMaskIntoConstraints="NO" id="moE-bb-Zvg">
<rect key="frame" x="-3" y="-3" width="481" height="561"/>
<connections>
<segue destination="gPn-fP-LFc" kind="embed" id="2iB-9y-I9h"/>
</connections>
</containerView>
</subviews>
<constraints>
<constraint firstItem="moE-bb-Zvg" firstAttribute="top" secondItem="hB7-hN-SbB" secondAttribute="top" id="DUI-jy-8D7"/>
<constraint firstItem="moE-bb-Zvg" firstAttribute="leading" secondItem="hB7-hN-SbB" secondAttribute="leading" constant="-3" id="dCS-Kx-2UP"/>
<constraint firstAttribute="trailing" secondItem="moE-bb-Zvg" secondAttribute="trailing" id="qey-4e-xfu"/>
<constraint firstAttribute="bottom" secondItem="moE-bb-Zvg" secondAttribute="bottom" constant="-3" id="ziA-Xh-dlz"/>
</constraints>
</view>
</tabViewItem>
</tabViewItems>
</tabView>
</subviews>
<constraints>
<constraint firstAttribute="trailing" secondItem="ARv-cj-xlz" secondAttribute="trailing" id="nXk-bi-ua4"/>
<constraint firstAttribute="bottom" secondItem="ARv-cj-xlz" secondAttribute="bottom" id="nzf-Jw-Bpk"/>
<constraint firstItem="ARv-cj-xlz" firstAttribute="top" secondItem="BRY-0R-F3u" secondAttribute="top" id="v6W-0L-kQ1"/>
<constraint firstItem="ARv-cj-xlz" firstAttribute="leading" secondItem="BRY-0R-F3u" secondAttribute="leading" id="w2Z-xv-Fwz"/>
</constraints>
</view>
<connections>
<outlet property="browseTabView" destination="ARv-cj-xlz" id="h93-fi-yY7"/>
</connections>
</viewController>
</objects>
<point key="canvasLocation" x="1436" y="238"/>
<point key="canvasLocation" x="1626" y="373"/>
</scene>
<!--General-->
<scene sceneID="xTC-Y5-Agk">
@ -559,7 +509,7 @@
<autoresizingMask key="autoresizingMask"/>
<subviews>
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="wPm-sJ-e9E">
<rect key="frame" x="162" y="57" width="184" height="21"/>
<rect key="frame" x="162" y="58" width="184" height="22"/>
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" selectable="YES" editable="YES" sendsActionOnEndEditing="YES" borderStyle="bezel" alignment="left" placeholderString="127.0.0.1" drawsBackground="YES" id="MSX-mn-2ma">
<font key="font" usesAppearanceFont="YES"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
@ -570,7 +520,7 @@
</connections>
</textField>
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="IbX-oV-soD">
<rect key="frame" x="162" y="26" width="80" height="21"/>
<rect key="frame" x="162" y="26" width="80" height="22"/>
<constraints>
<constraint firstAttribute="width" constant="80" id="vW2-G6-2vi"/>
</constraints>
@ -588,7 +538,7 @@
</connections>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="kvB-99-zwY">
<rect key="frame" x="76" y="61" width="80" height="16"/>
<rect key="frame" x="76" y="62" width="80" height="17"/>
<textFieldCell key="cell" lineBreakMode="clipping" alignment="right" title="Server Host:" id="AVi-g9-Irz">
<font key="font" metaFont="system"/>
<color key="textColor" name="labelColor" catalog="System" colorSpace="catalog"/>
@ -596,7 +546,7 @@
</textFieldCell>
</textField>
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="AU9-wN-kbU">
<rect key="frame" x="78" y="30" width="76" height="16"/>
<rect key="frame" x="78" y="30" width="76" height="17"/>
<constraints>
<constraint firstAttribute="width" constant="72" id="Of6-Ls-knP"/>
</constraints>
@ -626,7 +576,7 @@
</viewController>
<customObject id="lzf-yO-5pP" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="1407" y="-501"/>
<point key="canvasLocation" x="1574" y="69"/>
</scene>
<!--Queue View Controller-->
<scene sceneID="QcX-dC-cTZ">
@ -696,7 +646,7 @@
<imageCell key="cell" refusesFirstResponder="YES" imageScaling="proportionallyDown" image="playButton" id="ckK-gW-Vhx"/>
</imageView>
<textField identifier="queuePosition" horizontalHuggingPriority="251" verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="mc4-Xr-oUl" userLabel="Queue Position View">
<rect key="frame" x="4" y="1" width="33" height="16"/>
<rect key="frame" x="4" y="0.0" width="33" height="17"/>
<textFieldCell key="cell" lineBreakMode="clipping" title="888." id="wpZ-1t-Do7">
<font key="font" metaFont="system"/>
<color key="textColor" name="tertiaryLabelColor" catalog="System" colorSpace="catalog"/>
@ -704,7 +654,7 @@
</textFieldCell>
</textField>
<textField verticalHuggingPriority="750" translatesAutoresizingMaskIntoConstraints="NO" id="i0h-bn-auJ" userLabel="Song Title View">
<rect key="frame" x="40" y="1" width="160" height="16"/>
<rect key="frame" x="40" y="0.0" width="160" height="17"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Table View Cell" id="ei8-1e-ErK">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
@ -749,7 +699,7 @@
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<textField verticalHuggingPriority="750" horizontalCompressionResistancePriority="250" translatesAutoresizingMaskIntoConstraints="NO" id="tBe-Q9-3Rw">
<rect key="frame" x="0.0" y="1" width="127" height="16"/>
<rect key="frame" x="0.0" y="0.0" width="127" height="17"/>
<textFieldCell key="cell" lineBreakMode="truncatingTail" sendsActionOnEndEditing="YES" title="Table View Cell" id="Ceb-ec-ydU">
<font key="font" metaFont="system"/>
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
@ -807,6 +757,9 @@
<constraint firstAttribute="width" secondItem="iUb-eV-Qws" secondAttribute="height" multiplier="1:1" id="f4L-V4-5x2"/>
<constraint firstItem="Dw3-M5-tWY" firstAttribute="top" secondItem="iUb-eV-Qws" secondAttribute="top" id="ue4-Gb-CaX"/>
</constraints>
<shadow key="shadow">
<color key="color" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</shadow>
</customView>
</subviews>
<holdingPriorities>
@ -837,7 +790,7 @@
</items>
</menu>
</objects>
<point key="canvasLocation" x="825" y="746"/>
<point key="canvasLocation" x="796" y="848"/>
</scene>
<!--Album View Controller-->
<scene sceneID="7Ua-Hj-zWt">
@ -853,10 +806,10 @@
<rect key="frame" x="0.0" y="0.0" width="450" height="300"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<collectionView identifier="albumCollectionView" selectable="YES" id="lfq-AB-epE">
<collectionView identifier="albumCollectionView" id="lfq-AB-epE">
<rect key="frame" x="0.0" y="0.0" width="450" height="158"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES"/>
<collectionViewLayout key="collectionViewLayout" id="YE8-sD-l5P" customClass="FlexibleGridViewLayout" customModule="Persephone" customModuleProvider="target"/>
<collectionViewLayout key="collectionViewLayout" id="YE8-sD-l5P" customClass="AlbumViewLayout" customModule="Persephone" customModuleProvider="target"/>
<color key="primaryBackgroundColor" name="controlBackgroundColor" catalog="System" colorSpace="catalog"/>
<connections>
<outlet property="delegate" destination="gPn-fP-LFc" id="LQ2-Vl-r08"/>
@ -899,7 +852,7 @@
</items>
</menu>
</objects>
<point key="canvasLocation" x="2038" y="87"/>
<point key="canvasLocation" x="329" y="1370"/>
</scene>
</scenes>
<resources>

View File

@ -16,11 +16,6 @@ struct UpdateCoverArtAction: Action {
var albumIndex: Int
}
struct UpdateAlbumMetaData: Action {
var metadata: Metadata
var albumIndex: Int
}
struct UpdateAlbumListAction: Action {
var albums: [MPDClient.MPDAlbum]
}

View File

@ -1,14 +0,0 @@
//
// ArtistListActions.swift
// Persephone
//
// Created by Daniel Barber on 2019/9/29.
// Copyright © 2019 Dan Barber. All rights reserved.
//
import AppKit
import ReSwift
struct UpdateArtistListAction: Action {
var artists: [String]
}

View File

@ -12,7 +12,6 @@ struct AppState: StateType {
var playerState = PlayerState()
var queueState = QueueState()
var albumListState = AlbumListState()
var artistListState = ArtistListState()
var preferencesState = PreferencesState()
var uiState = UIState()
}

View File

@ -1,13 +0,0 @@
//
// ArtistListState.swift
// Persephone
//
// Created by Daniel Barber on 2019/9/20.
// Copyright © 2019 Dan Barber. All rights reserved.
//
import ReSwift
struct ArtistListState: StateType, Equatable {
var artists: [Artist] = []
}

View File

@ -18,9 +18,6 @@ func albumListReducer(action: Action, state: AlbumListState?) -> AlbumListState
case let action as UpdateCoverArtAction:
state.albums[action.albumIndex].coverArt = .loaded(action.coverArt)
case let action as UpdateAlbumMetaData:
state.albums[action.albumIndex].metadata = action.metadata
case is ResetAlbumListCoverArtAction:
state.albums = state.albums.map {
var album = $0

View File

@ -13,7 +13,6 @@ func appReducer(action: Action, state: AppState?) -> AppState {
playerState: playerReducer(action: action, state: state?.playerState),
queueState: queueReducer(action: action, state: state?.queueState),
albumListState: albumListReducer(action: action, state: state?.albumListState),
artistListState: artistListReducer(action: action, state: state?.artistListState),
preferencesState: preferencesReducer(action: action, state: state?.preferencesState),
uiState: uiReducer(action: action, state: state?.uiState)
)

View File

@ -1,25 +0,0 @@
//
// ArtistReducer.swift
// Persephone
//
// Created by Daniel Barber on 2019/9/29.
// Copyright © 2019 Dan Barber. All rights reserved.
//
import ReSwift
func artistListReducer(action: Action, state: ArtistListState?) -> ArtistListState {
var state = state ?? ArtistListState()
switch action {
case let action as UpdateArtistListAction:
state.artists = action.artists.map { Artist(name: $0) }
default:
break
}
return state
}

View File

@ -31,9 +31,6 @@ func playerReducer(action: Action, state: PlayerState?) -> PlayerState {
App.store.dispatch(
UpdateQueuePlayerStateAction(state: state.state)
)
if let queuePos = state.status?.song {
App.store.dispatch(UpdateQueuePosAction(queuePos: queuePos))
}
}
case let action as UpdateCurrentSongAction:

View File

@ -0,0 +1,17 @@
//
// AlbumItemView.swift
// Persephone
//
// Created by Daniel Barber on 2019/2/17.
// Copyright © 2019 Dan Barber. All rights reserved.
//
import AppKit
class AlbumItemView: NSView {
required init?(coder decoder: NSCoder) {
super.init(coder: decoder)
}
@IBOutlet var imageView: NSImageView!
}