Files
ABS-Client/ABS Client/Audiobookshelf swift/Views/MediaItemContextMenu.swift
Scarriffle a17a61ad9a Home screen, library-wide search, splash with orbital particles, macOS download fix
- 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>
2026-06-23 08:54:43 +02:00

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")
}
}
}