diff --git a/Ferrite.xcodeproj/project.pbxproj b/Ferrite.xcodeproj/project.pbxproj index d51e8b3..3c46056 100644 --- a/Ferrite.xcodeproj/project.pbxproj +++ b/Ferrite.xcodeproj/project.pbxproj @@ -36,7 +36,6 @@ 0C41BC6528C2AEB900B47DD6 /* SearchModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C41BC6428C2AEB900B47DD6 /* SearchModels.swift */; }; 0C422E7E293542EA00486D65 /* PremiumizeWrapper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C422E7D293542EA00486D65 /* PremiumizeWrapper.swift */; }; 0C422E80293542F300486D65 /* PremiumizeModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C422E7F293542F300486D65 /* PremiumizeModels.swift */; }; - 0C42B5962932F2D5008057A0 /* DebridPickerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C42B5952932F2D5008057A0 /* DebridPickerView.swift */; }; 0C42B5982932F6DD008057A0 /* Set.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C42B5972932F6DD008057A0 /* Set.swift */; }; 0C445C62293F9A0B0060744D /* Bundle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C445C61293F9A0B0060744D /* Bundle.swift */; }; 0C448BE929A135F100F4E266 /* Introspect-Static in Frameworks */ = {isa = PBXBuildFile; productRef = 0C448BE829A135F100F4E266 /* Introspect-Static */; }; @@ -90,6 +89,11 @@ 0C84F4832895BFED0074B7C9 /* Source+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C84F47B2895BFED0074B7C9 /* Source+CoreDataProperties.swift */; }; 0C84F4842895BFED0074B7C9 /* SourceHtmlParser+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C84F47C2895BFED0074B7C9 /* SourceHtmlParser+CoreDataClass.swift */; }; 0C84F4852895BFED0074B7C9 /* SourceHtmlParser+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C84F47D2895BFED0074B7C9 /* SourceHtmlParser+CoreDataProperties.swift */; }; + 0C84FCE129E4B41D00B0DFE4 /* SourceFilterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C84FCE029E4B41D00B0DFE4 /* SourceFilterView.swift */; }; + 0C84FCE329E4B42600B0DFE4 /* IAFilterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C84FCE229E4B42600B0DFE4 /* IAFilterView.swift */; }; + 0C84FCE529E4B43200B0DFE4 /* SelectedDebridFilterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C84FCE429E4B43200B0DFE4 /* SelectedDebridFilterView.swift */; }; + 0C84FCE729E4B61A00B0DFE4 /* FilterModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C84FCE629E4B61A00B0DFE4 /* FilterModels.swift */; }; + 0C84FCE929E5ADEF00B0DFE4 /* FilterAmountLabelView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C84FCE829E5ADEF00B0DFE4 /* FilterAmountLabelView.swift */; }; 0C871BDF29994D9D005279AC /* FilterLabelView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C871BDE29994D9D005279AC /* FilterLabelView.swift */; }; 0C8DC35229CE287E008A83AD /* PluginInfoView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C8DC35129CE287E008A83AD /* PluginInfoView.swift */; }; 0C8DC35429CE2AB5008A83AD /* SourceSettingsBaseUrlView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C8DC35329CE2AB5008A83AD /* SourceSettingsBaseUrlView.swift */; }; @@ -182,7 +186,6 @@ 0C41BC6428C2AEB900B47DD6 /* SearchModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchModels.swift; sourceTree = ""; }; 0C422E7D293542EA00486D65 /* PremiumizeWrapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PremiumizeWrapper.swift; sourceTree = ""; }; 0C422E7F293542F300486D65 /* PremiumizeModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PremiumizeModels.swift; sourceTree = ""; }; - 0C42B5952932F2D5008057A0 /* DebridPickerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DebridPickerView.swift; sourceTree = ""; }; 0C42B5972932F6DD008057A0 /* Set.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Set.swift; sourceTree = ""; }; 0C445C61293F9A0B0060744D /* Bundle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Bundle.swift; sourceTree = ""; }; 0C44E2A728D4DDDC007711AE /* Application.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Application.swift; sourceTree = ""; }; @@ -230,6 +233,11 @@ 0C84F47B2895BFED0074B7C9 /* Source+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Source+CoreDataProperties.swift"; sourceTree = ""; }; 0C84F47C2895BFED0074B7C9 /* SourceHtmlParser+CoreDataClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SourceHtmlParser+CoreDataClass.swift"; sourceTree = ""; }; 0C84F47D2895BFED0074B7C9 /* SourceHtmlParser+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SourceHtmlParser+CoreDataProperties.swift"; sourceTree = ""; }; + 0C84FCE029E4B41D00B0DFE4 /* SourceFilterView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SourceFilterView.swift; sourceTree = ""; }; + 0C84FCE229E4B42600B0DFE4 /* IAFilterView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IAFilterView.swift; sourceTree = ""; }; + 0C84FCE429E4B43200B0DFE4 /* SelectedDebridFilterView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectedDebridFilterView.swift; sourceTree = ""; }; + 0C84FCE629E4B61A00B0DFE4 /* FilterModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FilterModels.swift; sourceTree = ""; }; + 0C84FCE829E5ADEF00B0DFE4 /* FilterAmountLabelView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FilterAmountLabelView.swift; sourceTree = ""; }; 0C871BDE29994D9D005279AC /* FilterLabelView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FilterLabelView.swift; sourceTree = ""; }; 0C8DC35129CE287E008A83AD /* PluginInfoView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PluginInfoView.swift; sourceTree = ""; }; 0C8DC35329CE2AB5008A83AD /* SourceSettingsBaseUrlView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SourceSettingsBaseUrlView.swift; sourceTree = ""; }; @@ -322,6 +330,7 @@ 0C0755C32934244500ECA142 /* ComponentViews */ = { isa = PBXGroup; children = ( + 0C84FCDB29E4B3F400B0DFE4 /* Filters */, 0C3E00D4296F560800ECECB2 /* Plugin */, 0C0755C42934245800ECA142 /* Debrid */, 0CA3B23528C265FD00616D3A /* Library */, @@ -334,7 +343,6 @@ 0C0755C42934245800ECA142 /* Debrid */ = { isa = PBXGroup; children = ( - 0C42B5952932F2D5008057A0 /* DebridPickerView.swift */, 0C0755C5293424A200ECA142 /* DebridLabelView.swift */, ); path = Debrid; @@ -378,6 +386,7 @@ 0C6C7C9C29315292002DF910 /* AllDebridModels.swift */, 0C7ED14028D61BBA009E29AD /* BackupModels.swift */, 0C0755C7293425B500ECA142 /* DebridManagerModels.swift */, + 0C84FCE629E4B61A00B0DFE4 /* FilterModels.swift */, 0C68135128BC1A7C00FAD890 /* GithubModels.swift */, 0C422E7F293542F300486D65 /* PremiumizeModels.swift */, 0C0167DB29293FA900B65783 /* RealDebridModels.swift */, @@ -493,6 +502,18 @@ path = Source; sourceTree = ""; }; + 0C84FCDB29E4B3F400B0DFE4 /* Filters */ = { + isa = PBXGroup; + children = ( + 0C84FCE029E4B41D00B0DFE4 /* SourceFilterView.swift */, + 0C84FCE229E4B42600B0DFE4 /* IAFilterView.swift */, + 0C84FCE429E4B43200B0DFE4 /* SelectedDebridFilterView.swift */, + 0C871BDE29994D9D005279AC /* FilterLabelView.swift */, + 0C84FCE829E5ADEF00B0DFE4 /* FilterAmountLabelView.swift */, + ); + path = Filters; + sourceTree = ""; + }; 0CA0545C288F7CB200850554 /* Settings */ = { isa = PBXGroup; children = ( @@ -532,7 +553,6 @@ children = ( 0C44E2A928D4DFC4007711AE /* Modifiers */, 0CDCB91728C662640098B513 /* EmptyInstructionView.swift */, - 0C871BDE29994D9D005279AC /* FilterLabelView.swift */, 0CA148C1288903F000DE2211 /* NavView.swift */, 0CA3FB1F28B91D9500FA10A8 /* IndeterminateProgressView.swift */, 0CB6516928C5B4A600DCA721 /* InlineHeader.swift */, @@ -802,6 +822,7 @@ 0C70E40628C40C4E00A5C72D /* NotificationCenter.swift in Sources */, 0C84F4832895BFED0074B7C9 /* Source+CoreDataProperties.swift in Sources */, 0C2D9653299316CC00A504B6 /* Tag.swift in Sources */, + 0C84FCE129E4B41D00B0DFE4 /* SourceFilterView.swift in Sources */, 0CD5E78928CD932B001BF684 /* DisabledAppearance.swift in Sources */, 0CA148DB288903F000DE2211 /* NavView.swift in Sources */, 0CA3B23C28C2AA5600616D3A /* Bookmark+CoreDataClass.swift in Sources */, @@ -820,7 +841,6 @@ 0C5005522992B6750064606A /* PluginTagsView.swift in Sources */, 0CB0AB5F29BD2A200015422C /* KodiServerView.swift in Sources */, 0CF2C0A529D1EBD400E716DD /* UIApplication.swift in Sources */, - 0C42B5962932F2D5008057A0 /* DebridPickerView.swift in Sources */, 0C2886D72960C50900D6FC16 /* RealDebridCloudView.swift in Sources */, 0C3DD44229B6ACD9006429DB /* KodiServer+CoreDataClass.swift in Sources */, 0C794B6B289DACF100DD1CC8 /* PluginCatalogButtonView.swift in Sources */, @@ -839,6 +859,7 @@ 0CC389542970AD900066D06F /* Action+CoreDataProperties.swift in Sources */, 0C7ED14128D61BBA009E29AD /* BackupModels.swift in Sources */, 0CAF9319296399190050812A /* PremiumizeCloudView.swift in Sources */, + 0C84FCE529E4B43200B0DFE4 /* SelectedDebridFilterView.swift in Sources */, 0CA148EC288903F000DE2211 /* ContentView.swift in Sources */, 0CC389532970AD900066D06F /* Action+CoreDataClass.swift in Sources */, 0C03EB72296F619900162E9A /* PluginList+CoreDataProperties.swift in Sources */, @@ -881,8 +902,10 @@ 0C41BC6328C2AD0F00B47DD6 /* SearchResultButtonView.swift in Sources */, 0CA05459288EE9E600850554 /* PluginManager.swift in Sources */, 0C84F4772895BE680074B7C9 /* FerriteDB.xcdatamodeld in Sources */, + 0C84FCE729E4B61A00B0DFE4 /* FilterModels.swift in Sources */, 0C12D43D28CC332A000195BF /* HistoryButtonView.swift in Sources */, 0C733287289C4C820058D1FE /* SourceSettingsView.swift in Sources */, + 0C84FCE929E5ADEF00B0DFE4 /* FilterAmountLabelView.swift in Sources */, 0C10848B28BD9A38008F0BA6 /* SettingsAppVersionView.swift in Sources */, 0CA05457288EE58200850554 /* SettingsPluginListView.swift in Sources */, 0C78041D28BFB3EA001E8CA3 /* String.swift in Sources */, @@ -898,6 +921,7 @@ 0C7075E429D374C50093DB2D /* Color.swift in Sources */, 0C8DC35229CE287E008A83AD /* PluginInfoView.swift in Sources */, 0C422E80293542F300486D65 /* PremiumizeModels.swift in Sources */, + 0C84FCE329E4B42600B0DFE4 /* IAFilterView.swift in Sources */, 0C8DC35629CE2ABF008A83AD /* SourceSettingsApiView.swift in Sources */, 0C4CFC4D28970C8B00AD9FAD /* SourceComplexQuery+CoreDataClass.swift in Sources */, 0C0974B029CCAAAF006DE7A3 /* OperatingSystemVersion.swift in Sources */, diff --git a/Ferrite/Models/FilterModels.swift b/Ferrite/Models/FilterModels.swift new file mode 100644 index 0000000..03cf910 --- /dev/null +++ b/Ferrite/Models/FilterModels.swift @@ -0,0 +1,14 @@ +// +// FilterModels.swift +// Ferrite +// +// Created by Brian Dashore on 4/10/23. +// + +import Foundation + +enum FilterType { + case source + case IA + case sort +} diff --git a/Ferrite/ViewModels/NavigationViewModel.swift b/Ferrite/ViewModels/NavigationViewModel.swift index 6ca6540..fdebe78 100644 --- a/Ferrite/ViewModels/NavigationViewModel.swift +++ b/Ferrite/ViewModels/NavigationViewModel.swift @@ -48,6 +48,9 @@ public class NavigationViewModel: ObservableObject { @Published var selectedTitle: String = "" @Published var selectedBatchTitle: String = "" + // For filters + @Published var enabledFilters: Set = [] + @Published var kodiExpanded: Bool = false @Published var currentChoiceSheet: ChoiceSheetType? diff --git a/Ferrite/ViewModels/PluginManager.swift b/Ferrite/ViewModels/PluginManager.swift index 5374cfc..b857554 100644 --- a/Ferrite/ViewModels/PluginManager.swift +++ b/Ferrite/ViewModels/PluginManager.swift @@ -265,6 +265,19 @@ public class PluginManager: ObservableObject { return Application.shared.appVersion >= minVersion } + // Fetches sources using the background context + public func fetchInstalledSources(searchResultsEmpty: Bool) -> [Source] { + let backgroundContext = PersistenceController.shared.backgroundContext + + if !filteredInstalledSources.isEmpty && !searchResultsEmpty { + return filteredInstalledSources + } else if let sources = try? backgroundContext.fetch(Source.fetchRequest()) { + return sources.compactMap { $0 } + } else { + return [] + } + } + @MainActor public func runDefaultAction(urlString: String?, navModel: NavigationViewModel) { let context = PersistenceController.shared.backgroundContext diff --git a/Ferrite/Views/CommonViews/FilterLabelView.swift b/Ferrite/Views/CommonViews/FilterLabelView.swift deleted file mode 100644 index 39171b4..0000000 --- a/Ferrite/Views/CommonViews/FilterLabelView.swift +++ /dev/null @@ -1,30 +0,0 @@ -// -// FilterLabelView.swift -// Ferrite -// -// Created by Brian Dashore on 2/12/23. -// - -import SwiftUI - -struct FilterLabelView: View { - var name: String - - var body: some View { - HStack(spacing: 4) { - Text(name) - .opacity(0.6) - .foregroundColor(.primary) - - Image(systemName: "chevron.down") - .foregroundColor(.init(uiColor: .tertiaryLabel)) - } - .padding(.horizontal, 9) - .padding(.vertical, 7) - .font( - .caption - .weight(.medium) - ) - .background(Capsule().foregroundColor(.init(uiColor: .secondarySystemFill))) - } -} diff --git a/Ferrite/Views/ComponentViews/Filters/FilterAmountLabelView.swift b/Ferrite/Views/ComponentViews/Filters/FilterAmountLabelView.swift new file mode 100644 index 0000000..0664fc4 --- /dev/null +++ b/Ferrite/Views/ComponentViews/Filters/FilterAmountLabelView.swift @@ -0,0 +1,24 @@ +// +// FilterAmountLabelView.swift +// Ferrite +// +// Created by Brian Dashore on 4/11/23. +// + +import SwiftUI + +struct FilterAmountLabelView: View { + @Environment (\.colorScheme) var colorScheme + + var amount: Int + + var body: some View { + Text(String(amount)) + .padding(5) + .foregroundColor(colorScheme == .light ? .white : .accentColor) + .background { + Circle() + .foregroundColor(colorScheme == .light ? .accentColor : .white) + } + } +} diff --git a/Ferrite/Views/ComponentViews/Filters/FilterLabelView.swift b/Ferrite/Views/ComponentViews/Filters/FilterLabelView.swift new file mode 100644 index 0000000..115d37e --- /dev/null +++ b/Ferrite/Views/ComponentViews/Filters/FilterLabelView.swift @@ -0,0 +1,43 @@ +// +// FilterLabelView.swift +// Ferrite +// +// Created by Brian Dashore on 2/12/23. +// + +import SwiftUI + +struct FilterLabelView: View { + @Environment(\.colorScheme) var colorScheme + + var name: String + var count: Int? + + var body: some View { + HStack(spacing: 4) { + if let count, count > 1 { + FilterAmountLabelView(amount: count) + } + + Text(name) + .opacity(count ?? 0 > 0 ? 1 : 0.6) + .foregroundColor(count ?? 0 > 0 && colorScheme == .light ? .accentColor : .primary) + + Image(systemName: "chevron.down") + .foregroundColor(count ?? 0 > 0 ? (colorScheme == .light ? .accentColor : .primary) : .init(uiColor: .tertiaryLabel)) + } + .padding(.horizontal, 9) + .padding(.vertical, count ?? 1 > 1 ? 2 : 7) + .font( + .caption + .weight(.medium) + ) + .background( + Capsule() + .foregroundColor( + count ?? 0 > 0 ? .accentColor : .init(uiColor: .secondarySystemFill) + ) + .opacity(count ?? 0 > 0 && colorScheme == .light ? 0.1 : 1) + ) + } +} diff --git a/Ferrite/Views/ComponentViews/Filters/IAFilterView.swift b/Ferrite/Views/ComponentViews/Filters/IAFilterView.swift new file mode 100644 index 0000000..68365e0 --- /dev/null +++ b/Ferrite/Views/ComponentViews/Filters/IAFilterView.swift @@ -0,0 +1,47 @@ +// +// IAFilterView.swift +// Ferrite +// +// Created by Brian Dashore on 4/10/23. +// + +import SwiftUI + +// TODO: Make this use multiple selections +struct IAFilterView: View { + @EnvironmentObject var debridManager: DebridManager + @EnvironmentObject var navModel: NavigationViewModel + + var body: some View { + Menu { + Picker("", selection: $debridManager.filteredIAStatus) { + Text("All").tag([] as [IAStatus]) + + ForEach(IAStatus.allCases, id: \.self) { status in + Text(status.rawValue).tag([status]) + } + } + } label: { + FilterLabelView( + name: debridManager.filteredIAStatus.first?.rawValue ?? "Cache Status", + count: debridManager.filteredIAStatus.count + ) + } + .id(debridManager.filteredIAStatus) + .onChange(of: debridManager.filteredIAStatus) { newSources in + if newSources.isEmpty { + navModel.enabledFilters.remove(.IA) + } else { + navModel.enabledFilters.insert(.IA) + } + } + .onChange(of: navModel.enabledFilters) { newFilters in + if newFilters.isEmpty { + Task { + try? await Task.sleep(seconds: 0.25) + debridManager.filteredIAStatus = [] + } + } + } + } +} diff --git a/Ferrite/Views/ComponentViews/Debrid/DebridPickerView.swift b/Ferrite/Views/ComponentViews/Filters/SelectedDebridFilterView.swift similarity index 79% rename from Ferrite/Views/ComponentViews/Debrid/DebridPickerView.swift rename to Ferrite/Views/ComponentViews/Filters/SelectedDebridFilterView.swift index a4e6178..a282976 100644 --- a/Ferrite/Views/ComponentViews/Debrid/DebridPickerView.swift +++ b/Ferrite/Views/ComponentViews/Filters/SelectedDebridFilterView.swift @@ -1,13 +1,13 @@ // -// DebridChoiceView.swift +// SelectedDebridFilterView.swift // Ferrite // -// Created by Brian Dashore on 11/26/22. +// Created by Brian Dashore on 4/10/23. // import SwiftUI -struct DebridPickerView: View { +struct SelectedDebridFilterView: View { @EnvironmentObject var debridManager: DebridManager @ViewBuilder var label: Content @@ -28,5 +28,6 @@ struct DebridPickerView: View { } label: { label } + .id(debridManager.selectedDebridType) } } diff --git a/Ferrite/Views/ComponentViews/Filters/SourceFilterView.swift b/Ferrite/Views/ComponentViews/Filters/SourceFilterView.swift new file mode 100644 index 0000000..9d45ead --- /dev/null +++ b/Ferrite/Views/ComponentViews/Filters/SourceFilterView.swift @@ -0,0 +1,55 @@ +// +// SourceFilterView.swift +// Ferrite +// +// Created by Brian Dashore on 4/10/23. +// + +import SwiftUI + +// TODO: Make this use multiple selections +struct SourceFilterView: View { + @EnvironmentObject var pluginManager: PluginManager + @EnvironmentObject var navModel: NavigationViewModel + + @FetchRequest( + entity: Source.entity(), + sortDescriptors: [] + ) var sources: FetchedResults + + var body: some View { + Menu { + Picker("", selection: $pluginManager.filteredInstalledSources) { + Text("All").tag([] as [Source]) + + ForEach(sources, id: \.self) { source in + if source.enabled { + Text(source.name) + .tag([source]) + } + } + } + } label: { + FilterLabelView( + name: pluginManager.filteredInstalledSources.first?.name ?? "Source", + count: pluginManager.filteredInstalledSources.count + ) + } + .id(pluginManager.filteredInstalledSources) + .onChange(of: pluginManager.filteredInstalledSources) { newSources in + if newSources.isEmpty { + navModel.enabledFilters.remove(.source) + } else { + navModel.enabledFilters.insert(.source) + } + } + .onChange(of: navModel.enabledFilters) { newFilters in + if newFilters.isEmpty { + Task { + try? await Task.sleep(seconds: 0.25) + pluginManager.filteredInstalledSources = [] + } + } + } + } +} diff --git a/Ferrite/Views/ComponentViews/SearchResult/SearchFilterHeaderView.swift b/Ferrite/Views/ComponentViews/SearchResult/SearchFilterHeaderView.swift index 7bb8920..13e0938 100644 --- a/Ferrite/Views/ComponentViews/SearchResult/SearchFilterHeaderView.swift +++ b/Ferrite/Views/ComponentViews/SearchResult/SearchFilterHeaderView.swift @@ -12,61 +12,57 @@ struct SearchFilterHeaderView: View { @EnvironmentObject var debridManager: DebridManager @EnvironmentObject var pluginManager: PluginManager - - var sources: FetchedResults + @EnvironmentObject var navModel: NavigationViewModel var body: some View { ScrollView(.horizontal, showsIndicators: false) { HStack(spacing: 6) { + // MARK: - Current filters + + if !navModel.enabledFilters.isEmpty { + Menu { + Button("Clear filters", role: .destructive) { + navModel.enabledFilters = [] + } + } label: { + HStack(spacing: 4) { + Image(systemName: "line.3.horizontal.decrease") + .opacity(0.6) + .foregroundColor(.primary) + + FilterAmountLabelView(amount: navModel.enabledFilters.count) + } + .padding(.horizontal, 9) + .padding(.vertical, 2) + .font( + .caption + .weight(.medium) + ) + .background(Capsule().foregroundColor(.init(uiColor: .secondarySystemFill))) + } + + Divider() + .frame(width:2, height: 20) + } + // MARK: - Source filter picker - // TODO: Make this use multiple selections - Menu { - Picker("", selection: $pluginManager.filteredInstalledSources) { - Text("All").tag([] as [Source]) - - ForEach(sources, id: \.self) { source in - if source.enabled { - Text(source.name) - .tag([source]) - } - } - } - } label: { - FilterLabelView( - name: pluginManager.filteredInstalledSources.first?.name ?? "Source" - ) - } - .id(pluginManager.filteredInstalledSources) + SourceFilterView() // MARK: - Selected debrid picker - DebridPickerView { + SelectedDebridFilterView { FilterLabelView(name: debridManager.selectedDebridType?.toString() ?? "Debrid") } - .id(debridManager.selectedDebridType) // MARK: - Cache status picker - // TODO: Make this use multiple selections if !debridManager.enabledDebrids.isEmpty { - Menu { - Picker("", selection: $debridManager.filteredIAStatus) { - Text("All").tag([] as [IAStatus]) - - ForEach(IAStatus.allCases, id: \.self) { status in - Text(status.rawValue).tag([status]) - } - } - } label: { - FilterLabelView( - name: debridManager.filteredIAStatus.first?.rawValue ?? "Cache Status" - ) - } - .id(debridManager.filteredIAStatus) + IAFilterView() } } .padding(.horizontal, verticalSizeClass == .compact ? 65 : 18) + .animation(.easeInOut, value: navModel.enabledFilters) } } } diff --git a/Ferrite/Views/ContentView.swift b/Ferrite/Views/ContentView.swift index e93d379..5826aff 100644 --- a/Ferrite/Views/ContentView.swift +++ b/Ferrite/Views/ContentView.swift @@ -56,7 +56,7 @@ struct ContentView: View { prompt: navModel.searchPrompt, dismiss: $dismissAction, scopeBarContent: { - SearchFilterHeaderView(sources: sources) + SearchFilterHeaderView() }, onSubmit: { if @@ -75,21 +75,15 @@ struct ContentView: View { .onAppear { navModel.getSearchPrompt() } - .onChange(of: isEditingSearch) { newVal in - print(newVal) - } } } func executeSearch() { scrapingModel.runningSearchTask = Task { await scrapingModel.scanSources( - sources: - scrapingModel.searchResults.isEmpty ? - sources.compactMap { $0 } : - (pluginManager.filteredInstalledSources.isEmpty ? - sources.compactMap { $0 } : - pluginManager.filteredInstalledSources), + sources: pluginManager.fetchInstalledSources( + searchResultsEmpty: scrapingModel.searchResults.isEmpty + ), searchText: searchText, debridManager: debridManager ) diff --git a/Ferrite/Views/LibraryView.swift b/Ferrite/Views/LibraryView.swift index f2b2644..fd5a87a 100644 --- a/Ferrite/Views/LibraryView.swift +++ b/Ferrite/Views/LibraryView.swift @@ -68,7 +68,7 @@ struct LibraryView: View { switch navModel.libraryPickerSelection { case .bookmarks, .debridCloud: - DebridPickerView { + SelectedDebridFilterView { Text(debridManager.selectedDebridType?.toString(abbreviated: true) ?? "Debrid") } .transaction {