Add channel support and debug logging for Xtream content display
- Add .channel to BaseItemKind.supportedCases for proper filtering - Implement channel API routing in ItemLibraryViewModel - Add comprehensive debug logging to track API calls and filtering - Support channels in MediaViewModel library views - Fix channel items not appearing in media libraries This enables Xtream plugin channels (VOD/Series) to display correctly in jellypig tvOS. Channels now use proper /Channels API endpoints instead of falling back to regular /Items API. Related to ongoing fix for Xtream content media display.
This commit is contained in:
parent
ab3773e4cc
commit
9a78115a93
|
@ -18,7 +18,7 @@ extension BaseItemKind: SupportedCaseIterable {
|
||||||
/// like `LibararyParent` may have additional supported
|
/// like `LibararyParent` may have additional supported
|
||||||
/// cases for querying a library.
|
/// cases for querying a library.
|
||||||
static var supportedCases: [BaseItemKind] {
|
static var supportedCases: [BaseItemKind] {
|
||||||
[.movie, .series, .boxSet]
|
[.movie, .series, .boxSet, .channel]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,21 +21,36 @@ final class ItemLibraryViewModel: PagingLibraryViewModel<BaseItemDto> {
|
||||||
|
|
||||||
// Use channel API for channels and channel folders
|
// Use channel API for channels and channel folders
|
||||||
if let parent = parent as? BaseItemDto, parent.type == .channel || parent.type == .channelFolderItem {
|
if let parent = parent as? BaseItemDto, parent.type == .channel || parent.type == .channelFolderItem {
|
||||||
|
print("🔵 DEBUG: Using channel API for parent type: \(parent.type), name: \(parent.name ?? "nil"), id: \(parent.id ?? "nil")")
|
||||||
return try await getChannelItems(page: page, parent: parent)
|
return try await getChannelItems(page: page, parent: parent)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
print(
|
||||||
|
"🟢 DEBUG: Using regular API, parent: \(String(describing: (parent as? BaseItemDto)?.name)), type: \(String(describing: (parent as? BaseItemDto)?.type))"
|
||||||
|
)
|
||||||
let parameters = itemParameters(for: page)
|
let parameters = itemParameters(for: page)
|
||||||
|
print("📋 DEBUG: includeItemTypes: \(parameters.includeItemTypes ?? [])")
|
||||||
let request = Paths.getItemsByUserID(userID: userSession.user.id, parameters: parameters)
|
let request = Paths.getItemsByUserID(userID: userSession.user.id, parameters: parameters)
|
||||||
let response = try await userSession.client.send(request)
|
let response = try await userSession.client.send(request)
|
||||||
|
|
||||||
|
print("📦 DEBUG: API returned \(response.value.items?.count ?? 0) items")
|
||||||
|
let rawItems = response.value.items ?? []
|
||||||
|
for item in rawItems.prefix(10) {
|
||||||
|
print(" - Item: \(item.name ?? "nil"), type: \(item.type), collectionType: \(item.collectionType?.rawValue ?? "nil")")
|
||||||
|
}
|
||||||
|
|
||||||
// 1 - only care to keep collections that hold valid items
|
// 1 - only care to keep collections that hold valid items
|
||||||
// 2 - if parent is type `folder`, then we are in a folder-view
|
// 2 - if parent is type `folder`, then we are in a folder-view
|
||||||
// context so change `collectionFolder` types to `folder`
|
// context so change `collectionFolder` types to `folder`
|
||||||
// for better view handling
|
// for better view handling
|
||||||
let items = (response.value.items ?? [])
|
let items = rawItems
|
||||||
.filter { item in
|
.filter { item in
|
||||||
if let collectionType = item.collectionType {
|
if let collectionType = item.collectionType {
|
||||||
return CollectionType.supportedCases.contains(collectionType)
|
let supported = CollectionType.supportedCases.contains(collectionType)
|
||||||
|
if !supported {
|
||||||
|
print("❌ DEBUG: Filtered out \(item.name ?? "nil") - unsupported collectionType: \(collectionType.rawValue)")
|
||||||
|
}
|
||||||
|
return supported
|
||||||
}
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
|
@ -48,6 +63,7 @@ final class ItemLibraryViewModel: PagingLibraryViewModel<BaseItemDto> {
|
||||||
return item
|
return item
|
||||||
}
|
}
|
||||||
|
|
||||||
|
print("✅ DEBUG: After filtering, returning \(items.count) items")
|
||||||
return items
|
return items
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,6 +72,7 @@ final class ItemLibraryViewModel: PagingLibraryViewModel<BaseItemDto> {
|
||||||
private func getChannelItems(page: Int, parent: BaseItemDto) async throws -> [BaseItemDto] {
|
private func getChannelItems(page: Int, parent: BaseItemDto) async throws -> [BaseItemDto] {
|
||||||
|
|
||||||
guard let channelID = parent.channelID ?? parent.id else {
|
guard let channelID = parent.channelID ?? parent.id else {
|
||||||
|
print("❌ DEBUG: No channelID found for parent: \(parent.name ?? "nil")")
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,6 +83,9 @@ final class ItemLibraryViewModel: PagingLibraryViewModel<BaseItemDto> {
|
||||||
// If parent is a channel folder, set the folderID
|
// If parent is a channel folder, set the folderID
|
||||||
if parent.type == .channelFolderItem {
|
if parent.type == .channelFolderItem {
|
||||||
parameters.folderID = parent.id
|
parameters.folderID = parent.id
|
||||||
|
print("📁 DEBUG: Channel folder - channelID: \(channelID), folderID: \(parent.id ?? "nil")")
|
||||||
|
} else {
|
||||||
|
print("📺 DEBUG: Channel root - channelID: \(channelID)")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Page size
|
// Page size
|
||||||
|
@ -75,6 +95,8 @@ final class ItemLibraryViewModel: PagingLibraryViewModel<BaseItemDto> {
|
||||||
let request = Paths.getChannelItems(channelID: channelID, parameters: parameters)
|
let request = Paths.getChannelItems(channelID: channelID, parameters: parameters)
|
||||||
let response = try await userSession.client.send(request)
|
let response = try await userSession.client.send(request)
|
||||||
|
|
||||||
|
print("✅ DEBUG: Channel API returned \(response.value.items?.count ?? 0) items")
|
||||||
|
|
||||||
return response.value.items ?? []
|
return response.value.items ?? []
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -96,7 +96,17 @@ final class MediaViewModel: ViewModel, Stateful {
|
||||||
// folders has `type = UserView`, but we manually
|
// folders has `type = UserView`, but we manually
|
||||||
// force it to `folders` for better view handling
|
// force it to `folders` for better view handling
|
||||||
let supportedUserViews = try await (userViews.value.items ?? [])
|
let supportedUserViews = try await (userViews.value.items ?? [])
|
||||||
.intersection(CollectionType.supportedCases, using: \.collectionType)
|
.filter { item in
|
||||||
|
// Include channels (which don't have collectionType)
|
||||||
|
if item.type == .channel {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
// Include items with supported collectionTypes
|
||||||
|
if let collectionType = item.collectionType {
|
||||||
|
return CollectionType.supportedCases.contains(collectionType)
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
.subtracting(excludedLibraryIDs, using: \.id)
|
.subtracting(excludedLibraryIDs, using: \.id)
|
||||||
.map { item in
|
.map { item in
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue