Ferrite-backup/Ferrite/ViewModels/NavigationViewModel.swift
kingbri b85752c92c RealDebrid: Improve fetch and recache times
To declutter a RealDebrid user's library, check if the file and
unrestricted link exist and serve those existing links. Otherwise
perform a download like normal.

Sometimes RealDebrid deletes cached items, but still keeps them on
instant availability. Add a way to tell the user that the item
is downloading along with an option to cancel it.

Also remove unnecessary published variables from viewmodels

Signed-off-by: kingbri <bdashore3@proton.me>
2022-10-05 10:47:59 -04:00

166 lines
5.7 KiB
Swift

//
// NavigationViewModel.swift
// Ferrite
//
// Created by Brian Dashore on 7/24/22.
//
import SwiftUI
enum ViewTab {
case search
case sources
case settings
case library
}
@MainActor
class NavigationViewModel: ObservableObject {
var toastModel: ToastViewModel?
// Used between SearchResultsView and MagnetChoiceView
enum ChoiceSheetType: Identifiable {
var id: Int {
hashValue
}
case magnet
case batch
case activity
}
@Published var isEditingSearch: Bool = false
@Published var isSearching: Bool = false
@Published var selectedSearchResult: SearchResult?
@Published var hideNavigationBar = false
@Published var currentChoiceSheet: ChoiceSheetType?
var activityItems: [Any] = []
// Used to show the activity sheet in the share menu
@Published var showLocalActivitySheet = false
@Published var selectedTab: ViewTab = .search
@Published var showSearchProgress: Bool = false
// Used between SourceListView and SourceSettingsView
@Published var showSourceSettings: Bool = false
var selectedSource: Source?
@Published var showSourceListEditor: Bool = false
var selectedSourceList: SourceList?
@AppStorage("Actions.DefaultDebrid") var defaultDebridAction: DefaultDebridActionType = .none
@AppStorage("Actions.DefaultMagnet") var defaultMagnetAction: DefaultMagnetActionType = .none
public func runDebridAction(urlString: String, _ action: DefaultDebridActionType? = nil) {
let selectedAction = action ?? defaultDebridAction
switch selectedAction {
case .none:
currentChoiceSheet = .magnet
case .outplayer:
if let downloadUrl = URL(string: "outplayer://\(urlString)") {
UIApplication.shared.open(downloadUrl)
} else {
toastModel?.updateToastDescription("Could not create an Outplayer URL")
}
case .vlc:
if let downloadUrl = URL(string: "vlc://\(urlString)") {
UIApplication.shared.open(downloadUrl)
} else {
toastModel?.updateToastDescription("Could not create a VLC URL")
}
case .infuse:
if let downloadUrl = URL(string: "infuse://x-callback-url/play?url=\(urlString)") {
UIApplication.shared.open(downloadUrl)
} else {
toastModel?.updateToastDescription("Could not create a Infuse URL")
}
case .shareDownload:
if let downloadUrl = URL(string: urlString), currentChoiceSheet == nil {
activityItems = [downloadUrl]
currentChoiceSheet = .activity
} else {
toastModel?.updateToastDescription("Could not create object for sharing")
}
}
}
public func runMagnetAction(magnetString: String?, _ action: DefaultMagnetActionType? = nil) {
let selectedAction = action ?? defaultMagnetAction
guard let magnetLink = magnetString else {
toastModel?.updateToastDescription("Could not run your action because the magnet link is invalid.")
print("Magnet action error: The magnet link is invalid.")
return
}
switch selectedAction {
case .none:
currentChoiceSheet = .magnet
case .webtor:
if let url = URL(string: "https://webtor.io/#/show?magnet=\(magnetLink)") {
UIApplication.shared.open(url)
} else {
toastModel?.updateToastDescription("Could not create a WebTor URL")
}
case .shareMagnet:
if let magnetUrl = URL(string: magnetLink),
currentChoiceSheet == nil
{
activityItems = [magnetUrl]
currentChoiceSheet = .activity
} else {
toastModel?.updateToastDescription("Could not create object for sharing")
}
}
}
public func addToHistory(name: String?, source: String?, url: String?, subName: String? = nil) {
let backgroundContext = PersistenceController.shared.backgroundContext
let newHistoryEntry = HistoryEntry(context: backgroundContext)
newHistoryEntry.name = name
newHistoryEntry.source = source
newHistoryEntry.url = url
newHistoryEntry.subName = subName
let now = Date()
newHistoryEntry.timeStamp = now.timeIntervalSince1970
let dateString = DateFormatter.historyDateFormatter.string(from: now)
let historyRequest = History.fetchRequest()
historyRequest.predicate = NSPredicate(format: "dateString = %@", dateString)
if var histories = try? backgroundContext.fetch(historyRequest) {
for (i, history) in histories.enumerated() {
let existingEntries = history.entryArray.filter { $0.url == newHistoryEntry.url && $0.name == newHistoryEntry.name }
if !existingEntries.isEmpty {
for entry in existingEntries {
PersistenceController.shared.delete(entry, context: backgroundContext)
}
}
if history.entryArray.isEmpty {
PersistenceController.shared.delete(history, context: backgroundContext)
histories.remove(at: i)
}
}
newHistoryEntry.parentHistory = histories.first ?? History(context: backgroundContext)
} else {
newHistoryEntry.parentHistory = History(context: backgroundContext)
}
newHistoryEntry.parentHistory?.dateString = dateString
newHistoryEntry.parentHistory?.date = now
PersistenceController.shared.save(backgroundContext)
}
}