mirror of
https://github.com/danbee/persephone
synced 2025-03-04 08:39:11 +00:00
Mostly working, albumlist is not showing album art
This commit is contained in:
parent
bb5a7c2c5c
commit
2e6c903d74
@ -88,6 +88,10 @@
|
||||
E4B11B6F226A5C7A0075461B /* UpdateStatusAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4B11B6E226A5C7A0075461B /* UpdateStatusAction.swift */; };
|
||||
E4B11B71226A64E60075461B /* UpdateElapsedTimeAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4B11B70226A64E60075461B /* UpdateElapsedTimeAction.swift */; };
|
||||
E4B11B73226A6C770075461B /* TrackTimer.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4B11B72226A6C770075461B /* TrackTimer.swift */; };
|
||||
E4B11B75226CC4D30075461B /* QueueReducer.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4B11B74226CC4D30075461B /* QueueReducer.swift */; };
|
||||
E4B11B77226CC6BE0075461B /* UpdateQueuePosAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4B11B76226CC6BE0075461B /* UpdateQueuePosAction.swift */; };
|
||||
E4B11B79226D346B0075461B /* AlbumListReducer.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4B11B78226D346B0075461B /* AlbumListReducer.swift */; };
|
||||
E4B11B7B226D34F80075461B /* UpdateAlbumListAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4B11B7A226D34F80075461B /* UpdateAlbumListAction.swift */; };
|
||||
E4C8B53C22342005009A20F3 /* PreferencesWindowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4C8B53B22342005009A20F3 /* PreferencesWindowController.swift */; };
|
||||
E4C8B53E22349002009A20F3 /* MPDIdle.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4C8B53D22349002009A20F3 /* MPDIdle.swift */; };
|
||||
E4E8CC902204EC7F0024217A /* Delegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4E8CC8F2204EC7F0024217A /* Delegate.swift */; };
|
||||
@ -267,6 +271,10 @@
|
||||
E4B11B6E226A5C7A0075461B /* UpdateStatusAction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UpdateStatusAction.swift; sourceTree = "<group>"; };
|
||||
E4B11B70226A64E60075461B /* UpdateElapsedTimeAction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UpdateElapsedTimeAction.swift; sourceTree = "<group>"; };
|
||||
E4B11B72226A6C770075461B /* TrackTimer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrackTimer.swift; sourceTree = "<group>"; };
|
||||
E4B11B74226CC4D30075461B /* QueueReducer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QueueReducer.swift; sourceTree = "<group>"; };
|
||||
E4B11B76226CC6BE0075461B /* UpdateQueuePosAction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UpdateQueuePosAction.swift; sourceTree = "<group>"; };
|
||||
E4B11B78226D346B0075461B /* AlbumListReducer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlbumListReducer.swift; sourceTree = "<group>"; };
|
||||
E4B11B7A226D34F80075461B /* UpdateAlbumListAction.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UpdateAlbumListAction.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>"; };
|
||||
E4E8CC8F2204EC7F0024217A /* Delegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Delegate.swift; sourceTree = "<group>"; };
|
||||
@ -566,6 +574,8 @@
|
||||
children = (
|
||||
E4B11B60226A4BFF0075461B /* PlayerReducer.swift */,
|
||||
E4B11B62226A4C510075461B /* AppReducer.swift */,
|
||||
E4B11B74226CC4D30075461B /* QueueReducer.swift */,
|
||||
E4B11B78226D346B0075461B /* AlbumListReducer.swift */,
|
||||
);
|
||||
path = Reducers;
|
||||
sourceTree = "<group>";
|
||||
@ -584,9 +594,11 @@
|
||||
E4B11B6B226A5AF50075461B /* Actions */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
E4B11B6C226A5B180075461B /* UpdateQueueAction.swift */,
|
||||
E4B11B6E226A5C7A0075461B /* UpdateStatusAction.swift */,
|
||||
E4B11B7A226D34F80075461B /* UpdateAlbumListAction.swift */,
|
||||
E4B11B70226A64E60075461B /* UpdateElapsedTimeAction.swift */,
|
||||
E4B11B6C226A5B180075461B /* UpdateQueueAction.swift */,
|
||||
E4B11B76226CC6BE0075461B /* UpdateQueuePosAction.swift */,
|
||||
E4B11B6E226A5C7A0075461B /* UpdateStatusAction.swift */,
|
||||
);
|
||||
path = Actions;
|
||||
sourceTree = "<group>";
|
||||
@ -837,6 +849,7 @@
|
||||
E4F6B467221E233200ACF42A /* AlbumDataSource.swift in Sources */,
|
||||
E408D3C2220E134F0006D9BE /* AlbumViewController.swift in Sources */,
|
||||
E40FE71B221B904300A4223F /* NSEvent.swift in Sources */,
|
||||
E4B11B7B226D34F80075461B /* UpdateAlbumListAction.swift in Sources */,
|
||||
E4B11B6D226A5B180075461B /* UpdateQueueAction.swift in Sources */,
|
||||
E4B11B68226A4FA00075461B /* QueueState.swift in Sources */,
|
||||
E4928E0B2218D62A001D4BEA /* CGColor.swift in Sources */,
|
||||
@ -848,6 +861,7 @@
|
||||
E41E5307223C019100173814 /* MPDClient+Status.swift in Sources */,
|
||||
E41E5310223EF6CE00173814 /* AlbumArtService+Remote.swift in Sources */,
|
||||
E41E530B223C033700173814 /* MPDClient+Album.swift in Sources */,
|
||||
E4B11B77226CC6BE0075461B /* UpdateQueuePosAction.swift in Sources */,
|
||||
E42410B62241B956005ED6DF /* MPDClient+Database.swift in Sources */,
|
||||
E4A642DA22090CBE00067D21 /* MPDStatus.swift in Sources */,
|
||||
E47E2FD72220720300F747E6 /* AlbumItemView.swift in Sources */,
|
||||
@ -870,8 +884,10 @@
|
||||
E419E2872249B96600216A8C /* Song.swift in Sources */,
|
||||
E439109822640213002982E9 /* SongNotifierService.swift in Sources */,
|
||||
E407861C2110CE6E006887B1 /* AppDelegate.swift in Sources */,
|
||||
E4B11B75226CC4D30075461B /* QueueReducer.swift in Sources */,
|
||||
E41E5309223C020400173814 /* MPDClient+Command.swift in Sources */,
|
||||
E4B11B73226A6C770075461B /* TrackTimer.swift in Sources */,
|
||||
E4B11B79226D346B0075461B /* AlbumListReducer.swift in Sources */,
|
||||
E47E2FE52220AA0700F747E6 /* AlbumViewLayout.swift in Sources */,
|
||||
E41E52FF223BF95E00173814 /* MPDClient+Transport.swift in Sources */,
|
||||
E47E2FD322205D2500F747E6 /* MainWindow.swift in Sources */,
|
||||
|
||||
13
Persephone/Actions/UpdateAlbumListAction.swift
Normal file
13
Persephone/Actions/UpdateAlbumListAction.swift
Normal file
@ -0,0 +1,13 @@
|
||||
//
|
||||
// UpdateAlbumListAction.swift
|
||||
// Persephone
|
||||
//
|
||||
// Created by Daniel Barber on 2019/4/21.
|
||||
// Copyright © 2019 Dan Barber. All rights reserved.
|
||||
//
|
||||
|
||||
import ReSwift
|
||||
|
||||
struct UpdateAlbumListAction: Action {
|
||||
var albums: [MPDClient.MPDAlbum]
|
||||
}
|
||||
13
Persephone/Actions/UpdateQueuePosAction.swift
Normal file
13
Persephone/Actions/UpdateQueuePosAction.swift
Normal file
@ -0,0 +1,13 @@
|
||||
//
|
||||
// UpdateQueuePosAction.swift
|
||||
// Persephone
|
||||
//
|
||||
// Created by Daniel Barber on 2019/4/21.
|
||||
// Copyright © 2019 Dan Barber. All rights reserved.
|
||||
//
|
||||
|
||||
import ReSwift
|
||||
|
||||
struct UpdateQueuePosAction: Action {
|
||||
var queuePos: Int
|
||||
}
|
||||
@ -21,7 +21,7 @@ class AppDelegate: NSObject, NSApplicationDelegate, MediaKeyTapDelegate {
|
||||
|
||||
static let trackTimer = TrackTimer()
|
||||
|
||||
static let store = Store(reducer: appReducer, state: nil)
|
||||
static let store = Store<AppState>(reducer: appReducer, state: nil)
|
||||
|
||||
func applicationDidFinishLaunching(_ aNotification: Notification) {
|
||||
connect()
|
||||
|
||||
@ -7,10 +7,14 @@
|
||||
//
|
||||
|
||||
import Cocoa
|
||||
import ReSwift
|
||||
|
||||
class AlbumViewController: NSViewController,
|
||||
NSCollectionViewDelegate,
|
||||
NSCollectionViewDelegateFlowLayout {
|
||||
NSCollectionViewDelegateFlowLayout,
|
||||
StoreSubscriber {
|
||||
typealias StoreSubscriberStateType = AlbumListState
|
||||
|
||||
var preferences = Preferences()
|
||||
|
||||
let paddingWidth: CGFloat = 40
|
||||
@ -21,22 +25,14 @@ class AlbumViewController: NSViewController,
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
AppDelegate.store.subscribe(self) {
|
||||
(subscription: Subscription<AppState>) -> Subscription<AlbumListState> in
|
||||
|
||||
subscription.select { state -> AlbumListState in state.albumListState }
|
||||
}
|
||||
|
||||
albumScrollView.postsBoundsChangedNotifications = true
|
||||
|
||||
NotificationCenter.default.addObserver(
|
||||
self,
|
||||
selector: #selector(updateAlbums(_:)),
|
||||
name: Notification.loadedAlbums,
|
||||
object: AppDelegate.mpdClient
|
||||
)
|
||||
|
||||
NotificationCenter.default.addObserver(
|
||||
self,
|
||||
selector: #selector(clearAlbums(_:)),
|
||||
name: Notification.willDisconnect,
|
||||
object: AppDelegate.mpdClient
|
||||
)
|
||||
|
||||
albumCollectionView.dataSource = dataSource
|
||||
|
||||
preferences.addObserver(self, forKeyPath: "mpdLibraryDir")
|
||||
@ -72,24 +68,15 @@ class AlbumViewController: NSViewController,
|
||||
case "mpdLibraryDir":
|
||||
albumCollectionView.reloadData()
|
||||
case "fetchMissingArtworkFromInternet":
|
||||
dataSource.resetCoverArt()
|
||||
// dataSource.resetCoverArt()
|
||||
albumCollectionView.reloadData()
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
@objc func updateAlbums(_ notification: Notification) {
|
||||
guard let albums = notification.userInfo?[Notification.albumsKey] as? [MPDClient.MPDAlbum]
|
||||
else { return }
|
||||
|
||||
dataSource.albums = albums.map { Album(mpdAlbum: $0) }
|
||||
albumCollectionView.reloadData()
|
||||
}
|
||||
|
||||
@objc func clearAlbums(_ notification: Notification) {
|
||||
dataSource.albums = []
|
||||
|
||||
func newState(state: StoreSubscriberStateType) {
|
||||
print("New album list state")
|
||||
albumCollectionView.reloadData()
|
||||
}
|
||||
|
||||
|
||||
@ -16,26 +16,16 @@ class NotificationsController: MPDClientDelegate {
|
||||
}
|
||||
|
||||
func willDisconnect(mpdClient: MPDClient) {
|
||||
DispatchQueue.main.async {
|
||||
AppDelegate.store.dispatch(UpdateAlbumListAction(albums: []))
|
||||
}
|
||||
sendNotification(name: Notification.willDisconnect)
|
||||
}
|
||||
|
||||
func didUpdateStatus(mpdClient: MPDClient, status: MPDClient.MPDStatus) {
|
||||
AppDelegate.store.dispatch(UpdateStatusAction(status: status))
|
||||
sendNotification(
|
||||
name: Notification.stateChanged,
|
||||
userInfo: [Notification.stateKey: status.state]
|
||||
)
|
||||
sendNotification(
|
||||
name: Notification.timeChanged,
|
||||
userInfo: [
|
||||
Notification.totalTimeKey: status.totalTime,
|
||||
Notification.elapsedTimeMsKey: status.elapsedTimeMs
|
||||
]
|
||||
)
|
||||
}
|
||||
|
||||
func didUpdateTime(mpdClient: MPDClient, total: UInt, elapsedMs: UInt) {
|
||||
|
||||
DispatchQueue.main.async {
|
||||
AppDelegate.store.dispatch(UpdateStatusAction(status: status))
|
||||
}
|
||||
}
|
||||
|
||||
func willStartDatabaseUpdate(mpdClient: MPDClient) {
|
||||
@ -47,21 +37,22 @@ class NotificationsController: MPDClientDelegate {
|
||||
}
|
||||
|
||||
func didUpdateQueue(mpdClient: MPDClient, queue: [MPDClient.MPDSong]) {
|
||||
//AppDelegate.store.dispatch(UpdateQueueAction(queue: queue))
|
||||
sendNotification(
|
||||
name: Notification.queueChanged,
|
||||
userInfo: [Notification.queueKey: queue]
|
||||
)
|
||||
DispatchQueue.main.async {
|
||||
AppDelegate.store.dispatch(UpdateQueueAction(queue: queue))
|
||||
}
|
||||
}
|
||||
|
||||
func didUpdateQueuePos(mpdClient: MPDClient, song: Int) {
|
||||
sendNotification(
|
||||
name: Notification.queuePosChanged,
|
||||
userInfo: [Notification.queuePosKey: song]
|
||||
)
|
||||
DispatchQueue.main.async {
|
||||
AppDelegate.store.dispatch(UpdateQueuePosAction(queuePos: song))
|
||||
}
|
||||
}
|
||||
|
||||
func didLoadAlbums(mpdClient: MPDClient, albums: [MPDClient.MPDAlbum]) {
|
||||
print("Albums")
|
||||
DispatchQueue.main.async {
|
||||
AppDelegate.store.dispatch(UpdateAlbumListAction(albums: albums))
|
||||
}
|
||||
sendNotification(
|
||||
name: Notification.loadedAlbums,
|
||||
userInfo: [Notification.albumsKey: albums]
|
||||
|
||||
@ -7,10 +7,13 @@
|
||||
//
|
||||
|
||||
import Cocoa
|
||||
import PromiseKit
|
||||
import ReSwift
|
||||
|
||||
class QueueViewController: NSViewController,
|
||||
NSOutlineViewDelegate {
|
||||
NSOutlineViewDelegate,
|
||||
StoreSubscriber {
|
||||
typealias StoreSubscriberStateType = QueueState
|
||||
|
||||
var dataSource = QueueDataSource()
|
||||
|
||||
@IBOutlet var queueView: NSOutlineView!
|
||||
@ -19,11 +22,22 @@ class QueueViewController: NSViewController,
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
setupNotificationObservers()
|
||||
AppDelegate.store.subscribe(self) {
|
||||
(subscription: Subscription<AppState>) -> Subscription<QueueState> in
|
||||
|
||||
subscription.select { state in state.queueState }
|
||||
}
|
||||
|
||||
queueView.dataSource = dataSource
|
||||
queueView.columnAutoresizingStyle = .sequentialColumnAutoresizingStyle
|
||||
}
|
||||
}
|
||||
|
||||
func newState(state: StoreSubscriberStateType) {
|
||||
print("New queue state")
|
||||
dataSource.setQueueIcon()
|
||||
queueView.reloadData()
|
||||
updateAlbumArt(state)
|
||||
}
|
||||
|
||||
override func keyDown(with event: NSEvent) {
|
||||
switch event.keyCode {
|
||||
@ -42,15 +56,8 @@ class QueueViewController: NSViewController,
|
||||
}
|
||||
}
|
||||
|
||||
@objc func stateChanged(_ notification: Notification) {
|
||||
guard let state = notification.userInfo?[Notification.stateKey] as? MPDClient.MPDStatus.State
|
||||
else { return }
|
||||
|
||||
dataSource.setQueueIcon(state)
|
||||
}
|
||||
|
||||
func notifyTrack() {
|
||||
guard let currentSong = dataSource.currentSong,
|
||||
func notifyTrack(_ state: QueueState) {
|
||||
guard let currentSong = state.currentSong,
|
||||
let status = AppDelegate.mpdClient.status,
|
||||
status.state == .playing
|
||||
else { return }
|
||||
@ -59,25 +66,10 @@ class QueueViewController: NSViewController,
|
||||
.deliver()
|
||||
}
|
||||
|
||||
@objc func queueChanged(_ notification: Notification) {
|
||||
guard let queue = notification.userInfo?[Notification.queueKey] as? [MPDClient.MPDSong]
|
||||
else { return }
|
||||
|
||||
dataSource.updateQueue(queue)
|
||||
queueView.reloadData()
|
||||
}
|
||||
|
||||
@objc func queuePosChanged(_ notification: Notification) {
|
||||
guard let queuePos = notification.userInfo?[Notification.queuePosKey] as? Int
|
||||
else { return }
|
||||
|
||||
dataSource.setQueuePos(queuePos)
|
||||
queueView.reloadData()
|
||||
updateAlbumArt()
|
||||
}
|
||||
|
||||
func updateAlbumArt() {
|
||||
if let playingQueueItem = dataSource.queue.first(where: { $0.isPlaying }) {
|
||||
func updateAlbumArt(_ state: QueueState) {
|
||||
if let playingQueueItem = state.queue.first(
|
||||
where: { $0.isPlaying }
|
||||
) {
|
||||
let albumArtService = AlbumArtService(song: playingQueueItem.song)
|
||||
|
||||
albumArtService.fetchBigAlbumArt()
|
||||
@ -88,7 +80,7 @@ class QueueViewController: NSViewController,
|
||||
self.queueAlbumArtImage.image = NSImage.defaultCoverArt
|
||||
}
|
||||
|
||||
self.notifyTrack()
|
||||
self.notifyTrack(state)
|
||||
}
|
||||
.cauterize()
|
||||
} else {
|
||||
@ -168,27 +160,4 @@ func cellForSongTitle(_ outlineView: NSOutlineView, with queueItem: QueueItem) -
|
||||
|
||||
return cellView
|
||||
}
|
||||
|
||||
func setupNotificationObservers() {
|
||||
NotificationCenter.default.addObserver(
|
||||
self,
|
||||
selector: #selector(stateChanged(_:)),
|
||||
name: Notification.stateChanged,
|
||||
object: AppDelegate.mpdClient
|
||||
)
|
||||
|
||||
NotificationCenter.default.addObserver(
|
||||
self,
|
||||
selector: #selector(queueChanged(_:)),
|
||||
name: Notification.queueChanged,
|
||||
object: AppDelegate.mpdClient
|
||||
)
|
||||
|
||||
NotificationCenter.default.addObserver(
|
||||
self,
|
||||
selector: #selector(queuePosChanged(_:)),
|
||||
name: Notification.queuePosChanged,
|
||||
object: AppDelegate.mpdClient
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -10,7 +10,7 @@ import Cocoa
|
||||
import ReSwift
|
||||
|
||||
class WindowController: NSWindowController, StoreSubscriber {
|
||||
typealias StoreSubscriberStateType = AppState
|
||||
typealias StoreSubscriberStateType = PlayerState
|
||||
|
||||
enum TransportAction: Int {
|
||||
case prevTrack, playPause, stop, nextTrack
|
||||
@ -23,8 +23,11 @@ class WindowController: NSWindowController, StoreSubscriber {
|
||||
super.windowDidLoad()
|
||||
window?.titleVisibility = .hidden
|
||||
|
||||
// TODO: We will want to filter this subscribe later
|
||||
AppDelegate.store.subscribe(self)
|
||||
AppDelegate.store.subscribe(self) {
|
||||
(subscription: Subscription<AppState>) -> Subscription<PlayerState> in
|
||||
|
||||
subscription.select { state in state.playerState }
|
||||
}
|
||||
|
||||
NotificationCenter.default.addObserver(
|
||||
self,
|
||||
@ -44,12 +47,13 @@ class WindowController: NSWindowController, StoreSubscriber {
|
||||
trackRemaining.font = .timerFont
|
||||
}
|
||||
|
||||
func newState(state: WindowController.StoreSubscriberStateType) {
|
||||
self.state = state.playerState.state
|
||||
func newState(state: StoreSubscriberStateType) {
|
||||
print("New player state")
|
||||
self.state = state.state
|
||||
|
||||
DispatchQueue.main.async {
|
||||
self.setTransportControlState(state.playerState)
|
||||
self.setTrackProgressControls(state.playerState)
|
||||
self.setTransportControlState(state)
|
||||
self.setTrackProgressControls(state)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -10,45 +10,44 @@ import Cocoa
|
||||
import PromiseKit
|
||||
|
||||
class AlbumDataSource: NSObject, NSCollectionViewDataSource {
|
||||
var albums: [Album] = []
|
||||
|
||||
func collectionView(_ collectionView: NSCollectionView, numberOfItemsInSection section: Int) -> Int {
|
||||
return albums.count
|
||||
}
|
||||
|
||||
func resetCoverArt() {
|
||||
albums = albums.map {
|
||||
var album = $0
|
||||
album.coverArtFetched = false
|
||||
return album
|
||||
}
|
||||
return AppDelegate.store.state.albumListState.albums.count
|
||||
}
|
||||
//
|
||||
// func resetCoverArt() {
|
||||
// albums = AppDelegate.store.state.albumListState.albums.map {
|
||||
// var album = $0
|
||||
// album.coverArtFetched = false
|
||||
// return album
|
||||
// }
|
||||
// }
|
||||
|
||||
func collectionView(_ collectionView: NSCollectionView, itemForRepresentedObjectAt indexPath: IndexPath) -> NSCollectionViewItem {
|
||||
let albums = AppDelegate.store.state.albumListState.albums
|
||||
let item = collectionView.makeItem(withIdentifier: .albumViewItem, for: indexPath)
|
||||
guard let albumViewItem = item as? AlbumViewItem else { return item }
|
||||
|
||||
albumViewItem.view.wantsLayer = true
|
||||
albumViewItem.setAlbum(albums[indexPath.item])
|
||||
|
||||
if albums[indexPath.item].coverArt == nil &&
|
||||
!albums[indexPath.item].coverArtFetched {
|
||||
|
||||
AppDelegate.mpdClient.getAlbumFirstSong(for: albums[indexPath.item].mpdAlbum) {
|
||||
guard let song = $0 else { return }
|
||||
|
||||
AlbumArtService(song: Song(mpdSong: song))
|
||||
.fetchAlbumArt()
|
||||
.done { image in
|
||||
self.albums[indexPath.item].coverArt = image
|
||||
self.albums[indexPath.item].coverArtFetched = true
|
||||
|
||||
DispatchQueue.main.async {
|
||||
collectionView.reloadItems(at: [indexPath])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// if albums[indexPath.item].coverArt == nil &&
|
||||
// !albums[indexPath.item].coverArtFetched {
|
||||
//
|
||||
// AppDelegate.mpdClient.getAlbumFirstSong(for: albums[indexPath.item].mpdAlbum) {
|
||||
// guard let song = $0 else { return }
|
||||
//
|
||||
// AlbumArtService(song: Song(mpdSong: song))
|
||||
// .fetchAlbumArt()
|
||||
// .done { image in
|
||||
// self.albums[indexPath.item].coverArt = image
|
||||
// self.albums[indexPath.item].coverArtFetched = true
|
||||
//
|
||||
// DispatchQueue.main.async {
|
||||
// collectionView.reloadItems(at: [indexPath])
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
return albumViewItem
|
||||
}
|
||||
|
||||
@ -9,46 +9,13 @@
|
||||
import Cocoa
|
||||
|
||||
class QueueDataSource: NSObject, NSOutlineViewDataSource {
|
||||
var queue: [QueueItem] = []
|
||||
var queuePos: Int = -1
|
||||
var currentSong: Song?
|
||||
|
||||
var queueIcon: NSImage? = nil
|
||||
|
||||
func updateQueue(_ queue: [MPDClient.MPDSong]) {
|
||||
queuePos = -1
|
||||
|
||||
self.queue = queue.enumerated().map { index, mpdSong in
|
||||
let song = Song(mpdSong: mpdSong)
|
||||
return QueueItem(
|
||||
song: song,
|
||||
queuePos: index,
|
||||
isPlaying: index == queuePos
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
func setQueuePos(_ queuePos: Int) {
|
||||
let oldSongRowPos = self.queuePos
|
||||
let newSongRowPos = queuePos
|
||||
self.queuePos = queuePos
|
||||
|
||||
if oldSongRowPos >= 0 {
|
||||
queue[oldSongRowPos].isPlaying = false
|
||||
}
|
||||
if newSongRowPos >= 0 {
|
||||
queue[newSongRowPos].isPlaying = true
|
||||
currentSong = queue[newSongRowPos].song
|
||||
} else {
|
||||
currentSong = nil
|
||||
}
|
||||
}
|
||||
|
||||
func setQueueIcon(_ state: MPDClient.MPDStatus.State) {
|
||||
switch state {
|
||||
case .playing:
|
||||
func setQueueIcon() {
|
||||
switch AppDelegate.store.state.playerState.state {
|
||||
case .playing?:
|
||||
queueIcon = .playIcon
|
||||
case .paused:
|
||||
case .paused?:
|
||||
queueIcon = .pauseIcon
|
||||
default:
|
||||
queueIcon = nil
|
||||
@ -56,7 +23,7 @@ class QueueDataSource: NSObject, NSOutlineViewDataSource {
|
||||
}
|
||||
|
||||
func outlineView(_ outlineView: NSOutlineView, numberOfChildrenOfItem item: Any?) -> Int {
|
||||
return queue.count + 1
|
||||
return AppDelegate.store.state.queueState.queue.count + 1
|
||||
}
|
||||
|
||||
func outlineView(_ outlineView: NSOutlineView, isItemExpandable item: Any) -> Bool {
|
||||
@ -65,7 +32,7 @@ class QueueDataSource: NSObject, NSOutlineViewDataSource {
|
||||
|
||||
func outlineView(_ outlineView: NSOutlineView, child index: Int, ofItem item: Any?) -> Any {
|
||||
if index > 0 {
|
||||
return queue[index - 1]
|
||||
return AppDelegate.store.state.queueState.queue[index - 1]
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
|
||||
@ -30,3 +30,10 @@ struct Album {
|
||||
return "\(title) - \(artist)".sha1()
|
||||
}
|
||||
}
|
||||
|
||||
extension Album: Equatable {
|
||||
static func == (lhs: Album, rhs: Album) -> Bool {
|
||||
return (lhs.artist == rhs.artist) &&
|
||||
(lhs.title == rhs.title)
|
||||
}
|
||||
}
|
||||
|
||||
@ -13,3 +13,11 @@ struct QueueItem {
|
||||
var queuePos: Int
|
||||
var isPlaying: Bool
|
||||
}
|
||||
|
||||
extension QueueItem: Equatable {
|
||||
static func == (lhs: QueueItem, rhs: QueueItem) -> Bool {
|
||||
return (lhs.song == rhs.song) &&
|
||||
(lhs.queuePos == rhs.queuePos) &&
|
||||
(lhs.isPlaying == rhs.isPlaying)
|
||||
}
|
||||
}
|
||||
|
||||
@ -23,3 +23,11 @@ struct Song {
|
||||
return Album(mpdAlbum: mpdSong.album)
|
||||
}
|
||||
}
|
||||
|
||||
extension Song: Equatable {
|
||||
static func == (lhs: Song, rhs: Song) -> Bool {
|
||||
return (lhs.title == rhs.title) &&
|
||||
(lhs.artist == rhs.artist) &&
|
||||
(lhs.album == rhs.album)
|
||||
}
|
||||
}
|
||||
|
||||
@ -21,7 +21,7 @@ class TrackTimer: NSObject {
|
||||
startTime = CACurrentMediaTime()
|
||||
startElapsed = Double(elapsedTimeMs) / 1000
|
||||
|
||||
DispatchQueue.main.sync {
|
||||
DispatchQueue.main.async {
|
||||
self.timer = Timer.scheduledTimer(
|
||||
withTimeInterval: 0.25,
|
||||
repeats: true
|
||||
|
||||
22
Persephone/Reducers/AlbumListReducer.swift
Normal file
22
Persephone/Reducers/AlbumListReducer.swift
Normal file
@ -0,0 +1,22 @@
|
||||
//
|
||||
// AlbumListReducer.swift
|
||||
// Persephone
|
||||
//
|
||||
// Created by Daniel Barber on 2019/4/21.
|
||||
// Copyright © 2019 Dan Barber. All rights reserved.
|
||||
//
|
||||
|
||||
import ReSwift
|
||||
|
||||
func albumListReducer(action: Action, state: AlbumListState?) -> AlbumListState {
|
||||
var state = state ?? AlbumListState()
|
||||
|
||||
switch action {
|
||||
case let action as UpdateAlbumListAction:
|
||||
state.albums = action.albums.map { Album(mpdAlbum: $0) }
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
return state
|
||||
}
|
||||
@ -6,11 +6,13 @@
|
||||
// Copyright © 2019 Dan Barber. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import ReSwift
|
||||
|
||||
func appReducer(action: Action, state: AppState?) -> AppState {
|
||||
print(action)
|
||||
return AppState(
|
||||
playerState: playerReducer(action: action, state: state?.playerState)
|
||||
playerState: playerReducer(action: action, state: state?.playerState),
|
||||
queueState: queueReducer(action: action, state: state?.queueState),
|
||||
albumListState: albumListReducer(action: action, state: state?.albumListState)
|
||||
)
|
||||
}
|
||||
|
||||
45
Persephone/Reducers/QueueReducer.swift
Normal file
45
Persephone/Reducers/QueueReducer.swift
Normal file
@ -0,0 +1,45 @@
|
||||
//
|
||||
// QueueReducer.swift
|
||||
// Persephone
|
||||
//
|
||||
// Created by Daniel Barber on 2019/4/21.
|
||||
// Copyright © 2019 Dan Barber. All rights reserved.
|
||||
//
|
||||
|
||||
import ReSwift
|
||||
|
||||
func queueReducer(action: Action, state: QueueState?) -> QueueState {
|
||||
var state = state ?? QueueState()
|
||||
|
||||
switch action {
|
||||
case let action as UpdateQueueAction:
|
||||
state.queuePos = -1
|
||||
|
||||
state.queue = action.queue.enumerated().map { index, mpdSong in
|
||||
let song = Song(mpdSong: mpdSong)
|
||||
|
||||
return QueueItem(
|
||||
song: song,
|
||||
queuePos: index,
|
||||
isPlaying: index == state.queuePos
|
||||
)
|
||||
}
|
||||
|
||||
case let action as UpdateQueuePosAction:
|
||||
let oldSongRowPos = state.queuePos
|
||||
let newSongRowPos = action.queuePos
|
||||
state.queuePos = action.queuePos
|
||||
|
||||
if oldSongRowPos >= 0 {
|
||||
state.queue[oldSongRowPos].isPlaying = false
|
||||
}
|
||||
if newSongRowPos >= 0 {
|
||||
state.queue[newSongRowPos].isPlaying = true
|
||||
}
|
||||
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
return state
|
||||
}
|
||||
@ -10,4 +10,11 @@ import ReSwift
|
||||
|
||||
struct AlbumListState: StateType {
|
||||
var albums: [Album] = []
|
||||
var albumsWithUpdates: [Int]
|
||||
}
|
||||
|
||||
extension AlbumListState: Equatable {
|
||||
static func == (lhs: AlbumListState, rhs: AlbumListState) -> Bool {
|
||||
return lhs.albums == rhs.albums
|
||||
}
|
||||
}
|
||||
|
||||
@ -10,6 +10,6 @@ import ReSwift
|
||||
|
||||
struct AppState: StateType {
|
||||
var playerState = PlayerState()
|
||||
// var queueState = QueueState()
|
||||
// var albumListState = AlbumListState()
|
||||
var queueState = QueueState()
|
||||
var albumListState = AlbumListState()
|
||||
}
|
||||
|
||||
@ -17,3 +17,11 @@ struct PlayerState: StateType {
|
||||
var totalTime: UInt?
|
||||
var elapsedTimeMs: UInt?
|
||||
}
|
||||
|
||||
extension PlayerState: Equatable {
|
||||
static func == (lhs: PlayerState, rhs: PlayerState) -> Bool {
|
||||
return (lhs.state == rhs.state) &&
|
||||
(lhs.totalTime == rhs.totalTime) &&
|
||||
(lhs.elapsedTimeMs == rhs.elapsedTimeMs)
|
||||
}
|
||||
}
|
||||
|
||||
@ -12,3 +12,10 @@ struct QueueState: StateType {
|
||||
var queue: [QueueItem] = []
|
||||
var queuePos: Int = -1
|
||||
}
|
||||
|
||||
extension QueueState: Equatable {
|
||||
static func == (lhs: QueueState, rhs: QueueState) -> Bool {
|
||||
return (lhs.queue == rhs.queue) &&
|
||||
(lhs.queuePos == rhs.queuePos)
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user