Ferrite: Concurrency, cleanup, and format

Use strict concurrency checking in Xcode 14 to find misuses with
Swift concurrency.

Cleanup files and rearrange them along with fixing comment headers.

Signed-off-by: kingbri <bdashore3@proton.me>
This commit is contained in:
kingbri 2022-09-16 13:07:28 -04:00
parent b85752c92c
commit a89e832d1c
41 changed files with 304 additions and 292 deletions

View file

@ -14,13 +14,13 @@
0C31133C28B1ABFA004DCB0D /* SourceJsonParser+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C31133A28B1ABFA004DCB0D /* SourceJsonParser+CoreDataClass.swift */; };
0C31133D28B1ABFA004DCB0D /* SourceJsonParser+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C31133B28B1ABFA004DCB0D /* SourceJsonParser+CoreDataProperties.swift */; };
0C32FB532890D19D002BD219 /* AboutView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C32FB522890D19D002BD219 /* AboutView.swift */; };
0C32FB552890D1BF002BD219 /* UIApplication.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C32FB542890D1BF002BD219 /* UIApplication.swift */; };
0C32FB572890D1F2002BD219 /* ListRowViews.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C32FB562890D1F2002BD219 /* ListRowViews.swift */; };
0C360C5C28C7DF1400884ED3 /* DynamicFetchRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C360C5B28C7DF1400884ED3 /* DynamicFetchRequest.swift */; };
0C391EC928CA63F0009F1CA1 /* DynamicActionSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C391EC828CA63F0009F1CA1 /* DynamicActionSheet.swift */; };
0C391ECB28CAA44B009F1CA1 /* AlertButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C391ECA28CAA44B009F1CA1 /* AlertButton.swift */; };
0C41BC6328C2AD0F00B47DD6 /* SearchResultButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C41BC6228C2AD0F00B47DD6 /* SearchResultButtonView.swift */; };
0C41BC6528C2AEB900B47DD6 /* SearchModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C41BC6428C2AEB900B47DD6 /* SearchModels.swift */; };
0C44E2A828D4DDDC007711AE /* Application.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C44E2A728D4DDDC007711AE /* Application.swift */; };
0C4CFC462897030D00AD9FAD /* Regex in Frameworks */ = {isa = PBXBuildFile; productRef = 0C4CFC452897030D00AD9FAD /* Regex */; };
0C4CFC4D28970C8B00AD9FAD /* SourceComplexQuery+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C4CFC4728970C8B00AD9FAD /* SourceComplexQuery+CoreDataClass.swift */; };
0C4CFC4E28970C8B00AD9FAD /* SourceComplexQuery+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C4CFC4828970C8B00AD9FAD /* SourceComplexQuery+CoreDataProperties.swift */; };
@ -41,8 +41,8 @@
0C750745289B003E004B3906 /* SourceRssParser+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C750743289B003E004B3906 /* SourceRssParser+CoreDataProperties.swift */; };
0C78041D28BFB3EA001E8CA3 /* String.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C78041C28BFB3EA001E8CA3 /* String.swift */; };
0C794B67289DACB600DD1CC8 /* SourceUpdateButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C794B66289DACB600DD1CC8 /* SourceUpdateButtonView.swift */; };
0C794B69289DACC800DD1CC8 /* InstalledSourceView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C794B68289DACC800DD1CC8 /* InstalledSourceView.swift */; };
0C794B6B289DACF100DD1CC8 /* SourceCatalogView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C794B6A289DACF100DD1CC8 /* SourceCatalogView.swift */; };
0C794B69289DACC800DD1CC8 /* InstalledSourceButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C794B68289DACC800DD1CC8 /* InstalledSourceButtonView.swift */; };
0C794B6B289DACF100DD1CC8 /* SourceCatalogButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C794B6A289DACF100DD1CC8 /* SourceCatalogButtonView.swift */; };
0C794B6D289EFA2E00DD1CC8 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0C794B6C289EFA2E00DD1CC8 /* LaunchScreen.storyboard */; };
0C79DC072899AF3C003F1C5A /* SourceSeedLeech+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C79DC052899AF3C003F1C5A /* SourceSeedLeech+CoreDataClass.swift */; };
0C79DC082899AF3C003F1C5A /* SourceSeedLeech+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C79DC062899AF3C003F1C5A /* SourceSeedLeech+CoreDataProperties.swift */; };
@ -98,7 +98,6 @@
0CD4CAC628C980EB0046E1DC /* HistoryActionsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0CD4CAC528C980EB0046E1DC /* HistoryActionsView.swift */; };
0CD5E78928CD932B001BF684 /* DisabledAppearance.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0CD5E78828CD932B001BF684 /* DisabledAppearance.swift */; };
0CDCB91828C662640098B513 /* EmptyInstructionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0CDCB91728C662640098B513 /* EmptyInstructionView.swift */; };
0CFEFCFD288A006200B3F490 /* GroupBoxStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0CFEFCFC288A006200B3F490 /* GroupBoxStyle.swift */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
@ -109,13 +108,13 @@
0C31133A28B1ABFA004DCB0D /* SourceJsonParser+CoreDataClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SourceJsonParser+CoreDataClass.swift"; sourceTree = "<group>"; };
0C31133B28B1ABFA004DCB0D /* SourceJsonParser+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SourceJsonParser+CoreDataProperties.swift"; sourceTree = "<group>"; };
0C32FB522890D19D002BD219 /* AboutView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AboutView.swift; sourceTree = "<group>"; };
0C32FB542890D1BF002BD219 /* UIApplication.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIApplication.swift; sourceTree = "<group>"; };
0C32FB562890D1F2002BD219 /* ListRowViews.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListRowViews.swift; sourceTree = "<group>"; };
0C360C5B28C7DF1400884ED3 /* DynamicFetchRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DynamicFetchRequest.swift; sourceTree = "<group>"; };
0C391EC828CA63F0009F1CA1 /* DynamicActionSheet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DynamicActionSheet.swift; sourceTree = "<group>"; };
0C391ECA28CAA44B009F1CA1 /* AlertButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlertButton.swift; sourceTree = "<group>"; };
0C41BC6228C2AD0F00B47DD6 /* SearchResultButtonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchResultButtonView.swift; sourceTree = "<group>"; };
0C41BC6428C2AEB900B47DD6 /* SearchModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SearchModels.swift; sourceTree = "<group>"; };
0C44E2A728D4DDDC007711AE /* Application.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Application.swift; sourceTree = "<group>"; };
0C4CFC4728970C8B00AD9FAD /* SourceComplexQuery+CoreDataClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SourceComplexQuery+CoreDataClass.swift"; sourceTree = "<group>"; };
0C4CFC4828970C8B00AD9FAD /* SourceComplexQuery+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SourceComplexQuery+CoreDataProperties.swift"; sourceTree = "<group>"; };
0C54D36128C5086E00BFEEE2 /* History+CoreDataClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "History+CoreDataClass.swift"; sourceTree = "<group>"; };
@ -131,8 +130,8 @@
0C750743289B003E004B3906 /* SourceRssParser+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SourceRssParser+CoreDataProperties.swift"; sourceTree = "<group>"; };
0C78041C28BFB3EA001E8CA3 /* String.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = String.swift; sourceTree = "<group>"; };
0C794B66289DACB600DD1CC8 /* SourceUpdateButtonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SourceUpdateButtonView.swift; sourceTree = "<group>"; };
0C794B68289DACC800DD1CC8 /* InstalledSourceView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InstalledSourceView.swift; sourceTree = "<group>"; };
0C794B6A289DACF100DD1CC8 /* SourceCatalogView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SourceCatalogView.swift; sourceTree = "<group>"; };
0C794B68289DACC800DD1CC8 /* InstalledSourceButtonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InstalledSourceButtonView.swift; sourceTree = "<group>"; };
0C794B6A289DACF100DD1CC8 /* SourceCatalogButtonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SourceCatalogButtonView.swift; sourceTree = "<group>"; };
0C794B6C289EFA2E00DD1CC8 /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = LaunchScreen.storyboard; sourceTree = "<group>"; };
0C79DC052899AF3C003F1C5A /* SourceSeedLeech+CoreDataClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SourceSeedLeech+CoreDataClass.swift"; sourceTree = "<group>"; };
0C79DC062899AF3C003F1C5A /* SourceSeedLeech+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SourceSeedLeech+CoreDataProperties.swift"; sourceTree = "<group>"; };
@ -188,7 +187,6 @@
0CD4CAC528C980EB0046E1DC /* HistoryActionsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HistoryActionsView.swift; sourceTree = "<group>"; };
0CD5E78828CD932B001BF684 /* DisabledAppearance.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DisabledAppearance.swift; sourceTree = "<group>"; };
0CDCB91728C662640098B513 /* EmptyInstructionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmptyInstructionView.swift; sourceTree = "<group>"; };
0CFEFCFC288A006200B3F490 /* GroupBoxStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GroupBoxStyle.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@ -237,22 +235,62 @@
0C0D50E3288DFE6E0035ECC8 /* Models */ = {
isa = PBXGroup;
children = (
0CA148C4288903F000DE2211 /* RealDebridModels.swift */,
0C0D50E4288DFE7F0035ECC8 /* SourceModels.swift */,
0C95D8D928A55BB6005E22B3 /* SettingsModels.swift */,
0C68135128BC1A7C00FAD890 /* GithubModels.swift */,
0CA148C4288903F000DE2211 /* RealDebridModels.swift */,
0C41BC6428C2AEB900B47DD6 /* SearchModels.swift */,
0C95D8D928A55BB6005E22B3 /* SettingsModels.swift */,
0C0D50E4288DFE7F0035ECC8 /* SourceModels.swift */,
);
path = Models;
sourceTree = "<group>";
};
0C44E2A628D4DDC6007711AE /* Classes */ = {
isa = PBXGroup;
children = (
0C44E2A728D4DDDC007711AE /* Application.swift */,
);
path = Classes;
sourceTree = "<group>";
};
0C44E2A928D4DFC4007711AE /* Modifiers */ = {
isa = PBXGroup;
children = (
0C70E40128C3CE9C00A5C72D /* ConditionalContextMenu.swift */,
0CB6516228C5A57300DCA721 /* ConditionalId.swift */,
0CD5E78828CD932B001BF684 /* DisabledAppearance.swift */,
0CBAB83528D12ED500AC903E /* DisableInteraction.swift */,
0C7D11FB28AA01E900ED92DB /* DynamicAccentColor.swift */,
0C391EC828CA63F0009F1CA1 /* DynamicActionSheet.swift */,
0C626A9428CADB25003C7129 /* DynamicAlert.swift */,
0CB6516428C5A5D700DCA721 /* InlinedList.swift */,
);
path = Modifiers;
sourceTree = "<group>";
};
0C44E2AA28D4E09B007711AE /* Buttons */ = {
isa = PBXGroup;
children = (
0C794B68289DACC800DD1CC8 /* InstalledSourceButtonView.swift */,
0C794B6A289DACF100DD1CC8 /* SourceCatalogButtonView.swift */,
0C794B66289DACB600DD1CC8 /* SourceUpdateButtonView.swift */,
);
path = Buttons;
sourceTree = "<group>";
};
0C44E2AB28D4E126007711AE /* SearchResultViews */ = {
isa = PBXGroup;
children = (
0C41BC6228C2AD0F00B47DD6 /* SearchResultButtonView.swift */,
0C57D4CB289032ED008534E8 /* SearchResultRDView.swift */,
);
path = SearchResultViews;
sourceTree = "<group>";
};
0C794B65289DAC9F00DD1CC8 /* SourceViews */ = {
isa = PBXGroup;
children = (
0C44E2AA28D4E09B007711AE /* Buttons */,
0C733286289C4C820058D1FE /* SourceSettingsView.swift */,
0C794B66289DACB600DD1CC8 /* SourceUpdateButtonView.swift */,
0C794B68289DACC800DD1CC8 /* InstalledSourceView.swift */,
0C794B6A289DACF100DD1CC8 /* SourceCatalogView.swift */,
);
path = SourceViews;
sourceTree = "<group>";
@ -277,6 +315,7 @@
0C0D50E3288DFE6E0035ECC8 /* Models */,
0CA148EF2889061600DE2211 /* ViewModels */,
0CA148EE2889061200DE2211 /* Views */,
0C44E2A628D4DDC6007711AE /* Classes */,
0CA148C8288903F000DE2211 /* Extensions */,
0CA148C5288903F000DE2211 /* Preview Content */,
0CA148C7288903F000DE2211 /* FerriteApp.swift */,
@ -289,22 +328,14 @@
0CA148C0288903F000DE2211 /* CommonViews */ = {
isa = PBXGroup;
children = (
0CA148C1288903F000DE2211 /* NavView.swift */,
0CFEFCFC288A006200B3F490 /* GroupBoxStyle.swift */,
0C32FB562890D1F2002BD219 /* ListRowViews.swift */,
0C7D11FB28AA01E900ED92DB /* DynamicAccentColor.swift */,
0CA3FB1F28B91D9500FA10A8 /* IndeterminateProgressView.swift */,
0CB6516228C5A57300DCA721 /* ConditionalId.swift */,
0CB6516428C5A5D700DCA721 /* InlinedList.swift */,
0CB6516928C5B4A600DCA721 /* InlineHeader.swift */,
0CDCB91728C662640098B513 /* EmptyInstructionView.swift */,
0C360C5B28C7DF1400884ED3 /* DynamicFetchRequest.swift */,
0C70E40128C3CE9C00A5C72D /* ConditionalContextMenu.swift */,
0C391EC828CA63F0009F1CA1 /* DynamicActionSheet.swift */,
0C44E2A928D4DFC4007711AE /* Modifiers */,
0C391ECA28CAA44B009F1CA1 /* AlertButton.swift */,
0C626A9428CADB25003C7129 /* DynamicAlert.swift */,
0CD5E78828CD932B001BF684 /* DisabledAppearance.swift */,
0CBAB83528D12ED500AC903E /* DisableInteraction.swift */,
0C360C5B28C7DF1400884ED3 /* DynamicFetchRequest.swift */,
0CDCB91728C662640098B513 /* EmptyInstructionView.swift */,
0CA148C1288903F000DE2211 /* NavView.swift */,
0CA3FB1F28B91D9500FA10A8 /* IndeterminateProgressView.swift */,
0CB6516928C5B4A600DCA721 /* InlineHeader.swift */,
0C32FB562890D1F2002BD219 /* ListRowViews.swift */,
);
path = CommonViews;
sourceTree = "<group>";
@ -322,12 +353,11 @@
children = (
0CA148C9288903F000DE2211 /* Collection.swift */,
0CA148CA288903F000DE2211 /* Data.swift */,
0CA148CB288903F000DE2211 /* Task.swift */,
0C32FB542890D1BF002BD219 /* UIApplication.swift */,
0C7D11FD28AA03FE00ED92DB /* View.swift */,
0C78041C28BFB3EA001E8CA3 /* String.swift */,
0C70E40528C40C4E00A5C72D /* NotificationCenter.swift */,
0CA429F728C5098D000D0610 /* DateFormatter.swift */,
0C70E40528C40C4E00A5C72D /* NotificationCenter.swift */,
0C78041C28BFB3EA001E8CA3 /* String.swift */,
0CA148CB288903F000DE2211 /* Task.swift */,
0C7D11FD28AA03FE00ED92DB /* View.swift */,
);
path = Extensions;
sourceTree = "<group>";
@ -339,19 +369,18 @@
0C794B65289DAC9F00DD1CC8 /* SourceViews */,
0CA148F02889062700DE2211 /* RepresentableViews */,
0CA148C0288903F000DE2211 /* CommonViews */,
0C44E2AB28D4E126007711AE /* SearchResultViews */,
0CA0545C288F7CB200850554 /* SettingsViews */,
0CA148D3288903F000DE2211 /* SearchResultsView.swift */,
0C41BC6228C2AD0F00B47DD6 /* SearchResultButtonView.swift */,
0C57D4CB289032ED008534E8 /* SearchResultRDView.swift */,
0CA148D4288903F000DE2211 /* ContentView.swift */,
0CA148D1288903F000DE2211 /* MainView.swift */,
0CA148D4288903F000DE2211 /* ContentView.swift */,
0CA148D3288903F000DE2211 /* SearchResultsView.swift */,
0CA3B23328C2658700616D3A /* LibraryView.swift */,
0C0D50E6288DFF850035ECC8 /* SourcesView.swift */,
0CA148BB288903F000DE2211 /* SettingsView.swift */,
0C32FB522890D19D002BD219 /* AboutView.swift */,
0CA148BC288903F000DE2211 /* LoginWebView.swift */,
0CBC76FC288D914F0054BE44 /* BatchChoiceView.swift */,
0CA148BD288903F000DE2211 /* MagnetChoiceView.swift */,
0C0D50E6288DFF850035ECC8 /* SourcesView.swift */,
0C32FB522890D19D002BD219 /* AboutView.swift */,
0CA3B23328C2658700616D3A /* LibraryView.swift */,
);
path = Views;
sourceTree = "<group>";
@ -379,8 +408,8 @@
0CA148F12889066000DE2211 /* API */ = {
isa = PBXGroup;
children = (
0CA148D0288903F000DE2211 /* RealDebridWrapper.swift */,
0C68134F28BC1A2D00FAD890 /* GithubWrapper.swift */,
0CA148D0288903F000DE2211 /* RealDebridWrapper.swift */,
);
path = API;
sourceTree = "<group>";
@ -528,21 +557,21 @@
0C360C5C28C7DF1400884ED3 /* DynamicFetchRequest.swift in Sources */,
0CA429F828C5098D000D0610 /* DateFormatter.swift in Sources */,
0C84F4872895BFED0074B7C9 /* SourceList+CoreDataProperties.swift in Sources */,
0C794B6B289DACF100DD1CC8 /* SourceCatalogView.swift in Sources */,
0C794B6B289DACF100DD1CC8 /* SourceCatalogButtonView.swift in Sources */,
0C54D36428C5086E00BFEEE2 /* History+CoreDataProperties.swift in Sources */,
0CA148E9288903F000DE2211 /* MainView.swift in Sources */,
0CBC76FD288D914F0054BE44 /* BatchChoiceView.swift in Sources */,
0C32FB552890D1BF002BD219 /* UIApplication.swift in Sources */,
0C7D11FE28AA03FE00ED92DB /* View.swift in Sources */,
0CA3B23728C2660700616D3A /* HistoryView.swift in Sources */,
0C70E40228C3CE9C00A5C72D /* ConditionalContextMenu.swift in Sources */,
0C0D50E7288DFF850035ECC8 /* SourcesView.swift in Sources */,
0CA3B23428C2658700616D3A /* LibraryView.swift in Sources */,
0C44E2A828D4DDDC007711AE /* Application.swift in Sources */,
0CA148EC288903F000DE2211 /* ContentView.swift in Sources */,
0C95D8D828A55B03005E22B3 /* DefaultActionsPickerViews.swift in Sources */,
0CA148E1288903F000DE2211 /* Collection.swift in Sources */,
0C750744289B003E004B3906 /* SourceRssParser+CoreDataClass.swift in Sources */,
0C794B69289DACC800DD1CC8 /* InstalledSourceView.swift in Sources */,
0C794B69289DACC800DD1CC8 /* InstalledSourceButtonView.swift in Sources */,
0C79DC082899AF3C003F1C5A /* SourceSeedLeech+CoreDataProperties.swift in Sources */,
0CD4CAC628C980EB0046E1DC /* HistoryActionsView.swift in Sources */,
0CA148DD288903F000DE2211 /* ScrapingViewModel.swift in Sources */,
@ -556,7 +585,6 @@
0C626A9528CADB25003C7129 /* DynamicAlert.swift in Sources */,
0CA148E7288903F000DE2211 /* ToastViewModel.swift in Sources */,
0C68135228BC1A7C00FAD890 /* GithubModels.swift in Sources */,
0CFEFCFD288A006200B3F490 /* GroupBoxStyle.swift in Sources */,
0C391EC928CA63F0009F1CA1 /* DynamicActionSheet.swift in Sources */,
0CA3B23928C2660D00616D3A /* BookmarksView.swift in Sources */,
0C79DC072899AF3C003F1C5A /* SourceSeedLeech+CoreDataClass.swift in Sources */,

View file

@ -255,7 +255,8 @@ public class RealDebrid {
hash: hash,
expiryTimeStamp: Date().timeIntervalSince1970 + 300,
files: files,
batches: batches)
batches: batches
)
)
} else {
availableHashes.append(

View file

@ -1,14 +1,17 @@
//
// UIApplication.swift
// Application.swift
// Ferrite
//
// Created by Brian Dashore on 7/26/22.
// Created by Brian Dashore on 9/16/22.
//
// A thread-safe UIApplication alternative for specifying app properties
//
import SwiftUI
import Foundation
public class Application {
static let shared = Application()
// Extensions to get the version/build number for AboutView
extension UIApplication {
var appVersion: String {
Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as? String ?? "0.0.0"
}

View file

@ -6,27 +6,22 @@
//
//
import Foundation
import CoreData
import Foundation
extension Bookmark {
@nonobjc public class func fetchRequest() -> NSFetchRequest<Bookmark> {
return NSFetchRequest<Bookmark>(entityName: "Bookmark")
public extension Bookmark {
@nonobjc class func fetchRequest() -> NSFetchRequest<Bookmark> {
NSFetchRequest<Bookmark>(entityName: "Bookmark")
}
@NSManaged public var leechers: String?
@NSManaged public var magnetHash: String?
@NSManaged public var magnetLink: String?
@NSManaged public var seeders: String?
@NSManaged public var size: String?
@NSManaged public var source: String
@NSManaged public var title: String?
@NSManaged public var orderNum: Int16
@NSManaged var leechers: String?
@NSManaged var magnetHash: String?
@NSManaged var magnetLink: String?
@NSManaged var seeders: String?
@NSManaged var size: String?
@NSManaged var source: String
@NSManaged var title: String?
@NSManaged var orderNum: Int16
}
extension Bookmark : Identifiable {
}
extension Bookmark: Identifiable {}

View file

@ -6,10 +6,8 @@
//
//
import Foundation
import CoreData
import Foundation
@objc(History)
public class History: NSManagedObject {
}
public class History: NSManagedObject {}

View file

@ -6,21 +6,19 @@
//
//
import Foundation
import CoreData
import Foundation
extension History {
@nonobjc public class func fetchRequest() -> NSFetchRequest<History> {
return NSFetchRequest<History>(entityName: "History")
public extension History {
@nonobjc class func fetchRequest() -> NSFetchRequest<History> {
NSFetchRequest<History>(entityName: "History")
}
@NSManaged public var date: Date?
@NSManaged public var dateString: String?
@NSManaged public var entries: NSSet?
var entryArray: [HistoryEntry] {
@NSManaged var date: Date?
@NSManaged var dateString: String?
@NSManaged var entries: NSSet?
internal var entryArray: [HistoryEntry] {
let entrySet = entries as? Set<HistoryEntry> ?? []
return entrySet.sorted {
@ -30,22 +28,19 @@ extension History {
}
// MARK: Generated accessors for entries
extension History {
public extension History {
@objc(addEntriesObject:)
@NSManaged public func addToEntries(_ value: HistoryEntry)
@NSManaged func addToEntries(_ value: HistoryEntry)
@objc(removeEntriesObject:)
@NSManaged public func removeFromEntries(_ value: HistoryEntry)
@NSManaged func removeFromEntries(_ value: HistoryEntry)
@objc(addEntries:)
@NSManaged public func addToEntries(_ values: NSSet)
@NSManaged func addToEntries(_ values: NSSet)
@objc(removeEntries:)
@NSManaged public func removeFromEntries(_ values: NSSet)
@NSManaged func removeFromEntries(_ values: NSSet)
}
extension History : Identifiable {
}
extension History: Identifiable {}

View file

@ -21,7 +21,7 @@ enum HistoryDeleteError: Error {
// No iCloud until finalized sources
struct PersistenceController {
static var shared = PersistenceController()
static let shared = PersistenceController()
// Coredata storage
let container: NSPersistentContainer
@ -91,7 +91,6 @@ struct PersistenceController {
save()
}
func getHistoryPredicate(range: HistoryDeleteRange) -> NSPredicate? {
if range == .allTime {
return nil

View file

@ -9,6 +9,6 @@ import Foundation
extension Notification.Name {
static var didDeleteBookmark: Notification.Name {
return Notification.Name("Deleted bookmark")
Notification.Name("Deleted bookmark")
}
}

View file

@ -25,8 +25,10 @@ extension View {
// MARK: Modifiers
func dynamicAccentColor(_ color: Color) -> some View {
modifier(DynamicAccentColor(color: color))
func conditionalContextMenu<InternalContent: View, ID: Hashable>(id: ID,
@ViewBuilder _ internalContent: @escaping () -> InternalContent) -> some View
{
modifier(ConditionalContextMenu(internalContent, id: id))
}
func conditionalId<ID: Hashable>(_ id: ID) -> some View {
@ -37,36 +39,31 @@ extension View {
modifier(DisabledAppearance(disabled: disabled, dimmedOpacity: dimmedOpacity, animation: animation))
}
func inlinedList() -> some View {
modifier(InlinedList())
func disableInteraction(_ disabled: Bool) -> some View {
modifier(DisableInteraction(disabled: disabled))
}
func conditionalContextMenu<InternalContent: View, ID: Hashable>(
id: ID,
@ViewBuilder _ internalContent: @escaping () -> InternalContent
) -> some View {
modifier(ConditionalContextMenu(internalContent, id: id))
func dynamicAccentColor(_ color: Color) -> some View {
modifier(DynamicAccentColor(color: color))
}
func dynamicActionSheet(
isPresented: Binding<Bool>,
title: String,
message: String? = nil,
buttons: [AlertButton]) -> some View
func dynamicActionSheet(isPresented: Binding<Bool>,
title: String,
message: String? = nil,
buttons: [AlertButton]) -> some View
{
modifier(DynamicActionSheet(isPresented: isPresented, title: title, message: message, buttons: buttons))
}
func dynamicAlert(
isPresented: Binding<Bool>,
title: String,
message: String? = nil,
buttons: [AlertButton]) -> some View
func dynamicAlert(isPresented: Binding<Bool>,
title: String,
message: String? = nil,
buttons: [AlertButton]) -> some View
{
modifier(DynamicAlert(isPresented: isPresented, title: title, message: message, buttons: buttons))
}
func disableInteraction(_ disabled: Bool) -> some View {
modifier(DisableInteraction(disabled: disabled))
func inlinedList() -> some View {
modifier(InlinedList())
}
}

View file

@ -7,7 +7,7 @@
import Foundation
public struct GithubRelease: Codable, Hashable {
public struct GithubRelease: Codable, Hashable, Sendable {
let htmlUrl: String
let tagName: String

View file

@ -10,138 +10,138 @@ import Foundation
// MARK: - device code endpoint
public struct DeviceCodeResponse: Codable {
let deviceCode, userCode: String
let interval, expiresIn: Int
let verificationURL, directVerificationURL: String
public struct DeviceCodeResponse: Codable, Sendable {
let deviceCode, userCode: String
let interval, expiresIn: Int
let verificationURL, directVerificationURL: String
enum CodingKeys: String, CodingKey {
case deviceCode = "device_code"
case userCode = "user_code"
case interval
case expiresIn = "expires_in"
case verificationURL = "verification_url"
case directVerificationURL = "direct_verification_url"
}
enum CodingKeys: String, CodingKey {
case deviceCode = "device_code"
case userCode = "user_code"
case interval
case expiresIn = "expires_in"
case verificationURL = "verification_url"
case directVerificationURL = "direct_verification_url"
}
}
// MARK: - device credentials endpoint
public struct DeviceCredentialsResponse: Codable {
let clientID, clientSecret: String?
public struct DeviceCredentialsResponse: Codable, Sendable {
let clientID, clientSecret: String?
enum CodingKeys: String, CodingKey {
case clientID = "client_id"
case clientSecret = "client_secret"
}
enum CodingKeys: String, CodingKey {
case clientID = "client_id"
case clientSecret = "client_secret"
}
}
// MARK: - token endpoint
public struct TokenResponse: Codable {
let accessToken: String
let expiresIn: Int
let refreshToken, tokenType: String
public struct TokenResponse: Codable, Sendable {
let accessToken: String
let expiresIn: Int
let refreshToken, tokenType: String
enum CodingKeys: String, CodingKey {
case accessToken = "access_token"
case expiresIn = "expires_in"
case refreshToken = "refresh_token"
case tokenType = "token_type"
}
enum CodingKeys: String, CodingKey {
case accessToken = "access_token"
case expiresIn = "expires_in"
case refreshToken = "refresh_token"
case tokenType = "token_type"
}
}
// MARK: - instantAvailability endpoint
// Thanks Skitty!
public struct InstantAvailabilityResponse: Codable {
var data: InstantAvailabilityData?
public struct InstantAvailabilityResponse: Codable, Sendable {
var data: InstantAvailabilityData?
public init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
public init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
if let data = try? container.decode(InstantAvailabilityData.self) {
self.data = data
}
}
if let data = try? container.decode(InstantAvailabilityData.self) {
self.data = data
}
}
}
struct InstantAvailabilityData: Codable {
var rd: [[String: InstantAvailabilityInfo]]
struct InstantAvailabilityData: Codable, Sendable {
var rd: [[String: InstantAvailabilityInfo]]
}
struct InstantAvailabilityInfo: Codable {
var filename: String
var filesize: Int
struct InstantAvailabilityInfo: Codable, Sendable {
var filename: String
var filesize: Int
}
// MARK: - Instant Availability client side structures
public struct RealDebridIA: Codable, Hashable {
let hash: String
let expiryTimeStamp: Double
var files: [RealDebridIAFile] = []
var batches: [RealDebridIABatch] = []
public struct RealDebridIA: Codable, Hashable, Sendable {
let hash: String
let expiryTimeStamp: Double
var files: [RealDebridIAFile] = []
var batches: [RealDebridIABatch] = []
}
public struct RealDebridIABatch: Codable, Hashable {
let files: [RealDebridIABatchFile]
public struct RealDebridIABatch: Codable, Hashable, Sendable {
let files: [RealDebridIABatchFile]
}
public struct RealDebridIABatchFile: Codable, Hashable {
let id: Int
let fileName: String
public struct RealDebridIABatchFile: Codable, Hashable, Sendable {
let id: Int
let fileName: String
}
public struct RealDebridIAFile: Codable, Hashable {
let name: String
let batchIndex: Int
let batchFileIndex: Int
public struct RealDebridIAFile: Codable, Hashable, Sendable {
let name: String
let batchIndex: Int
let batchFileIndex: Int
}
public enum RealDebridIAStatus: Codable, Hashable {
case full
case partial
case none
public enum RealDebridIAStatus: Codable, Hashable, Sendable {
case full
case partial
case none
}
// MARK: - addMagnet endpoint
public struct AddMagnetResponse: Codable {
let id: String
let uri: String
public struct AddMagnetResponse: Codable, Sendable {
let id: String
let uri: String
}
// MARK: - torrentInfo endpoint
struct TorrentInfoResponse: Codable {
let id, filename, originalFilename, hash: String
let bytes, originalBytes: Int
let host: String
let split, progress: Int
let status, added: String
let files: [TorrentInfoFile]
let links: [String]
let ended: String?
let speed: Int?
let seeders: Int?
struct TorrentInfoResponse: Codable, Sendable {
let id, filename, originalFilename, hash: String
let bytes, originalBytes: Int
let host: String
let split, progress: Int
let status, added: String
let files: [TorrentInfoFile]
let links: [String]
let ended: String?
let speed: Int?
let seeders: Int?
enum CodingKeys: String, CodingKey {
case id, filename
case originalFilename = "original_filename"
case hash, bytes
case originalBytes = "original_bytes"
case host, split, progress, status, added, files, links, ended, speed, seeders
}
enum CodingKeys: String, CodingKey {
case id, filename
case originalFilename = "original_filename"
case hash, bytes
case originalBytes = "original_bytes"
case host, split, progress, status, added, files, links, ended, speed, seeders
}
}
struct TorrentInfoFile: Codable {
let id: Int
let path: String
let bytes, selected: Int
struct TorrentInfoFile: Codable, Sendable {
let id: Int
let path: String
let bytes, selected: Int
}
public struct UserTorrentsResponse: Codable {
public struct UserTorrentsResponse: Codable, Sendable {
let id, filename, hash: String
let bytes: Int
let host: String
@ -154,26 +154,26 @@ public struct UserTorrentsResponse: Codable {
// MARK: - unrestrictLink endpoint
struct UnrestrictLinkResponse: Codable {
let id, filename, mimeType: String
let filesize: Int
let link: String
let host: String
let hostIcon: String
let chunks, crc: Int
let download: String
let streamable: Int
struct UnrestrictLinkResponse: Codable, Sendable {
let id, filename, mimeType: String
let filesize: Int
let link: String
let host: String
let hostIcon: String
let chunks, crc: Int
let download: String
let streamable: Int
enum CodingKeys: String, CodingKey {
case id, filename, mimeType, filesize, link, host
case hostIcon = "host_icon"
case chunks, crc, download, streamable
}
enum CodingKeys: String, CodingKey {
case id, filename, mimeType, filesize, link, host
case hostIcon = "host_icon"
case chunks, crc, download, streamable
}
}
// MARK: - User downloads list
public struct UserDownloadsResponse: Codable {
public struct UserDownloadsResponse: Codable, Sendable {
let id, filename, mimeType: String
let filesize: Int
let link: String

View file

@ -7,7 +7,7 @@
import Foundation
public struct SearchResult: Hashable, Codable {
public struct SearchResult: Hashable, Codable, Sendable {
let title: String?
let source: String
let size: String?

View file

@ -7,18 +7,18 @@
import Foundation
public enum ApiCredentialResponseType: String, Codable, Hashable {
public enum ApiCredentialResponseType: String, Codable, Hashable, Sendable {
case json
case text
}
public struct SourceListJson: Codable {
public struct SourceListJson: Codable, Sendable {
let name: String
let author: String
var sources: [SourceJson]
}
public struct SourceJson: Codable, Hashable {
public struct SourceJson: Codable, Hashable, Sendable {
let name: String
let version: Int16
let minVersion: String?
@ -34,20 +34,20 @@ public struct SourceJson: Codable, Hashable {
let htmlParser: SourceHtmlParserJson?
}
public enum SourcePreferredParser: Int16, CaseIterable {
public enum SourcePreferredParser: Int16, CaseIterable, Sendable {
// case none = 0
case scraping = 1
case rss = 2
case siteApi = 3
}
public struct SourceApiJson: Codable, Hashable {
public struct SourceApiJson: Codable, Hashable, Sendable {
let apiUrl: String?
let clientId: SourceApiCredentialJson?
let clientSecret: SourceApiCredentialJson?
}
public struct SourceApiCredentialJson: Codable, Hashable {
public struct SourceApiCredentialJson: Codable, Hashable, Sendable {
let query: String?
let value: String?
let dynamic: Bool?
@ -56,7 +56,7 @@ public struct SourceApiCredentialJson: Codable, Hashable {
let expiryLength: Double?
}
public struct SourceJsonParserJson: Codable, Hashable {
public struct SourceJsonParserJson: Codable, Hashable, Sendable {
let searchUrl: String
let results: String?
let subResults: String?
@ -67,7 +67,7 @@ public struct SourceJsonParserJson: Codable, Hashable {
let sl: SourceSLJson?
}
public struct SourceRssParserJson: Codable, Hashable {
public struct SourceRssParserJson: Codable, Hashable, Sendable {
let rssUrl: String?
let searchUrl: String
let items: String
@ -78,7 +78,7 @@ public struct SourceRssParserJson: Codable, Hashable {
let sl: SourceSLJson?
}
public struct SourceHtmlParserJson: Codable, Hashable {
public struct SourceHtmlParserJson: Codable, Hashable, Sendable {
let searchUrl: String
let rows: String
let magnet: SourceMagnetJson
@ -87,21 +87,21 @@ public struct SourceHtmlParserJson: Codable, Hashable {
let sl: SourceSLJson?
}
public struct SouceComplexQueryJson: Codable, Hashable {
public struct SouceComplexQueryJson: Codable, Hashable, Sendable {
let query: String
let discriminator: String?
let attribute: String?
let regex: String?
}
public struct SourceMagnetJson: Codable, Hashable {
public struct SourceMagnetJson: Codable, Hashable, Sendable {
let query: String
let attribute: String
let regex: String?
let externalLinkQuery: String?
}
public struct SourceSLJson: Codable, Hashable {
public struct SourceSLJson: Codable, Hashable, Sendable {
let seeders: String?
let leechers: String?
let combined: String?

View file

@ -174,7 +174,7 @@ public class DebridManager: ObservableObject {
// If the links match from a user's downloads, no need to re-run a download
if let existingTorrent = existingTorrents[safe: 0],
let torrentLink = existingTorrent.links[safe: selectedRealDebridFile?.batchFileIndex ?? 0]
let torrentLink = existingTorrent.links[safe: selectedRealDebridFile?.batchFileIndex ?? 0]
{
let existingLinks = try await realDebrid.userDownloads().filter { $0.link == torrentLink }
if let existingLink = existingLinks[safe: 0]?.download {

View file

@ -1,5 +1,5 @@
//
// SourceViewModel.swift
// SourceManager.swift
// Ferrite
//
// Created by Brian Dashore on 7/25/22.
@ -75,7 +75,7 @@ public class SourceManager: ObservableObject {
return true
}
return UIApplication.shared.appVersion >= minVersion
return Application.shared.appVersion >= minVersion
}
// Fetches sources using the background context

View file

@ -11,9 +11,9 @@ struct AboutView: View {
var body: some View {
List {
Section {
ListRowTextView(leftText: "Version", rightText: UIApplication.shared.appVersion)
ListRowTextView(leftText: "Build number", rightText: UIApplication.shared.appBuild)
ListRowTextView(leftText: "Build type", rightText: UIApplication.shared.buildType)
ListRowTextView(leftText: "Version", rightText: Application.shared.appVersion)
ListRowTextView(leftText: "Build number", rightText: Application.shared.appBuild)
ListRowTextView(leftText: "Build type", rightText: Application.shared.buildType)
ListRowLinkView(text: "Discord server", link: "https://discord.gg/sYQxnuD7Fj")
ListRowLinkView(text: "GitHub repository", link: "https://github.com/bdashore3/Ferrite")
} header: {

View file

@ -4,6 +4,8 @@
//
// Created by Brian Dashore on 9/8/22.
//
// Universal alert button for dynamic alert views
//
import SwiftUI
@ -20,7 +22,7 @@ struct AlertButton: Identifiable {
// Used for all buttons
init(_ label: String, role: Role? = nil, action: @escaping () -> Void) {
self.id = UUID()
id = UUID()
self.label = label
self.action = action
self.role = role
@ -28,19 +30,19 @@ struct AlertButton: Identifiable {
// Used for buttons with no action
init(_ label: String = "Cancel", role: Role? = nil) {
self.id = UUID()
id = UUID()
self.label = label
self.action = { }
action = {}
self.role = role
}
func toActionButton() -> Alert.Button {
if let role = role {
switch role {
case .cancel:
return .cancel(Text(label))
case .destructive:
return .destructive(Text(label), action: action)
case .cancel:
return .cancel(Text(label))
case .destructive:
return .destructive(Text(label), action: action)
}
} else {
return .default(Text(label), action: action)

View file

@ -4,6 +4,9 @@
//
// Created by Brian Dashore on 9/6/22.
//
// Used for FetchRequests with a dynamic predicate
// iOS 14 compatible view
//
import CoreData
import SwiftUI

View file

@ -1,20 +0,0 @@
//
// GroupBoxStyle.swift
// Ferrite
//
// Created by Brian Dashore on 7/21/22.
//
import SwiftUI
struct ErrorGroupBoxStyle: GroupBoxStyle {
func makeBody(configuration: Configuration) -> some View {
VStack {
configuration.label
configuration.content
}
.padding(10)
.background(Color(UIColor.secondarySystemGroupedBackground))
.clipShape(RoundedRectangle(cornerRadius: 8, style: .continuous))
}
}

View file

@ -4,11 +4,11 @@
//
// Created by Brian Dashore on 7/26/22.
//
// List row button, text, and link boilerplate
//
import SwiftUI
// These views were imported from Asobi
// View alias for a list row with an external link
struct ListRowLinkView: View {
let text: String
let link: String

View file

@ -4,7 +4,7 @@
//
// Created by Brian Dashore on 9/4/22.
//
// Only applies an ID for below iOS 16
// Applies an ID below iOS 16
// This is due to ID workarounds making iOS 16 apps crash
//

View file

@ -4,7 +4,7 @@
//
// Created by Brian Dashore on 9/13/22.
//
// Disables interaction without applying the appearance
// Disables interaction on any view without applying the appearance
//
import SwiftUI

View file

@ -4,6 +4,8 @@
//
// Created by Brian Dashore on 9/10/22.
//
// Adds opacity transitions to the disabled modifier
//
import SwiftUI

View file

@ -1,9 +1,11 @@
//
// dynamicAccentColor.swift
// DynamicAccentColor.swift
// Ferrite
//
// Created by Brian Dashore on 8/15/22.
//
// Wrapper that switches between tint and accentColor
//
import SwiftUI

View file

@ -4,6 +4,8 @@
//
// Created by Brian Dashore on 9/8/22.
//
// Switches between confirmationDialog and actionSheet
//
import SwiftUI
@ -36,7 +38,7 @@ struct DynamicActionSheet: ViewModifier {
ActionSheet(
title: Text(title),
message: message.map { Text($0) } ?? nil,
buttons: [buttons.map { $0.toActionButton() }, [.cancel()]].flatMap{ $0 }
buttons: [buttons.map { $0.toActionButton() }, [.cancel()]].flatMap { $0 }
)
}
}

View file

@ -4,6 +4,8 @@
//
// Created by Brian Dashore on 9/8/22.
//
// Switches between iOS 15 and 14 alert initalizers
//
import SwiftUI

View file

@ -4,8 +4,8 @@
//
// Created by Brian Dashore on 9/4/22.
//
// Removes the top padding on lists for iOS 16
// Use UITableView.appearance().contentInset.top = -20 for iOS 15 and below in the App file
// Removes the top padding on unsectioned lists
// If a list is sectioned, see InlineHeader
//
import Introspect

View file

@ -3,6 +3,9 @@
// Ferrite
//
// Created by Brian Dashore on 7/4/22.
// Contributed by Mantton
//
// A wrapper that switches between NavigationStack and the legacy NavigationView
//
import SwiftUI

View file

@ -1,5 +1,5 @@
//
// Library.swift
// LibraryView.swift
// Ferrite
//
// Created by Brian Dashore on 9/2/22.

View file

@ -37,7 +37,7 @@ struct BookmarksView: View {
}
}
}
.onMove { (source, destination) in
.onMove { source, destination in
var changedBookmarks = bookmarks.map { $0 }
changedBookmarks.move(fromOffsets: source, toOffset: destination)
@ -56,7 +56,7 @@ struct BookmarksView: View {
.onAppear {
if realDebridEnabled {
viewTask = Task {
let hashes = bookmarks.compactMap { $0.magnetHash }
let hashes = bookmarks.compactMap(\.magnetHash)
await debridManager.populateDebridHashes(hashes)
}
}

View file

@ -21,7 +21,7 @@ struct HistoryButtonView: View {
Task {
debridManager.realDebridDownloadUrl = url
navModel.runDebridAction(urlString: url)
if navModel.currentChoiceSheet != .magnet {
debridManager.realDebridDownloadUrl = ""
}
@ -37,19 +37,19 @@ struct HistoryButtonView: View {
VStack(alignment: .leading, spacing: 3) {
Text(entry.name ?? "Unknown title")
.font(entry.subName == nil ? .body : .subheadline)
if let subName = entry.subName {
Text(subName)
.foregroundColor(.gray)
.font(.subheadline)
}
}
HStack {
Text(entry.source ?? "Unknown source")
Spacer()
Text("DEBRID")
.fontWeight(.bold)
.padding(3)

View file

@ -42,7 +42,7 @@ struct MagnetChoiceView: View {
showLinkCopyAlert.toggle()
}
.dynamicAlert(
isPresented: $showLinkCopyAlert ,
isPresented: $showLinkCopyAlert,
title: "Copied",
message: "Download link copied successfully",
buttons: [AlertButton("OK")]

View file

@ -71,7 +71,7 @@ struct MainView: View {
}
let releaseVersion = String(latestRelease.tagName.dropFirst())
if releaseVersion > UIApplication.shared.appVersion {
if releaseVersion > Application.shared.appVersion {
releaseVersionString = latestRelease.tagName
releaseUrlString = latestRelease.htmlUrl
showUpdateAlert.toggle()

View file

@ -13,7 +13,7 @@ struct WebView: UIViewRepresentable {
func makeUIView(context: Context) -> WKWebView {
let webView = WKWebView()
webView.load(URLRequest(url: url))
let _ = webView.load(URLRequest(url: url))
return webView
}

View file

@ -25,13 +25,13 @@ struct SearchResultButtonView: View {
Button {
if debridManager.currentDebridTask == nil {
navModel.selectedSearchResult = result
switch debridManager.matchSearchResult(result: result) {
case .full:
if debridManager.setSelectedRdResult(result: result) {
debridManager.currentDebridTask = Task {
await debridManager.fetchRdDownload(searchResult: result)
if !debridManager.realDebridDownloadUrl.isEmpty {
navModel.addToHistory(name: result.title, source: result.source, url: debridManager.realDebridDownloadUrl)
navModel.runDebridAction(urlString: debridManager.realDebridDownloadUrl)
@ -83,9 +83,9 @@ struct SearchResultButtonView: View {
newBookmark.magnetLink = result.magnetLink
newBookmark.seeders = result.seeders
newBookmark.leechers = result.leechers
existingBookmark = newBookmark
PersistenceController.shared.save(backgroundContext)
} label: {
Text("Bookmark")
@ -111,7 +111,7 @@ struct SearchResultButtonView: View {
}
.onAppear {
// Only run a exists request if a bookmark isn't passed to the view
if existingBookmark == nil && !runOnce {
if existingBookmark == nil, !runOnce {
let bookmarkRequest = Bookmark.fetchRequest()
bookmarkRequest.predicate = NSPredicate(
format: "title == %@ AND source == %@ AND magnetLink == %@ AND magnetHash = %@",

View file

@ -1,5 +1,5 @@
//
// InstalledSourceView.swift
// InstalledSourceButtonView.swift
// Ferrite
//
// Created by Brian Dashore on 8/5/22.
@ -7,7 +7,7 @@
import SwiftUI
struct InstalledSourceView: View {
struct InstalledSourceButtonView: View {
let backgroundContext = PersistenceController.shared.backgroundContext
@EnvironmentObject var navModel: NavigationViewModel

View file

@ -50,7 +50,7 @@ struct SourcesView: View {
if !installedSources.isEmpty {
Section(header: InlineHeader("Installed")) {
ForEach(installedSources, id: \.self) { source in
InstalledSourceView(installedSource: source)
InstalledSourceButtonView(installedSource: source)
}
}
}