Sprachwahl in der App — bei Serien und bei Filmen

Auf der Serienseite stand ein Menü für den Ton, gefüllt mit zwanzig
Sprachen, von denen die Serie zwei hatte. Für Untertitel gab es keines,
und auf der Filmseite überhaupt nichts.

Jetzt beides an beiden Orten, und zwar nur mit dem, was es wirklich gibt:

Bei einer **Serie** über den neuen Endpunkt — die Schnittmenge über alle
Folgen. Was dadurch wegfällt, steht als Satz darunter, sonst sähe eine
gekürzte Liste aus wie die ganze Wahrheit.

Bei einem **Film** aus den Spuren der Datei. Kein Serverweg nötig: dort
ist die Datei der Titel, und ihre Spuren stehen in der Antwort, die die
Seite ohnehin geholt hat.

Ton und Untertitel teilen sich einen Typ. Sie unterscheiden sich in genau
zwei Punkten — woher der Wert kommt und ob es „Keine" gibt; ein zweiter
Typ wäre dieselbe Datei mit zwei geänderten Zeilen. „Keine" gibt es nur
beim Untertitel: ein Film ohne Tonspur ist kein Wunsch, sondern ein
Fehler.

Die Untertitelsprache liegt je Titel, in einem Topf für Serien und Filme
— eine Filmkennung kollidiert mit keiner Serie, und zwei Wörterbücher für
dieselbe Frage liefen auseinander. Der Spieler liest sie jetzt: vorher
kannte er nur die allgemeine, und eine Serie im Original mit deutschen
Untertiteln liess sich nicht einstellen, ohne sie überall einzuschalten.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Scarriffle
2026-10-10 21:56:15 +02:00
co-authored by Claude Opus 5
parent 95d7eee8c3
commit 84612335ec
9 changed files with 377 additions and 22 deletions
@@ -147,6 +147,18 @@ public actor FlaroBackend: MediaBackend {
items: titel)
}
public func availableLanguages(inSeries id: String) async -> AvailableLanguages? {
guard let roh = try? await client.send(
FlaroRequest(path: "/api/v1/series/\(id)/languages"),
as: Wire.Sprachauswahl.self)
else { return nil }
return AvailableLanguages(
audio: roh.audio.map { LanguageOption(code: $0.code, name: $0.name) },
subtitles: roh.subtitles.map { LanguageOption(code: $0.code, name: $0.name) },
partial: roh.partial)
}
public func items(
inLibrary library: MediaLibrary,
query: MediaQuery,
@@ -212,6 +212,17 @@ enum Wire {
let subtitleStreams: [Stromspur]
}
struct Sprachangabe: Decodable, Sendable {
let code: String
let name: String
}
struct Sprachauswahl: Decodable, Sendable {
let audio: [Sprachangabe]
let subtitles: [Sprachangabe]
let partial: Int
}
struct LoginRequest: Encodable, Sendable {
let userName: String
let password: String