mirror of
https://github.com/danbee/persephone
synced 2025-03-04 08:39:11 +00:00
WIP: Get album metadata when fetching albums
This commit is contained in:
parent
4af3e7aead
commit
42d274058f
@ -74,7 +74,6 @@
|
|||||||
E489E39D22B9CF0000CA8CBD /* NSView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E489E39C22B9CF0000CA8CBD /* NSView.swift */; };
|
E489E39D22B9CF0000CA8CBD /* NSView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E489E39C22B9CF0000CA8CBD /* NSView.swift */; };
|
||||||
E489E3A422B9D31800CA8CBD /* DraggedSongView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E489E3A222B9D31800CA8CBD /* DraggedSongView.swift */; };
|
E489E3A422B9D31800CA8CBD /* DraggedSongView.swift in Sources */ = {isa = PBXBuildFile; fileRef = E489E3A222B9D31800CA8CBD /* DraggedSongView.swift */; };
|
||||||
E489E3A522B9D31800CA8CBD /* DraggedSongView.xib in Resources */ = {isa = PBXBuildFile; fileRef = E489E3A322B9D31800CA8CBD /* DraggedSongView.xib */; };
|
E489E3A522B9D31800CA8CBD /* DraggedSongView.xib in Resources */ = {isa = PBXBuildFile; fileRef = E489E3A322B9D31800CA8CBD /* DraggedSongView.xib */; };
|
||||||
E48E92D7235113DF00A5E1BB /* Metadata.swift in Sources */ = {isa = PBXBuildFile; fileRef = E48E92D6235113DF00A5E1BB /* Metadata.swift */; };
|
|
||||||
E4928E0B2218D62A001D4BEA /* CGColor.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4928E0A2218D62A001D4BEA /* CGColor.swift */; };
|
E4928E0B2218D62A001D4BEA /* CGColor.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4928E0A2218D62A001D4BEA /* CGColor.swift */; };
|
||||||
E49A5482233E580800EED353 /* PromiseKit in Frameworks */ = {isa = PBXBuildFile; productRef = E49A5481233E580800EED353 /* PromiseKit */; };
|
E49A5482233E580800EED353 /* PromiseKit in Frameworks */ = {isa = PBXBuildFile; productRef = E49A5481233E580800EED353 /* PromiseKit */; };
|
||||||
E49A5485233E5ADC00EED353 /* Differ in Frameworks */ = {isa = PBXBuildFile; productRef = E49A5484233E5ADC00EED353 /* Differ */; };
|
E49A5485233E5ADC00EED353 /* Differ in Frameworks */ = {isa = PBXBuildFile; productRef = E49A5484233E5ADC00EED353 /* Differ */; };
|
||||||
@ -279,7 +278,6 @@
|
|||||||
E489E39C22B9CF0000CA8CBD /* NSView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSView.swift; sourceTree = "<group>"; };
|
E489E39C22B9CF0000CA8CBD /* NSView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSView.swift; sourceTree = "<group>"; };
|
||||||
E489E3A222B9D31800CA8CBD /* DraggedSongView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DraggedSongView.swift; sourceTree = "<group>"; };
|
E489E3A222B9D31800CA8CBD /* DraggedSongView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DraggedSongView.swift; sourceTree = "<group>"; };
|
||||||
E489E3A322B9D31800CA8CBD /* DraggedSongView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = DraggedSongView.xib; sourceTree = "<group>"; };
|
E489E3A322B9D31800CA8CBD /* DraggedSongView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = DraggedSongView.xib; sourceTree = "<group>"; };
|
||||||
E48E92D6235113DF00A5E1BB /* Metadata.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Metadata.swift; sourceTree = "<group>"; };
|
|
||||||
E4928E0A2218D62A001D4BEA /* CGColor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CGColor.swift; sourceTree = "<group>"; };
|
E4928E0A2218D62A001D4BEA /* CGColor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CGColor.swift; sourceTree = "<group>"; };
|
||||||
E4A3A6A022A457B600EA2C40 /* AlbumDetailSongListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlbumDetailSongListView.swift; sourceTree = "<group>"; };
|
E4A3A6A022A457B600EA2C40 /* AlbumDetailSongListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlbumDetailSongListView.swift; sourceTree = "<group>"; };
|
||||||
E4A642D922090CBE00067D21 /* MPDStatus.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPDStatus.swift; sourceTree = "<group>"; };
|
E4A642D922090CBE00067D21 /* MPDStatus.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MPDStatus.swift; sourceTree = "<group>"; };
|
||||||
@ -736,7 +734,6 @@
|
|||||||
E419E2862249B96600216A8C /* Song.swift */,
|
E419E2862249B96600216A8C /* Song.swift */,
|
||||||
E47E2FDC2220A6D100F747E6 /* Time.swift */,
|
E47E2FDC2220A6D100F747E6 /* Time.swift */,
|
||||||
E4B11B72226A6C770075461B /* TrackTimer.swift */,
|
E4B11B72226A6C770075461B /* TrackTimer.swift */,
|
||||||
E48E92D6235113DF00A5E1BB /* Metadata.swift */,
|
|
||||||
);
|
);
|
||||||
path = Models;
|
path = Models;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -950,7 +947,6 @@
|
|||||||
E41E5307223C019100173814 /* MPDClient+Status.swift in Sources */,
|
E41E5307223C019100173814 /* MPDClient+Status.swift in Sources */,
|
||||||
E41E5310223EF6CE00173814 /* CoverArtService+Remote.swift in Sources */,
|
E41E5310223EF6CE00173814 /* CoverArtService+Remote.swift in Sources */,
|
||||||
E442CCCD2347E73C00004E0C /* Artist.swift in Sources */,
|
E442CCCD2347E73C00004E0C /* Artist.swift in Sources */,
|
||||||
E48E92D7235113DF00A5E1BB /* Metadata.swift in Sources */,
|
|
||||||
E41E530B223C033700173814 /* MPDClient+Album.swift in Sources */,
|
E41E530B223C033700173814 /* MPDClient+Album.swift in Sources */,
|
||||||
E42410B62241B956005ED6DF /* MPDClient+Database.swift in Sources */,
|
E42410B62241B956005ED6DF /* MPDClient+Database.swift in Sources */,
|
||||||
E4235640228623D2001216D6 /* QueueSongTitleView.swift in Sources */,
|
E4235640228623D2001216D6 /* QueueSongTitleView.swift in Sources */,
|
||||||
|
|||||||
@ -25,28 +25,18 @@ class AlbumDataSource: NSObject, NSCollectionViewDataSource {
|
|||||||
|
|
||||||
switch albums[indexPath.item].coverArt {
|
switch albums[indexPath.item].coverArt {
|
||||||
case .notLoaded:
|
case .notLoaded:
|
||||||
App.mpdClient.getAlbumFirstSong(for: albums[indexPath.item].mpdAlbum) { mpdSong in
|
let album = albums[indexPath.item]
|
||||||
guard let mpdSong = mpdSong else { return }
|
guard let path = album.mpdAlbum.path else { break }
|
||||||
|
|
||||||
DispatchQueue.main.async {
|
CoverArtService(path: path, album: album)
|
||||||
App.store.dispatch(
|
.fetchCoverArt()
|
||||||
UpdateAlbumMetaData(
|
.done { image in
|
||||||
metadata: Metadata(date: mpdSong.date),
|
DispatchQueue.main.async {
|
||||||
albumIndex: indexPath.item
|
App.store.dispatch(
|
||||||
|
UpdateCoverArtAction(coverArt: image, albumIndex: indexPath.item)
|
||||||
)
|
)
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
CoverArtService(song: Song(mpdSong: mpdSong))
|
|
||||||
.fetchCoverArt()
|
|
||||||
.done { image in
|
|
||||||
DispatchQueue.main.async {
|
|
||||||
App.store.dispatch(
|
|
||||||
UpdateCoverArtAction(coverArt: image, albumIndex: indexPath.item)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|||||||
@ -49,7 +49,7 @@ class AlbumDetailView: NSViewController {
|
|||||||
|
|
||||||
getAlbumSongs(for: album)
|
getAlbumSongs(for: album)
|
||||||
|
|
||||||
let date = album.metadata?.date ?? ""
|
let date = album.mpdAlbum.date ?? ""
|
||||||
|
|
||||||
albumTitle.stringValue = album.title
|
albumTitle.stringValue = album.title
|
||||||
albumMetadata.stringValue = "\(album.artist) · \(date)"
|
albumMetadata.stringValue = "\(album.artist) · \(date)"
|
||||||
@ -132,12 +132,12 @@ class AlbumDetailView: NSViewController {
|
|||||||
self.dataSource.albumSongs[1].song
|
self.dataSource.albumSongs[1].song
|
||||||
else { return }
|
else { return }
|
||||||
|
|
||||||
self.getBigCoverArt(song: song)
|
self.getBigCoverArt(song: song, album: album)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func getBigCoverArt(song: Song) {
|
func getBigCoverArt(song: Song, album: Album) {
|
||||||
let coverArtService = CoverArtService(song: song)
|
let coverArtService = CoverArtService(path: song.mpdSong.path, album: album)
|
||||||
|
|
||||||
coverArtService.fetchBigCoverArt()
|
coverArtService.fetchBigCoverArt()
|
||||||
.done(on: DispatchQueue.main) { [weak self] image in
|
.done(on: DispatchQueue.main) { [weak self] image in
|
||||||
|
|||||||
@ -22,7 +22,7 @@ class UserNotificationsController {
|
|||||||
status.state == .playing
|
status.state == .playing
|
||||||
else { return }
|
else { return }
|
||||||
|
|
||||||
let coverArtService = CoverArtService(song: currentSong)
|
let coverArtService = CoverArtService(path: currentSong.mpdSong.path, album: currentSong.album)
|
||||||
|
|
||||||
coverArtService.fetchBigCoverArt()
|
coverArtService.fetchBigCoverArt()
|
||||||
.done() {
|
.done() {
|
||||||
|
|||||||
@ -161,7 +161,8 @@ class WindowController: NSWindowController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@IBAction func handleSearchQuery(_ sender: NSSearchField) {
|
@IBAction func handleSearchQuery(_ sender: NSSearchField) {
|
||||||
App.store.dispatch(SetSearchQuery(searchQuery: sender.stringValue))
|
//App.store.dispatch(SetSearchQuery(searchQuery: sender.stringValue))
|
||||||
|
App.mpdClient.fetchAlbums(filter: sender.stringValue)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -11,7 +11,11 @@ import mpdclient
|
|||||||
|
|
||||||
extension MPDClient {
|
extension MPDClient {
|
||||||
func fetchAllAlbums() {
|
func fetchAllAlbums() {
|
||||||
enqueueCommand(command: .fetchAllAlbums)
|
enqueueCommand(command: .fetchAlbums, userData: ["filter": ""])
|
||||||
|
}
|
||||||
|
|
||||||
|
func fetchAlbums(filter: String) {
|
||||||
|
enqueueCommand(command: .fetchAlbums, userData: ["filter": filter])
|
||||||
}
|
}
|
||||||
|
|
||||||
func playAlbum(_ album: MPDAlbum) {
|
func playAlbum(_ album: MPDAlbum) {
|
||||||
@ -49,7 +53,7 @@ extension MPDClient {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func allAlbums(filter: String) {
|
func albums(filter: String) {
|
||||||
var albums: [MPDAlbum] = []
|
var albums: [MPDAlbum] = []
|
||||||
|
|
||||||
mpd_search_db_songs(self.connection, false)
|
mpd_search_db_songs(self.connection, false)
|
||||||
@ -66,7 +70,12 @@ extension MPDClient {
|
|||||||
while let song = mpd_recv_song(self.connection) {
|
while let song = mpd_recv_song(self.connection) {
|
||||||
let mpdSong = MPDSong(song)
|
let mpdSong = MPDSong(song)
|
||||||
|
|
||||||
let mpdAlbum = MPDAlbum(title: mpdSong.album.title, artist: mpdSong.artist)
|
let mpdAlbum = MPDAlbum(
|
||||||
|
title: mpdSong.album.title,
|
||||||
|
artist: mpdSong.artist,
|
||||||
|
date: mpdSong.date,
|
||||||
|
path: mpdSong.path
|
||||||
|
)
|
||||||
if (mpdAlbum != albums.last) {
|
if (mpdAlbum != albums.last) {
|
||||||
albums.append(mpdAlbum)
|
albums.append(mpdAlbum)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -92,8 +92,9 @@ extension MPDClient {
|
|||||||
allArtists()
|
allArtists()
|
||||||
|
|
||||||
// Album commands
|
// Album commands
|
||||||
case .fetchAllAlbums:
|
case .fetchAlbums:
|
||||||
allAlbums(filter: "")
|
guard let filter = userData["filter"] as? String else { return }
|
||||||
|
albums(filter: filter)
|
||||||
case .playAlbum:
|
case .playAlbum:
|
||||||
guard let album = userData["album"] as? MPDAlbum else { return }
|
guard let album = userData["album"] as? MPDAlbum else { return }
|
||||||
sendPlayAlbum(album)
|
sendPlayAlbum(album)
|
||||||
|
|||||||
@ -12,5 +12,7 @@ extension MPDClient {
|
|||||||
struct MPDAlbum: Equatable {
|
struct MPDAlbum: Equatable {
|
||||||
let title: String
|
let title: String
|
||||||
let artist: String
|
let artist: String
|
||||||
|
var date: String?
|
||||||
|
var path: String?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -41,7 +41,7 @@ extension MPDClient {
|
|||||||
case fetchAllArtists
|
case fetchAllArtists
|
||||||
|
|
||||||
// Album commands
|
// Album commands
|
||||||
case fetchAllAlbums
|
case fetchAlbums
|
||||||
case playAlbum
|
case playAlbum
|
||||||
case getAlbumFirstSong
|
case getAlbumFirstSong
|
||||||
case getAlbumSongs
|
case getAlbumSongs
|
||||||
|
|||||||
@ -36,7 +36,9 @@ extension MPDClient {
|
|||||||
var album: MPDAlbum {
|
var album: MPDAlbum {
|
||||||
return MPDAlbum(
|
return MPDAlbum(
|
||||||
title: getTag(.album),
|
title: getTag(.album),
|
||||||
artist: artist
|
artist: artist,
|
||||||
|
date: date,
|
||||||
|
path: path
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,6 +54,13 @@ extension MPDClient {
|
|||||||
return getTag(.date)
|
return getTag(.date)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var path: String {
|
||||||
|
return uriString
|
||||||
|
.split(separator: "/")
|
||||||
|
.dropLast()
|
||||||
|
.joined(separator: "/")
|
||||||
|
}
|
||||||
|
|
||||||
func getTag(_ tagType: MPDTag) -> String {
|
func getTag(_ tagType: MPDTag) -> String {
|
||||||
guard let tag = mpd_song_get_tag(song, tagType.mpdTag(), 0)
|
guard let tag = mpd_song_get_tag(song, tagType.mpdTag(), 0)
|
||||||
else { return "" }
|
else { return "" }
|
||||||
|
|||||||
@ -12,7 +12,6 @@ import CryptoSwift
|
|||||||
struct Album {
|
struct Album {
|
||||||
var mpdAlbum: MPDClient.MPDAlbum
|
var mpdAlbum: MPDClient.MPDAlbum
|
||||||
var coverArt: Loading<NSImage?> = .notLoaded
|
var coverArt: Loading<NSImage?> = .notLoaded
|
||||||
var metadata: Metadata?
|
|
||||||
|
|
||||||
init(mpdAlbum: MPDClient.MPDAlbum) {
|
init(mpdAlbum: MPDClient.MPDAlbum) {
|
||||||
self.mpdAlbum = mpdAlbum
|
self.mpdAlbum = mpdAlbum
|
||||||
@ -26,6 +25,11 @@ struct Album {
|
|||||||
return mpdAlbum.artist
|
return mpdAlbum.artist
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var date: String {
|
||||||
|
guard let date = mpdAlbum.date else { return "" }
|
||||||
|
return date
|
||||||
|
}
|
||||||
|
|
||||||
var hash: String {
|
var hash: String {
|
||||||
return "\(title) - \(artist)".sha1()
|
return "\(title) - \(artist)".sha1()
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,13 +0,0 @@
|
|||||||
//
|
|
||||||
// Metadata.swift
|
|
||||||
// Persephone
|
|
||||||
//
|
|
||||||
// Created by Daniel Barber on 2019/10/11.
|
|
||||||
// Copyright © 2019 Dan Barber. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
|
||||||
|
|
||||||
struct Metadata {
|
|
||||||
var date: String?
|
|
||||||
}
|
|
||||||
@ -10,7 +10,7 @@ import AppKit
|
|||||||
import PromiseKit
|
import PromiseKit
|
||||||
|
|
||||||
class CoverArtService {
|
class CoverArtService {
|
||||||
let song: Song
|
let path: String
|
||||||
let album: Album
|
let album: Album
|
||||||
|
|
||||||
let cachedArtworkSize = 180
|
let cachedArtworkSize = 180
|
||||||
@ -21,9 +21,9 @@ class CoverArtService {
|
|||||||
var session = URLSession(configuration: .default)
|
var session = URLSession(configuration: .default)
|
||||||
let coverArtQueue = DispatchQueue(label: "coverArtQueue", qos: .utility)
|
let coverArtQueue = DispatchQueue(label: "coverArtQueue", qos: .utility)
|
||||||
|
|
||||||
init(song: Song) {
|
init(path: String, album: Album) {
|
||||||
self.song = song
|
self.path = path
|
||||||
self.album = song.album
|
self.album = album
|
||||||
}
|
}
|
||||||
|
|
||||||
func fetchBigCoverArt() -> Promise<NSImage?> {
|
func fetchBigCoverArt() -> Promise<NSImage?> {
|
||||||
|
|||||||
@ -40,7 +40,7 @@ extension CoverArtService {
|
|||||||
|
|
||||||
if self.fileSystemArtworkFilePath() == nil {
|
if self.fileSystemArtworkFilePath() == nil {
|
||||||
FileManager.default.createFile(
|
FileManager.default.createFile(
|
||||||
atPath: "\(self.musicDir)/\(self.songPath)/\(artworkFileName)",
|
atPath: "\(self.musicDir)/\(self.path)/\(artworkFileName)",
|
||||||
contents: data,
|
contents: data,
|
||||||
attributes: nil
|
attributes: nil
|
||||||
)
|
)
|
||||||
@ -52,21 +52,12 @@ extension CoverArtService {
|
|||||||
|
|
||||||
return self.coverArtFilenames
|
return self.coverArtFilenames
|
||||||
.lazy
|
.lazy
|
||||||
.map { "\(musicDir)/\(self.songPath)/\($0)" }
|
.map { "\(musicDir)/\(self.path)/\($0)" }
|
||||||
.first {
|
.first {
|
||||||
FileManager.default.fileExists(atPath: $0)
|
FileManager.default.fileExists(atPath: $0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var songPath: String {
|
|
||||||
return song
|
|
||||||
.mpdSong
|
|
||||||
.uriString
|
|
||||||
.split(separator: "/")
|
|
||||||
.dropLast()
|
|
||||||
.joined(separator: "/")
|
|
||||||
}
|
|
||||||
|
|
||||||
func tryImage(_ filePath: String) -> NSImage? {
|
func tryImage(_ filePath: String) -> NSImage? {
|
||||||
guard let data = FileManager.default.contents(atPath: filePath),
|
guard let data = FileManager.default.contents(atPath: filePath),
|
||||||
let image = NSImage(data: data)
|
let image = NSImage(data: data)
|
||||||
|
|||||||
@ -16,11 +16,6 @@ struct UpdateCoverArtAction: Action {
|
|||||||
var albumIndex: Int
|
var albumIndex: Int
|
||||||
}
|
}
|
||||||
|
|
||||||
struct UpdateAlbumMetaData: Action {
|
|
||||||
var metadata: Metadata
|
|
||||||
var albumIndex: Int
|
|
||||||
}
|
|
||||||
|
|
||||||
struct UpdateAlbumListAction: Action {
|
struct UpdateAlbumListAction: Action {
|
||||||
var albums: [MPDClient.MPDAlbum]
|
var albums: [MPDClient.MPDAlbum]
|
||||||
}
|
}
|
||||||
|
|||||||
@ -18,9 +18,6 @@ func albumListReducer(action: Action, state: AlbumListState?) -> AlbumListState
|
|||||||
case let action as UpdateCoverArtAction:
|
case let action as UpdateCoverArtAction:
|
||||||
state.albums[action.albumIndex].coverArt = .loaded(action.coverArt)
|
state.albums[action.albumIndex].coverArt = .loaded(action.coverArt)
|
||||||
|
|
||||||
case let action as UpdateAlbumMetaData:
|
|
||||||
state.albums[action.albumIndex].metadata = action.metadata
|
|
||||||
|
|
||||||
case is ResetAlbumListCoverArtAction:
|
case is ResetAlbumListCoverArtAction:
|
||||||
state.albums = state.albums.map {
|
state.albums = state.albums.map {
|
||||||
var album = $0
|
var album = $0
|
||||||
|
|||||||
@ -40,7 +40,7 @@ func playerReducer(action: Action, state: PlayerState?) -> PlayerState {
|
|||||||
state.currentSong = action.currentSong
|
state.currentSong = action.currentSong
|
||||||
|
|
||||||
if let currentSong = state.currentSong {
|
if let currentSong = state.currentSong {
|
||||||
let coverArtService = CoverArtService(song: currentSong)
|
let coverArtService = CoverArtService(path: currentSong.mpdSong.path, album: currentSong.album)
|
||||||
|
|
||||||
coverArtService.fetchBigCoverArt()
|
coverArtService.fetchBigCoverArt()
|
||||||
.done() { image in
|
.done() { image in
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user