iOS 1.0 RC 2: Plex streams under upload caps, shuffle and album radio stations, Recently Added list, photo covers, crossfade
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
c0e33b5e3e
commit
2fb8040388
17 files changed
+412
-74
No files matched your search
@@ -78,7 +78,14 @@ struct MediaMenu {
|
||||
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) }]
|
||||
var acts: [SheetAction] = [
|
||||
SheetAction("Choose from Photos…", icon: "photo.on.rectangle") {
|
||||
overlays.pickPhoto { data in
|
||||
if !lists.setPhotoArt(pl.id, data) { overlays.hud("Couldn't use that photo", "exclamationmark.triangle") }
|
||||
}
|
||||
},
|
||||
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) })
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import PhotosUI
|
||||
import SwiftUI
|
||||
|
||||
struct SheetAction: Identifiable {
|
||||
@@ -29,6 +30,9 @@ final class Overlays {
|
||||
var prompt: Prompt?
|
||||
var hud: Hud?
|
||||
var addToPlaylist: AddToPlaylist?
|
||||
/// Set while the Photos picker is up; gets the picked image's data.
|
||||
var photoPick: ((Data) -> Void)?
|
||||
var photoShown = false
|
||||
/// 1 while the Now Playing sheet is up, so its host shows overlays instead of the root's.
|
||||
var level = 0
|
||||
|
||||
@@ -65,6 +69,10 @@ final class Overlays {
|
||||
present { self.addToPlaylist = AddToPlaylist(tracks: tracks, title: title, skip: skip) }
|
||||
}
|
||||
|
||||
func pickPhoto(_ run: @escaping (Data) -> Void) {
|
||||
present { self.photoPick = run; self.photoShown = true }
|
||||
}
|
||||
|
||||
func hud(_ text: String, _ icon: String = "checkmark") {
|
||||
hudTask?.cancel()
|
||||
withAnimation(.easeOut(duration: 0.15)) { hud = Hud(text: text, icon: icon) }
|
||||
@@ -81,6 +89,7 @@ struct OverlayHost: ViewModifier {
|
||||
let overlays: Overlays
|
||||
let level: Int
|
||||
@State private var text = ""
|
||||
@State private var photo: PhotosPickerItem?
|
||||
@Environment(\.palette) private var p
|
||||
|
||||
private var mine: Bool { overlays.level == level }
|
||||
@@ -116,6 +125,17 @@ struct OverlayHost: ViewModifier {
|
||||
if let m = p.message { Text(m) }
|
||||
}
|
||||
.onChange(of: overlays.prompt?.title) { _, _ in text = overlays.prompt?.initial ?? "" }
|
||||
.photosPicker(isPresented: Binding(get: { mine && overlays.photoShown }, set: { overlays.photoShown = $0 }),
|
||||
selection: $photo, matching: .images)
|
||||
.onChange(of: photo) { _, item in
|
||||
guard let item, let run = overlays.photoPick else { return }
|
||||
photo = nil
|
||||
overlays.photoPick = nil
|
||||
Task { @MainActor in
|
||||
if let data = try? await item.loadTransferable(type: Data.self) { run(data) }
|
||||
else { overlays.hud("Couldn't load that photo", "exclamationmark.triangle") }
|
||||
}
|
||||
}
|
||||
.sheet(item: Binding(get: { mine ? overlays.addToPlaylist : nil }, set: { overlays.addToPlaylist = $0 })) { r in
|
||||
AddToPlaylistSheet(req: r, overlays: overlays).environment(\.palette, p).tint(p.accent)
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user