SearchResults: Add source filtering
Presenting all source results can be annoying to a user. Add filtering to filter by a specific source. Signed-off-by: kingbri <bdashore3@gmail.com>
This commit is contained in:
parent
1eef8202ca
commit
119a3a18b1
6 changed files with 137 additions and 62 deletions
|
|
@ -11,6 +11,7 @@
|
||||||
0C0D50E2288DF7700035ECC8 /* TorrentSource+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C0D50E0288DF7700035ECC8 /* TorrentSource+CoreDataProperties.swift */; };
|
0C0D50E2288DF7700035ECC8 /* TorrentSource+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C0D50E0288DF7700035ECC8 /* TorrentSource+CoreDataProperties.swift */; };
|
||||||
0C0D50E5288DFE7F0035ECC8 /* SourceModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C0D50E4288DFE7F0035ECC8 /* SourceModels.swift */; };
|
0C0D50E5288DFE7F0035ECC8 /* SourceModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C0D50E4288DFE7F0035ECC8 /* SourceModels.swift */; };
|
||||||
0C0D50E7288DFF850035ECC8 /* SourceListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C0D50E6288DFF850035ECC8 /* SourceListView.swift */; };
|
0C0D50E7288DFF850035ECC8 /* SourceListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C0D50E6288DFF850035ECC8 /* SourceListView.swift */; };
|
||||||
|
0C57D4CC289032ED008534E8 /* SearchResultRDView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C57D4CB289032ED008534E8 /* SearchResultRDView.swift */; };
|
||||||
0C64A4B4288903680079976D /* Base32 in Frameworks */ = {isa = PBXBuildFile; productRef = 0C64A4B3288903680079976D /* Base32 */; };
|
0C64A4B4288903680079976D /* Base32 in Frameworks */ = {isa = PBXBuildFile; productRef = 0C64A4B3288903680079976D /* Base32 */; };
|
||||||
0C64A4B7288903880079976D /* KeychainSwift in Frameworks */ = {isa = PBXBuildFile; productRef = 0C64A4B6288903880079976D /* KeychainSwift */; };
|
0C64A4B7288903880079976D /* KeychainSwift in Frameworks */ = {isa = PBXBuildFile; productRef = 0C64A4B6288903880079976D /* KeychainSwift */; };
|
||||||
0C90E32C2888E5D000C0BC89 /* ActivityView in Frameworks */ = {isa = PBXBuildFile; productRef = 0C90E32B2888E5D000C0BC89 /* ActivityView */; };
|
0C90E32C2888E5D000C0BC89 /* ActivityView in Frameworks */ = {isa = PBXBuildFile; productRef = 0C90E32B2888E5D000C0BC89 /* ActivityView */; };
|
||||||
|
|
@ -52,6 +53,7 @@
|
||||||
0C0D50E0288DF7700035ECC8 /* TorrentSource+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TorrentSource+CoreDataProperties.swift"; sourceTree = "<group>"; };
|
0C0D50E0288DF7700035ECC8 /* TorrentSource+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TorrentSource+CoreDataProperties.swift"; sourceTree = "<group>"; };
|
||||||
0C0D50E4288DFE7F0035ECC8 /* SourceModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SourceModels.swift; sourceTree = "<group>"; };
|
0C0D50E4288DFE7F0035ECC8 /* SourceModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SourceModels.swift; sourceTree = "<group>"; };
|
||||||
0C0D50E6288DFF850035ECC8 /* SourceListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SourceListView.swift; sourceTree = "<group>"; };
|
0C0D50E6288DFF850035ECC8 /* SourceListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SourceListView.swift; sourceTree = "<group>"; };
|
||||||
|
0C57D4CB289032ED008534E8 /* SearchResultRDView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchResultRDView.swift; sourceTree = "<group>"; };
|
||||||
0CA05456288EE58200850554 /* SettingsSourceUrlView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsSourceUrlView.swift; sourceTree = "<group>"; };
|
0CA05456288EE58200850554 /* SettingsSourceUrlView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsSourceUrlView.swift; sourceTree = "<group>"; };
|
||||||
0CA05458288EE9E600850554 /* SourceManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SourceManager.swift; sourceTree = "<group>"; };
|
0CA05458288EE9E600850554 /* SourceManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SourceManager.swift; sourceTree = "<group>"; };
|
||||||
0CA0545A288EEA4E00850554 /* SourceListEditorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SourceListEditorView.swift; sourceTree = "<group>"; };
|
0CA0545A288EEA4E00850554 /* SourceListEditorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SourceListEditorView.swift; sourceTree = "<group>"; };
|
||||||
|
|
@ -179,6 +181,7 @@
|
||||||
0CA148C0288903F000DE2211 /* CommonViews */,
|
0CA148C0288903F000DE2211 /* CommonViews */,
|
||||||
0CA0545C288F7CB200850554 /* SettingsViews */,
|
0CA0545C288F7CB200850554 /* SettingsViews */,
|
||||||
0CA148D3288903F000DE2211 /* SearchResultsView.swift */,
|
0CA148D3288903F000DE2211 /* SearchResultsView.swift */,
|
||||||
|
0C57D4CB289032ED008534E8 /* SearchResultRDView.swift */,
|
||||||
0CA148D4288903F000DE2211 /* ContentView.swift */,
|
0CA148D4288903F000DE2211 /* ContentView.swift */,
|
||||||
0CA148D1288903F000DE2211 /* MainView.swift */,
|
0CA148D1288903F000DE2211 /* MainView.swift */,
|
||||||
0CA148BB288903F000DE2211 /* SettingsView.swift */,
|
0CA148BB288903F000DE2211 /* SettingsView.swift */,
|
||||||
|
|
@ -346,6 +349,7 @@
|
||||||
0CA148E6288903F000DE2211 /* WebView.swift in Sources */,
|
0CA148E6288903F000DE2211 /* WebView.swift in Sources */,
|
||||||
0CA148E2288903F000DE2211 /* Data.swift in Sources */,
|
0CA148E2288903F000DE2211 /* Data.swift in Sources */,
|
||||||
0C0D50E1288DF7700035ECC8 /* TorrentSource+CoreDataClass.swift in Sources */,
|
0C0D50E1288DF7700035ECC8 /* TorrentSource+CoreDataClass.swift in Sources */,
|
||||||
|
0C57D4CC289032ED008534E8 /* SearchResultRDView.swift in Sources */,
|
||||||
0CA05459288EE9E600850554 /* SourceManager.swift in Sources */,
|
0CA05459288EE9E600850554 /* SourceManager.swift in Sources */,
|
||||||
0CA05457288EE58200850554 /* SettingsSourceUrlView.swift in Sources */,
|
0CA05457288EE58200850554 /* SettingsSourceUrlView.swift in Sources */,
|
||||||
0CA148DE288903F000DE2211 /* RealDebridModels.swift in Sources */,
|
0CA148DE288903F000DE2211 /* RealDebridModels.swift in Sources */,
|
||||||
|
|
|
||||||
|
|
@ -27,9 +27,10 @@ class ScrapingViewModel: ObservableObject {
|
||||||
@Published var debridHashes: [String] = []
|
@Published var debridHashes: [String] = []
|
||||||
@Published var searchText: String = ""
|
@Published var searchText: String = ""
|
||||||
@Published var selectedSearchResult: SearchResult?
|
@Published var selectedSearchResult: SearchResult?
|
||||||
|
@Published var filteredSource: TorrentSource?
|
||||||
|
|
||||||
@MainActor
|
@MainActor
|
||||||
public func scanSources(sources: FetchedResults<TorrentSource>) async {
|
public func scanSources(sources: [TorrentSource]) async {
|
||||||
if sources.isEmpty {
|
if sources.isEmpty {
|
||||||
print("Sources empty")
|
print("Sources empty")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,21 +18,70 @@ struct ContentView: View {
|
||||||
sortDescriptors: []
|
sortDescriptors: []
|
||||||
) var sources: FetchedResults<TorrentSource>
|
) var sources: FetchedResults<TorrentSource>
|
||||||
|
|
||||||
|
@State private var selectedSource: TorrentSource? {
|
||||||
|
didSet {
|
||||||
|
scrapingModel.filteredSource = selectedSource
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
NavView {
|
NavView {
|
||||||
VStack {
|
VStack(spacing: 10) {
|
||||||
|
HStack {
|
||||||
|
Text("Filter")
|
||||||
|
.foregroundColor(.secondary)
|
||||||
|
|
||||||
|
Menu {
|
||||||
|
Button {
|
||||||
|
selectedSource = nil
|
||||||
|
} label: {
|
||||||
|
Text("None")
|
||||||
|
|
||||||
|
if (selectedSource == nil) {
|
||||||
|
Image(systemName: "checkmark")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ForEach(sources, id: \.self) { source in
|
||||||
|
if let name = source.name, source.enabled {
|
||||||
|
Button {
|
||||||
|
selectedSource = source
|
||||||
|
} label: {
|
||||||
|
Text(name)
|
||||||
|
|
||||||
|
if selectedSource == source {
|
||||||
|
Image(systemName: "checkmark")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} label: {
|
||||||
|
Text(selectedSource?.name ?? "Source")
|
||||||
|
.padding(.trailing, -3)
|
||||||
|
Image(systemName: "chevron.down")
|
||||||
|
}
|
||||||
|
.foregroundColor(.primary)
|
||||||
|
|
||||||
|
Spacer()
|
||||||
|
}
|
||||||
|
.padding(.horizontal, 20)
|
||||||
|
|
||||||
SearchResultsView()
|
SearchResultsView()
|
||||||
}
|
}
|
||||||
.searchable(text: $scrapingModel.searchText)
|
.searchable(text: $scrapingModel.searchText)
|
||||||
.onSubmit(of: .search) {
|
.onSubmit(of: .search) {
|
||||||
Task {
|
Task {
|
||||||
await scrapingModel.scanSources(sources: sources)
|
await scrapingModel.scanSources(sources: sources.compactMap { $0 })
|
||||||
await debridManager.populateDebridHashes(scrapingModel.searchResults)
|
await debridManager.populateDebridHashes(scrapingModel.searchResults)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.navigationTitle("Search")
|
.navigationTitle("Search")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func performSearch() {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ContentView_Previews: PreviewProvider {
|
struct ContentView_Previews: PreviewProvider {
|
||||||
|
|
|
||||||
49
Ferrite/Views/SearchResultRDView.swift
Normal file
49
Ferrite/Views/SearchResultRDView.swift
Normal file
|
|
@ -0,0 +1,49 @@
|
||||||
|
//
|
||||||
|
// SearchResultRDView.swift
|
||||||
|
// Ferrite
|
||||||
|
//
|
||||||
|
// Created by Brian Dashore on 7/26/22.
|
||||||
|
//
|
||||||
|
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct SearchResultRDView: View {
|
||||||
|
@EnvironmentObject var debridManager: DebridManager
|
||||||
|
|
||||||
|
@AppStorage("RealDebrid.Enabled") var realDebridEnabled = false
|
||||||
|
|
||||||
|
var result: SearchResult
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
HStack {
|
||||||
|
Text(result.source)
|
||||||
|
|
||||||
|
Spacer()
|
||||||
|
|
||||||
|
Text(result.size)
|
||||||
|
|
||||||
|
if realDebridEnabled {
|
||||||
|
Text("RD")
|
||||||
|
.fontWeight(.bold)
|
||||||
|
.padding(2)
|
||||||
|
.background {
|
||||||
|
switch debridManager.matchSearchResult(result: result) {
|
||||||
|
case .full:
|
||||||
|
Color.green
|
||||||
|
.cornerRadius(4)
|
||||||
|
.opacity(0.5)
|
||||||
|
case .partial:
|
||||||
|
Color.orange
|
||||||
|
.cornerRadius(4)
|
||||||
|
.opacity(0.5)
|
||||||
|
case .none:
|
||||||
|
Color.red
|
||||||
|
.cornerRadius(4)
|
||||||
|
.opacity(0.5)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.font(.caption)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -9,7 +9,6 @@ import SwiftUI
|
||||||
|
|
||||||
struct SearchResultsView: View {
|
struct SearchResultsView: View {
|
||||||
@Environment(\.isSearching) var isSearching
|
@Environment(\.isSearching) var isSearching
|
||||||
@Environment(\.colorScheme) var colorScheme
|
|
||||||
|
|
||||||
@EnvironmentObject var scrapingModel: ScrapingViewModel
|
@EnvironmentObject var scrapingModel: ScrapingViewModel
|
||||||
@EnvironmentObject var debridManager: DebridManager
|
@EnvironmentObject var debridManager: DebridManager
|
||||||
|
|
@ -20,69 +19,42 @@ struct SearchResultsView: View {
|
||||||
var body: some View {
|
var body: some View {
|
||||||
List {
|
List {
|
||||||
ForEach(scrapingModel.searchResults, id: \.self) { result in
|
ForEach(scrapingModel.searchResults, id: \.self) { result in
|
||||||
VStack(alignment: .leading) {
|
if result.source == scrapingModel.filteredSource?.name || scrapingModel.filteredSource == nil {
|
||||||
Button {
|
VStack(alignment: .leading) {
|
||||||
scrapingModel.selectedSearchResult = result
|
Button {
|
||||||
|
scrapingModel.selectedSearchResult = result
|
||||||
|
|
||||||
switch debridManager.matchSearchResult(result: result) {
|
switch debridManager.matchSearchResult(result: result) {
|
||||||
case .full:
|
case .full:
|
||||||
Task {
|
Task {
|
||||||
await debridManager.fetchRdDownload(searchResult: result)
|
await debridManager.fetchRdDownload(searchResult: result)
|
||||||
|
navigationModel.currentChoiceSheet = .magnet
|
||||||
|
}
|
||||||
|
case .partial:
|
||||||
|
if debridManager.setSelectedRdResult(result: result) {
|
||||||
|
navigationModel.currentChoiceSheet = .batch
|
||||||
|
}
|
||||||
|
case .none:
|
||||||
navigationModel.currentChoiceSheet = .magnet
|
navigationModel.currentChoiceSheet = .magnet
|
||||||
}
|
}
|
||||||
case .partial:
|
} label: {
|
||||||
if debridManager.setSelectedRdResult(result: result) {
|
Text(result.title)
|
||||||
navigationModel.currentChoiceSheet = .batch
|
.font(.callout)
|
||||||
|
.fixedSize(horizontal: false, vertical: true)
|
||||||
|
}
|
||||||
|
.sheet(item: $navigationModel.currentChoiceSheet) { item in
|
||||||
|
switch item {
|
||||||
|
case .magnet:
|
||||||
|
MagnetChoiceView()
|
||||||
|
case .batch:
|
||||||
|
BatchChoiceView()
|
||||||
}
|
}
|
||||||
case .none:
|
|
||||||
navigationModel.currentChoiceSheet = .magnet
|
|
||||||
}
|
}
|
||||||
} label: {
|
.tint(.primary)
|
||||||
Text(result.title)
|
.padding(.bottom, 5)
|
||||||
.font(.callout)
|
|
||||||
.fixedSize(horizontal: false, vertical: true)
|
SearchResultRDView(result: result)
|
||||||
}
|
}
|
||||||
.sheet(item: $navigationModel.currentChoiceSheet) { item in
|
|
||||||
switch item {
|
|
||||||
case .magnet:
|
|
||||||
MagnetChoiceView()
|
|
||||||
case .batch:
|
|
||||||
BatchChoiceView()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.tint(colorScheme == .light ? .black : .white)
|
|
||||||
.padding(.bottom, 5)
|
|
||||||
|
|
||||||
HStack {
|
|
||||||
Text(result.source)
|
|
||||||
|
|
||||||
Spacer()
|
|
||||||
|
|
||||||
Text(result.size)
|
|
||||||
|
|
||||||
if realDebridEnabled {
|
|
||||||
Text("RD")
|
|
||||||
.fontWeight(.bold)
|
|
||||||
.padding(2)
|
|
||||||
.background {
|
|
||||||
switch debridManager.matchSearchResult(result: result) {
|
|
||||||
case .full:
|
|
||||||
Color.green
|
|
||||||
.cornerRadius(4)
|
|
||||||
.opacity(0.5)
|
|
||||||
case .partial:
|
|
||||||
Color.orange
|
|
||||||
.cornerRadius(4)
|
|
||||||
.opacity(0.5)
|
|
||||||
case .none:
|
|
||||||
Color.red
|
|
||||||
.cornerRadius(4)
|
|
||||||
.opacity(0.5)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.font(.caption)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ struct SourceListView: View {
|
||||||
get: { source.enabled },
|
get: { source.enabled },
|
||||||
set: {
|
set: {
|
||||||
source.enabled = $0
|
source.enabled = $0
|
||||||
PersistenceController.shared.save(backgroundContext)
|
PersistenceController.shared.save()
|
||||||
})) {
|
})) {
|
||||||
Text(source.name ?? "Unknown Source")
|
Text(source.name ?? "Unknown Source")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue