diff --git a/Mac/Components/Shared/Extensions/CGColor.swift b/Mac/Components/Shared/Extensions/CGColor.swift deleted file mode 100644 index 3e508c5..0000000 --- a/Mac/Components/Shared/Extensions/CGColor.swift +++ /dev/null @@ -1,14 +0,0 @@ -// -// NSColor.swift -// Persephone -// -// Created by Daniel Barber on 2019/2/16. -// Copyright © 2019 Dan Barber. All rights reserved. -// - -import AppKit - -extension CGColor { - static let albumBorderColorLight = NSColor.black.withAlphaComponent(0.15).cgColor - static let albumBorderColorDark = NSColor.white.withAlphaComponent(0.15).cgColor -} diff --git a/Persephone.xcodeproj/project.pbxproj b/Persephone.xcodeproj/project.pbxproj index 63ff64e..e0ed2df 100644 --- a/Persephone.xcodeproj/project.pbxproj +++ b/Persephone.xcodeproj/project.pbxproj @@ -19,6 +19,23 @@ E408D3C2220E134F0006D9BE /* AlbumViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E408D3C1220E134F0006D9BE /* AlbumViewController.swift */; }; E408D3CB220E341D0006D9BE /* AlbumViewItem.xib in Resources */ = {isa = PBXBuildFile; fileRef = E408D3C9220E341D0006D9BE /* AlbumViewItem.xib */; }; E40FE71B221B904300A4223F /* NSEvent.swift in Sources */ = {isa = PBXBuildFile; fileRef = E40FE71A221B904300A4223F /* NSEvent.swift */; }; + E41222112431425400473C1D /* App.swift in Sources */ = {isa = PBXBuildFile; fileRef = E41221FD2431425400473C1D /* App.swift */; }; + E41222122431425400473C1D /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = E41221FE2431425400473C1D /* AppDelegate.swift */; }; + E41222132431425400473C1D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E41221FF2431425400473C1D /* LaunchScreen.storyboard */; }; + E41222142431425400473C1D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E41222012431425400473C1D /* Main.storyboard */; }; + E41222162431425400473C1D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = E41222042431425400473C1D /* Assets.xcassets */; }; + E41222172431425400473C1D /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = E41222052431425400473C1D /* SceneDelegate.swift */; }; + E41222182431425400473C1D /* AlbumItemCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = E41222092431425400473C1D /* AlbumItemCell.swift */; }; + E41222192431425400473C1D /* AlbumViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E412220A2431425400473C1D /* AlbumViewController.swift */; }; + E412221A2431425400473C1D /* AlbumViewController+UICollectionViewDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = E412220B2431425400473C1D /* AlbumViewController+UICollectionViewDataSource.swift */; }; + E412221B2431425400473C1D /* AlbumViewController+UICollectionViewDelegateFlowLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = E412220C2431425400473C1D /* AlbumViewController+UICollectionViewDelegateFlowLayout.swift */; }; + E412221C2431431500473C1D /* Persephone_iOSTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E41221F72431425300473C1D /* Persephone_iOSTests.swift */; }; + E412221F2431432100473C1D /* Persephone_iOSUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E41221FB2431425300473C1D /* Persephone_iOSUITests.swift */; }; + E41222232431530900473C1D /* Kingfisher in Frameworks */ = {isa = PBXBuildFile; productRef = E41222222431530900473C1D /* Kingfisher */; }; + E41222242431535E00473C1D /* MPDAlbumArtImageDataProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4BB7F8E23E5E7BC00906E2F /* MPDAlbumArtImageDataProvider.swift */; }; + E4122228243153B200473C1D /* CGSize.swift in Sources */ = {isa = PBXBuildFile; fileRef = E41222272431539800473C1D /* CGSize.swift */; }; + E41222292431555100473C1D /* CGColor.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4928E0A2218D62A001D4BEA /* CGColor.swift */; }; + E412222C2431830500473C1D /* AlbumDetailViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E412222B2431830500473C1D /* AlbumDetailViewController.swift */; }; E419E2872249B96600216A8C /* Song.swift in Sources */ = {isa = PBXBuildFile; fileRef = E419E2862249B96600216A8C /* Song.swift */; }; E41B22C621FB932700D544F6 /* MPDClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = E41B22C521FB932700D544F6 /* MPDClient.swift */; }; E41E52FD223BF87300173814 /* MPDClient+Connection.swift in Sources */ = {isa = PBXBuildFile; fileRef = E41E52FC223BF87300173814 /* MPDClient+Connection.swift */; }; @@ -391,6 +408,23 @@ E411C26D241C10F0008B9682 /* Persephone.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Persephone.app; sourceTree = BUILT_PRODUCTS_DIR; }; E411C282241C10F5008B9682 /* Persephone-iOSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Persephone-iOSTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; E411C28D241C10F5008B9682 /* Persephone-iOSUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Persephone-iOSUITests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; + E41221F72431425300473C1D /* Persephone_iOSTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Persephone_iOSTests.swift; sourceTree = ""; }; + E41221F82431425300473C1D /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + E41221FA2431425300473C1D /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + E41221FB2431425300473C1D /* Persephone_iOSUITests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Persephone_iOSUITests.swift; sourceTree = ""; }; + E41221FD2431425400473C1D /* App.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = App.swift; sourceTree = ""; }; + E41221FE2431425400473C1D /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + E41222002431425400473C1D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + E41222022431425400473C1D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + E41222032431425400473C1D /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + E41222042431425400473C1D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + E41222052431425400473C1D /* SceneDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; + E41222092431425400473C1D /* AlbumItemCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AlbumItemCell.swift; sourceTree = ""; }; + E412220A2431425400473C1D /* AlbumViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AlbumViewController.swift; sourceTree = ""; }; + E412220B2431425400473C1D /* AlbumViewController+UICollectionViewDataSource.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "AlbumViewController+UICollectionViewDataSource.swift"; sourceTree = ""; }; + E412220C2431425400473C1D /* AlbumViewController+UICollectionViewDelegateFlowLayout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "AlbumViewController+UICollectionViewDelegateFlowLayout.swift"; sourceTree = ""; }; + E41222272431539800473C1D /* CGSize.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CGSize.swift; sourceTree = ""; }; + E412222B2431830500473C1D /* AlbumDetailViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlbumDetailViewController.swift; sourceTree = ""; }; E419E2862249B96600216A8C /* Song.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Song.swift; sourceTree = ""; }; E41B22C421FB715A00D544F6 /* module.modulemap */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.module-map"; path = module.modulemap; sourceTree = ""; }; E41B22C521FB932700D544F6 /* MPDClient.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPDClient.swift; sourceTree = ""; }; @@ -678,6 +712,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + E41222232431530900473C1D /* Kingfisher in Frameworks */, E480513824255CE000362CF3 /* ReSwift in Frameworks */, E480513A24255CF200362CF3 /* CryptoSwift in Frameworks */, ); @@ -705,6 +740,9 @@ children = ( E45E4FD822515D87004B537F /* Brewfile */, E42A8F3922176D6400A13ED9 /* LICENSE.md */, + E41221FC2431425300473C1D /* iOS */, + E41221F62431425300473C1D /* iOSTests */, + E41221F92431425300473C1D /* iOSUITests */, E407861A2110CE6E006887B1 /* Mac */, E407862D2110CE70006887B1 /* MacTests */, E40786382110CE70006887B1 /* MacUITests */, @@ -765,15 +803,14 @@ E408D3B7220DE8CC0006D9BE /* Extensions */ = { isa = PBXGroup; children = ( - E4928E0A2218D62A001D4BEA /* CGColor.swift */, E40FE71A221B904300A4223F /* NSEvent.swift */, E435E3E1221CD4E200184CFC /* NSFont.swift */, E435E3E3221CD75D00184CFC /* NSImage.swift */, - E408D3B8220DE98F0006D9BE /* NSUserInterfaceItemIdentifier.swift */, E489E39822B85D0400CA8CBD /* NSPasteboard.swift */, - E489E39C22B9CF0000CA8CBD /* NSView.swift */, E43AC1F022C68E6A001E483C /* NSPasteboardItem.swift */, E4DA820523D6236200C1EE58 /* NSSize.swift */, + E408D3B8220DE98F0006D9BE /* NSUserInterfaceItemIdentifier.swift */, + E489E39C22B9CF0000CA8CBD /* NSView.swift */, ); path = Extensions; sourceTree = ""; @@ -804,6 +841,7 @@ E411C268241C02B2008B9682 /* Shared */ = { isa = PBXGroup; children = ( + E4BB7F8D23E5E7A300906E2F /* ImageDataProviders */, E483CE67242FEF82001F742E /* Delegates */, E48056C22426D73300362CF3 /* libmpdclient */, E48051512425607100362CF3 /* Controllers */, @@ -820,11 +858,98 @@ E411C29D241C123C008B9682 /* Extensions */ = { isa = PBXGroup; children = ( + E4928E0A2218D62A001D4BEA /* CGColor.swift */, E408D3B5220DD8970006D9BE /* Notification.swift */, ); path = Extensions; sourceTree = ""; }; + E41221F62431425300473C1D /* iOSTests */ = { + isa = PBXGroup; + children = ( + E41221F82431425300473C1D /* Info.plist */, + E41221F72431425300473C1D /* Persephone_iOSTests.swift */, + ); + path = iOSTests; + sourceTree = ""; + }; + E41221F92431425300473C1D /* iOSUITests */ = { + isa = PBXGroup; + children = ( + E41221FA2431425300473C1D /* Info.plist */, + E41221FB2431425300473C1D /* Persephone_iOSUITests.swift */, + ); + path = iOSUITests; + sourceTree = ""; + }; + E41221FC2431425300473C1D /* iOS */ = { + isa = PBXGroup; + children = ( + E41221FD2431425400473C1D /* App.swift */, + E41221FE2431425400473C1D /* AppDelegate.swift */, + E41222042431425400473C1D /* Assets.xcassets */, + E41222062431425400473C1D /* Components */, + E41222032431425400473C1D /* Info.plist */, + E41221FF2431425400473C1D /* LaunchScreen.storyboard */, + E41222012431425400473C1D /* Main.storyboard */, + E41222052431425400473C1D /* SceneDelegate.swift */, + ); + path = iOS; + sourceTree = ""; + }; + E41222062431425400473C1D /* Components */ = { + isa = PBXGroup; + children = ( + E41222252431538700473C1D /* Shared */, + E41222072431425400473C1D /* Browser */, + ); + path = Components; + sourceTree = ""; + }; + E41222072431425400473C1D /* Browser */ = { + isa = PBXGroup; + children = ( + E412222A243182F700473C1D /* Album Detail */, + E41222082431425400473C1D /* Album Browser */, + ); + path = Browser; + sourceTree = ""; + }; + E41222082431425400473C1D /* Album Browser */ = { + isa = PBXGroup; + children = ( + E41222092431425400473C1D /* AlbumItemCell.swift */, + E412220A2431425400473C1D /* AlbumViewController.swift */, + E412220B2431425400473C1D /* AlbumViewController+UICollectionViewDataSource.swift */, + E412220C2431425400473C1D /* AlbumViewController+UICollectionViewDelegateFlowLayout.swift */, + ); + path = "Album Browser"; + sourceTree = ""; + }; + E41222252431538700473C1D /* Shared */ = { + isa = PBXGroup; + children = ( + E41222262431539000473C1D /* Extensions */, + ); + path = Shared; + sourceTree = ""; + }; + E41222262431539000473C1D /* Extensions */ = { + isa = PBXGroup; + children = ( + E41222272431539800473C1D /* CGSize.swift */, + ); + path = Extensions; + sourceTree = ""; + }; + E412222A243182F700473C1D /* Album Detail */ = { + isa = PBXGroup; + children = ( + E412222B2431830500473C1D /* AlbumDetailViewController.swift */, + ); + path = "Album Detail"; + sourceTree = ""; + }; E41B22C721FB966C00D544F6 /* include */ = { isa = PBXGroup; children = ( @@ -929,10 +1054,10 @@ E442CCC82347D65300004E0C /* Album Detail */ = { isa = PBXGroup; children = ( - E43B67A922909793007DCF55 /* AlbumDetailView.xib */, E4A3A6A022A457B600EA2C40 /* AlbumDetailSongListView.swift */, E45878372296173C00586A1C /* AlbumDetailSongRowView.swift */, E43B67A822909793007DCF55 /* AlbumDetailView.swift */, + E43B67A922909793007DCF55 /* AlbumDetailView.xib */, E4E7A6AC22AAAF98006D566C /* AlbumDetailView+NSTableViewDelegate.swift */, E43B67AC229194CD007DCF55 /* AlbumTracksDataSource.swift */, 38BAC36A249CB1A6004BAEA4 /* AlbumDetailSongTitleView.swift */, @@ -943,7 +1068,6 @@ E442CCC92347D6FD00004E0C /* Shared */ = { isa = PBXGroup; children = ( - E4BB7F8D23E5E7A300906E2F /* ImageDataProviders */, E4E13C2C2350D8CB00092A6E /* Layouts */, E408D3B7220DE8CC0006D9BE /* Extensions */, E489E3A222B9D31800CA8CBD /* DraggedSongView.swift */, @@ -1385,6 +1509,7 @@ packageProductDependencies = ( E480513724255CE000362CF3 /* ReSwift */, E480513924255CF200362CF3 /* CryptoSwift */, + E41222222431530900473C1D /* Kingfisher */, ); productName = "Persephone-iOS"; productReference = E411C26D241C10F0008B9682 /* Persephone.app */; @@ -1546,12 +1671,15 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + E41222132431425400473C1D /* LaunchScreen.storyboard in Resources */, + E41222142431425400473C1D /* Main.storyboard in Resources */, E48059112426D73600362CF3 /* win64.txt in Resources */, E480590F2426D73600362CF3 /* configure.py in Resources */, E48058292426D73500362CF3 /* version.h.in in Resources */, E48059152426D73600362CF3 /* build.sh in Resources */, E48059132426D73600362CF3 /* win32.txt in Resources */, E48059C12426D73600362CF3 /* libmpdclient.vapi in Resources */, + E41222162431425400473C1D /* Assets.xcassets in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1782,11 +1910,13 @@ E48059EB2426D73600362CF3 /* coutput.c in Sources */, E48059FB2426D73600362CF3 /* recv.c in Sources */, E480511A24255BAF00362CF3 /* Time.swift in Sources */, + E41222112431425400473C1D /* App.swift in Sources */, E480514C24255E7D00362CF3 /* QueueActions.swift in Sources */, E480511E24255BD500362CF3 /* RawRepresentable.swift in Sources */, E4805A1D2426D73600362CF3 /* kvlist.c in Sources */, E4805A2B2426D73600362CF3 /* message.c in Sources */, E48059C92426D73600362CF3 /* async.c in Sources */, + E4122228243153B200473C1D /* CGSize.swift in Sources */, E480514924255E7D00362CF3 /* AlbumListActions.swift in Sources */, E480511624255BAF00362CF3 /* Loading.swift in Sources */, E480514324255E7700362CF3 /* AppReducer.swift in Sources */, @@ -1802,17 +1932,20 @@ E480512724255BDB00362CF3 /* MPDClient+Queue.swift in Sources */, E480513D24255E7200362CF3 /* PlayerState.swift in Sources */, E480511D24255BD200362CF3 /* MPDClientWrapper.c in Sources */, + E41222242431535E00473C1D /* MPDAlbumArtImageDataProvider.swift in Sources */, E480512924255BDB00362CF3 /* MPDClient+Status.swift in Sources */, E48059FD2426D73600362CF3 /* neighbor.c in Sources */, E4805A252426D73600362CF3 /* iso8601.c in Sources */, E480512C24255BDF00362CF3 /* MPDCommand.swift in Sources */, E48059F52426D73600362CF3 /* search.c in Sources */, E4805A1F2426D73600362CF3 /* idle.c in Sources */, + E41222182431425400473C1D /* AlbumItemCell.swift in Sources */, E480511724255BAF00362CF3 /* MPDServer.swift in Sources */, E48059C32426D73600362CF3 /* directory.c in Sources */, E480514A24255E7D00362CF3 /* PlayerActions.swift in Sources */, E48059DF2426D73600362CF3 /* audio_format.c in Sources */, E48059CF2426D73600362CF3 /* cpartition.c in Sources */, + E412221B2431425400473C1D /* AlbumViewController+UICollectionViewDelegateFlowLayout.swift in Sources */, E4805A012426D73600362CF3 /* quote.c in Sources */, E4805A092426D73600362CF3 /* fd_util.c in Sources */, E48059D52426D73600362CF3 /* resolver.c in Sources */, @@ -1823,6 +1956,7 @@ E480513124255BDF00362CF3 /* MPDStatus.swift in Sources */, E480514424255E7700362CF3 /* PlayerReducer.swift in Sources */, E480514524255E7700362CF3 /* PreferencesReducer.swift in Sources */, + E41222292431555100473C1D /* CGColor.swift in Sources */, E480511F24255BDB00362CF3 /* MPDClient+Album.swift in Sources */, E4805A0B2426D73600362CF3 /* sync.c in Sources */, E4805A052426D73600362CF3 /* connection.c in Sources */, @@ -1843,21 +1977,26 @@ E480513024255BDF00362CF3 /* MPDSong.swift in Sources */, E480511524255BAF00362CF3 /* DraggedSongType.swift in Sources */, E480512B24255BDF00362CF3 /* MPDAlbum.swift in Sources */, + E412221A2431425400473C1D /* AlbumViewController+UICollectionViewDataSource.swift in Sources */, + E41222172431425400473C1D /* SceneDelegate.swift in Sources */, E48059DB2426D73600362CF3 /* entity.c in Sources */, E48051522425626300362CF3 /* MPDServerController.swift in Sources */, E480511324255BAF00362CF3 /* DraggedAlbum.swift in Sources */, + E41222122431425400473C1D /* AppDelegate.swift in Sources */, E4805A072426D73600362CF3 /* error.c in Sources */, E480514124255E7200362CF3 /* UIState.swift in Sources */, E48059E72426D73600362CF3 /* playlist.c in Sources */, E480512E24255BDF00362CF3 /* MPDIdle.swift in Sources */, E48059E92426D73600362CF3 /* queue.c in Sources */, E48059D12426D73600362CF3 /* send.c in Sources */, + E412222C2431830500473C1D /* AlbumDetailViewController.swift in Sources */, E4805A1B2426D73600362CF3 /* cmessage.c in Sources */, E48059E52426D73600362CF3 /* run.c in Sources */, E480514D24255E7D00362CF3 /* ServerActions.swift in Sources */, E480511C24255BBF00362CF3 /* MPDClient.swift in Sources */, E480513B24255E7200362CF3 /* AlbumListState.swift in Sources */, E480512224255BDB00362CF3 /* MPDClient+Connection.swift in Sources */, + E41222192431425400473C1D /* AlbumViewController.swift in Sources */, E480511124255BA900362CF3 /* MachTime.swift in Sources */, E4805A112426D73600362CF3 /* tag.c in Sources */, E4805A192426D73600362CF3 /* status.c in Sources */, @@ -1888,6 +2027,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + E412221C2431431500473C1D /* Persephone_iOSTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1895,6 +2035,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + E412221F2431432100473C1D /* Persephone_iOSUITests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1932,6 +2073,22 @@ name = Main.storyboard; sourceTree = ""; }; + E41221FF2431425400473C1D /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + E41222002431425400473C1D /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; + E41222012431425400473C1D /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + E41222022431425400473C1D /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ @@ -2527,6 +2684,11 @@ /* End XCRemoteSwiftPackageReference section */ /* Begin XCSwiftPackageProductDependency section */ + E41222222431530900473C1D /* Kingfisher */ = { + isa = XCSwiftPackageProductDependency; + package = E43BEC9E238835DC00CAF1EB /* XCRemoteSwiftPackageReference "Kingfisher" */; + productName = Kingfisher; + }; E43BEC9F238835DC00CAF1EB /* Kingfisher */ = { isa = XCSwiftPackageProductDependency; package = E43BEC9E238835DC00CAF1EB /* XCRemoteSwiftPackageReference "Kingfisher" */; diff --git a/Resources/export/iOS-1024x1024.png b/Resources/export/iOS-1024x1024.png new file mode 100644 index 0000000..ab9d583 Binary files /dev/null and b/Resources/export/iOS-1024x1024.png differ diff --git a/Resources/export/iOS-120x120.png b/Resources/export/iOS-120x120.png new file mode 100644 index 0000000..3113588 Binary files /dev/null and b/Resources/export/iOS-120x120.png differ diff --git a/Resources/export/iOS-152x152.png b/Resources/export/iOS-152x152.png new file mode 100644 index 0000000..ef93bfb Binary files /dev/null and b/Resources/export/iOS-152x152.png differ diff --git a/Resources/export/iOS-167x167.png b/Resources/export/iOS-167x167.png new file mode 100644 index 0000000..e8e6f5a Binary files /dev/null and b/Resources/export/iOS-167x167.png differ diff --git a/Resources/export/iOS-180x180.png b/Resources/export/iOS-180x180.png new file mode 100644 index 0000000..4933413 Binary files /dev/null and b/Resources/export/iOS-180x180.png differ diff --git a/Resources/export/iOS-20x20.png b/Resources/export/iOS-20x20.png new file mode 100644 index 0000000..5826066 Binary files /dev/null and b/Resources/export/iOS-20x20.png differ diff --git a/Resources/export/iOS-29x29.png b/Resources/export/iOS-29x29.png new file mode 100644 index 0000000..b711b1d Binary files /dev/null and b/Resources/export/iOS-29x29.png differ diff --git a/Resources/export/iOS-40x40.png b/Resources/export/iOS-40x40.png new file mode 100644 index 0000000..80df49d Binary files /dev/null and b/Resources/export/iOS-40x40.png differ diff --git a/Resources/export/iOS-58x58.png b/Resources/export/iOS-58x58.png new file mode 100644 index 0000000..88ae461 Binary files /dev/null and b/Resources/export/iOS-58x58.png differ diff --git a/Resources/export/iOS-60x60.png b/Resources/export/iOS-60x60.png new file mode 100644 index 0000000..cbd7eac Binary files /dev/null and b/Resources/export/iOS-60x60.png differ diff --git a/Resources/export/iOS-76x76.png b/Resources/export/iOS-76x76.png new file mode 100644 index 0000000..1281205 Binary files /dev/null and b/Resources/export/iOS-76x76.png differ diff --git a/Resources/export/iOS-80x80.png b/Resources/export/iOS-80x80.png new file mode 100644 index 0000000..72fa309 Binary files /dev/null and b/Resources/export/iOS-80x80.png differ diff --git a/Resources/export/iOS-87x87.png b/Resources/export/iOS-87x87.png new file mode 100644 index 0000000..55159f9 Binary files /dev/null and b/Resources/export/iOS-87x87.png differ diff --git a/Resources/icons.sketch b/Resources/icons.sketch index 3ac177b..eb180ac 100644 Binary files a/Resources/icons.sketch and b/Resources/icons.sketch differ diff --git a/Shared/Extensions/CGColor.swift b/Shared/Extensions/CGColor.swift new file mode 100644 index 0000000..3e296b1 --- /dev/null +++ b/Shared/Extensions/CGColor.swift @@ -0,0 +1,14 @@ +// +// NSColor.swift +// Persephone +// +// Created by Daniel Barber on 2019/2/16. +// Copyright © 2019 Dan Barber. All rights reserved. +// + +import CoreGraphics + +extension CGColor { + static let albumBorderColorLight = CGColor.init(srgbRed: 0, green: 0, blue: 0, alpha: 0.15) + static let albumBorderColorDark = CGColor.init(srgbRed: 255, green: 255, blue: 255, alpha: 0.15) +} diff --git a/Mac/Components/Shared/ImageDataProviders/MPDAlbumArtImageDataProvider.swift b/Shared/ImageDataProviders/MPDAlbumArtImageDataProvider.swift similarity index 100% rename from Mac/Components/Shared/ImageDataProviders/MPDAlbumArtImageDataProvider.swift rename to Shared/ImageDataProviders/MPDAlbumArtImageDataProvider.swift diff --git a/iOS/Assets.xcassets/AppIcon.appiconset/Contents.json b/iOS/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..065e2ac --- /dev/null +++ b/iOS/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,116 @@ +{ + "images" : [ + { + "filename" : "iOS-40x40-1.png", + "idiom" : "iphone", + "scale" : "2x", + "size" : "20x20" + }, + { + "filename" : "iOS-60x60.png", + "idiom" : "iphone", + "scale" : "3x", + "size" : "20x20" + }, + { + "filename" : "iOS-58x58-1.png", + "idiom" : "iphone", + "scale" : "2x", + "size" : "29x29" + }, + { + "filename" : "iOS-87x87.png", + "idiom" : "iphone", + "scale" : "3x", + "size" : "29x29" + }, + { + "filename" : "iOS-80x80.png", + "idiom" : "iphone", + "scale" : "2x", + "size" : "40x40" + }, + { + "filename" : "iOS-120x120.png", + "idiom" : "iphone", + "scale" : "3x", + "size" : "40x40" + }, + { + "filename" : "iOS-120x120-1.png", + "idiom" : "iphone", + "scale" : "2x", + "size" : "60x60" + }, + { + "filename" : "iOS-180x180.png", + "idiom" : "iphone", + "scale" : "3x", + "size" : "60x60" + }, + { + "filename" : "iOS-20x20.png", + "idiom" : "ipad", + "scale" : "1x", + "size" : "20x20" + }, + { + "filename" : "iOS-40x40.png", + "idiom" : "ipad", + "scale" : "2x", + "size" : "20x20" + }, + { + "filename" : "iOS-29x29.png", + "idiom" : "ipad", + "scale" : "1x", + "size" : "29x29" + }, + { + "filename" : "iOS-58x58.png", + "idiom" : "ipad", + "scale" : "2x", + "size" : "29x29" + }, + { + "filename" : "iOS-40x40-2.png", + "idiom" : "ipad", + "scale" : "1x", + "size" : "40x40" + }, + { + "filename" : "iOS-80x80-1.png", + "idiom" : "ipad", + "scale" : "2x", + "size" : "40x40" + }, + { + "filename" : "iOS-76x76.png", + "idiom" : "ipad", + "scale" : "1x", + "size" : "76x76" + }, + { + "filename" : "iOS-152x152.png", + "idiom" : "ipad", + "scale" : "2x", + "size" : "76x76" + }, + { + "filename" : "iOS-167x167.png", + "idiom" : "ipad", + "scale" : "2x", + "size" : "83.5x83.5" + }, + { + "filename" : "iOS-1024x1024.png", + "idiom" : "ios-marketing", + "scale" : "1x", + "size" : "1024x1024" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOS/Assets.xcassets/AppIcon.appiconset/iOS-1024x1024.png b/iOS/Assets.xcassets/AppIcon.appiconset/iOS-1024x1024.png new file mode 100644 index 0000000..ab9d583 Binary files /dev/null and b/iOS/Assets.xcassets/AppIcon.appiconset/iOS-1024x1024.png differ diff --git a/iOS/Assets.xcassets/AppIcon.appiconset/iOS-120x120-1.png b/iOS/Assets.xcassets/AppIcon.appiconset/iOS-120x120-1.png new file mode 100644 index 0000000..3113588 Binary files /dev/null and b/iOS/Assets.xcassets/AppIcon.appiconset/iOS-120x120-1.png differ diff --git a/iOS/Assets.xcassets/AppIcon.appiconset/iOS-120x120.png b/iOS/Assets.xcassets/AppIcon.appiconset/iOS-120x120.png new file mode 100644 index 0000000..3113588 Binary files /dev/null and b/iOS/Assets.xcassets/AppIcon.appiconset/iOS-120x120.png differ diff --git a/iOS/Assets.xcassets/AppIcon.appiconset/iOS-152x152.png b/iOS/Assets.xcassets/AppIcon.appiconset/iOS-152x152.png new file mode 100644 index 0000000..ef93bfb Binary files /dev/null and b/iOS/Assets.xcassets/AppIcon.appiconset/iOS-152x152.png differ diff --git a/iOS/Assets.xcassets/AppIcon.appiconset/iOS-167x167.png b/iOS/Assets.xcassets/AppIcon.appiconset/iOS-167x167.png new file mode 100644 index 0000000..e8e6f5a Binary files /dev/null and b/iOS/Assets.xcassets/AppIcon.appiconset/iOS-167x167.png differ diff --git a/iOS/Assets.xcassets/AppIcon.appiconset/iOS-180x180.png b/iOS/Assets.xcassets/AppIcon.appiconset/iOS-180x180.png new file mode 100644 index 0000000..4933413 Binary files /dev/null and b/iOS/Assets.xcassets/AppIcon.appiconset/iOS-180x180.png differ diff --git a/iOS/Assets.xcassets/AppIcon.appiconset/iOS-20x20.png b/iOS/Assets.xcassets/AppIcon.appiconset/iOS-20x20.png new file mode 100644 index 0000000..5826066 Binary files /dev/null and b/iOS/Assets.xcassets/AppIcon.appiconset/iOS-20x20.png differ diff --git a/iOS/Assets.xcassets/AppIcon.appiconset/iOS-29x29.png b/iOS/Assets.xcassets/AppIcon.appiconset/iOS-29x29.png new file mode 100644 index 0000000..b711b1d Binary files /dev/null and b/iOS/Assets.xcassets/AppIcon.appiconset/iOS-29x29.png differ diff --git a/iOS/Assets.xcassets/AppIcon.appiconset/iOS-40x40-1.png b/iOS/Assets.xcassets/AppIcon.appiconset/iOS-40x40-1.png new file mode 100644 index 0000000..80df49d Binary files /dev/null and b/iOS/Assets.xcassets/AppIcon.appiconset/iOS-40x40-1.png differ diff --git a/iOS/Assets.xcassets/AppIcon.appiconset/iOS-40x40-2.png b/iOS/Assets.xcassets/AppIcon.appiconset/iOS-40x40-2.png new file mode 100644 index 0000000..80df49d Binary files /dev/null and b/iOS/Assets.xcassets/AppIcon.appiconset/iOS-40x40-2.png differ diff --git a/iOS/Assets.xcassets/AppIcon.appiconset/iOS-40x40.png b/iOS/Assets.xcassets/AppIcon.appiconset/iOS-40x40.png new file mode 100644 index 0000000..80df49d Binary files /dev/null and b/iOS/Assets.xcassets/AppIcon.appiconset/iOS-40x40.png differ diff --git a/iOS/Assets.xcassets/AppIcon.appiconset/iOS-58x58-1.png b/iOS/Assets.xcassets/AppIcon.appiconset/iOS-58x58-1.png new file mode 100644 index 0000000..88ae461 Binary files /dev/null and b/iOS/Assets.xcassets/AppIcon.appiconset/iOS-58x58-1.png differ diff --git a/iOS/Assets.xcassets/AppIcon.appiconset/iOS-58x58.png b/iOS/Assets.xcassets/AppIcon.appiconset/iOS-58x58.png new file mode 100644 index 0000000..88ae461 Binary files /dev/null and b/iOS/Assets.xcassets/AppIcon.appiconset/iOS-58x58.png differ diff --git a/iOS/Assets.xcassets/AppIcon.appiconset/iOS-60x60.png b/iOS/Assets.xcassets/AppIcon.appiconset/iOS-60x60.png new file mode 100644 index 0000000..cbd7eac Binary files /dev/null and b/iOS/Assets.xcassets/AppIcon.appiconset/iOS-60x60.png differ diff --git a/iOS/Assets.xcassets/AppIcon.appiconset/iOS-76x76.png b/iOS/Assets.xcassets/AppIcon.appiconset/iOS-76x76.png new file mode 100644 index 0000000..1281205 Binary files /dev/null and b/iOS/Assets.xcassets/AppIcon.appiconset/iOS-76x76.png differ diff --git a/iOS/Assets.xcassets/AppIcon.appiconset/iOS-80x80-1.png b/iOS/Assets.xcassets/AppIcon.appiconset/iOS-80x80-1.png new file mode 100644 index 0000000..72fa309 Binary files /dev/null and b/iOS/Assets.xcassets/AppIcon.appiconset/iOS-80x80-1.png differ diff --git a/iOS/Assets.xcassets/AppIcon.appiconset/iOS-80x80.png b/iOS/Assets.xcassets/AppIcon.appiconset/iOS-80x80.png new file mode 100644 index 0000000..72fa309 Binary files /dev/null and b/iOS/Assets.xcassets/AppIcon.appiconset/iOS-80x80.png differ diff --git a/iOS/Assets.xcassets/AppIcon.appiconset/iOS-87x87.png b/iOS/Assets.xcassets/AppIcon.appiconset/iOS-87x87.png new file mode 100644 index 0000000..95371dc Binary files /dev/null and b/iOS/Assets.xcassets/AppIcon.appiconset/iOS-87x87.png differ diff --git a/iOS/Assets.xcassets/Contents.json b/iOS/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/iOS/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/iOS/Assets.xcassets/defaultCoverArt.imageset/Contents.json b/iOS/Assets.xcassets/defaultCoverArt.imageset/Contents.json new file mode 100644 index 0000000..1b44a55 --- /dev/null +++ b/iOS/Assets.xcassets/defaultCoverArt.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "filename" : "blankAlbumLight.pdf", + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "filename" : "blankAlbumDark.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/iOS/Assets.xcassets/defaultCoverArt.imageset/blankAlbumDark.pdf b/iOS/Assets.xcassets/defaultCoverArt.imageset/blankAlbumDark.pdf new file mode 100644 index 0000000..01942a6 Binary files /dev/null and b/iOS/Assets.xcassets/defaultCoverArt.imageset/blankAlbumDark.pdf differ diff --git a/iOS/Assets.xcassets/defaultCoverArt.imageset/blankAlbumLight.pdf b/iOS/Assets.xcassets/defaultCoverArt.imageset/blankAlbumLight.pdf new file mode 100644 index 0000000..ed083f0 Binary files /dev/null and b/iOS/Assets.xcassets/defaultCoverArt.imageset/blankAlbumLight.pdf differ diff --git a/iOS/Assets.xcassets/playButtonLarge.imageset/Contents.json b/iOS/Assets.xcassets/playButtonLarge.imageset/Contents.json new file mode 100644 index 0000000..f5d8b34 --- /dev/null +++ b/iOS/Assets.xcassets/playButtonLarge.imageset/Contents.json @@ -0,0 +1,15 @@ +{ + "images" : [ + { + "filename" : "playButtonLarge.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "template-rendering-intent" : "template" + } +} diff --git a/iOS/Assets.xcassets/playButtonLarge.imageset/playButtonLarge.pdf b/iOS/Assets.xcassets/playButtonLarge.imageset/playButtonLarge.pdf new file mode 100644 index 0000000..a04b172 Binary files /dev/null and b/iOS/Assets.xcassets/playButtonLarge.imageset/playButtonLarge.pdf differ diff --git a/iOS/Base.lproj/LaunchScreen.storyboard b/iOS/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..865e932 --- /dev/null +++ b/iOS/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/iOS/Base.lproj/Main.storyboard b/iOS/Base.lproj/Main.storyboard new file mode 100644 index 0000000..8d9ff95 --- /dev/null +++ b/iOS/Base.lproj/Main.storyboard @@ -0,0 +1,216 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/iOS/Components/Browser/Album Browser/AlbumItemCell.swift b/iOS/Components/Browser/Album Browser/AlbumItemCell.swift new file mode 100644 index 0000000..11c6569 --- /dev/null +++ b/iOS/Components/Browser/Album Browser/AlbumItemCell.swift @@ -0,0 +1,76 @@ +// +// AlbumItemCell.swift +// Persephone +// +// Created by Daniel Barber on 2020-3-28. +// Copyright © 2020 Dan Barber. All rights reserved. +// + +import UIKit +import Kingfisher + +class AlbumItemCell: UICollectionViewCell { + var album: Album? + + override func didMoveToSuperview() { + albumCoverView.layer.backgroundColor = UIColor.black.cgColor + albumCoverView.layer.cornerRadius = 4 + albumCoverView.layer.borderWidth = 0.5 + albumCoverView.layer.masksToBounds = true + setAppearance() + } + + func setAlbum(_ album: Album) { + self.album = album + albumTitle.text = album.title + albumArtist.text = album.artist + setAlbumCover(album) + } + + func setAlbumCover(_ album: Album) { + guard let song = album.mpdAlbum.firstSong + else { return } + + let provider = MPDAlbumArtImageDataProvider( + songUri: song.uriString, + cacheKey: album.hash + ) + + albumCoverView.kf.setImage( + with: .provider(provider), + placeholder: UIImage(named: "defaultCoverArt"), + options: [ + .processor(DownsamplingImageProcessor(size: .albumListCoverSize)), + .scaleFactor(traitCollection.displayScale), + ] + ) { result in + switch result { + case .success(let imageResult): + guard let imageData = imageResult.image.pngData() + else { return } + + let _ = RawImageDataProvider( + data: imageData, + cacheKey: album.hash + ) + + case .failure(_): + break + } + } + } + + override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { + setAppearance() + } + + func setAppearance() { + let darkMode = traitCollection.userInterfaceStyle == .dark + + albumCoverView.layer.borderColor = darkMode ? CGColor.albumBorderColorDark : CGColor.albumBorderColorLight + } + + @IBOutlet var albumCoverView: UIImageView! + @IBOutlet var albumTitle: UILabel! + @IBOutlet var albumArtist: UILabel! +} diff --git a/iOS/Components/Browser/Album Browser/AlbumViewController+UICollectionViewDataSource.swift b/iOS/Components/Browser/Album Browser/AlbumViewController+UICollectionViewDataSource.swift new file mode 100644 index 0000000..6f28842 --- /dev/null +++ b/iOS/Components/Browser/Album Browser/AlbumViewController+UICollectionViewDataSource.swift @@ -0,0 +1,33 @@ +// +// AlbumDataSource.swift +// Persephone +// +// Created by Daniel Barber on 2019/2/20. +// Copyright © 2019 Dan Barber. All rights reserved. +// + +import UIKit + +extension AlbumViewController { + override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { + return albums.count + } + + override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { + let item = collectionView.dequeueReusableCell(withReuseIdentifier: "AlbumViewCell", for: indexPath) + guard let albumViewCell = item as? AlbumItemCell else { return item } + + //albumViewItem.view.wantsLayer = true + albumViewCell.setAlbum(albums[indexPath.item]) + + return albumViewCell + } +// +// override func indexTitles(for collectionView: UICollectionView) -> [String]? { +// return ["#"] +// } +// +// override func collectionView(_ collectionView: UICollectionView, indexPathForIndexTitle title: String, at index: Int) -> IndexPath { +// return IndexPath(index: 0) +// } +} diff --git a/iOS/Components/Browser/Album Browser/AlbumViewController+UICollectionViewDelegateFlowLayout.swift b/iOS/Components/Browser/Album Browser/AlbumViewController+UICollectionViewDelegateFlowLayout.swift new file mode 100644 index 0000000..70643c7 --- /dev/null +++ b/iOS/Components/Browser/Album Browser/AlbumViewController+UICollectionViewDelegateFlowLayout.swift @@ -0,0 +1,33 @@ +// +// AlbumViewController+UICollectionViewDelegateFlowLayout.swift +// Persephone +// +// Created by Daniel Barber on 2020-3-28. +// Copyright © 2020 Dan Barber. All rights reserved. +// + +import UIKit + +extension AlbumViewController: UICollectionViewDelegateFlowLayout { + func collectionView(_ collectionView: UICollectionView, + layout collectionViewLayout: UICollectionViewLayout, + sizeForItemAt indexPath: IndexPath) -> CGSize { + let paddingSpace = sectionInsets.left * (itemsPerRow + 1) + let availableWidth = view.frame.width - paddingSpace + let widthPerItem = availableWidth / itemsPerRow + + return CGSize(width: widthPerItem, height: widthPerItem + 48) + } + + func collectionView(_ collectionView: UICollectionView, + layout collectionViewLayout: UICollectionViewLayout, + insetForSectionAt section: Int) -> UIEdgeInsets { + return sectionInsets + } + + func collectionView(_ collectionView: UICollectionView, + layout collectionViewLayout: UICollectionViewLayout, + minimumLineSpacingForSectionAt section: Int) -> CGFloat { + return sectionInsets.left / 2 + } +} diff --git a/iOS/Components/Browser/Album Browser/AlbumViewController.swift b/iOS/Components/Browser/Album Browser/AlbumViewController.swift new file mode 100644 index 0000000..bb65348 --- /dev/null +++ b/iOS/Components/Browser/Album Browser/AlbumViewController.swift @@ -0,0 +1,67 @@ +// +// ViewController.swift +// Persephone-iOS +// +// Created by Daniel Barber on 2020-3-13. +// Copyright © 2020 Dan Barber. All rights reserved. +// + +import UIKit +import ReSwift + +class AlbumViewController: UICollectionViewController { + var albums: [Album] = [] + + let itemsPerRow: CGFloat = 2 + + let sectionInsets = UIEdgeInsets( + top: 20.0, + left: 20.0, + bottom: 30.0, + right: 20.0 + ) + + override func viewDidLoad() { + super.viewDidLoad() + + App.store.subscribe(self) { + $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) + + title = "Albums" + navigationController?.navigationBar.prefersLargeTitles = true + } + + @objc func didConnect() { + App.mpdClient.fetchAllAlbums() + } + + @objc func willDisconnect() { + DispatchQueue.main.async { + App.store.dispatch(UpdateAlbumListAction(albums: [])) + } + } + + override func prepare(for segue: UIStoryboardSegue, sender: Any?) { + guard let detailView = segue.destination as? AlbumDetailViewController, + let sender = sender as? AlbumItemCell + else { return } + + detailView.setAlbum(sender.album) + } + + @IBOutlet var albumCollectionView: UICollectionView! +} + +extension AlbumViewController: StoreSubscriber { + typealias StoreSubscriberStateType = AlbumListState + + func newState(state: StoreSubscriberStateType) { + albums = state.albums + + albumCollectionView.reloadData() + } +} diff --git a/iOS/Components/Browser/Album Detail/AlbumDetailViewController.swift b/iOS/Components/Browser/Album Detail/AlbumDetailViewController.swift new file mode 100644 index 0000000..b267dd1 --- /dev/null +++ b/iOS/Components/Browser/Album Detail/AlbumDetailViewController.swift @@ -0,0 +1,98 @@ +// +// AlbumDetailController.swift +// Persephone-iOS +// +// Created by Daniel Barber on 2020-3-29. +// Copyright © 2020 Dan Barber. All rights reserved. +// + +import UIKit +import Kingfisher + +class AlbumDetailViewController: UIViewController { + var album: Album? + var albumSongs: [Song] = [] + + override func viewDidLoad() { + super.viewDidLoad() + + navigationItem.largeTitleDisplayMode = .never + + albumCoverView.layer.backgroundColor = UIColor.black.cgColor + albumCoverView.layer.cornerRadius = 4 + albumCoverView.layer.borderWidth = 0.5 + albumCoverView.layer.masksToBounds = true + + playAlbumButton.layer.cornerRadius = 8 + setAppearance() + } + + override func viewWillAppear(_ animated: Bool) { + guard let album = album else { return } + + albumTitle.text = album.title + albumArtist.text = album.artist + + getAlbumSongs(for: album) + } + + func setAlbum(_ album: Album?) { + guard let album = album else { return } + + self.album = album + } + + func getAlbumSongs(for album: Album) { + App.mpdClient.getAlbumSongs(for: album.mpdAlbum) { [weak self] (mpdSongs: [MPDClient.MPDSong]) in + guard let self = self else { return } + + DispatchQueue.main.async { + self.albumSongs = mpdSongs.map { Song(mpdSong: $0) } + + //self.albumTracksView.reloadData() + + guard let mpdSong = album.mpdAlbum.firstSong + else { return } + + self.getBigCoverArt(song: Song(mpdSong: mpdSong), album: album) + } + } + } + + func getBigCoverArt(song: Song, album: Album) { + let provider = MPDAlbumArtImageDataProvider( + songUri: song.mpdSong.uriString, + cacheKey: album.hash + ) + + albumCoverView.kf.setImage( + with: .provider(provider), + placeholder: UIImage(named: "defaultCoverArt"), + options: [ + .processor(DownsamplingImageProcessor(size: .albumDetailCoverSize)), + .scaleFactor(traitCollection.displayScale), + ] + ) + } + + override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { + setAppearance() + } + + func setAppearance() { + let darkMode = traitCollection.userInterfaceStyle == .dark + + albumCoverView.layer.borderColor = darkMode ? CGColor.albumBorderColorDark : CGColor.albumBorderColorLight + } + + @IBAction func playAlbumAction(_ sender: Any) { + guard let album = album else { return } + + App.mpdClient.playAlbum(album.mpdAlbum) + } + + @IBOutlet var playAlbumButton: UIButton! + @IBOutlet var albumCoverView: UIImageView! + @IBOutlet var albumTitle: UILabel! + @IBOutlet var albumArtist: UILabel! +} diff --git a/iOS/Components/Shared/Extensions/CGSize.swift b/iOS/Components/Shared/Extensions/CGSize.swift new file mode 100644 index 0000000..e3812a6 --- /dev/null +++ b/iOS/Components/Shared/Extensions/CGSize.swift @@ -0,0 +1,17 @@ +// +// NSSize.swift +// Persephone +// +// Created by Daniel Barber on 1/20/20. +// Copyright © 2020 Dan Barber. All rights reserved. +// + +import CoreGraphics + +extension CGSize { + static let queueSongCoverSize = CGSize(width: 32, height: 32) + static let albumListCoverSize = CGSize(width: 180, height: 180) + static let albumDetailCoverSize = CGSize(width: 500, height: 500) + static let currentlyPlayingCoverSize = albumDetailCoverSize + static let notificationCoverSize = albumListCoverSize +} diff --git a/iOS/SceneDelegate.swift b/iOS/SceneDelegate.swift new file mode 100644 index 0000000..2fc33dc --- /dev/null +++ b/iOS/SceneDelegate.swift @@ -0,0 +1,57 @@ +// +// SceneDelegate.swift +// Persephone-iOS +// +// Created by Daniel Barber on 2020-3-13. +// Copyright © 2020 Dan Barber. All rights reserved. +// + +import UIKit + +class SceneDelegate: UIResponder, UIWindowSceneDelegate { + + var window: UIWindow? + + + func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { + // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. + // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. + // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). + guard let _ = (scene as? UIWindowScene) else { return } + + _ = App.mpdServerController + + App.store.dispatch(UpdateServerHost(host: "192.168.1.42")) + } + + func sceneDidDisconnect(_ scene: UIScene) { + // Called as the scene is being released by the system. + // This occurs shortly after the scene enters the background, or when its session is discarded. + // Release any resources associated with this scene that can be re-created the next time the scene connects. + // The scene may re-connect later, as its session was not neccessarily discarded (see `application:didDiscardSceneSessions` instead). + } + + func sceneDidBecomeActive(_ scene: UIScene) { + // Called when the scene has moved from an inactive state to an active state. + // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. + } + + func sceneWillResignActive(_ scene: UIScene) { + // Called when the scene will move from an active state to an inactive state. + // This may occur due to temporary interruptions (ex. an incoming phone call). + } + + func sceneWillEnterForeground(_ scene: UIScene) { + // Called as the scene transitions from the background to the foreground. + // Use this method to undo the changes made on entering the background. + } + + func sceneDidEnterBackground(_ scene: UIScene) { + // Called as the scene transitions from the foreground to the background. + // Use this method to save data, release shared resources, and store enough scene-specific state information + // to restore the scene back to its current state. + } + + +} +