Aufnehmen, was noch gar nicht läuft

Der dritte Modus neben Raster und Senderliste — und der einzige, den es
nicht überall gibt. Bei Plex fehlt schlicht der Schalter dorthin, denn
supportsRecordings fragt die eigene Fähigkeit ab.

Vormerken sitzt im Blatt, das eine angetippte Sendung ohnehin schon
öffnet, statt in einem zweiten Kontextmenü daneben. Trägt die Sendung
bereits einen Serien-Timer, steht dort das statt der Knöpfe: zweimal
vormerken ist kein Wunsch, sondern ein Versehen.

Aufnahmen führen über die Detailseite statt unmittelbar in den Player.
Eine Aufnahme ist auf dem Server ein gewöhnlicher Eintrag, und erst dort
steht, in welchen Fassungen sie vorliegt — von der Liste aus zu starten
hieße, das zu raten.

Zwölf Schlüssel in DE und EN. Die Übersetzungsdatei ist dabei auf das
Format zurückgeschrieben worden, das auch im letzten Commit steht;
inhaltlich ist sie HEAD plus diese zwölf, nachgerechnet.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Scarriffle
2026-09-14 06:26:34 +02:00
co-authored by Claude Opus 5
parent eebe9280cb
commit 982ae83e76
4 changed files with 614 additions and 59 deletions
+40 -1
View File
@@ -26,6 +26,13 @@ struct ProgramGuide: View {
/// Blick darauf nicht zu finden.
let artwork: (LiveChannel) -> URL?
let onTune: (LiveChannel, LiveProgram?) -> Void
/// Eine Sendung vormerken — einmalig oder als ganze Reihe.
///
/// Beide optional: **nicht** jeder Server kann aufnehmen. `nil` heißt,
/// dass die Knöpfe gar nicht erst erscheinen — besser als ein Knopf, der
/// bei Plex nur eine Fehlermeldung auslöst.
var onRecord: ((LiveProgram) -> Void)?
var onRecordSeries: ((LiveProgram) -> Void)?
@Environment(\.flixyAccent) private var accent
@@ -65,7 +72,9 @@ struct ProgramGuide: View {
artworkURL: artwork(selection.channel),
program: selection.program,
isRunning: selection.program.isRunning(at: now),
onTune: { onTune(selection.channel, selection.program) }
onTune: { onTune(selection.channel, selection.program) },
onRecord: onRecord.map { record in { record(selection.program) } },
onRecordSeries: onRecordSeries.map { record in { record(selection.program) } }
)
}
// Die Fortschrittsbalken und die Jetzt-Linie stimmen sonst nach ein
@@ -287,6 +296,8 @@ private struct ProgramDetailSheet: View {
let program: LiveProgram
let isRunning: Bool
let onTune: () -> Void
let onRecord: (() -> Void)?
let onRecordSeries: (() -> Void)?
@Environment(\.flixyAccent) private var accent
@Environment(\.dismiss) private var dismiss
@@ -332,6 +343,34 @@ private struct ProgramDetailSheet: View {
.tint(accent)
}
// Vormerken steht auch bei einer laufenden Sendung: der
// Rest davon lässt sich noch aufnehmen. Bei einem Server
// ohne Aufnahmen fehlt hier schlicht alles.
if program.seriesTimerID != nil {
Label("liveTV.alreadyScheduled", systemImage: "checkmark.circle")
.font(.flixyCaption)
.foregroundStyle(Color.flixyTextSecondary)
} else if onRecord != nil || onRecordSeries != nil {
HStack(spacing: FlixySpacing.regular) {
if let onRecord {
Button { onRecord(); dismiss() } label: {
Label("liveTV.record", systemImage: "record.circle")
.frame(maxWidth: .infinity)
.padding(.vertical, FlixySpacing.snug)
}
.buttonStyle(.bordered)
}
if let onRecordSeries {
Button { onRecordSeries(); dismiss() } label: {
Label("liveTV.recordSeries", systemImage: "rectangle.stack.badge.record")
.frame(maxWidth: .infinity)
.padding(.vertical, FlixySpacing.snug)
}
.buttonStyle(.bordered)
}
}
}
if let summary = program.summary, !summary.isEmpty {
Text(summary)
.font(.flixyBody)