fix bug related to recursive folders.
fix UI/UX errors in a specific situation when searching. add UI animation in Search.
This commit is contained in:
parent
c75e5d227e
commit
2888099328
|
@ -11,6 +11,7 @@ import Combine
|
|||
import CombineExt
|
||||
import Foundation
|
||||
import JellyfinAPI
|
||||
import SwiftUI
|
||||
|
||||
final class LibrarySearchViewModel: ViewModel {
|
||||
|
||||
|
@ -42,8 +43,7 @@ final class LibrarySearchViewModel: ViewModel {
|
|||
}
|
||||
|
||||
func setupPublishersForSupportedItemType() {
|
||||
|
||||
let supportedItemTypeListPublishers = Publishers.CombineLatest3($movieItems, $showItems, $episodeItems)
|
||||
Publishers.CombineLatest3($movieItems, $showItems, $episodeItems)
|
||||
.debounce(for: 0.25, scheduler: DispatchQueue.main)
|
||||
.map { arg -> [ItemType] in
|
||||
var typeList = [ItemType]()
|
||||
|
@ -58,21 +58,29 @@ final class LibrarySearchViewModel: ViewModel {
|
|||
}
|
||||
return typeList
|
||||
}
|
||||
|
||||
supportedItemTypeListPublishers
|
||||
.assign(to: \.supportedItemTypeList, on: self)
|
||||
.receive(on: DispatchQueue.main)
|
||||
.sink(receiveValue: { [weak self] typeList in
|
||||
withAnimation {
|
||||
self?.supportedItemTypeList = typeList
|
||||
}
|
||||
})
|
||||
.store(in: &cancellables)
|
||||
|
||||
supportedItemTypeListPublishers
|
||||
.withLatestFrom(supportedItemTypeListPublishers, $selectedItemType)
|
||||
.compactMap { typeList, selectedItemType in
|
||||
if typeList.contains(selectedItemType) {
|
||||
$supportedItemTypeList
|
||||
.receive(on: DispatchQueue.main)
|
||||
.withLatestFrom($selectedItemType)
|
||||
.compactMap { selectedItemType in
|
||||
if self.supportedItemTypeList.contains(selectedItemType) {
|
||||
return selectedItemType
|
||||
} else {
|
||||
return typeList.first
|
||||
return self.supportedItemTypeList.first
|
||||
}
|
||||
}
|
||||
.assign(to: \.selectedItemType, on: self)
|
||||
.sink(receiveValue: { [weak self] itemType in
|
||||
withAnimation {
|
||||
self?.selectedItemType = itemType
|
||||
}
|
||||
})
|
||||
.store(in: &cancellables)
|
||||
}
|
||||
|
||||
|
@ -87,6 +95,7 @@ final class LibrarySearchViewModel: ViewModel {
|
|||
enableTotalRecordCount: false,
|
||||
enableImages: false)
|
||||
.trackActivity(loading)
|
||||
.receive(on: DispatchQueue.main)
|
||||
.sink(receiveCompletion: { [weak self] completion in
|
||||
self?.handleAPIRequestError(completion: completion)
|
||||
}, receiveValue: { [weak self] response in
|
||||
|
@ -99,8 +108,10 @@ final class LibrarySearchViewModel: ViewModel {
|
|||
ItemsAPI.getItemsByUserId(userId: SessionManager.main.currentLogin.user.id, limit: 50, recursive: true, searchTerm: query,
|
||||
sortOrder: [.ascending], parentId: parentID,
|
||||
fields: [.primaryImageAspectRatio, .seriesPrimaryImage, .seasonUserData, .overview, .genres, .people],
|
||||
includeItemTypes: [ItemType.movie.rawValue], sortBy: ["SortName"], enableUserData: true, enableImages: true)
|
||||
includeItemTypes: [ItemType.movie.rawValue], sortBy: ["SortName"], enableUserData: true,
|
||||
enableImages: true)
|
||||
.trackActivity(loading)
|
||||
.receive(on: DispatchQueue.main)
|
||||
.sink(receiveCompletion: { [weak self] completion in
|
||||
self?.handleAPIRequestError(completion: completion)
|
||||
}, receiveValue: { [weak self] response in
|
||||
|
@ -110,8 +121,10 @@ final class LibrarySearchViewModel: ViewModel {
|
|||
ItemsAPI.getItemsByUserId(userId: SessionManager.main.currentLogin.user.id, limit: 50, recursive: true, searchTerm: query,
|
||||
sortOrder: [.ascending], parentId: parentID,
|
||||
fields: [.primaryImageAspectRatio, .seriesPrimaryImage, .seasonUserData, .overview, .genres, .people],
|
||||
includeItemTypes: [ItemType.series.rawValue], sortBy: ["SortName"], enableUserData: true, enableImages: true)
|
||||
includeItemTypes: [ItemType.series.rawValue], sortBy: ["SortName"], enableUserData: true,
|
||||
enableImages: true)
|
||||
.trackActivity(loading)
|
||||
.receive(on: DispatchQueue.main)
|
||||
.sink(receiveCompletion: { [weak self] completion in
|
||||
self?.handleAPIRequestError(completion: completion)
|
||||
}, receiveValue: { [weak self] response in
|
||||
|
@ -121,8 +134,10 @@ final class LibrarySearchViewModel: ViewModel {
|
|||
ItemsAPI.getItemsByUserId(userId: SessionManager.main.currentLogin.user.id, limit: 50, recursive: true, searchTerm: query,
|
||||
sortOrder: [.ascending], parentId: parentID,
|
||||
fields: [.primaryImageAspectRatio, .seriesPrimaryImage, .seasonUserData, .overview, .genres, .people],
|
||||
includeItemTypes: [ItemType.episode.rawValue], sortBy: ["SortName"], enableUserData: true, enableImages: true)
|
||||
includeItemTypes: [ItemType.episode.rawValue], sortBy: ["SortName"], enableUserData: true,
|
||||
enableImages: true)
|
||||
.trackActivity(loading)
|
||||
.receive(on: DispatchQueue.main)
|
||||
.sink(receiveCompletion: { [weak self] completion in
|
||||
self?.handleAPIRequestError(completion: completion)
|
||||
}, receiveValue: { [weak self] response in
|
||||
|
|
|
@ -48,14 +48,13 @@ final class LibraryViewModel: ViewModel {
|
|||
}
|
||||
}
|
||||
|
||||
init(
|
||||
parentID: String? = nil,
|
||||
person: BaseItemPerson? = nil,
|
||||
genre: NameGuidPair? = nil,
|
||||
studio: NameGuidPair? = nil,
|
||||
filters: LibraryFilters = LibraryFilters(filters: [], sortOrder: [.ascending], withGenres: [], sortBy: [.name]),
|
||||
columns: Int = 7
|
||||
) {
|
||||
init(parentID: String? = nil,
|
||||
person: BaseItemPerson? = nil,
|
||||
genre: NameGuidPair? = nil,
|
||||
studio: NameGuidPair? = nil,
|
||||
filters: LibraryFilters = LibraryFilters(filters: [], sortOrder: [.ascending], withGenres: [], sortBy: [.name]),
|
||||
columns: Int = 7)
|
||||
{
|
||||
self.parentID = parentID
|
||||
self.person = person
|
||||
self.genre = genre
|
||||
|
@ -67,7 +66,6 @@ final class LibraryViewModel: ViewModel {
|
|||
$filters
|
||||
.sink(receiveValue: requestItems(with:))
|
||||
.store(in: &cancellables)
|
||||
|
||||
}
|
||||
|
||||
func requestItems(with filters: LibraryFilters) {
|
||||
|
@ -80,10 +78,13 @@ final class LibraryViewModel: ViewModel {
|
|||
genreIDs = filters.withGenres.compactMap(\.id)
|
||||
}
|
||||
let sortBy = filters.sortBy.map(\.rawValue)
|
||||
let shouldBeRecursive: Bool = filters.filters.contains(.isFavorite) || personIDs != [] || studioIDs != [] || genreIDs != []
|
||||
ItemsAPI.getItemsByUserId(userId: SessionManager.main.currentLogin.user.id, startIndex: currentPage * 100, limit: 100, recursive: shouldBeRecursive,
|
||||
|
||||
ItemsAPI.getItemsByUserId(userId: SessionManager.main.currentLogin.user.id, startIndex: currentPage * 100, limit: 100,
|
||||
recursive: true,
|
||||
searchTerm: nil, sortOrder: filters.sortOrder, parentId: parentID,
|
||||
fields: [.primaryImageAspectRatio, .seriesPrimaryImage, .seasonUserData, .overview, .genres, .people], includeItemTypes: filters.filters.contains(.isFavorite) ? ["Movie", "Series", "Season", "Episode"] : ["Movie", "Series"],
|
||||
fields: [.primaryImageAspectRatio, .seriesPrimaryImage, .seasonUserData, .overview, .genres, .people],
|
||||
includeItemTypes: filters.filters
|
||||
.contains(.isFavorite) ? ["Movie", "Series", "Season", "Episode"] : ["Movie", "Series"],
|
||||
filters: filters.filters, sortBy: sortBy, tags: filters.tags,
|
||||
enableUserData: true, personIds: personIDs, studioIds: studioIDs, genreIds: genreIDs, enableImages: true)
|
||||
.trackActivity(loading)
|
||||
|
@ -112,10 +113,13 @@ final class LibraryViewModel: ViewModel {
|
|||
genreIDs = filters.withGenres.compactMap(\.id)
|
||||
}
|
||||
let sortBy = filters.sortBy.map(\.rawValue)
|
||||
let shouldBeRecursive: Bool = filters.filters.contains(.isFavorite) || personIDs != [] || studioIDs != [] || genreIDs != []
|
||||
ItemsAPI.getItemsByUserId(userId: SessionManager.main.currentLogin.user.id, startIndex: currentPage * 100, limit: 100, recursive: shouldBeRecursive,
|
||||
|
||||
ItemsAPI.getItemsByUserId(userId: SessionManager.main.currentLogin.user.id, startIndex: currentPage * 100, limit: 100,
|
||||
recursive: true,
|
||||
searchTerm: nil, sortOrder: filters.sortOrder, parentId: parentID,
|
||||
fields: [.primaryImageAspectRatio, .seriesPrimaryImage, .seasonUserData, .overview, .genres, .people], includeItemTypes: filters.filters.contains(.isFavorite) ? ["Movie", "Series", "Season", "Episode"] : ["Movie", "Series"],
|
||||
fields: [.primaryImageAspectRatio, .seriesPrimaryImage, .seasonUserData, .overview, .genres, .people],
|
||||
includeItemTypes: filters.filters
|
||||
.contains(.isFavorite) ? ["Movie", "Series", "Season", "Episode"] : ["Movie", "Series"],
|
||||
filters: filters.filters, sortBy: sortBy, tags: filters.tags,
|
||||
enableUserData: true, personIds: personIDs, studioIds: studioIDs, genreIds: genreIDs, enableImages: true)
|
||||
.sink(receiveCompletion: { [weak self] completion in
|
||||
|
@ -148,10 +152,10 @@ final class LibraryViewModel: ViewModel {
|
|||
}
|
||||
|
||||
private func calculateRows(for itemList: [BaseItemDto]) -> [LibraryRow] {
|
||||
guard itemList.count > 0 else { return [] }
|
||||
guard !itemList.isEmpty else { return [] }
|
||||
let rowCount = itemList.count / columns
|
||||
var calculatedRows = [LibraryRow]()
|
||||
for i in (0...rowCount) {
|
||||
for i in 0 ... rowCount {
|
||||
let firstItemIndex = i * columns
|
||||
var lastItemIndex = firstItemIndex + columns
|
||||
if lastItemIndex > itemList.count {
|
||||
|
@ -159,22 +163,18 @@ final class LibraryViewModel: ViewModel {
|
|||
}
|
||||
|
||||
var rowCells = [LibraryRowCell]()
|
||||
for item in itemList[firstItemIndex..<lastItemIndex] {
|
||||
for item in itemList[firstItemIndex ..< lastItemIndex] {
|
||||
let newCell = LibraryRowCell(item: item)
|
||||
rowCells.append(newCell)
|
||||
}
|
||||
if i == rowCount && hasNextPage {
|
||||
if i == rowCount, hasNextPage {
|
||||
var loadingCell = LibraryRowCell(item: nil)
|
||||
loadingCell.loadingCell = true
|
||||
rowCells.append(loadingCell)
|
||||
}
|
||||
|
||||
calculatedRows.append(
|
||||
LibraryRow(
|
||||
section: i,
|
||||
items: rowCells
|
||||
)
|
||||
)
|
||||
calculatedRows.append(LibraryRow(section: i,
|
||||
items: rowCells))
|
||||
}
|
||||
return calculatedRows
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue