- Add Netflix-style Home with recent audiobooks/podcasts, list/grid toggle shared with Library - Add searchable libraries — audiobooks filter on title/author; podcasts also index and search episodes across the whole library - Add unified context menu (download / progress remove) across Home, Library, and PodcastDetail - Rework cover badges: listened checkmark top-right, download indicator bottom-right; hide progress bar when finished - Add AirPlay picker in PlayerBar - Replace splash with four-phase animation: orbital particles → attract → flash → fade; cross-platform iOS+macOS, runtime AppIcon lookup - Fix macOS parallel downloads: align connection settings with iOS, raise timeoutIntervalForRequest to 300s - Fix progress deletion using server-side progress UUID (DELETE /api/me/progress/:id) - Bump CFBundleVersion to 8 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
49 lines
1.8 KiB
Swift
49 lines
1.8 KiB
Swift
import SwiftUI
|
|
|
|
/// Unified right-click / long-press menu for any `LibraryItem` shown on the
|
|
/// Home, Library, or Heruntergeladen screens. Includes both download actions
|
|
/// (start / cancel / delete files) AND a "Fortschritt entfernen" action when
|
|
/// the user has any server-side progress on the item.
|
|
///
|
|
/// The "Fortschritt entfernen" row was previously Home-only; the download
|
|
/// rows were previously Library-only — combining them in one place means the
|
|
/// same menu shows up regardless of which screen the user is on.
|
|
@ViewBuilder
|
|
func mediaItemContextMenu(for item: LibraryItem, app: AppState) -> some View {
|
|
let key = item.downloadKey
|
|
let state = app.downloads.state(for: key)
|
|
if item.isPodcastContainer {
|
|
Text("Episoden zum Download in der Podcast-Ansicht auswählen")
|
|
} else {
|
|
switch state {
|
|
case .notDownloaded, .failed:
|
|
Button {
|
|
app.downloads.startDownload(item: item)
|
|
} label: {
|
|
Label("Für Offline herunterladen", systemImage: "arrow.down.circle")
|
|
}
|
|
case .downloading:
|
|
Button {
|
|
app.downloads.cancel(downloadKey: key)
|
|
} label: {
|
|
Label("Download abbrechen", systemImage: "xmark.circle")
|
|
}
|
|
case .downloaded:
|
|
Button(role: .destructive) {
|
|
app.downloads.delete(downloadKey: key)
|
|
} label: {
|
|
Label("Heruntergeladene Dateien löschen", systemImage: "trash")
|
|
}
|
|
}
|
|
}
|
|
|
|
if app.progressCache[item.syncKey] != nil {
|
|
Divider()
|
|
Button(role: .destructive) {
|
|
Task { await app.removeProgress(itemId: item.id, episodeId: item.episodeId) }
|
|
} label: {
|
|
Label("Fortschritt entfernen", systemImage: "arrow.uturn.backward.circle")
|
|
}
|
|
}
|
|
}
|