diff --git a/Shared/Coordinators/LibraryCoordinator.swift b/Shared/Coordinators/LibraryCoordinator.swift index 2c7c6392..3897ea20 100644 --- a/Shared/Coordinators/LibraryCoordinator.swift +++ b/Shared/Coordinators/LibraryCoordinator.swift @@ -6,6 +6,7 @@ // Copyright (c) 2022 Jellyfin & Jellyfin Contributors // +import Defaults import Foundation import JellyfinAPI import Stinsen @@ -63,9 +64,18 @@ final class LibraryCoordinator: NavigationCoordinatable { @ViewBuilder func makeStart() -> some View { if let parent = parameters.parent { - LibraryView(viewModel: LibraryViewModel(parent: parent, type: parameters.type, filters: parameters.filters)) + if parameters.filters == .init(), let id = parent.id, let storedFilters = Defaults[.libraryFilterStore][id] { + LibraryView(viewModel: LibraryViewModel(parent: parent, type: parameters.type, filters: storedFilters, saveFilters: true)) + } else { + LibraryView(viewModel: LibraryViewModel( + parent: parent, + type: parameters.type, + filters: parameters.filters, + saveFilters: false + )) + } } else { - LibraryView(viewModel: LibraryViewModel(filters: parameters.filters)) + LibraryView(viewModel: LibraryViewModel(filters: parameters.filters, saveFilters: false)) } } diff --git a/Shared/Objects/ItemFilters.swift b/Shared/Objects/ItemFilters.swift index a5f77e90..01380bda 100644 --- a/Shared/Objects/ItemFilters.swift +++ b/Shared/Objects/ItemFilters.swift @@ -7,13 +7,13 @@ // import Combine +import Defaults import Foundation import JellyfinAPI -struct ItemFilters: Hashable { +struct ItemFilters: Codable, Defaults.Serializable, Hashable { var genres: [Filter] = [] - var tags: [Filter] = [] var filters: [Filter] = [] var sortOrder: [Filter] = [APISortOrder.ascending.filter] var sortBy: [Filter] = [SortBy.name.filter] @@ -31,7 +31,7 @@ struct ItemFilters: Hashable { } // Type-erased object for use with WritableKeyPath - struct Filter: Displayable, Hashable, Identifiable { + struct Filter: Codable, Defaults.Serializable, Displayable, Hashable, Identifiable { var displayName: String var id: String? var filterName: String diff --git a/Shared/SwiftfinStore/SwiftfinStoreDefaults.swift b/Shared/SwiftfinStore/SwiftfinStoreDefaults.swift index 6dd20fe4..7f188742 100644 --- a/Shared/SwiftfinStore/SwiftfinStoreDefaults.swift +++ b/Shared/SwiftfinStore/SwiftfinStoreDefaults.swift @@ -26,6 +26,7 @@ extension Defaults.Keys { static let lastServerUserID = Defaults.Key("lastServerUserID", suite: .generalSuite) static let inNetworkBandwidth = Key("InNetworkBandwidth", default: 40_000_000, suite: .generalSuite) static let outOfNetworkBandwidth = Key("OutOfNetworkBandwidth", default: 40_000_000, suite: .generalSuite) + static let libraryFilterStore = Key<[String: ItemFilters]>("libraryFilterStore", default: [:], suite: .generalSuite) enum Customization { static let itemViewType = Key("itemViewType", default: .compactLogo, suite: .generalSuite) diff --git a/Shared/ViewModels/FilterViewModel.swift b/Shared/ViewModels/FilterViewModel.swift index 97b72d73..a32244ff 100644 --- a/Shared/ViewModels/FilterViewModel.swift +++ b/Shared/ViewModels/FilterViewModel.swift @@ -39,7 +39,6 @@ final class FilterViewModel: ViewModel { self?.handleAPIRequestError(completion: completion) }, receiveValue: { [weak self] queryFilters in self?.allFilters.genres = queryFilters.genres?.map(\.filter) ?? [] - self?.allFilters.tags = queryFilters.tags?.map(\.filter) ?? [] }) .store(in: &cancellables) } diff --git a/Shared/ViewModels/ItemTypeLibraryViewModel.swift b/Shared/ViewModels/ItemTypeLibraryViewModel.swift index 24f7b600..b1425b0c 100644 --- a/Shared/ViewModels/ItemTypeLibraryViewModel.swift +++ b/Shared/ViewModels/ItemTypeLibraryViewModel.swift @@ -39,7 +39,6 @@ final class ItemTypeLibraryViewModel: PagingLibraryViewModel { let sortBy: [String] = filters.sortBy.map(\.filterName).appending("IsFolder") let sortOrder = filters.sortOrder.map { SortOrder(rawValue: $0.filterName) ?? .ascending } let itemFilters: [ItemFilter] = filters.filters.compactMap { .init(rawValue: $0.filterName) } - let tags: [String] = filters.tags.map(\.filterName) ItemsAPI.getItemsByUserId( userId: SessionManager.main.currentLogin.user.id, @@ -51,7 +50,6 @@ final class ItemTypeLibraryViewModel: PagingLibraryViewModel { includeItemTypes: itemTypes, filters: itemFilters, sortBy: sortBy, - tags: tags, enableUserData: true, genreIds: genreIDs ) diff --git a/Shared/ViewModels/LibraryViewModel.swift b/Shared/ViewModels/LibraryViewModel.swift index 4f06a1c5..68d6e584 100644 --- a/Shared/ViewModels/LibraryViewModel.swift +++ b/Shared/ViewModels/LibraryViewModel.swift @@ -7,6 +7,7 @@ // import Combine +import Defaults import JellyfinAPI import SwiftUI import UIKit @@ -18,6 +19,7 @@ final class LibraryViewModel: PagingLibraryViewModel { let parent: LibraryParent? let type: LibraryParentType + private let saveFilters: Bool var libraryCoordinatorParameters: LibraryCoordinator.Parameters { if let parent = parent { @@ -27,32 +29,29 @@ final class LibraryViewModel: PagingLibraryViewModel { } } - init(filters: ItemFilters) { - self.parent = nil - self.type = .library - self.filterViewModel = .init(parent: nil, currentFilters: filters) - super.init() - - filterViewModel.$currentFilters - .sink { newFilters in - self.requestItems(with: newFilters, replaceCurrentItems: true) - } - .store(in: &cancellables) + convenience init(filters: ItemFilters, saveFilters: Bool = false) { + self.init(parent: nil, type: .library, filters: filters, saveFilters: saveFilters) } init( - parent: LibraryParent, + parent: LibraryParent?, type: LibraryParentType, - filters: ItemFilters = .init() + filters: ItemFilters = .init(), + saveFilters: Bool = false ) { self.parent = parent self.type = type self.filterViewModel = .init(parent: parent, currentFilters: filters) + self.saveFilters = saveFilters super.init() filterViewModel.$currentFilters .sink { newFilters in self.requestItems(with: newFilters, replaceCurrentItems: true) + + if self.saveFilters, let id = self.parent?.id { + Defaults[.libraryFilterStore][id] = newFilters + } } .store(in: &cancellables) } @@ -102,7 +101,6 @@ final class LibraryViewModel: PagingLibraryViewModel { let sortBy: [String] = filters.sortBy.map(\.filterName).appending("IsFolder") let sortOrder = filters.sortOrder.map { SortOrder(rawValue: $0.filterName) ?? .ascending } let itemFilters: [ItemFilter] = filters.filters.compactMap { .init(rawValue: $0.filterName) } - let tags: [String] = filters.tags.map(\.filterName) ItemsAPI.getItemsByUserId( userId: SessionManager.main.currentLogin.user.id, @@ -116,7 +114,6 @@ final class LibraryViewModel: PagingLibraryViewModel { includeItemTypes: includeItemTypes, filters: itemFilters, sortBy: sortBy, - tags: tags, enableUserData: true, personIds: personIDs, studioIds: studioIDs, diff --git a/Shared/ViewModels/SearchViewModel.swift b/Shared/ViewModels/SearchViewModel.swift index 0fe46d72..ed957017 100644 --- a/Shared/ViewModels/SearchViewModel.swift +++ b/Shared/ViewModels/SearchViewModel.swift @@ -86,7 +86,6 @@ final class SearchViewModel: ViewModel { let sortBy: [String] = filters.sortBy.map(\.filterName) let sortOrder = filters.sortOrder.map { SortOrder(rawValue: $0.filterName) ?? .ascending } let itemFilters: [ItemFilter] = filters.filters.compactMap { .init(rawValue: $0.filterName) } - let tags: [String] = filters.tags.map(\.filterName) ItemsAPI.getItemsByUserId( userId: SessionManager.main.currentLogin.user.id, @@ -98,7 +97,6 @@ final class SearchViewModel: ViewModel { includeItemTypes: [itemType], filters: itemFilters, sortBy: sortBy, - tags: tags, enableUserData: true, genreIds: genreIDs, enableImages: true diff --git a/Swiftfin/Components/FilterDrawerHStack/FilterDrawerHStack.swift b/Swiftfin/Components/FilterDrawerHStack/FilterDrawerHStack.swift index 5cbdf7c1..38c6f0ae 100644 --- a/Swiftfin/Components/FilterDrawerHStack/FilterDrawerHStack.swift +++ b/Swiftfin/Components/FilterDrawerHStack/FilterDrawerHStack.swift @@ -39,16 +39,6 @@ struct FilterDrawerHStack: View { )) } - FilterDrawerButton(title: L10n.tags, activated: viewModel.currentFilters.tags != []) - .onSelect { - onSelect(.init( - title: L10n.tags, - viewModel: viewModel, - filter: \.tags, - selectorType: .multi - )) - } - FilterDrawerButton(title: L10n.filters, activated: viewModel.currentFilters.filters != []) .onSelect { onSelect(.init(