iOS: section reorder and visibility, CarPlay downloads fix, stem playlist refresh fix
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
3e832e3125
commit
5b7fadb7f7
6 files changed
+122
-31
No files matched your search
@@ -59,22 +59,35 @@ final class StemPlaylists {
|
||||
/// Keeps each item's uid and mix, and leaves songs the library can't find as they are.
|
||||
/// Returns true when anything changed.
|
||||
@discardableResult
|
||||
func refresh(albumTracks: (String) async throws -> [Track]) async -> Bool {
|
||||
func refresh(albumTracks: (String) async throws -> [Track],
|
||||
search: ((String) async throws -> [Track])? = nil) async -> Bool {
|
||||
var fresh: [String: [Track]] = [:]
|
||||
for key in Set(lists.flatMap { $0.items.compactMap(\.track.albumKey) }) {
|
||||
if let t = try? await albumTracks(key) { fresh[key] = t }
|
||||
}
|
||||
var changed = false
|
||||
var found: [String: [Track]] = [:]
|
||||
func norm(_ s: String) -> String { s.folding(options: [.caseInsensitive, .diacriticInsensitive], locale: nil).trimmingCharacters(in: .whitespaces) }
|
||||
func pick(_ old: Track, _ pool: [Track]) -> Track? {
|
||||
pool.first { $0.ratingKey == old.ratingKey }
|
||||
?? old.partFile.flatMap { f in pool.first { $0.partFile == f } }
|
||||
?? pool.first { norm($0.title) == norm(old.title) && norm($0.artist) == norm(old.artist) && (old.album.isEmpty || norm($0.album) == norm(old.album)) }
|
||||
?? pool.first { norm($0.title) == norm(old.title) && norm($0.artist) == norm(old.artist) }
|
||||
}
|
||||
var changed = false, missed = 0
|
||||
for li in lists.indices {
|
||||
for ii in lists[li].items.indices {
|
||||
let old = lists[li].items[ii].track
|
||||
guard let key = old.albumKey, let pool = fresh[key] else { continue }
|
||||
guard var new = pool.first(where: { $0.ratingKey == old.ratingKey })
|
||||
?? pool.first(where: { $0.title == old.title && $0.artist == old.artist }) else { continue }
|
||||
var new = old.albumKey.flatMap { fresh[$0] }.flatMap { pick(old, $0) }
|
||||
if new == nil, let search {
|
||||
if found[old.title] == nil { found[old.title] = (try? await search(old.title)) ?? [] }
|
||||
new = pick(old, found[old.title] ?? [])
|
||||
}
|
||||
guard var new else { missed += 1; continue }
|
||||
if new.stemKey == nil { new.stemKey = old.stemKey }
|
||||
if new != old { lists[li].items[ii].track = new; changed = true }
|
||||
}
|
||||
}
|
||||
print("[stemplaylists] refresh: \(fresh.count) albums, changed=\(changed), unmatched=\(missed)")
|
||||
if changed { save() }
|
||||
return changed
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user