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

Dragged songs now have album art

This commit is contained in:
Daniel Barber 2020-02-02 22:04:11 -05:00
parent dbf454f509
commit feccf9b7df
Signed by: danbarber
GPG Key ID: 931D8112E0103DD8
13 changed files with 59 additions and 51 deletions

View File

@ -60,7 +60,7 @@ class AlbumViewItem: NSCollectionViewItem {
else { return } else { return }
let provider = MPDAlbumArtImageDataProvider( let provider = MPDAlbumArtImageDataProvider(
song: song, songUri: song.uriString,
cacheKey: album.hash cacheKey: album.hash
) )

View File

@ -136,7 +136,7 @@ class AlbumDetailView: NSViewController {
func getBigCoverArt(song: Song, album: Album) { func getBigCoverArt(song: Song, album: Album) {
let provider = MPDAlbumArtImageDataProvider( let provider = MPDAlbumArtImageDataProvider(
song: song.mpdSong, songUri: song.mpdSong.uriString,
cacheKey: album.hash cacheKey: album.hash
) )
@ -154,13 +154,14 @@ class AlbumDetailView: NSViewController {
func cacheSmallCover(song: Song, album: Album) { func cacheSmallCover(song: Song, album: Album) {
let provider = MPDAlbumArtImageDataProvider( let provider = MPDAlbumArtImageDataProvider(
song: song.mpdSong, songUri: song.mpdSong.uriString,
cacheKey: album.hash cacheKey: album.hash
) )
_ = KingfisherManager.shared.retrieveImage( _ = KingfisherManager.shared.retrieveImage(
with: .provider(provider), with: .provider(provider),
options: [ options: [
.memoryCacheExpiration(.never),
.processor(DownsamplingImageProcessor(size: .queueSongCoverSize)), .processor(DownsamplingImageProcessor(size: .queueSongCoverSize)),
.scaleFactor(2), .scaleFactor(2),
] ]

View File

@ -49,7 +49,9 @@ class AlbumTracksDataSource: NSObject, NSTableViewDataSource {
draggedSong: DraggedSong( draggedSong: DraggedSong(
type: .albumSongItem(song.mpdSong.uriString), type: .albumSongItem(song.mpdSong.uriString),
title: song.title, title: song.title,
artist: song.artist artist: song.artist,
album: song.album.title,
uri: song.mpdSong.uriString
), ),
ofType: .songPasteboardType ofType: .songPasteboardType
) )
@ -68,9 +70,11 @@ class AlbumTracksDataSource: NSObject, NSTableViewDataSource {
) { draggingItem, index, stop in ) { draggingItem, index, stop in
guard let item = draggingItem.item as? NSPasteboardItem, guard let item = draggingItem.item as? NSPasteboardItem,
let draggedSong = item.draggedSong(forType: .songPasteboardType), let draggedSong = item.draggedSong(forType: .songPasteboardType),
case let (title?, artist?) = ( case let (title, artist, album, uri) = (
draggedSong.title, draggedSong.title,
draggedSong.artist draggedSong.artist,
draggedSong.album,
draggedSong.uri
) )
else { return } else { return }
@ -78,7 +82,9 @@ class AlbumTracksDataSource: NSObject, NSTableViewDataSource {
let component = NSDraggingImageComponent(key: NSDraggingItem.ImageComponentKey.icon) let component = NSDraggingImageComponent(key: NSDraggingItem.ImageComponentKey.icon)
let draggedSongView = DraggedSongView( let draggedSongView = DraggedSongView(
title: title, title: title,
artist: artist artist: artist,
album: album,
uri: uri
) )
component.contents = draggedSongView.view.image() component.contents = draggedSongView.view.image()

View File

@ -21,7 +21,7 @@ class CurrentCoverArtView: NSImageView {
func setSongImage(_ song: Song) { func setSongImage(_ song: Song) {
let provider = MPDAlbumArtImageDataProvider( let provider = MPDAlbumArtImageDataProvider(
song: song.mpdSong, songUri: song.mpdSong.uriString,
cacheKey: song.album.hash cacheKey: song.album.hash
) )

View File

@ -43,7 +43,9 @@ class QueueDataSource: NSObject, NSOutlineViewDataSource {
draggedSong: DraggedSong( draggedSong: DraggedSong(
type: .queueItem(queueItem.queuePos), type: .queueItem(queueItem.queuePos),
title: queueItem.song.title, title: queueItem.song.title,
artist: queueItem.song.artist artist: queueItem.song.artist,
album: queueItem.song.album.title,
uri: queueItem.song.mpdSong.uriString
), ),
ofType: .songPasteboardType ofType: .songPasteboardType
) )
@ -127,9 +129,11 @@ class QueueDataSource: NSObject, NSOutlineViewDataSource {
guard let item = draggingItem.item as? NSPasteboardItem, guard let item = draggingItem.item as? NSPasteboardItem,
let data = item.data(forType: .songPasteboardType), let data = item.data(forType: .songPasteboardType),
let draggedSong = try? PropertyListDecoder().decode(DraggedSong.self, from: data), let draggedSong = try? PropertyListDecoder().decode(DraggedSong.self, from: data),
case let (title?, artist?) = ( case let (title, artist, album, uri) = (
draggedSong.title, draggedSong.title,
draggedSong.artist draggedSong.artist,
draggedSong.album,
draggedSong.uri
) )
else { return } else { return }
@ -137,7 +141,9 @@ class QueueDataSource: NSObject, NSOutlineViewDataSource {
let component = NSDraggingImageComponent(key: NSDraggingItem.ImageComponentKey.icon) let component = NSDraggingImageComponent(key: NSDraggingItem.ImageComponentKey.icon)
let draggedSongView = DraggedSongView( let draggedSongView = DraggedSongView(
title: title, title: title,
artist: artist artist: artist,
album: album,
uri: uri
) )
let view = draggedSongView.view let view = draggedSongView.view

View File

@ -65,7 +65,7 @@ class QueueSongCoverView: NSTableCellView {
isPlaying = queueItem.isPlaying isPlaying = queueItem.isPlaying
let provider = MPDAlbumArtImageDataProvider( let provider = MPDAlbumArtImageDataProvider(
song: song.mpdSong, songUri: song.mpdSong.uriString,
cacheKey: song.album.hash cacheKey: song.album.hash
) )

View File

@ -16,11 +16,14 @@ class DraggedSongView: NSViewController {
private let songTitle: String private let songTitle: String
private let songArtist: String private let songArtist: String
private var songCoverImage: NSImage? private let songAlbum: String
private let songUri: String
init(title: String, artist: String) { init(title: String, artist: String, album: String, uri: String) {
songTitle = title songTitle = title
songArtist = artist songArtist = artist
songAlbum = album
songUri = uri
super.init(nibName: nil, bundle: nil) super.init(nibName: nil, bundle: nil)
} }
@ -57,25 +60,20 @@ class DraggedSongView: NSViewController {
} }
func setCoverArt() { func setCoverArt() {
let mpdAlbum = MPDClient.MPDAlbum( let mpdAlbum = MPDClient.MPDAlbum(title: songAlbum, artist: songArtist)
title: titleLabel.stringValue,
artist: artistLabel.stringValue let provider = MPDAlbumArtImageDataProvider(
songUri: songUri,
cacheKey: Album(mpdAlbum: mpdAlbum).hash
) )
KingfisherManager.shared.cache.retrieveImage( coverImage.kf.setImage(
forKey: Album(mpdAlbum: mpdAlbum).hash, with: .provider(provider),
placeholder: NSImage.defaultCoverArt,
options: [ options: [
.processor(DownsamplingImageProcessor(size: .queueSongCoverSize)), .processor(DownsamplingImageProcessor(size: .queueSongCoverSize)),
.scaleFactor(2), .scaleFactor(2),
], ]
callbackQueue: .untouch )
) { result in
switch result {
case .success(let cacheResult):
self.coverImage.image = cacheResult.image
case .failure(_):
return
}
}
} }
} }

View File

@ -10,17 +10,17 @@ import Foundation
import Kingfisher import Kingfisher
public struct MPDAlbumArtImageDataProvider: ImageDataProvider { public struct MPDAlbumArtImageDataProvider: ImageDataProvider {
let song: MPDClient.MPDSong let songUri: String
init(song: MPDClient.MPDSong, cacheKey: String? = nil) { init(songUri: String, cacheKey: String? = nil) {
self.song = song self.songUri = songUri
self.cacheKey = cacheKey ?? song.uriString self.cacheKey = cacheKey ?? songUri
} }
public var cacheKey: String public var cacheKey: String
public func data(handler: @escaping (Result<Data, Error>) -> Void) { public func data(handler: @escaping (Result<Data, Error>) -> Void) {
App.mpdClient.fetchAlbumArt(song: song) { imageData in App.mpdClient.fetchAlbumArt(songUri: songUri) { imageData in
guard let imageData = imageData guard let imageData = imageData
else { return } else { return }
@ -29,6 +29,6 @@ public struct MPDAlbumArtImageDataProvider: ImageDataProvider {
} }
public var contentURL: String? { public var contentURL: String? {
return song.uriString return songUri
} }
} }

View File

@ -24,7 +24,7 @@ class UserNotificationsController {
else { return } else { return }
let provider = MPDAlbumArtImageDataProvider( let provider = MPDAlbumArtImageDataProvider(
song: song.mpdSong, songUri: song.mpdSong.uriString,
cacheKey: song.album.hash cacheKey: song.album.hash
) )

View File

@ -122,11 +122,11 @@ extension MPDClient {
// Song commands // Song commands
case .fetchAlbumArt: case .fetchAlbumArt:
guard let song = userData["song"] as? MPDSong, guard let songUri = userData["songUri"] as? String,
let callback = userData["callback"] as? (Data?) -> Void let callback = userData["callback"] as? (Data?) -> Void
else { return } else { return }
sendFetchAlbumArt(for: song, callback: callback) sendFetchAlbumArt(forUri: songUri, callback: callback)
} }
} }

View File

@ -10,10 +10,10 @@ import Foundation
import mpdclient import mpdclient
extension MPDClient { extension MPDClient {
func fetchAlbumArt(song: MPDSong, callback: @escaping (Data?) -> Void) { func fetchAlbumArt(songUri: String, callback: @escaping (Data?) -> Void) {
enqueueCommand( enqueueCommand(
command: .fetchAlbumArt, command: .fetchAlbumArt,
userData: ["song": song, "callback": callback] userData: ["songUri": songUri, "callback": callback]
) )
} }
@ -33,14 +33,14 @@ extension MPDClient {
return songs return songs
} }
func sendFetchAlbumArt(for song: MPDSong, callback: @escaping (Data?) -> Void) -> Void { func sendFetchAlbumArt(forUri songUri: String, callback: @escaping (Data?) -> Void) -> Void {
var imageData: Data? var imageData: Data?
var currentOffset: Int32 = 0 var currentOffset: Int32 = 0
var size: Int? var size: Int?
while size == nil || currentOffset < size! { while size == nil || currentOffset < size! {
mpd_send_albumart(self.connection, song.uri, String(currentOffset)) mpd_send_albumart(self.connection, songUri, String(currentOffset))
guard let sizePair = mpd_recv_pair(self.connection) else { guard let sizePair = mpd_recv_pair(self.connection) else {
mpd_connection_clear_error(self.connection) mpd_connection_clear_error(self.connection)

View File

@ -53,11 +53,6 @@ extension MPDClient {
return getTag(.date) return getTag(.date)
} }
var path: String {
return NSString(string: uriString)
.deletingLastPathComponent
}
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 "" }

View File

@ -8,6 +8,8 @@
struct DraggedSong: Codable { struct DraggedSong: Codable {
var type: DraggedSongType var type: DraggedSongType
var title: String? var title: String
var artist: String? var artist: String
var album: String
var uri: String
} }