mirror of
https://github.com/danbee/persephone
synced 2025-03-04 08:39:11 +00:00
We use the RawImageDataProvider here to pass the already downloaded image onto this transform, to avoid fetching it from MPD again. The 180x180 size artwork is plenty big enough to use as source for the 32x32 queue/dragged song artwork.
172 lines
4.5 KiB
Swift
172 lines
4.5 KiB
Swift
//
|
|
// AlbumViewItem.swift
|
|
// Persephone
|
|
//
|
|
// Created by Daniel Barber on 2019/2/08.
|
|
// Copyright © 2019 Dan Barber. All rights reserved.
|
|
//
|
|
|
|
import AppKit
|
|
import Kingfisher
|
|
|
|
class AlbumViewItem: NSCollectionViewItem {
|
|
var observer: NSKeyValueObservation?
|
|
var album: Album?
|
|
|
|
override var isSelected: Bool {
|
|
didSet {
|
|
setAppearance(selected: isSelected)
|
|
}
|
|
}
|
|
|
|
override func viewDidLoad() {
|
|
super.viewDidLoad()
|
|
|
|
albumCoverView.wantsLayer = true
|
|
albumCoverView.layer?.backgroundColor = NSColor.black.cgColor
|
|
albumCoverView.layer?.cornerRadius = 4
|
|
albumCoverView.layer?.borderWidth = 1
|
|
albumCoverView.layer?.masksToBounds = true
|
|
|
|
albumCoverBox.wantsLayer = true
|
|
albumCoverBox.layer?.cornerRadius = 7
|
|
albumCoverBox.layer?.borderWidth = 5
|
|
|
|
setAppearance(selected: false)
|
|
|
|
if #available(OSX 10.14, *) {
|
|
observer = NSApp.observe(\.effectiveAppearance) { (app, _) in
|
|
self.setAppearance(selected: false)
|
|
}
|
|
}
|
|
}
|
|
|
|
override func prepareForReuse() {
|
|
super.prepareForReuse()
|
|
|
|
albumCoverView.image = .defaultCoverArt
|
|
AlbumDetailView.popover.close()
|
|
}
|
|
|
|
func setAlbum(_ album: Album) {
|
|
self.album = album
|
|
albumTitle.stringValue = album.title
|
|
albumArtist.stringValue = album.artist
|
|
setAlbumCover(album)
|
|
}
|
|
|
|
func setAlbumCover(_ album: Album) {
|
|
guard let song = album.mpdAlbum.firstSong
|
|
else { return }
|
|
|
|
let provider = MPDAlbumArtImageDataProvider(
|
|
songUri: song.uriString,
|
|
cacheKey: album.hash
|
|
)
|
|
|
|
albumCoverView.kf.setImage(
|
|
with: .provider(provider),
|
|
placeholder: NSImage.defaultCoverArt,
|
|
options: [
|
|
.processor(DownsamplingImageProcessor(size: .albumListCoverSize)),
|
|
.scaleFactor(2),
|
|
]
|
|
) { result in
|
|
switch result {
|
|
case .success(let imageResult):
|
|
guard let imageData = imageResult.image.tiffRepresentation
|
|
else { return }
|
|
|
|
let rawProvider = RawImageDataProvider(
|
|
data: imageData,
|
|
cacheKey: album.hash
|
|
)
|
|
|
|
self.cacheSmallCover(provider: rawProvider)
|
|
|
|
case .failure(_):
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
func cacheSmallCover(provider: ImageDataProvider) {
|
|
_ = KingfisherManager.shared.retrieveImage(
|
|
with: .provider(provider),
|
|
options: [
|
|
.memoryCacheExpiration(.never),
|
|
.processor(DownsamplingImageProcessor(size: .queueSongCoverSize)),
|
|
.scaleFactor(2),
|
|
]
|
|
) { result in }
|
|
}
|
|
|
|
func setAppearance(selected isSelected: Bool) {
|
|
guard let viewLayer = albumCoverView.layer,
|
|
let boxLayer = albumCoverBox.layer
|
|
else { return }
|
|
|
|
if #available(OSX 10.14, *) {
|
|
let darkMode = NSApp.effectiveAppearance.bestMatch(from:
|
|
[.darkAqua, .aqua]) == .darkAqua
|
|
|
|
viewLayer.borderColor = darkMode ? .albumBorderColorDark : .albumBorderColorLight
|
|
boxLayer.borderColor = isSelected ? NSColor.controlAccentColor.cgColor : CGColor.clear
|
|
boxLayer.backgroundColor = albumCoverBox.layer?.borderColor
|
|
} else {
|
|
viewLayer.borderColor = .albumBorderColorLight
|
|
boxLayer.borderColor = isSelected ? NSColor.selectedControlColor.cgColor : CGColor.clear
|
|
boxLayer.backgroundColor = albumCoverBox.layer?.borderColor
|
|
}
|
|
}
|
|
|
|
func refreshAlbumArt() {
|
|
guard let album = album,
|
|
let mpdSong = album.mpdAlbum.firstSong
|
|
else { return }
|
|
|
|
let song = Song(mpdSong: mpdSong)
|
|
|
|
CoverArtService(song: song).refresh {
|
|
self.setAlbumCover(album)
|
|
}
|
|
}
|
|
|
|
@IBAction func showAlbumDetail(_ sender: NSButton) {
|
|
guard let album = album else { return }
|
|
|
|
AlbumDetailView.shared.setAlbum(album)
|
|
|
|
AlbumDetailView.popover.contentViewController = AlbumDetailView.shared
|
|
AlbumDetailView.popover.behavior = .transient
|
|
AlbumDetailView.popover.show(
|
|
relativeTo: albumCoverView.bounds,
|
|
of: albumCoverView,
|
|
preferredEdge: .maxY
|
|
)
|
|
}
|
|
|
|
@IBOutlet var albumCoverBox: NSBox!
|
|
@IBOutlet var albumCoverView: NSButton!
|
|
@IBOutlet var albumTitle: NSTextField!
|
|
@IBOutlet var albumArtist: NSTextField!
|
|
|
|
@IBAction func playAlbumMenuAction(_ sender: NSMenuItem) {
|
|
guard let album = album else { return }
|
|
|
|
App.mpdClient.playAlbum(album.mpdAlbum)
|
|
}
|
|
|
|
@IBAction func addAlbumToQueueMenuAction(_ sender: NSMenuItem) {
|
|
guard let album = album else { return }
|
|
|
|
let queueLength = App.store.state.queueState.queue.count
|
|
|
|
App.mpdClient.addAlbumToQueue(album: album.mpdAlbum, at: queueLength)
|
|
}
|
|
|
|
@IBAction func refreshAlbumArtMenuAction(_ sender: NSMenuItem) {
|
|
refreshAlbumArt()
|
|
}
|
|
}
|