1
1
mirror of https://github.com/danbee/persephone synced 2025-03-04 08:39:11 +00:00
persephone/Persephone/Components/Browser/Album Browser/AlbumViewItem.swift
Daniel Barber cd2e5efc95
Cache the small image when we get the browser art
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.
2020-02-16 12:51:11 -05:00

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()
}
}