Skip to content

Commit

Permalink
SongsVC: add play all songs function
Browse files Browse the repository at this point in the history
  • Loading branch information
BLeeEZ committed May 14, 2022
1 parent a951cfc commit e8b3042
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 30 deletions.
6 changes: 6 additions & 0 deletions Amperfy/Screens/ViewController/SongsVC.swift
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,12 @@ class SongsVC: SingleFetchedResultsTableViewController<SongMO> {
@objc private func optionsPressed() {
let alert = UIAlertController(title: "Songs", message: nil, preferredStyle: .actionSheet)

alert.addAction(UIAlertAction(title: "Play all displayed songs", style: .default, handler: { _ in
guard let displayedSongsMO = self.fetchedResultsController.fetchedObjects else { return }
let displayedSongs = displayedSongsMO.compactMap{ Song(managedObject: $0) }
guard displayedSongs.count > 0 else { return }
self.appDelegate.player.play(context: PlayContext(name: "Song Collection", playables: displayedSongs))
}))
if self.appDelegate.persistentStorage.settings.isOnlineMode {
alert.addAction(UIAlertAction(title: "Play random songs", style: .default, handler: { _ in
self.appDelegate.persistentStorage.persistentContainer.performBackgroundTask() { (context) in
Expand Down
85 changes: 55 additions & 30 deletions Amperfy/Storage/EntityWrappers/Playlist.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,19 @@ public class Playlist: Identifyable {

let managedObject: PlaylistMO
private let library: LibraryStorage
private var kvoToken: NSKeyValueObservation?
private var isInternalArrayUpdateNeeded = false

init(library: LibraryStorage, managedObject: PlaylistMO) {
self.library = library
self.managedObject = managedObject
kvoToken = self.managedObject.observe(\.items, options: .new) { (playlist, change) in
self.isInternalArrayUpdateNeeded = true
}
}

deinit {
kvoToken?.invalidate()
}

var identifier: String {
Expand All @@ -27,27 +36,46 @@ public class Playlist: Identifyable {
return Playlist(library: library, managedObject: playlistMO)
}

private var sortedPlaylistItems: [PlaylistItem] {
var sortedItems = [PlaylistItem]()
guard let itemsMO = managedObject.items?.allObjects as? [PlaylistItemMO] else {
return sortedItems
}
sortedItems = itemsMO.lazy
private var internalSortedPlaylistItems: [PlaylistItem]?
private func updateSortedPlaylistItems() {
guard let itemsMO = managedObject.items?.allObjects as? [PlaylistItemMO] else { return }
internalSortedPlaylistItems = itemsMO
.sorted(by: { $0.order < $1.order })
.compactMap{ PlaylistItem(library: library, managedObject: $0) }
return sortedItems
}
private var sortedPlaylistItems: [PlaylistItem] {
if internalSortedPlaylistItems == nil || isInternalArrayUpdateNeeded { updateInternalArrays() }
return internalSortedPlaylistItems ?? [PlaylistItem]()
}

private var internalSortedCachedPlaylistItems: [PlaylistItem]?
private func updateSortedCachedPlaylistItems() {
internalSortedCachedPlaylistItems = sortedPlaylistItems.filter{ return $0.playable?.isCached ?? false }
}
private var sortedCachedPlaylistItems: [PlaylistItem] {
var sortedCachedItems = [PlaylistItem]()
guard let itemsMO = managedObject.items?.allObjects as? [PlaylistItemMO] else {
return sortedCachedItems
}
sortedCachedItems = itemsMO.lazy
.filter{ return $0.playable?.file != nil }
.sorted(by: { $0.order < $1.order })
.compactMap{ PlaylistItem(library: library, managedObject: $0) }
return sortedCachedItems
if internalSortedCachedPlaylistItems == nil || isInternalArrayUpdateNeeded { updateInternalArrays() }
return internalSortedCachedPlaylistItems ?? [PlaylistItem]()
}
var items: [PlaylistItem] {
return sortedPlaylistItems
}


private var internalPlayables: [AbstractPlayable]?
private func updateInternalPlayables() {
internalPlayables = sortedPlaylistItems.compactMap{ $0.playable }
}
var playables: [AbstractPlayable] {
if internalPlayables == nil || isInternalArrayUpdateNeeded { updateInternalArrays() }
updateInternalPlayables()
return internalPlayables ?? [AbstractPlayable]()
}

private func updateInternalArrays() {
isInternalArrayUpdateNeeded = false
updateSortedPlaylistItems()
updateSortedCachedPlaylistItems()
updateInternalPlayables()
}

var songCount: Int {
Expand All @@ -57,20 +85,7 @@ public class Playlist: Identifyable {
managedObject.songCount = Int16(newValue)
}
}
var playables: [AbstractPlayable] {
var sortedPlayables = [AbstractPlayable]()
guard let itemsMO = managedObject.items?.allObjects as? [PlaylistItemMO] else {
return sortedPlayables
}
sortedPlayables = itemsMO.lazy
.sorted(by: { $0.order < $1.order })
.compactMap{ $0.playable }
.compactMap{ AbstractPlayable(managedObject: $0) }
return sortedPlayables
}
var items: [PlaylistItem] {
return sortedPlaylistItems
}

var id: String {
get {
return managedObject.id
Expand Down Expand Up @@ -184,13 +199,15 @@ public class Playlist: Identifyable {
songCount += playablesToInsert.count
updateChangeDate()
library.saveContext()
isInternalArrayUpdateNeeded = true
}

func append(playable: AbstractPlayable) {
createPlaylistItem(for: playable)
songCount += 1
updateChangeDate()
library.saveContext()
isInternalArrayUpdateNeeded = true
}

func append(playables playablesToAppend: [AbstractPlayable]) {
Expand All @@ -199,6 +216,7 @@ public class Playlist: Identifyable {
}
songCount += playablesToAppend.count
library.saveContext()
isInternalArrayUpdateNeeded = true
}

private func createPlaylistItem(for playable: AbstractPlayable, customOrder: Int? = nil) {
Expand All @@ -212,6 +230,7 @@ public class Playlist: Identifyable {
songCount += 1
updateChangeDate()
managedObject.addToItems(item.managedObject)
isInternalArrayUpdateNeeded = true
}

func movePlaylistItem(fromIndex: Int, to: Int) {
Expand All @@ -232,6 +251,7 @@ public class Playlist: Identifyable {

updateChangeDate()
library.saveContext()
isInternalArrayUpdateNeeded = true
}

func remove(at index: Int) {
Expand All @@ -246,6 +266,7 @@ public class Playlist: Identifyable {
songCount -= 1
updateChangeDate()
library.saveContext()
isInternalArrayUpdateNeeded = true
}
}

Expand All @@ -257,6 +278,7 @@ public class Playlist: Identifyable {
break
}
}
isInternalArrayUpdateNeeded = true
}

func getFirstIndex(playable: AbstractPlayable) -> Int? {
Expand All @@ -275,6 +297,7 @@ public class Playlist: Identifyable {
songCount = 0
updateChangeDate()
library.saveContext()
isInternalArrayUpdateNeeded = true
}

func shuffle() {
Expand All @@ -290,6 +313,7 @@ public class Playlist: Identifyable {
localSortedPlaylistItems[i].order = shuffeldIndexes[i]
}
library.saveContext()
isInternalArrayUpdateNeeded = true
}

func updateChangeDate() {
Expand All @@ -307,6 +331,7 @@ public class Playlist: Identifyable {
if hasInconsistencyDetected {
os_log(.debug, "Playlist inconsistency detected and fixed!")
library.saveContext()
isInternalArrayUpdateNeeded = true
}
}

Expand Down

0 comments on commit e8b3042

Please sign in to comment.