Basic support for folder-type library items
- Add a new BaseItemDto.ItemType member: .folder. - Use CollectionItemViewModel to display folder-type item. - For each episode in a folder, fallback to primary image if series primary image is not available.
This commit is contained in:
parent
4e8a419dbc
commit
3f52223be5
|
@ -120,8 +120,12 @@ public extension BaseItemDto {
|
|||
}
|
||||
|
||||
func getSeriesPrimaryImage(maxWidth: Int) -> URL {
|
||||
guard let seriesId = seriesId else {
|
||||
return getPrimaryImage(maxWidth: maxWidth)
|
||||
}
|
||||
|
||||
let x = UIScreen.main.nativeScale * CGFloat(maxWidth)
|
||||
let urlString = ImageAPI.getItemImageWithRequestBuilder(itemId: seriesId ?? "",
|
||||
let urlString = ImageAPI.getItemImageWithRequestBuilder(itemId: seriesId,
|
||||
imageType: .primary,
|
||||
maxWidth: Int(x),
|
||||
quality: 96,
|
||||
|
@ -227,6 +231,7 @@ public extension BaseItemDto {
|
|||
case series = "Series"
|
||||
case boxset = "BoxSet"
|
||||
case collectionFolder = "CollectionFolder"
|
||||
case folder = "Folder"
|
||||
|
||||
case unknown
|
||||
|
||||
|
@ -249,7 +254,7 @@ public extension BaseItemDto {
|
|||
|
||||
func portraitHeaderViewURL(maxWidth: Int) -> URL {
|
||||
switch itemType {
|
||||
case .movie, .season, .series, .boxset, .collectionFolder:
|
||||
case .movie, .season, .series, .boxset, .collectionFolder, .folder:
|
||||
return getPrimaryImage(maxWidth: maxWidth)
|
||||
case .episode:
|
||||
return getSeriesPrimaryImage(maxWidth: maxWidth)
|
||||
|
|
|
@ -94,10 +94,14 @@ final class LibraryViewModel: ViewModel {
|
|||
genreIDs = filters.withGenres.compactMap(\.id)
|
||||
}
|
||||
let sortBy = filters.sortBy.map(\.rawValue)
|
||||
let queryRecursive = filters.filters.contains(.isFavorite) ||
|
||||
self.person != nil ||
|
||||
self.genre != nil ||
|
||||
self.studio != nil
|
||||
|
||||
ItemsAPI.getItemsByUserId(userId: SessionManager.main.currentLogin.user.id, startIndex: currentPage * pageItemSize,
|
||||
limit: pageItemSize,
|
||||
recursive: true,
|
||||
recursive: queryRecursive,
|
||||
searchTerm: nil,
|
||||
sortOrder: filters.sortOrder,
|
||||
parentId: parentID,
|
||||
|
@ -112,7 +116,7 @@ final class LibraryViewModel: ViewModel {
|
|||
],
|
||||
includeItemTypes: filters.filters
|
||||
.contains(.isFavorite) ? ["Movie", "Series", "Season", "Episode", "BoxSet"] :
|
||||
["Movie", "Series", "BoxSet"],
|
||||
["Movie", "Series", "BoxSet", "Folder"],
|
||||
filters: filters.filters,
|
||||
sortBy: sortBy,
|
||||
tags: filters.tags,
|
||||
|
|
|
@ -51,7 +51,7 @@ private struct ItemView: View {
|
|||
self.viewModel = EpisodeItemViewModel(item: item)
|
||||
case .series:
|
||||
self.viewModel = SeriesItemViewModel(item: item)
|
||||
case .boxset:
|
||||
case .boxset, .folder:
|
||||
self.viewModel = CollectionItemViewModel(item: item)
|
||||
default:
|
||||
self.viewModel = ItemViewModel(item: item)
|
||||
|
|
|
@ -73,36 +73,32 @@ struct LibraryListView: View {
|
|||
}
|
||||
|
||||
ForEach(viewModel.libraries, id: \.id) { library in
|
||||
if library.collectionType ?? "" == "movies" || library.collectionType ?? "" == "tvshows" {
|
||||
Button {
|
||||
libraryListRouter.route(to: \.library,
|
||||
(viewModel: LibraryViewModel(parentID: library.id),
|
||||
title: library.name ?? ""))
|
||||
} label: {
|
||||
ZStack {
|
||||
ImageView(src: library.getPrimaryImage(maxWidth: 500), bh: library.getPrimaryImageBlurHash())
|
||||
.opacity(0.4)
|
||||
.accessibilityIgnoresInvertColors()
|
||||
HStack {
|
||||
Spacer()
|
||||
VStack {
|
||||
Text(library.name ?? "")
|
||||
.foregroundColor(.white)
|
||||
.font(.title2)
|
||||
.fontWeight(.semibold)
|
||||
}
|
||||
Spacer()
|
||||
}.padding(32)
|
||||
}.background(Color.black)
|
||||
.frame(minWidth: 100, maxWidth: .infinity)
|
||||
.frame(height: 100)
|
||||
}
|
||||
.cornerRadius(10)
|
||||
.shadow(radius: 5)
|
||||
.padding(.bottom, 5)
|
||||
} else {
|
||||
EmptyView()
|
||||
Button {
|
||||
libraryListRouter.route(to: \.library,
|
||||
(viewModel: LibraryViewModel(parentID: library.id),
|
||||
title: library.name ?? ""))
|
||||
} label: {
|
||||
ZStack {
|
||||
ImageView(src: library.getPrimaryImage(maxWidth: 500), bh: library.getPrimaryImageBlurHash())
|
||||
.opacity(0.4)
|
||||
.accessibilityIgnoresInvertColors()
|
||||
HStack {
|
||||
Spacer()
|
||||
VStack {
|
||||
Text(library.name ?? "")
|
||||
.foregroundColor(.white)
|
||||
.font(.title2)
|
||||
.fontWeight(.semibold)
|
||||
}
|
||||
Spacer()
|
||||
}.padding(32)
|
||||
}.background(Color.black)
|
||||
.frame(minWidth: 100, maxWidth: .infinity)
|
||||
.frame(height: 100)
|
||||
}
|
||||
.cornerRadius(10)
|
||||
.shadow(radius: 5)
|
||||
.padding(.bottom, 5)
|
||||
}
|
||||
} else {
|
||||
ProgressView()
|
||||
|
|
|
@ -45,10 +45,8 @@ struct LibraryView: View {
|
|||
VStack {
|
||||
LazyVGrid(columns: tracks) {
|
||||
ForEach(viewModel.items, id: \.id) { item in
|
||||
if item.type != "Folder" {
|
||||
PortraitItemButton(item: item) { item in
|
||||
libraryRouter.route(to: \.item, item)
|
||||
}
|
||||
PortraitItemButton(item: item) { item in
|
||||
libraryRouter.route(to: \.item, item)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue