diff --git a/Mac/Components/Browser/Album Detail/AlbumTracksDataSource.swift b/Mac/Components/Browser/Album Detail/AlbumTracksDataSource.swift index 59b74d0..2589d02 100644 --- a/Mac/Components/Browser/Album Detail/AlbumTracksDataSource.swift +++ b/Mac/Components/Browser/Album Detail/AlbumTracksDataSource.swift @@ -9,21 +9,6 @@ import AppKit class AlbumTracksDataSource: NSObject, NSTableViewDataSource { - struct AlbumSongItem { - let disc: String? - let song: Song? - - init(song: Song) { - self.disc = nil - self.song = song - } - - init(disc: String) { - self.disc = disc - self.song = nil - } - } - var albumSongs: [AlbumSongItem] = [] var showSongArtist: Bool = false diff --git a/Mac/Components/Window/Base.lproj/Main.storyboard b/Mac/Components/Window/Base.lproj/Main.storyboard index 4ab71d9..4448111 100644 --- a/Mac/Components/Window/Base.lproj/Main.storyboard +++ b/Mac/Components/Window/Base.lproj/Main.storyboard @@ -298,7 +298,7 @@ - + @@ -320,7 +320,7 @@ - + @@ -347,7 +347,7 @@ - + @@ -369,7 +369,7 @@ - + @@ -385,7 +385,7 @@ - + @@ -398,7 +398,7 @@ - + @@ -414,7 +414,7 @@ - + @@ -516,7 +516,7 @@ - + @@ -554,7 +554,7 @@ - + @@ -566,7 +566,7 @@ - + @@ -614,7 +614,7 @@ - + @@ -637,7 +637,7 @@ - + @@ -651,7 +651,7 @@ - + @@ -677,7 +677,7 @@ - + @@ -712,7 +712,7 @@ - + @@ -757,7 +757,7 @@ - + @@ -778,7 +778,7 @@ - + @@ -805,7 +805,7 @@ - + @@ -818,7 +818,7 @@ - + diff --git a/Persephone.xcodeproj/project.pbxproj b/Persephone.xcodeproj/project.pbxproj index e0ed2df..68a0dac 100644 --- a/Persephone.xcodeproj/project.pbxproj +++ b/Persephone.xcodeproj/project.pbxproj @@ -35,7 +35,9 @@ 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 */; }; + E41222302432B0A300473C1D /* AlbumTracksDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = E412222F2432B0A300473C1D /* AlbumTracksDataSource.swift */; }; + E41222322432B14000473C1D /* AlbumSongItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = E41222312432B14000473C1D /* AlbumSongItem.swift */; }; + E41222332432B15100473C1D /* AlbumSongItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = E41222312432B14000473C1D /* AlbumSongItem.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 */; }; @@ -292,6 +294,8 @@ E4B11BBE2275EDAA0075461B /* PlayerActions.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4B11BBD2275EDAA0075461B /* PlayerActions.swift */; }; E4B11BC02275EE150075461B /* QueueActions.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4B11BBF2275EE150075461B /* QueueActions.swift */; }; E4B11BC22275EE410075461B /* AlbumListActions.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4B11BC12275EE410075461B /* AlbumListActions.swift */; }; + E4B3B3642432DB7A007E25D2 /* AlbumSongCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4B3B3622432DA4B007E25D2 /* AlbumSongCell.swift */; }; + E4B3B3672432DF1B007E25D2 /* AlbumSongListViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4B3B3652432DEDB007E25D2 /* AlbumSongListViewController.swift */; }; E4B3DF6523D66A4400728F6B /* QueueSongCoverView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4B3DF6423D66A4400728F6B /* QueueSongCoverView.swift */; }; E4B46F8F2402E89800152157 /* MPDError.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4B46F8E2402E89800152157 /* MPDError.swift */; }; E4B5AE7E22F4C49600CCEC65 /* MPDServerDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4B5AE7D22F4C49600CCEC65 /* MPDServerDelegate.swift */; }; @@ -424,7 +428,8 @@ 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 = ""; }; + E412222F2432B0A300473C1D /* AlbumTracksDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlbumTracksDataSource.swift; sourceTree = ""; }; + E41222312432B14000473C1D /* AlbumSongItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlbumSongItem.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 = ""; }; @@ -647,6 +652,8 @@ E4B11BBD2275EDAA0075461B /* PlayerActions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerActions.swift; sourceTree = ""; }; E4B11BBF2275EE150075461B /* QueueActions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QueueActions.swift; sourceTree = ""; }; E4B11BC12275EE410075461B /* AlbumListActions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlbumListActions.swift; sourceTree = ""; }; + E4B3B3622432DA4B007E25D2 /* AlbumSongCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlbumSongCell.swift; sourceTree = ""; }; + E4B3B3652432DEDB007E25D2 /* AlbumSongListViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlbumSongListViewController.swift; sourceTree = ""; }; E4B3DF6423D66A4400728F6B /* QueueSongCoverView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QueueSongCoverView.swift; sourceTree = ""; }; E4B46F8E2402E89800152157 /* MPDError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPDError.swift; sourceTree = ""; }; E4B5AE7D22F4C49600CCEC65 /* MPDServerDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPDServerDelegate.swift; sourceTree = ""; }; @@ -945,7 +952,9 @@ E412222A243182F700473C1D /* Album Detail */ = { isa = PBXGroup; children = ( - E412222B2431830500473C1D /* AlbumDetailViewController.swift */, + E412222F2432B0A300473C1D /* AlbumTracksDataSource.swift */, + E4B3B3622432DA4B007E25D2 /* AlbumSongCell.swift */, + E4B3B3652432DEDB007E25D2 /* AlbumSongListViewController.swift */, ); path = "Album Detail"; sourceTree = ""; @@ -1410,6 +1419,7 @@ isa = PBXGroup; children = ( E450AD7D222620A10091BED3 /* Album.swift */, + E41222312432B14000473C1D /* AlbumSongItem.swift */, E43AC1F422C6A4F4001E483C /* DraggedAlbum.swift */, E451E36C22BD23DB008BE9B2 /* DraggedSong.swift */, E451E36A22BD214D008BE9B2 /* DraggedSongType.swift */, @@ -1729,6 +1739,7 @@ E48059EE2426D73600362CF3 /* socket.c in Sources */, E4F6B467221E233200ACF42A /* AlbumDataSource.swift in Sources */, E4B11BA92274EDE30075461B /* Loading.swift in Sources */, + E41222332432B15100473C1D /* AlbumSongItem.swift in Sources */, E408D3C2220E134F0006D9BE /* AlbumViewController.swift in Sources */, E42A4D4F22E20D7D001C6CAD /* MPDTag.swift in Sources */, E48059D82426D73600362CF3 /* database.c in Sources */, @@ -1952,15 +1963,18 @@ E48059D72426D73600362CF3 /* ierror.c in Sources */, E48059F32426D73600362CF3 /* capabilities.c in Sources */, E483CE69242FEFB8001F742E /* Notification.swift in Sources */, + E41222322432B14000473C1D /* AlbumSongItem.swift in Sources */, E480511B24255BAF00362CF3 /* TrackTimer.swift in Sources */, E480513124255BDF00362CF3 /* MPDStatus.swift in Sources */, E480514424255E7700362CF3 /* PlayerReducer.swift in Sources */, + E4B3B3672432DF1B007E25D2 /* AlbumSongListViewController.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 */, E480512324255BDB00362CF3 /* MPDClient+Database.swift in Sources */, + E41222302432B0A300473C1D /* AlbumTracksDataSource.swift in Sources */, E48059ED2426D73600362CF3 /* stats.c in Sources */, E480514824255E7700362CF3 /* UIReducer.swift in Sources */, E480512124255BDB00362CF3 /* MPDClient+Command.swift in Sources */, @@ -1975,6 +1989,7 @@ E480513E24255E7200362CF3 /* PreferencesState.swift in Sources */, E4805A132426D73600362CF3 /* rplaylist.c in Sources */, E480513024255BDF00362CF3 /* MPDSong.swift in Sources */, + E4B3B3642432DB7A007E25D2 /* AlbumSongCell.swift in Sources */, E480511524255BAF00362CF3 /* DraggedSongType.swift in Sources */, E480512B24255BDF00362CF3 /* MPDAlbum.swift in Sources */, E412221A2431425400473C1D /* AlbumViewController+UICollectionViewDataSource.swift in Sources */, @@ -1989,7 +2004,6 @@ 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 */, diff --git a/Shared/Models/AlbumSongItem.swift b/Shared/Models/AlbumSongItem.swift new file mode 100644 index 0000000..e9b5fd2 --- /dev/null +++ b/Shared/Models/AlbumSongItem.swift @@ -0,0 +1,24 @@ +// +// AlbumSongItem.swift +// Persephone-iOS +// +// Created by Daniel Barber on 2020-3-30. +// Copyright © 2020 Dan Barber. All rights reserved. +// + +import Foundation + +struct AlbumSongItem { + let disc: String? + let song: Song? + + init(song: Song) { + self.disc = nil + self.song = song + } + + init(disc: String) { + self.disc = disc + self.song = nil + } +} diff --git a/iOS/Assets.xcassets/defaultCoverArt.imageset/Contents.json b/iOS/Assets.xcassets/defaultCoverArt.imageset/Contents.json index 1b44a55..3312479 100644 --- a/iOS/Assets.xcassets/defaultCoverArt.imageset/Contents.json +++ b/iOS/Assets.xcassets/defaultCoverArt.imageset/Contents.json @@ -18,5 +18,9 @@ "info" : { "author" : "xcode", "version" : 1 + }, + "properties" : { + "auto-scaling" : "auto", + "preserves-vector-representation" : true } } diff --git a/iOS/Base.lproj/Main.storyboard b/iOS/Base.lproj/Main.storyboard index 8d9ff95..4fadc83 100644 --- a/iOS/Base.lproj/Main.storyboard +++ b/iOS/Base.lproj/Main.storyboard @@ -3,7 +3,6 @@ - @@ -67,7 +66,7 @@ - + @@ -81,94 +80,159 @@ - - + + - - + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - + + + + + + - - + + - + @@ -210,7 +274,6 @@ - diff --git a/iOS/Components/Browser/Album Browser/AlbumViewController.swift b/iOS/Components/Browser/Album Browser/AlbumViewController.swift index bb65348..dbc610f 100644 --- a/iOS/Components/Browser/Album Browser/AlbumViewController.swift +++ b/iOS/Components/Browser/Album Browser/AlbumViewController.swift @@ -46,7 +46,7 @@ class AlbumViewController: UICollectionViewController { } override func prepare(for segue: UIStoryboardSegue, sender: Any?) { - guard let detailView = segue.destination as? AlbumDetailViewController, + guard let detailView = segue.destination as? AlbumSongListViewController, let sender = sender as? AlbumItemCell else { return } diff --git a/iOS/Components/Browser/Album Detail/AlbumSongCell.swift b/iOS/Components/Browser/Album Detail/AlbumSongCell.swift new file mode 100644 index 0000000..ad203ae --- /dev/null +++ b/iOS/Components/Browser/Album Detail/AlbumSongCell.swift @@ -0,0 +1,24 @@ +// +// AlbumSongCell.swift +// Persephone +// +// Created by Daniel Barber on 2020-3-30. +// Copyright © 2020 Dan Barber. All rights reserved. +// + +import UIKit + +class AlbumSongCell: UITableViewCell { + var albumSongItem: AlbumSongItem? + + func setSongItem(songItem: AlbumSongItem) { + albumSongItem = songItem + + trackNumber.text = songItem.song?.trackNumber + songTitle.text = songItem.song?.title + } + + @IBOutlet var trackNumber: UILabel! + @IBOutlet var songTitle: UILabel! + @IBOutlet var songDuration: UILabel! +} diff --git a/iOS/Components/Browser/Album Detail/AlbumDetailViewController.swift b/iOS/Components/Browser/Album Detail/AlbumSongListViewController.swift similarity index 60% rename from iOS/Components/Browser/Album Detail/AlbumDetailViewController.swift rename to iOS/Components/Browser/Album Detail/AlbumSongListViewController.swift index b267dd1..50c5276 100644 --- a/iOS/Components/Browser/Album Detail/AlbumDetailViewController.swift +++ b/iOS/Components/Browser/Album Detail/AlbumSongListViewController.swift @@ -1,39 +1,58 @@ // -// AlbumDetailController.swift -// Persephone-iOS +// AlbumSongListViewController.swift +// Persephone // -// Created by Daniel Barber on 2020-3-29. +// Created by Daniel Barber on 2020-3-30. // Copyright © 2020 Dan Barber. All rights reserved. // import UIKit import Kingfisher -class AlbumDetailViewController: UIViewController { +class AlbumSongListViewController: UITableViewController { var album: Album? var albumSongs: [Song] = [] + var dataSource = AlbumTracksDataSource() override func viewDidLoad() { super.viewDidLoad() + albumTracksView.dataSource = dataSource + albumTracksView.layoutMargins = UIEdgeInsets(top: 0, left: 20, bottom: 0, right: 20) + 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 + addAlbumToQueueButton.layer.cornerRadius = 8 setAppearance() } - + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + guard let album = album else { return } + + getAlbumSongs(for: album) albumTitle.text = album.title - albumArtist.text = album.artist + albumMetadata.text = "\(album.artist) · \(album.date)" - getAlbumSongs(for: album) + var layoutSize = UIView.layoutFittingExpandedSize + layoutSize.width = UIScreen.main.bounds.width + + let headerViewSize = albumTracksView.tableHeaderView? + .systemLayoutSizeFitting( + layoutSize, + withHorizontalFittingPriority: .defaultHigh, + verticalFittingPriority: .defaultLow + ) + + albumTracksView.tableHeaderView?.frame.size = headerViewSize! } func setAlbum(_ album: Album?) { @@ -41,24 +60,26 @@ class AlbumDetailViewController: UIViewController { 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.dataSource.setAlbumSongs( + mpdSongs.map { Song(mpdSong: $0) } + ) - //self.albumTracksView.reloadData() + 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, @@ -74,9 +95,11 @@ class AlbumDetailViewController: UIViewController { ] ) } - - override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { - setAppearance() + + @IBAction func playAlbumAction(_ sender: Any) { + guard let album = album else { return } + + App.mpdClient.playAlbum(album.mpdAlbum) } func setAppearance() { @@ -85,14 +108,18 @@ class AlbumDetailViewController: UIViewController { albumCoverView.layer.borderColor = darkMode ? CGColor.albumBorderColorDark : CGColor.albumBorderColorLight } - @IBAction func playAlbumAction(_ sender: Any) { - guard let album = album else { return } - - App.mpdClient.playAlbum(album.mpdAlbum) - } - + // @IBAction func addAlbumToQueueAction(_ sender: Any) { + // guard let album = album else { return } + // + // let queueLength = App.store.state.queueState.queue.count + // + // App.mpdClient.addAlbumToQueue(album: album.mpdAlbum, at: queueLength) + // } + @IBOutlet var addAlbumToQueueButton: UIButton! @IBOutlet var playAlbumButton: UIButton! - @IBOutlet var albumCoverView: UIImageView! @IBOutlet var albumTitle: UILabel! - @IBOutlet var albumArtist: UILabel! + @IBOutlet var albumMetadata: UILabel! + + @IBOutlet var albumCoverView: UIImageView! + @IBOutlet var albumTracksView: UITableView! } diff --git a/iOS/Components/Browser/Album Detail/AlbumTracksDataSource.swift b/iOS/Components/Browser/Album Detail/AlbumTracksDataSource.swift new file mode 100644 index 0000000..9dbfc05 --- /dev/null +++ b/iOS/Components/Browser/Album Detail/AlbumTracksDataSource.swift @@ -0,0 +1,39 @@ +// +// AlbumTracksDataSource.swift +// Persephone +// +// Created by Daniel Barber on 2019/5/19. +// Copyright © 2019 Dan Barber. All rights reserved. +// + +import UIKit + +class AlbumTracksDataSource: NSObject, UITableViewDataSource { + var albumSongs: [AlbumSongItem] = [] + + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return albumSongs.count + } + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + guard let albumSongCell = tableView.dequeueReusableCell(withIdentifier: "albumSongCell") as? AlbumSongCell + else { return AlbumSongCell() } + + albumSongCell.setSongItem(songItem: albumSongs[indexPath.row]) + + return albumSongCell + } + + func setAlbumSongs(_ songs: [Song]) { + var disc: String? = "" + + songs.forEach { song in + if song.disc != disc && song.disc != "0" { + disc = song.disc + albumSongs.append(AlbumSongItem(disc: song.disc)) + } + + albumSongs.append(AlbumSongItem(song: song)) + } + } +} diff --git a/iOS/Components/Shared/Extensions/CGSize.swift b/iOS/Components/Shared/Extensions/CGSize.swift index e3812a6..82bd7f8 100644 --- a/iOS/Components/Shared/Extensions/CGSize.swift +++ b/iOS/Components/Shared/Extensions/CGSize.swift @@ -1,17 +1,20 @@ // -// NSSize.swift +// CGSize.swift // Persephone // // Created by Daniel Barber on 1/20/20. // Copyright © 2020 Dan Barber. All rights reserved. // -import CoreGraphics +import UIKit extension CGSize { + static let albumListWidth = (UIScreen.main.bounds.width - 60) / 2 + static let albumDetailWidth = UIScreen.main.bounds.width - 40 + 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 albumListCoverSize = CGSize(width: albumListWidth, height: albumListWidth) + static let albumDetailCoverSize = CGSize(width: albumDetailWidth, height: albumDetailWidth) static let currentlyPlayingCoverSize = albumDetailCoverSize static let notificationCoverSize = albumListCoverSize }