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:
parent
dbf454f509
commit
feccf9b7df
@ -60,7 +60,7 @@ class AlbumViewItem: NSCollectionViewItem {
|
||||
else { return }
|
||||
|
||||
let provider = MPDAlbumArtImageDataProvider(
|
||||
song: song,
|
||||
songUri: song.uriString,
|
||||
cacheKey: album.hash
|
||||
)
|
||||
|
||||
|
||||
@ -136,7 +136,7 @@ class AlbumDetailView: NSViewController {
|
||||
|
||||
func getBigCoverArt(song: Song, album: Album) {
|
||||
let provider = MPDAlbumArtImageDataProvider(
|
||||
song: song.mpdSong,
|
||||
songUri: song.mpdSong.uriString,
|
||||
cacheKey: album.hash
|
||||
)
|
||||
|
||||
@ -154,13 +154,14 @@ class AlbumDetailView: NSViewController {
|
||||
|
||||
func cacheSmallCover(song: Song, album: Album) {
|
||||
let provider = MPDAlbumArtImageDataProvider(
|
||||
song: song.mpdSong,
|
||||
songUri: song.mpdSong.uriString,
|
||||
cacheKey: album.hash
|
||||
)
|
||||
|
||||
_ = KingfisherManager.shared.retrieveImage(
|
||||
with: .provider(provider),
|
||||
options: [
|
||||
.memoryCacheExpiration(.never),
|
||||
.processor(DownsamplingImageProcessor(size: .queueSongCoverSize)),
|
||||
.scaleFactor(2),
|
||||
]
|
||||
|
||||
@ -49,7 +49,9 @@ class AlbumTracksDataSource: NSObject, NSTableViewDataSource {
|
||||
draggedSong: DraggedSong(
|
||||
type: .albumSongItem(song.mpdSong.uriString),
|
||||
title: song.title,
|
||||
artist: song.artist
|
||||
artist: song.artist,
|
||||
album: song.album.title,
|
||||
uri: song.mpdSong.uriString
|
||||
),
|
||||
ofType: .songPasteboardType
|
||||
)
|
||||
@ -68,9 +70,11 @@ class AlbumTracksDataSource: NSObject, NSTableViewDataSource {
|
||||
) { draggingItem, index, stop in
|
||||
guard let item = draggingItem.item as? NSPasteboardItem,
|
||||
let draggedSong = item.draggedSong(forType: .songPasteboardType),
|
||||
case let (title?, artist?) = (
|
||||
case let (title, artist, album, uri) = (
|
||||
draggedSong.title,
|
||||
draggedSong.artist
|
||||
draggedSong.artist,
|
||||
draggedSong.album,
|
||||
draggedSong.uri
|
||||
)
|
||||
else { return }
|
||||
|
||||
@ -78,7 +82,9 @@ class AlbumTracksDataSource: NSObject, NSTableViewDataSource {
|
||||
let component = NSDraggingImageComponent(key: NSDraggingItem.ImageComponentKey.icon)
|
||||
let draggedSongView = DraggedSongView(
|
||||
title: title,
|
||||
artist: artist
|
||||
artist: artist,
|
||||
album: album,
|
||||
uri: uri
|
||||
)
|
||||
|
||||
component.contents = draggedSongView.view.image()
|
||||
|
||||
@ -21,7 +21,7 @@ class CurrentCoverArtView: NSImageView {
|
||||
|
||||
func setSongImage(_ song: Song) {
|
||||
let provider = MPDAlbumArtImageDataProvider(
|
||||
song: song.mpdSong,
|
||||
songUri: song.mpdSong.uriString,
|
||||
cacheKey: song.album.hash
|
||||
)
|
||||
|
||||
|
||||
@ -43,7 +43,9 @@ class QueueDataSource: NSObject, NSOutlineViewDataSource {
|
||||
draggedSong: DraggedSong(
|
||||
type: .queueItem(queueItem.queuePos),
|
||||
title: queueItem.song.title,
|
||||
artist: queueItem.song.artist
|
||||
artist: queueItem.song.artist,
|
||||
album: queueItem.song.album.title,
|
||||
uri: queueItem.song.mpdSong.uriString
|
||||
),
|
||||
ofType: .songPasteboardType
|
||||
)
|
||||
@ -127,9 +129,11 @@ class QueueDataSource: NSObject, NSOutlineViewDataSource {
|
||||
guard let item = draggingItem.item as? NSPasteboardItem,
|
||||
let data = item.data(forType: .songPasteboardType),
|
||||
let draggedSong = try? PropertyListDecoder().decode(DraggedSong.self, from: data),
|
||||
case let (title?, artist?) = (
|
||||
case let (title, artist, album, uri) = (
|
||||
draggedSong.title,
|
||||
draggedSong.artist
|
||||
draggedSong.artist,
|
||||
draggedSong.album,
|
||||
draggedSong.uri
|
||||
)
|
||||
else { return }
|
||||
|
||||
@ -137,7 +141,9 @@ class QueueDataSource: NSObject, NSOutlineViewDataSource {
|
||||
let component = NSDraggingImageComponent(key: NSDraggingItem.ImageComponentKey.icon)
|
||||
let draggedSongView = DraggedSongView(
|
||||
title: title,
|
||||
artist: artist
|
||||
artist: artist,
|
||||
album: album,
|
||||
uri: uri
|
||||
)
|
||||
|
||||
let view = draggedSongView.view
|
||||
|
||||
@ -65,7 +65,7 @@ class QueueSongCoverView: NSTableCellView {
|
||||
isPlaying = queueItem.isPlaying
|
||||
|
||||
let provider = MPDAlbumArtImageDataProvider(
|
||||
song: song.mpdSong,
|
||||
songUri: song.mpdSong.uriString,
|
||||
cacheKey: song.album.hash
|
||||
)
|
||||
|
||||
|
||||
@ -16,11 +16,14 @@ class DraggedSongView: NSViewController {
|
||||
|
||||
private let songTitle: 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
|
||||
songArtist = artist
|
||||
songAlbum = album
|
||||
songUri = uri
|
||||
|
||||
super.init(nibName: nil, bundle: nil)
|
||||
}
|
||||
@ -57,25 +60,20 @@ class DraggedSongView: NSViewController {
|
||||
}
|
||||
|
||||
func setCoverArt() {
|
||||
let mpdAlbum = MPDClient.MPDAlbum(
|
||||
title: titleLabel.stringValue,
|
||||
artist: artistLabel.stringValue
|
||||
let mpdAlbum = MPDClient.MPDAlbum(title: songAlbum, artist: songArtist)
|
||||
|
||||
let provider = MPDAlbumArtImageDataProvider(
|
||||
songUri: songUri,
|
||||
cacheKey: Album(mpdAlbum: mpdAlbum).hash
|
||||
)
|
||||
|
||||
KingfisherManager.shared.cache.retrieveImage(
|
||||
forKey: Album(mpdAlbum: mpdAlbum).hash,
|
||||
coverImage.kf.setImage(
|
||||
with: .provider(provider),
|
||||
placeholder: NSImage.defaultCoverArt,
|
||||
options: [
|
||||
.processor(DownsamplingImageProcessor(size: .queueSongCoverSize)),
|
||||
.scaleFactor(2),
|
||||
],
|
||||
callbackQueue: .untouch
|
||||
) { result in
|
||||
switch result {
|
||||
case .success(let cacheResult):
|
||||
self.coverImage.image = cacheResult.image
|
||||
case .failure(_):
|
||||
return
|
||||
}
|
||||
}
|
||||
]
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -10,17 +10,17 @@ import Foundation
|
||||
import Kingfisher
|
||||
|
||||
public struct MPDAlbumArtImageDataProvider: ImageDataProvider {
|
||||
let song: MPDClient.MPDSong
|
||||
let songUri: String
|
||||
|
||||
init(song: MPDClient.MPDSong, cacheKey: String? = nil) {
|
||||
self.song = song
|
||||
self.cacheKey = cacheKey ?? song.uriString
|
||||
init(songUri: String, cacheKey: String? = nil) {
|
||||
self.songUri = songUri
|
||||
self.cacheKey = cacheKey ?? songUri
|
||||
}
|
||||
|
||||
public var cacheKey: String
|
||||
|
||||
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
|
||||
else { return }
|
||||
|
||||
@ -29,6 +29,6 @@ public struct MPDAlbumArtImageDataProvider: ImageDataProvider {
|
||||
}
|
||||
|
||||
public var contentURL: String? {
|
||||
return song.uriString
|
||||
return songUri
|
||||
}
|
||||
}
|
||||
|
||||
@ -24,7 +24,7 @@ class UserNotificationsController {
|
||||
else { return }
|
||||
|
||||
let provider = MPDAlbumArtImageDataProvider(
|
||||
song: song.mpdSong,
|
||||
songUri: song.mpdSong.uriString,
|
||||
cacheKey: song.album.hash
|
||||
)
|
||||
|
||||
|
||||
@ -122,11 +122,11 @@ extension MPDClient {
|
||||
|
||||
// Song commands
|
||||
case .fetchAlbumArt:
|
||||
guard let song = userData["song"] as? MPDSong,
|
||||
guard let songUri = userData["songUri"] as? String,
|
||||
let callback = userData["callback"] as? (Data?) -> Void
|
||||
else { return }
|
||||
|
||||
sendFetchAlbumArt(for: song, callback: callback)
|
||||
sendFetchAlbumArt(forUri: songUri, callback: callback)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -10,10 +10,10 @@ import Foundation
|
||||
import mpdclient
|
||||
|
||||
extension MPDClient {
|
||||
func fetchAlbumArt(song: MPDSong, callback: @escaping (Data?) -> Void) {
|
||||
func fetchAlbumArt(songUri: String, callback: @escaping (Data?) -> Void) {
|
||||
enqueueCommand(
|
||||
command: .fetchAlbumArt,
|
||||
userData: ["song": song, "callback": callback]
|
||||
userData: ["songUri": songUri, "callback": callback]
|
||||
)
|
||||
}
|
||||
|
||||
@ -33,14 +33,14 @@ extension MPDClient {
|
||||
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 currentOffset: Int32 = 0
|
||||
|
||||
var size: Int?
|
||||
|
||||
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 {
|
||||
mpd_connection_clear_error(self.connection)
|
||||
|
||||
@ -53,11 +53,6 @@ extension MPDClient {
|
||||
return getTag(.date)
|
||||
}
|
||||
|
||||
var path: String {
|
||||
return NSString(string: uriString)
|
||||
.deletingLastPathComponent
|
||||
}
|
||||
|
||||
func getTag(_ tagType: MPDTag) -> String {
|
||||
guard let tag = mpd_song_get_tag(song, tagType.mpdTag(), 0)
|
||||
else { return "" }
|
||||
|
||||
@ -8,6 +8,8 @@
|
||||
|
||||
struct DraggedSong: Codable {
|
||||
var type: DraggedSongType
|
||||
var title: String?
|
||||
var artist: String?
|
||||
var title: String
|
||||
var artist: String
|
||||
var album: String
|
||||
var uri: String
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user