Phase 4 und Teile von Phase 5
Download-Regeln - Automatisches Löschen nach dem Ansehen, mit Frist statt sofort: wer die letzte Szene noch einmal sucht, soll sie nicht schon verloren haben. „Nie" ist die Voreinstellung. - „Halte N ungesehene Folgen offline": wartende und laufende Downloads zählen mit, sonst würde bei jedem Durchlauf nachgelegt, bis die ganze Serie auf dem Gerät liegt. - Beides als reine Rechnung ohne Zugriff auf Datenbank oder Dateien — bei einer Regel, die Filme löscht, ist Prüfbarkeit keine Formsache. 13 Tests. Qualitätswahl beim Download - transcodedDownloadURL über den Universal-Transcoder mit protocol=http statt über die umständliche Sync-API. NOCH NICHT AM SERVER GEPRÜFT: offen ist, ob Plex eine Content-Length mitschickt (sonst kein Fortschritt und kein Fortsetzen) und ob die Datei durchsuchbar ist. Steht so im Quelltext; Original bleibt Voreinstellung. Erscheinungsbild - Akzentfarbe: zehn kuratierte Kacheln plus freie Hex-Eingabe. Bei einer eigenen Farbe greift die Kontrastkorrektur und sagt es auch — sonst wirkt sie wie ein Fehler. - Vorschaufläche mit Knopf, Symbol und Fortschrittsbalken. Serveraktionen - Gesehen-Status umschalten und Sterne setzen über ein Menü auf der Detailseite. - Suchlauf der Mediathek aus der Werkzeugleiste. 115 Tests. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -15,6 +15,7 @@ struct LibraryView: View {
|
||||
@State private var page: PlexPage<PlexItem>?
|
||||
@State private var isLoadingMore = false
|
||||
@State private var showsFilters = false
|
||||
@State private var isScanning = false
|
||||
|
||||
var body: some View {
|
||||
Group {
|
||||
@@ -141,9 +142,37 @@ struct LibraryView: View {
|
||||
.accessibilityLabel(Text("library.toggleLayout"))
|
||||
}
|
||||
|
||||
ToolbarItem(placement: .topBarTrailing) {
|
||||
Menu {
|
||||
Button {
|
||||
Task { await scan() }
|
||||
} label: {
|
||||
Label("library.scan", systemImage: "arrow.triangle.2.circlepath")
|
||||
}
|
||||
.disabled(isScanning)
|
||||
} label: {
|
||||
Image(systemName: "ellipsis.circle")
|
||||
}
|
||||
}
|
||||
|
||||
SearchToolbarItem()
|
||||
}
|
||||
|
||||
/// Stößt einen Suchlauf auf dem Server an.
|
||||
///
|
||||
/// Der Server meldet nicht, wann er fertig ist — die Liste wird deshalb
|
||||
/// nach kurzer Wartezeit neu geholt. Wer gerade Dateien abgelegt hat,
|
||||
/// sieht sie damit meistens schon.
|
||||
private func scan() async {
|
||||
guard let server = session.server, !isScanning else { return }
|
||||
isScanning = true
|
||||
defer { isScanning = false }
|
||||
|
||||
try? await server.refreshLibrary(library)
|
||||
try? await Task.sleep(for: .seconds(3))
|
||||
await reload()
|
||||
}
|
||||
|
||||
// MARK: - Laden
|
||||
|
||||
private func reload() async {
|
||||
|
||||
Reference in New Issue
Block a user