Backups in Ferrite archive a user's bookmarks, history, source lists, and source names. Sources are not archived due to the size of the backup increasing exponentially. These files use the .feb format to avoid JSON conflicts when opening the file in Ferrite. The backup file can be renamed to JSON for editing at any time. Add the Backport namespace to be used for ported features rather than making a file for every iOS 14 adaptation. Move history and bookmark creation to the PersistenceController rather than individual functions. Signed-off-by: kingbri <bdashore3@proton.me>
117 lines
4.2 KiB
Swift
117 lines
4.2 KiB
Swift
//
|
|
// ContentView.swift
|
|
// Ferrite
|
|
//
|
|
// Created by Brian Dashore on 7/1/22.
|
|
//
|
|
|
|
import SwiftUI
|
|
import SwiftUIX
|
|
|
|
struct ContentView: View {
|
|
@EnvironmentObject var scrapingModel: ScrapingViewModel
|
|
@EnvironmentObject var debridManager: DebridManager
|
|
@EnvironmentObject var navModel: NavigationViewModel
|
|
@EnvironmentObject var sourceManager: SourceManager
|
|
|
|
@AppStorage("RealDebrid.Enabled") var realDebridEnabled = false
|
|
|
|
@FetchRequest(
|
|
entity: Source.entity(),
|
|
sortDescriptors: []
|
|
) var sources: FetchedResults<Source>
|
|
|
|
@State private var selectedSource: Source? {
|
|
didSet {
|
|
scrapingModel.filteredSource = selectedSource
|
|
}
|
|
}
|
|
|
|
var body: some View {
|
|
NavView {
|
|
VStack(spacing: 10) {
|
|
HStack(spacing: 6) {
|
|
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: {
|
|
if selectedSource == source {
|
|
Label(name, systemImage: "checkmark")
|
|
} else {
|
|
Text(name)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} label: {
|
|
Text(selectedSource?.name ?? "Source")
|
|
.padding(.trailing, -3)
|
|
Image(systemName: "chevron.down")
|
|
}
|
|
.foregroundColor(.primary)
|
|
|
|
Spacer()
|
|
}
|
|
.padding(.vertical, 5)
|
|
.padding(.horizontal, 20)
|
|
|
|
SearchResultsView()
|
|
}
|
|
.navigationTitle("Search")
|
|
.navigationSearchBar {
|
|
SearchBar("Search",
|
|
text: $scrapingModel.searchText,
|
|
isEditing: $navModel.isEditingSearch,
|
|
onCommit: {
|
|
scrapingModel.searchResults = []
|
|
scrapingModel.runningSearchTask = Task {
|
|
navModel.isSearching = true
|
|
navModel.showSearchProgress = true
|
|
|
|
let sources = sourceManager.fetchInstalledSources()
|
|
await scrapingModel.scanSources(sources: sources)
|
|
|
|
if realDebridEnabled, !scrapingModel.searchResults.isEmpty {
|
|
debridManager.realDebridIAValues = []
|
|
|
|
await debridManager.populateDebridHashes(
|
|
scrapingModel.searchResults.compactMap(\.magnetHash)
|
|
)
|
|
}
|
|
|
|
navModel.showSearchProgress = false
|
|
}
|
|
})
|
|
.showsCancelButton(navModel.isEditingSearch || navModel.isSearching)
|
|
.onCancel {
|
|
scrapingModel.searchResults = []
|
|
scrapingModel.runningSearchTask?.cancel()
|
|
scrapingModel.runningSearchTask = nil
|
|
navModel.isSearching = false
|
|
scrapingModel.searchText = ""
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
struct ContentView_Previews: PreviewProvider {
|
|
static var previews: some View {
|
|
ContentView()
|
|
}
|
|
}
|