Ferrite: Format
Signed-off-by: kingbri <bdashore3@proton.me>
This commit is contained in:
parent
8c8e9d0215
commit
438e48be66
29 changed files with 165 additions and 192 deletions
|
|
@ -6,8 +6,8 @@
|
|||
//
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import CoreData
|
||||
import Foundation
|
||||
|
||||
@objc(Action)
|
||||
public class Action: NSManagedObject, Plugin {}
|
||||
|
|
|
|||
|
|
@ -6,66 +6,61 @@
|
|||
//
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import CoreData
|
||||
import Foundation
|
||||
|
||||
|
||||
extension Action {
|
||||
|
||||
@nonobjc public class func fetchRequest() -> NSFetchRequest<Action> {
|
||||
return NSFetchRequest<Action>(entityName: "Action")
|
||||
public extension Action {
|
||||
@nonobjc class func fetchRequest() -> NSFetchRequest<Action> {
|
||||
NSFetchRequest<Action>(entityName: "Action")
|
||||
}
|
||||
|
||||
@NSManaged public var id: UUID
|
||||
@NSManaged public var listId: UUID?
|
||||
@NSManaged public var name: String
|
||||
@NSManaged public var deeplink: String?
|
||||
@NSManaged public var version: Int16
|
||||
@NSManaged public var requires: [String]
|
||||
@NSManaged public var author: String
|
||||
@NSManaged public var enabled: Bool
|
||||
@NSManaged public var tags: NSOrderedSet?
|
||||
@NSManaged var id: UUID
|
||||
@NSManaged var listId: UUID?
|
||||
@NSManaged var name: String
|
||||
@NSManaged var deeplink: String?
|
||||
@NSManaged var version: Int16
|
||||
@NSManaged var requires: [String]
|
||||
@NSManaged var author: String
|
||||
@NSManaged var enabled: Bool
|
||||
@NSManaged var tags: NSOrderedSet?
|
||||
|
||||
public func getTags() -> [PluginTagJson] {
|
||||
return requires.map { PluginTagJson(name: $0, colorHex: nil) } + tagArray.map { $0.toJson() }
|
||||
func getTags() -> [PluginTagJson] {
|
||||
requires.map { PluginTagJson(name: $0, colorHex: nil) } + tagArray.map { $0.toJson() }
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: Generated accessors for tags
|
||||
extension Action {
|
||||
|
||||
public extension Action {
|
||||
@objc(insertObject:inTagsAtIndex:)
|
||||
@NSManaged public func insertIntoTags(_ value: PluginTag, at idx: Int)
|
||||
@NSManaged func insertIntoTags(_ value: PluginTag, at idx: Int)
|
||||
|
||||
@objc(removeObjectFromTagsAtIndex:)
|
||||
@NSManaged public func removeFromTags(at idx: Int)
|
||||
@NSManaged func removeFromTags(at idx: Int)
|
||||
|
||||
@objc(insertTags:atIndexes:)
|
||||
@NSManaged public func insertIntoTags(_ values: [PluginTag], at indexes: NSIndexSet)
|
||||
@NSManaged func insertIntoTags(_ values: [PluginTag], at indexes: NSIndexSet)
|
||||
|
||||
@objc(removeTagsAtIndexes:)
|
||||
@NSManaged public func removeFromTags(at indexes: NSIndexSet)
|
||||
@NSManaged func removeFromTags(at indexes: NSIndexSet)
|
||||
|
||||
@objc(replaceObjectInTagsAtIndex:withObject:)
|
||||
@NSManaged public func replaceTags(at idx: Int, with value: PluginTag)
|
||||
@NSManaged func replaceTags(at idx: Int, with value: PluginTag)
|
||||
|
||||
@objc(replaceTagsAtIndexes:withTags:)
|
||||
@NSManaged public func replaceTags(at indexes: NSIndexSet, with values: [PluginTag])
|
||||
@NSManaged func replaceTags(at indexes: NSIndexSet, with values: [PluginTag])
|
||||
|
||||
@objc(addTagsObject:)
|
||||
@NSManaged public func addToTags(_ value: PluginTag)
|
||||
@NSManaged func addToTags(_ value: PluginTag)
|
||||
|
||||
@objc(removeTagsObject:)
|
||||
@NSManaged public func removeFromTags(_ value: PluginTag)
|
||||
@NSManaged func removeFromTags(_ value: PluginTag)
|
||||
|
||||
@objc(addTags:)
|
||||
@NSManaged public func addToTags(_ values: NSOrderedSet)
|
||||
@NSManaged func addToTags(_ values: NSOrderedSet)
|
||||
|
||||
@objc(removeTags:)
|
||||
@NSManaged public func removeFromTags(_ values: NSOrderedSet)
|
||||
|
||||
@NSManaged func removeFromTags(_ values: NSOrderedSet)
|
||||
}
|
||||
|
||||
extension Action : Identifiable {
|
||||
|
||||
}
|
||||
extension Action: Identifiable {}
|
||||
|
|
|
|||
|
|
@ -6,10 +6,8 @@
|
|||
//
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import CoreData
|
||||
import Foundation
|
||||
|
||||
@objc(PluginList)
|
||||
public class PluginList: NSManagedObject {
|
||||
|
||||
}
|
||||
public class PluginList: NSManagedObject {}
|
||||
|
|
|
|||
|
|
@ -6,23 +6,18 @@
|
|||
//
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import CoreData
|
||||
import Foundation
|
||||
|
||||
|
||||
extension PluginList {
|
||||
|
||||
@nonobjc public class func fetchRequest() -> NSFetchRequest<PluginList> {
|
||||
return NSFetchRequest<PluginList>(entityName: "PluginList")
|
||||
public extension PluginList {
|
||||
@nonobjc class func fetchRequest() -> NSFetchRequest<PluginList> {
|
||||
NSFetchRequest<PluginList>(entityName: "PluginList")
|
||||
}
|
||||
|
||||
@NSManaged public var author: String
|
||||
@NSManaged public var id: UUID
|
||||
@NSManaged public var name: String
|
||||
@NSManaged public var urlString: String
|
||||
|
||||
@NSManaged var author: String
|
||||
@NSManaged var id: UUID
|
||||
@NSManaged var name: String
|
||||
@NSManaged var urlString: String
|
||||
}
|
||||
|
||||
extension PluginList : Identifiable {
|
||||
|
||||
}
|
||||
extension PluginList: Identifiable {}
|
||||
|
|
|
|||
|
|
@ -6,9 +6,8 @@
|
|||
//
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import CoreData
|
||||
import Foundation
|
||||
|
||||
@objc(PluginTag)
|
||||
public class PluginTag: NSManagedObject {
|
||||
}
|
||||
public class PluginTag: NSManagedObject {}
|
||||
|
|
|
|||
|
|
@ -6,26 +6,22 @@
|
|||
//
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import CoreData
|
||||
import Foundation
|
||||
|
||||
|
||||
extension PluginTag {
|
||||
|
||||
@nonobjc public class func fetchRequest() -> NSFetchRequest<PluginTag> {
|
||||
return NSFetchRequest<PluginTag>(entityName: "PluginTag")
|
||||
public extension PluginTag {
|
||||
@nonobjc class func fetchRequest() -> NSFetchRequest<PluginTag> {
|
||||
NSFetchRequest<PluginTag>(entityName: "PluginTag")
|
||||
}
|
||||
|
||||
@NSManaged public var colorHex: String?
|
||||
@NSManaged public var name: String
|
||||
@NSManaged public var parentAction: Action?
|
||||
@NSManaged public var parentSource: Source?
|
||||
@NSManaged var colorHex: String?
|
||||
@NSManaged var name: String
|
||||
@NSManaged var parentAction: Action?
|
||||
@NSManaged var parentSource: Source?
|
||||
|
||||
func toJson() -> PluginTagJson {
|
||||
return PluginTagJson(name: name, colorHex: colorHex)
|
||||
internal func toJson() -> PluginTagJson {
|
||||
PluginTagJson(name: name, colorHex: colorHex)
|
||||
}
|
||||
}
|
||||
|
||||
extension PluginTag : Identifiable {
|
||||
|
||||
}
|
||||
extension PluginTag: Identifiable {}
|
||||
|
|
|
|||
|
|
@ -6,73 +6,68 @@
|
|||
//
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import CoreData
|
||||
import Foundation
|
||||
|
||||
|
||||
extension Source {
|
||||
|
||||
@nonobjc public class func fetchRequest() -> NSFetchRequest<Source> {
|
||||
return NSFetchRequest<Source>(entityName: "Source")
|
||||
public extension Source {
|
||||
@nonobjc class func fetchRequest() -> NSFetchRequest<Source> {
|
||||
NSFetchRequest<Source>(entityName: "Source")
|
||||
}
|
||||
|
||||
@NSManaged public var id: UUID
|
||||
@NSManaged public var baseUrl: String?
|
||||
@NSManaged public var fallbackUrls: [String]?
|
||||
@NSManaged public var dynamicBaseUrl: Bool
|
||||
@NSManaged public var enabled: Bool
|
||||
@NSManaged public var name: String
|
||||
@NSManaged public var author: String
|
||||
@NSManaged public var listId: UUID?
|
||||
@NSManaged public var preferredParser: Int16
|
||||
@NSManaged public var version: Int16
|
||||
@NSManaged public var htmlParser: SourceHtmlParser?
|
||||
@NSManaged public var rssParser: SourceRssParser?
|
||||
@NSManaged public var jsonParser: SourceJsonParser?
|
||||
@NSManaged public var api: SourceApi?
|
||||
@NSManaged public var trackers: [String]?
|
||||
@NSManaged public var tags: NSOrderedSet?
|
||||
@NSManaged var id: UUID
|
||||
@NSManaged var baseUrl: String?
|
||||
@NSManaged var fallbackUrls: [String]?
|
||||
@NSManaged var dynamicBaseUrl: Bool
|
||||
@NSManaged var enabled: Bool
|
||||
@NSManaged var name: String
|
||||
@NSManaged var author: String
|
||||
@NSManaged var listId: UUID?
|
||||
@NSManaged var preferredParser: Int16
|
||||
@NSManaged var version: Int16
|
||||
@NSManaged var htmlParser: SourceHtmlParser?
|
||||
@NSManaged var rssParser: SourceRssParser?
|
||||
@NSManaged var jsonParser: SourceJsonParser?
|
||||
@NSManaged var api: SourceApi?
|
||||
@NSManaged var trackers: [String]?
|
||||
@NSManaged var tags: NSOrderedSet?
|
||||
|
||||
public func getTags() -> [PluginTagJson] {
|
||||
return tagArray.map { $0.toJson() }
|
||||
func getTags() -> [PluginTagJson] {
|
||||
tagArray.map { $0.toJson() }
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: Generated accessors for tags
|
||||
extension Source {
|
||||
|
||||
public extension Source {
|
||||
@objc(insertObject:inTagsAtIndex:)
|
||||
@NSManaged public func insertIntoTags(_ value: PluginTag, at idx: Int)
|
||||
@NSManaged func insertIntoTags(_ value: PluginTag, at idx: Int)
|
||||
|
||||
@objc(removeObjectFromTagsAtIndex:)
|
||||
@NSManaged public func removeFromTags(at idx: Int)
|
||||
@NSManaged func removeFromTags(at idx: Int)
|
||||
|
||||
@objc(insertTags:atIndexes:)
|
||||
@NSManaged public func insertIntoTags(_ values: [PluginTag], at indexes: NSIndexSet)
|
||||
@NSManaged func insertIntoTags(_ values: [PluginTag], at indexes: NSIndexSet)
|
||||
|
||||
@objc(removeTagsAtIndexes:)
|
||||
@NSManaged public func removeFromTags(at indexes: NSIndexSet)
|
||||
@NSManaged func removeFromTags(at indexes: NSIndexSet)
|
||||
|
||||
@objc(replaceObjectInTagsAtIndex:withObject:)
|
||||
@NSManaged public func replaceTags(at idx: Int, with value: PluginTag)
|
||||
@NSManaged func replaceTags(at idx: Int, with value: PluginTag)
|
||||
|
||||
@objc(replaceTagsAtIndexes:withTags:)
|
||||
@NSManaged public func replaceTags(at indexes: NSIndexSet, with values: [PluginTag])
|
||||
@NSManaged func replaceTags(at indexes: NSIndexSet, with values: [PluginTag])
|
||||
|
||||
@objc(addTagsObject:)
|
||||
@NSManaged public func addToTags(_ value: PluginTag)
|
||||
@NSManaged func addToTags(_ value: PluginTag)
|
||||
|
||||
@objc(removeTagsObject:)
|
||||
@NSManaged public func removeFromTags(_ value: PluginTag)
|
||||
@NSManaged func removeFromTags(_ value: PluginTag)
|
||||
|
||||
@objc(addTags:)
|
||||
@NSManaged public func addToTags(_ values: NSOrderedSet)
|
||||
@NSManaged func addToTags(_ values: NSOrderedSet)
|
||||
|
||||
@objc(removeTags:)
|
||||
@NSManaged public func removeFromTags(_ values: NSOrderedSet)
|
||||
|
||||
@NSManaged func removeFromTags(_ values: NSOrderedSet)
|
||||
}
|
||||
|
||||
extension Source : Identifiable {
|
||||
|
||||
}
|
||||
extension Source: Identifiable {}
|
||||
|
|
|
|||
|
|
@ -37,11 +37,11 @@ extension View {
|
|||
modifier(ViewDidAppearModifier(callback: callback))
|
||||
}
|
||||
|
||||
func customScopeBar<Content: View>(_ content: Content) -> some View {
|
||||
func customScopeBar(_ content: some View) -> some View {
|
||||
modifier(CustomScopeBarModifier(hostingContent: content))
|
||||
}
|
||||
|
||||
func customScopeBar<Content: View>(_ content: @escaping () -> Content) -> some View {
|
||||
func customScopeBar(_ content: @escaping () -> some View) -> some View {
|
||||
modifier(CustomScopeBarModifier(hostingContent: content()))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
import Foundation
|
||||
|
||||
public struct ActionJson: Codable, Hashable, PluginJson {
|
||||
public struct ActionJson: Codable, Hashable, PluginJson {
|
||||
public let name: String
|
||||
public let version: Int16
|
||||
let minVersion: String?
|
||||
|
|
@ -18,11 +18,11 @@ public struct ActionJson: Codable, Hashable, PluginJson {
|
|||
public var tags: [PluginTagJson]?
|
||||
}
|
||||
|
||||
extension ActionJson {
|
||||
public extension ActionJson {
|
||||
// Fetches all tags without optional requirement
|
||||
// Avoids the need for extra tag additions in DB
|
||||
public func getTags() -> [PluginTagJson] {
|
||||
return requires.map { PluginTagJson(name: $0.rawValue, colorHex: nil) } + (tags.map { $0 } ?? [])
|
||||
func getTags() -> [PluginTagJson] {
|
||||
requires.map { PluginTagJson(name: $0.rawValue, colorHex: nil) } + (tags.map { $0 } ?? [])
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ public struct Backup: Codable {
|
|||
var pluginListUrls: [String]?
|
||||
|
||||
// MARK: Remove once v1 backups are unsupported
|
||||
|
||||
var sourceLists: [PluginListBackupJson]?
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -29,10 +29,10 @@ public struct SourceJson: Codable, Hashable, Sendable, PluginJson {
|
|||
public var tags: [PluginTagJson]?
|
||||
}
|
||||
|
||||
extension SourceJson {
|
||||
public extension SourceJson {
|
||||
// Fetches all tags without optional requirement
|
||||
public func getTags() -> [PluginTagJson] {
|
||||
return tags ?? []
|
||||
func getTags() -> [PluginTagJson] {
|
||||
tags ?? []
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ public protocol Plugin: ObservableObject, NSManagedObject {
|
|||
|
||||
extension Plugin {
|
||||
var tagArray: [PluginTag] {
|
||||
return self.tags?.array as? [PluginTag] ?? []
|
||||
tags?.array as? [PluginTag] ?? []
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -93,19 +93,18 @@ public class PluginManager: ObservableObject {
|
|||
}
|
||||
|
||||
// forType required to guide generic inferences
|
||||
func fetchFilteredPlugins<P: Plugin, PJ: PluginJson>(
|
||||
forType: PJ.Type,
|
||||
installedPlugins: FetchedResults<P>,
|
||||
searchText: String
|
||||
) -> [PJ] {
|
||||
func fetchFilteredPlugins<PJ: PluginJson>(forType: PJ.Type,
|
||||
installedPlugins: FetchedResults<some Plugin>,
|
||||
searchText: String) -> [PJ]
|
||||
{
|
||||
let availablePlugins: [PJ] = fetchCastedPlugins(forType)
|
||||
|
||||
return availablePlugins
|
||||
.filter { availablePlugin in
|
||||
let pluginExists = installedPlugins.contains(where: {
|
||||
availablePlugin.name == $0.name &&
|
||||
availablePlugin.listId == $0.listId &&
|
||||
availablePlugin.author == $0.author
|
||||
availablePlugin.listId == $0.listId &&
|
||||
availablePlugin.author == $0.author
|
||||
})
|
||||
|
||||
if searchText.isEmpty {
|
||||
|
|
@ -116,19 +115,18 @@ public class PluginManager: ObservableObject {
|
|||
}
|
||||
}
|
||||
|
||||
func fetchUpdatedPlugins<P: Plugin, PJ: PluginJson>(
|
||||
forType: PJ.Type,
|
||||
installedPlugins: FetchedResults<P>,
|
||||
searchText: String
|
||||
) -> [PJ] {
|
||||
func fetchUpdatedPlugins<PJ: PluginJson>(forType: PJ.Type,
|
||||
installedPlugins: FetchedResults<some Plugin>,
|
||||
searchText: String) -> [PJ]
|
||||
{
|
||||
var updatedPlugins: [PJ] = []
|
||||
let availablePlugins: [PJ] = fetchCastedPlugins(forType)
|
||||
|
||||
for plugin in installedPlugins {
|
||||
if let availablePlugin = availablePlugins.first(where: {
|
||||
plugin.listId == $0.listId &&
|
||||
plugin.name == $0.name &&
|
||||
plugin.author == $0.author
|
||||
plugin.name == $0.name &&
|
||||
plugin.author == $0.author
|
||||
}),
|
||||
availablePlugin.version > plugin.version
|
||||
{
|
||||
|
|
@ -257,7 +255,7 @@ public class PluginManager: ObservableObject {
|
|||
if actionJson.requires.count < 1 {
|
||||
await toastModel?.updateToastDescription("Action addition error: actions must require an input. Please contact the action dev!")
|
||||
print("Action name \(actionJson.name) does not have a requires parameter")
|
||||
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -289,7 +287,7 @@ public class PluginManager: ObservableObject {
|
|||
newAction.version = actionJson.version
|
||||
newAction.author = actionJson.author ?? "Unknown"
|
||||
newAction.listId = actionJson.listId
|
||||
newAction.requires = actionJson.requires.map { $0.rawValue }
|
||||
newAction.requires = actionJson.requires.map(\.rawValue)
|
||||
newAction.enabled = true
|
||||
|
||||
if let jsonTags = actionJson.tags {
|
||||
|
|
@ -325,7 +323,7 @@ public class PluginManager: ObservableObject {
|
|||
if !dynamicBaseUrl, sourceJson.baseUrl == nil {
|
||||
await toastModel?.updateToastDescription("Not adding this source because base URL parameters are malformed. Please contact the source dev.")
|
||||
print("Not adding source \(sourceJson.name) because base URL parameters are malformed")
|
||||
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -483,7 +483,6 @@ class ScrapingViewModel: ObservableObject {
|
|||
}
|
||||
|
||||
for item in items {
|
||||
//print(item)
|
||||
// Parse magnet link or translate hash
|
||||
var magnetHash: String?
|
||||
if let magnetHashParser = rssParser.magnetHash {
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ class ToastViewModel: ObservableObject {
|
|||
@Published var showToast: Bool = false
|
||||
|
||||
@Published var indeterminateToastDescription: String? = nil
|
||||
@Published var indeterminateCancelAction: (() -> ())? = nil
|
||||
@Published var indeterminateCancelAction: (() -> Void)? = nil
|
||||
@Published var showIndeterminateToast: Bool = false
|
||||
|
||||
public func updateToastDescription(_ description: String, newToastType: ToastType? = nil) {
|
||||
|
|
@ -47,7 +47,7 @@ class ToastViewModel: ObservableObject {
|
|||
toastDescription = description
|
||||
}
|
||||
|
||||
public func updateIndeterminateToast(_ description: String, cancelAction: (() -> ())?) {
|
||||
public func updateIndeterminateToast(_ description: String, cancelAction: (() -> Void)?) {
|
||||
indeterminateToastDescription = description
|
||||
|
||||
if let cancelAction {
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@
|
|||
// Created by Brian Dashore on 9/29/22.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import Introspect
|
||||
import SwiftUI
|
||||
|
||||
public struct Backport<Content> {
|
||||
public let content: Content
|
||||
|
|
@ -21,12 +21,11 @@ extension View {
|
|||
}
|
||||
|
||||
extension Backport where Content: View {
|
||||
@ViewBuilder func alert(
|
||||
isPresented: Binding<Bool>,
|
||||
title: String,
|
||||
message: String?,
|
||||
buttons: [AlertButton] = []
|
||||
) -> some View {
|
||||
@ViewBuilder func alert(isPresented: Binding<Bool>,
|
||||
title: String,
|
||||
message: String?,
|
||||
buttons: [AlertButton] = []) -> some View
|
||||
{
|
||||
if #available(iOS 15, *) {
|
||||
content
|
||||
.alert(
|
||||
|
|
@ -69,11 +68,10 @@ extension Backport where Content: View {
|
|||
}
|
||||
}
|
||||
|
||||
@ViewBuilder func confirmationDialog(
|
||||
isPresented: Binding<Bool>,
|
||||
title: String, message: String?,
|
||||
buttons: [AlertButton]
|
||||
) -> some View {
|
||||
@ViewBuilder func confirmationDialog(isPresented: Binding<Bool>,
|
||||
title: String, message: String?,
|
||||
buttons: [AlertButton]) -> some View
|
||||
{
|
||||
if #available(iOS 15, *) {
|
||||
content
|
||||
.confirmationDialog(
|
||||
|
|
@ -125,7 +123,7 @@ extension Backport where Content: View {
|
|||
}
|
||||
}
|
||||
|
||||
@ViewBuilder func introspectSearchController(customize: @escaping (UISearchController) -> ()) -> some View {
|
||||
@ViewBuilder func introspectSearchController(customize: @escaping (UISearchController) -> Void) -> some View {
|
||||
if #available(iOS 15, *) {
|
||||
content.introspectSearchController(customize: customize)
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -11,7 +11,5 @@ struct LibraryHeaderView: View {
|
|||
@EnvironmentObject var debridManager: DebridManager
|
||||
|
||||
@Binding var selectedSegment: LibraryPickerSegment
|
||||
var body: some View {
|
||||
|
||||
}
|
||||
var body: some View {}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@
|
|||
// Created by Brian Dashore on 2/14/23.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
import Introspect
|
||||
import SwiftUI
|
||||
|
||||
struct CustomScopeBarModifier<V: View>: ViewModifier {
|
||||
let hostingContent: V
|
||||
|
|
@ -25,6 +25,7 @@ struct CustomScopeBarModifier<V: View>: ViewModifier {
|
|||
searchController.searchBar.autocapitalizationType = autocorrectSearch ? .sentences : .none
|
||||
|
||||
// MARK: One-time setup
|
||||
|
||||
guard hostingController == nil else { return }
|
||||
|
||||
searchController.hidesNavigationBarDuringPresentation = true
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ struct SearchableContent<Content: View>: View {
|
|||
lastHeight = newHeight
|
||||
}
|
||||
.transaction {
|
||||
if geom.size.height != lastHeight && searching {
|
||||
if geom.size.height != lastHeight, searching {
|
||||
$0.animation = .default.speed(2)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ struct TestHostingView: View {
|
|||
Text(textName)
|
||||
.opacity(0.6)
|
||||
.foregroundColor(.primary)
|
||||
|
||||
|
||||
Image(systemName: "chevron.down")
|
||||
.foregroundColor(.tertiaryLabel)
|
||||
}
|
||||
|
|
@ -49,7 +49,7 @@ struct TestHostingView: View {
|
|||
Text(secondTextName)
|
||||
.opacity(0.6)
|
||||
.foregroundColor(.primary)
|
||||
|
||||
|
||||
Image(systemName: "chevron.down")
|
||||
.foregroundColor(.tertiaryLabel)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ struct DebridPickerView<Content: View>: View {
|
|||
Picker("", selection: $debridManager.selectedDebridType) {
|
||||
Text("None")
|
||||
.tag(nil as DebridType?)
|
||||
|
||||
|
||||
ForEach(DebridType.allCases, id: \.self) { (debridType: DebridType) in
|
||||
if debridManager.enabledDebrids.contains(debridType) {
|
||||
Text(debridType.toString())
|
||||
|
|
|
|||
|
|
@ -26,30 +26,30 @@ struct BookmarksView: View {
|
|||
sortDescriptors: [NSSortDescriptor(keyPath: \Bookmark.orderNum, ascending: true)]
|
||||
) { (bookmarks: FetchedResults<Bookmark>) in
|
||||
List {
|
||||
if !bookmarks.isEmpty {
|
||||
ForEach(bookmarks, id: \.self) { bookmark in
|
||||
SearchResultButtonView(result: bookmark.toSearchResult(), existingBookmark: bookmark)
|
||||
}
|
||||
.onDelete { offsets in
|
||||
for index in offsets {
|
||||
if let bookmark = bookmarks[safe: index] {
|
||||
PersistenceController.shared.delete(bookmark, context: backgroundContext)
|
||||
NotificationCenter.default.post(name: .didDeleteBookmark, object: bookmark)
|
||||
}
|
||||
if !bookmarks.isEmpty {
|
||||
ForEach(bookmarks, id: \.self) { bookmark in
|
||||
SearchResultButtonView(result: bookmark.toSearchResult(), existingBookmark: bookmark)
|
||||
}
|
||||
.onDelete { offsets in
|
||||
for index in offsets {
|
||||
if let bookmark = bookmarks[safe: index] {
|
||||
PersistenceController.shared.delete(bookmark, context: backgroundContext)
|
||||
NotificationCenter.default.post(name: .didDeleteBookmark, object: bookmark)
|
||||
}
|
||||
}
|
||||
.onMove { source, destination in
|
||||
var changedBookmarks = bookmarks.map { $0 }
|
||||
|
||||
changedBookmarks.move(fromOffsets: source, toOffset: destination)
|
||||
|
||||
for reverseIndex in stride(from: changedBookmarks.count - 1, through: 0, by: -1) {
|
||||
changedBookmarks[reverseIndex].orderNum = Int16(reverseIndex)
|
||||
}
|
||||
|
||||
PersistenceController.shared.save()
|
||||
}
|
||||
}
|
||||
.onMove { source, destination in
|
||||
var changedBookmarks = bookmarks.map { $0 }
|
||||
|
||||
changedBookmarks.move(fromOffsets: source, toOffset: destination)
|
||||
|
||||
for reverseIndex in stride(from: changedBookmarks.count - 1, through: 0, by: -1) {
|
||||
changedBookmarks[reverseIndex].orderNum = Int16(reverseIndex)
|
||||
}
|
||||
|
||||
PersistenceController.shared.save()
|
||||
}
|
||||
}
|
||||
}
|
||||
.listStyle(.insetGrouped)
|
||||
.inlinedList(inset: Application.shared.osVersion.majorVersion > 14 ? 15 : -25)
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ struct SearchFilterHeaderView: View {
|
|||
}
|
||||
.id(scrapingModel.filteredSource)
|
||||
|
||||
DebridPickerView() {
|
||||
DebridPickerView {
|
||||
FilterLabelView(name: debridManager.selectedDebridType?.toString() ?? "Debrid")
|
||||
}
|
||||
.id(debridManager.selectedDebridType)
|
||||
|
|
|
|||
|
|
@ -44,12 +44,12 @@ struct ContentView: View {
|
|||
.listStyle(.insetGrouped)
|
||||
.inlinedList(inset: Application.shared.osVersion.majorVersion > 14 ? 20 : -20)
|
||||
.overlay {
|
||||
if scrapingModel.searchResults.isEmpty && isSearching && scrapingModel.runningSearchTask == nil {
|
||||
if scrapingModel.searchResults.isEmpty, isSearching, scrapingModel.runningSearchTask == nil {
|
||||
Text("No results found")
|
||||
}
|
||||
}
|
||||
.onChange(of: searchText) { newText in
|
||||
if newText.isEmpty && isSearching {
|
||||
if newText.isEmpty, isSearching {
|
||||
searchBarText = getSearchBarText()
|
||||
}
|
||||
}
|
||||
|
|
@ -124,7 +124,7 @@ struct ContentView: View {
|
|||
// Fetches random searchbar text if enabled, otherwise deinit the last case value
|
||||
func getSearchBarText() -> String {
|
||||
if usesRandomSearchText {
|
||||
let num = Int.random(in: 0..<searchBarTextArray.count - 1)
|
||||
let num = Int.random(in: 0 ..< searchBarTextArray.count - 1)
|
||||
if num == lastSearchTextIndex {
|
||||
lastSearchTextIndex = num + 1
|
||||
return searchBarTextArray[safe: num + 1] ?? "Search"
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ struct LibraryView: View {
|
|||
|
||||
switch navModel.libraryPickerSelection {
|
||||
case .bookmarks, .debridCloud:
|
||||
DebridPickerView() {
|
||||
DebridPickerView {
|
||||
Text(debridManager.selectedDebridType?.toString(abbreviated: true) ?? "Debrid")
|
||||
}
|
||||
.transaction {
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ struct MainView: View {
|
|||
isPresented: $backupManager.showRestoreAlert,
|
||||
title: "Restore backup?",
|
||||
message:
|
||||
"Merge (preferred): Will merge your current data with the backup \n\n" +
|
||||
"Merge (preferred): Will merge your current data with the backup \n\n" +
|
||||
"Overwrite: Will delete and replace all your data \n\n" +
|
||||
"If Merge causes app instability, uninstall Ferrite and use the Overwrite option.",
|
||||
buttons: [
|
||||
|
|
@ -140,7 +140,7 @@ struct MainView: View {
|
|||
isPresented: $showUpdateAlert,
|
||||
title: "Update available",
|
||||
message:
|
||||
"Ferrite \(releaseVersionString) can be downloaded. \n\n" +
|
||||
"Ferrite \(releaseVersionString) can be downloaded. \n\n" +
|
||||
"This alert can be disabled in Settings.",
|
||||
buttons: [
|
||||
.init("Download") {
|
||||
|
|
|
|||
|
|
@ -48,11 +48,11 @@ struct PluginsView: View {
|
|||
if checkedForPlugins {
|
||||
switch navModel.pluginPickerSelection {
|
||||
case .sources:
|
||||
if sources.isEmpty && pluginManager.availableSources.isEmpty {
|
||||
if sources.isEmpty, pluginManager.availableSources.isEmpty {
|
||||
EmptyInstructionView(title: "No Sources", message: "Add a plugin list in Settings")
|
||||
}
|
||||
case .actions:
|
||||
if actions.isEmpty && pluginManager.availableActions.isEmpty {
|
||||
if actions.isEmpty, pluginManager.availableActions.isEmpty {
|
||||
EmptyInstructionView(title: "No Actions", message: "Add a plugin list in Settings")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ struct SettingsView: View {
|
|||
}
|
||||
|
||||
Section(header: InlineHeader("Default actions")) {
|
||||
//if debridManager.enabledDebrids.count > 0 {
|
||||
if debridManager.enabledDebrids.count > 0 {
|
||||
NavigationLink(
|
||||
destination: DefaultActionPickerView(
|
||||
actionRequirement: .debrid,
|
||||
|
|
@ -115,7 +115,7 @@ struct SettingsView: View {
|
|||
}
|
||||
}
|
||||
)
|
||||
//}
|
||||
}
|
||||
|
||||
NavigationLink(
|
||||
destination: DefaultActionPickerView(
|
||||
|
|
|
|||
|
|
@ -116,7 +116,7 @@ struct ActionChoiceView: View {
|
|||
isPresented: $pluginManager.showBrokenDefaultActionAlert,
|
||||
title: "Action not found",
|
||||
message:
|
||||
"The default action could not be run. The action choice sheet has been opened. \n\n" +
|
||||
"The default action could not be run. The action choice sheet has been opened. \n\n" +
|
||||
"Please check your default actions in Settings"
|
||||
)
|
||||
.onDisappear {
|
||||
|
|
|
|||
Loading…
Reference in a new issue