From e3bcd8638a8ea49ac136c7cd6d03c56eb0b49067 Mon Sep 17 00:00:00 2001 From: Ashik K Date: Fri, 17 Oct 2025 09:53:23 +0200 Subject: [PATCH] Implement channel navigation for Jellyfin plugin channels MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Modified ItemLibraryViewModel to detect channel/channelFolderItem types - Added getChannelItems() method to use Paths.getChannelItems API for channels - Channel folders now use channelID and folderID parameters correctly - Modified PagingLibraryView to route .channelFolderItem to library grid view This enables proper navigation for Jellyfin.Xtream plugin channels: Channel → Grid of Categories → Grid of Content → Item Detail 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .../ItemLibraryViewModel.swift | 32 +++++++++++++++++++ .../PagingLibraryView/PagingLibraryView.swift | 2 +- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/Shared/ViewModels/LibraryViewModel/ItemLibraryViewModel.swift b/Shared/ViewModels/LibraryViewModel/ItemLibraryViewModel.swift index c51a0413..aa8d863a 100644 --- a/Shared/ViewModels/LibraryViewModel/ItemLibraryViewModel.swift +++ b/Shared/ViewModels/LibraryViewModel/ItemLibraryViewModel.swift @@ -19,6 +19,11 @@ final class ItemLibraryViewModel: PagingLibraryViewModel { override func get(page: Int) async throws -> [BaseItemDto] { + // Use channel API for channels and channel folders + if let parent = parent as? BaseItemDto, parent.type == .channel || parent.type == .channelFolderItem { + return try await getChannelItems(page: page, parent: parent) + } + let parameters = itemParameters(for: page) let request = Paths.getItemsByUserID(userID: userSession.user.id, parameters: parameters) let response = try await userSession.client.send(request) @@ -46,6 +51,33 @@ final class ItemLibraryViewModel: PagingLibraryViewModel { return items } + // MARK: getChannelItems + + private func getChannelItems(page: Int, parent: BaseItemDto) async throws -> [BaseItemDto] { + + guard let channelID = parent.channelID ?? parent.id else { + return [] + } + + var parameters = Paths.GetChannelItemsParameters() + parameters.userID = userSession.user.id + parameters.fields = .MinimumFields + + // If parent is a channel folder, set the folderID + if parent.type == .channelFolderItem { + parameters.folderID = parent.id + } + + // Page size + parameters.limit = pageSize + parameters.startIndex = page * pageSize + + let request = Paths.getChannelItems(channelID: channelID, parameters: parameters) + let response = try await userSession.client.send(request) + + return response.value.items ?? [] + } + // MARK: item parameters private func itemParameters(for page: Int?) -> Paths.GetItemsByUserIDParameters { diff --git a/jellypig tvOS/Views/PagingLibraryView/PagingLibraryView.swift b/jellypig tvOS/Views/PagingLibraryView/PagingLibraryView.swift index c7754a7f..d161cb11 100644 --- a/jellypig tvOS/Views/PagingLibraryView/PagingLibraryView.swift +++ b/jellypig tvOS/Views/PagingLibraryView/PagingLibraryView.swift @@ -101,7 +101,7 @@ struct PagingLibraryView: View { private func select(item: BaseItemDto) { switch item.type { - case .collectionFolder, .folder: + case .collectionFolder, .folder, .channelFolderItem: let viewModel = ItemLibraryViewModel(parent: item, filters: .default) router.route(to: \.library, viewModel) case .person: