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:
PangMo5 2022-01-03 00:27:44 +09:00
parent c75e5d227e
commit 2888099328
2 changed files with 54 additions and 39 deletions

View File

@ -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

View File

@ -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
}