From 1fa80110945ec46b170cd478e752aa58fe6b70e2 Mon Sep 17 00:00:00 2001 From: Scarriffle Date: Thu, 1 Oct 2026 10:25:16 +0200 Subject: [PATCH] =?UTF-8?q?Eine=20Mediathek=20fehlte=20ganz=20=E2=80=94=20?= =?UTF-8?q?=E2=80=9EHeimvideos"=20lagen=20bei=20den=20Fotos?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Jellyfin nennt „Heimvideos & Fotos" `collectionType: homevideos`. Die Zuordnung legte das zusammen mit `photos` auf `.photo` — und damit fiel die ganze Mediathek unter `MediaLibrary.isSupported` heraus: keine Reihe auf der Startseite, kein Eintrag in der Mediathekenleiste, nicht einmal eine Zeile in der Auswahl für den Aufmacher. Aus Sicht der App gab es sie nicht. Dass Fotos im Namen stehen, macht den Inhalt nicht zu Fotos. `photos` bleibt bei den Fotos, `homevideos` ist jetzt `.other` — wie alles, was der Server nicht einsortiert. Die Zuordnung steht dafür nicht mehr mitten in `libraries()`, sondern als eigene Funktion mit Tests. Sie entscheidet mehr, als sie aussieht: was hier als `.photo` oder `.music` landet, ist in der App unsichtbar, und das sieht aus wie ein Server, der nichts liefert — nicht wie eine Zuordnung, die zu scharf ist. Drei Tests halten es fest, darunter der Fall ohne Angabe: eine gemischte Mediathek meldet gar keine Art und muss trotzdem bleiben. iOS und tvOS bauen, 472 Tests grün. Co-Authored-By: Claude Opus 5 --- .../Sources/JellyfinKit/JellyfinBackend.swift | 37 ++++++++++++++---- .../JellyfinKitTests/TranslationTests.swift | 39 +++++++++++++++++++ 2 files changed, 68 insertions(+), 8 deletions(-) diff --git a/Packages/FlixyKit/Sources/JellyfinKit/JellyfinBackend.swift b/Packages/FlixyKit/Sources/JellyfinKit/JellyfinBackend.swift index 546cc46..b840ac1 100644 --- a/Packages/FlixyKit/Sources/JellyfinKit/JellyfinBackend.swift +++ b/Packages/FlixyKit/Sources/JellyfinKit/JellyfinBackend.swift @@ -73,14 +73,7 @@ public func isInLocalNetwork() async -> Bool { as: JellyfinItemPage.self ) return page.items.map { view in - let kind: MediaLibrary.Kind = switch view.collectionType { - case "movies": .movie - case "tvshows": .show - case "music": .music - case "homevideos", "photos": .photo - case "livetv": .liveTV - default: .other - } + let kind = MediaLibrary.Kind(jellyfinCollectionType: view.collectionType) return MediaLibrary( id: view.id, title: view.name ?? "—", @@ -634,3 +627,31 @@ extension MediaQuery.Sort { } } } + +extension MediaLibrary.Kind { + /// Was Jellyfin als Art einer Mediathek meldet. + /// + /// **Eigene Funktion, damit sie prüfbar ist.** Die Zuordnung entscheidet + /// mehr, als sie aussieht: was hier als `.photo` oder `.music` landet, + /// fällt unter `MediaLibrary.isSupported` heraus und ist in der App + /// **gar nicht vorhanden** — keine Reihe, kein Eintrag in der Leiste, + /// nicht einmal in der Auswahl für den Aufmacher. Ein Fehler hier sieht + /// aus wie eine Mediathek, die der Server nicht liefert. + /// + /// Genau das war mit `homevideos` der Fall: Jellyfin nennt „Heimvideos & + /// Fotos" so, und weil Fotos im Namen stehen, lag es bei den Fotos. Der + /// Inhalt sind Videos. + init(jellyfinCollectionType: String?) { + switch jellyfinCollectionType { + case "movies": self = .movie + case "tvshows": self = .show + case "music": self = .music + case "photos": self = .photo + case "livetv": self = .liveTV + // Auch `homevideos`, `musicvideos`, `mixed` und alles Unbekannte: + // Videos, die man ansehen kann, auch wenn der Server sie nicht + // einsortiert. + default: self = .other + } + } +} diff --git a/Packages/FlixyKit/Tests/JellyfinKitTests/TranslationTests.swift b/Packages/FlixyKit/Tests/JellyfinKitTests/TranslationTests.swift index 07097fd..ab713ae 100644 --- a/Packages/FlixyKit/Tests/JellyfinKitTests/TranslationTests.swift +++ b/Packages/FlixyKit/Tests/JellyfinKitTests/TranslationTests.swift @@ -182,3 +182,42 @@ struct TranslationTests { return item.asMediaItem(imageBase: JellyfinImagePaths()) } } + +@Suite("Die Art einer Mediathek") +struct LibraryKindTests { + + @Test( + "Die bekannten Arten", + arguments: [ + ("movies", MediaLibrary.Kind.movie), + ("tvshows", .show), + ("music", .music), + ("photos", .photo), + ("livetv", .liveTV), + ] + ) + func mapsKnownTypes(type: String, expected: MediaLibrary.Kind) { + #expect(MediaLibrary.Kind(jellyfinCollectionType: type) == expected) + } + + /// **Der Fall, der eine ganze Mediathek verschwinden liess.** Jellyfin + /// nennt „Heimvideos & Fotos" `homevideos`; weil Fotos im Namen stehen, + /// lag es bei den Fotos — und fiel damit unter `isSupported` heraus. Die + /// Mediathek war in der App nicht vorhanden, nicht einmal in der Auswahl + /// für den Aufmacher. + @Test("Heimvideos sind Videos, keine Fotos") + func homeVideosAreWatchable() { + let art = MediaLibrary.Kind(jellyfinCollectionType: "homevideos") + #expect(art == .other) + #expect(MediaLibrary(id: "1", title: "Videos", kind: art).isSupported) + } + + /// Eine gemischte Mediathek meldet gar keine Art. Sie deshalb + /// wegzulassen hiesse, den häufigsten selbstgebauten Fall zu übersehen. + @Test("Ohne Angabe bleibt sie trotzdem da") + func unknownStays() { + let art = MediaLibrary.Kind(jellyfinCollectionType: nil) + #expect(art == .other) + #expect(MediaLibrary(id: "1", title: "Gemischtes", kind: art).isSupported) + } +}