iOS: stem playlist refresh and covers, download queue page, reorderable Library, whole-library radio

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
rootandClaude Sonnet 5.5 committed 2026-10-28 15:49:09 -07:00
1 parent 7c8dfb54ca
commit a4c870251c
18 files changed
+514 -30

No files matched your search

+19 -1
View File
@@ -15,7 +15,14 @@ struct MediaMenu {
a.append(SheetAction("Remove Download", icon: "trash", destructive: true) { g.downloads.remove([t]) })
}
a.append(SheetAction("Add to Playlist…", icon: "text.badge.plus") { addToPlaylist([t]) })
if t.partFile != nil, g.stems.index.size > 0, g.stems.find(t) == nil { a.append(stemNow { [t] }) }
if t.partFile != nil, g.stems.index.size > 0, g.stems.find(t) == nil {
let s = g.stems.state(t)
if s == .stemming || s == .queued {
a.append(SheetAction(s == .stemming ? "Stemming…" : "Queued for Stems", icon: "waveform") {})
} else {
a.append(stemNow { [t] })
}
}
if allowGoTo, let k = t.albumKey {
a.append(SheetAction("Go to Album", icon: "square.stack") {
ui.showInLibrary(.AlbumPage(Album(ratingKey: k, title: t.album, artist: t.artist, artistKey: t.artistKey, year: t.year, thumb: t.thumb)))
@@ -68,6 +75,17 @@ struct MediaMenu {
{ pl.tracks }, confirm: false))
if pl.items.isEmpty { a = [] }
let lists = g.stemPlaylists
if !pl.items.isEmpty {
a.append(SheetAction("Change Cover…", icon: "photo") {
var seen = Set<String>()
var acts: [SheetAction] = [SheetAction("Automatic", icon: "wand.and.stars") { lists.setArt(pl.id, nil) }]
for t in pl.tracks {
guard let th = t.thumb, seen.insert(th).inserted, seen.count <= 20 else { continue }
acts.append(SheetAction(t.album, icon: th == pl.artThumb ? "checkmark" : "photo") { lists.setArt(pl.id, th) })
}
overlays.actions("Choose a Cover", acts)
})
}
a.append(SheetAction("Delete Stem Playlist", icon: "trash", destructive: true) {
overlays.confirm("Delete “\(pl.title)”?", "Stem playlists are only on this device.", "Delete") { lists.delete(pl.id); if onPage { ui.pop() } }
})