Ferrite: Clean up UI changes
- Migrate the empty view to a common view which vertically centers itself to the screen's bounds - Don't initialize underlying state variables in init as this is discouraged behavior. Instead, hook the source list editor to an ID that refreshes when an existing source list URL has been set Signed-off-by: kingbri <bdashore3@proton.me>
This commit is contained in:
parent
a9d2604fb3
commit
8306ca1f9b
12 changed files with 102 additions and 77 deletions
|
|
@ -78,6 +78,7 @@
|
||||||
0CBC76FD288D914F0054BE44 /* BatchChoiceView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0CBC76FC288D914F0054BE44 /* BatchChoiceView.swift */; };
|
0CBC76FD288D914F0054BE44 /* BatchChoiceView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0CBC76FC288D914F0054BE44 /* BatchChoiceView.swift */; };
|
||||||
0CBC76FF288DAAD00054BE44 /* NavigationViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0CBC76FE288DAAD00054BE44 /* NavigationViewModel.swift */; };
|
0CBC76FF288DAAD00054BE44 /* NavigationViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0CBC76FE288DAAD00054BE44 /* NavigationViewModel.swift */; };
|
||||||
0CBC7705288DE7F40054BE44 /* PersistenceController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0CBC7704288DE7F40054BE44 /* PersistenceController.swift */; };
|
0CBC7705288DE7F40054BE44 /* PersistenceController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0CBC7704288DE7F40054BE44 /* PersistenceController.swift */; };
|
||||||
|
0CDCB91828C662640098B513 /* EmptyInstructionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0CDCB91728C662640098B513 /* EmptyInstructionView.swift */; };
|
||||||
0CFEFCFD288A006200B3F490 /* GroupBoxStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0CFEFCFC288A006200B3F490 /* GroupBoxStyle.swift */; };
|
0CFEFCFD288A006200B3F490 /* GroupBoxStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0CFEFCFC288A006200B3F490 /* GroupBoxStyle.swift */; };
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
|
|
@ -148,6 +149,7 @@
|
||||||
0CBC76FE288DAAD00054BE44 /* NavigationViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationViewModel.swift; sourceTree = "<group>"; };
|
0CBC76FE288DAAD00054BE44 /* NavigationViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationViewModel.swift; sourceTree = "<group>"; };
|
||||||
0CBC7704288DE7F40054BE44 /* PersistenceController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PersistenceController.swift; sourceTree = "<group>"; };
|
0CBC7704288DE7F40054BE44 /* PersistenceController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PersistenceController.swift; sourceTree = "<group>"; };
|
||||||
0CC6E4D428A45BA000AF2BCC /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; sourceTree = "<group>"; };
|
0CC6E4D428A45BA000AF2BCC /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist; path = Info.plist; 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>"; };
|
0CFEFCFC288A006200B3F490 /* GroupBoxStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GroupBoxStyle.swift; sourceTree = "<group>"; };
|
||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
|
|
@ -252,6 +254,7 @@
|
||||||
0CB6516228C5A57300DCA721 /* ConditionalId.swift */,
|
0CB6516228C5A57300DCA721 /* ConditionalId.swift */,
|
||||||
0CB6516428C5A5D700DCA721 /* InlinedList.swift */,
|
0CB6516428C5A5D700DCA721 /* InlinedList.swift */,
|
||||||
0CB6516928C5B4A600DCA721 /* InlineHeader.swift */,
|
0CB6516928C5B4A600DCA721 /* InlineHeader.swift */,
|
||||||
|
0CDCB91728C662640098B513 /* EmptyInstructionView.swift */,
|
||||||
);
|
);
|
||||||
path = CommonViews;
|
path = CommonViews;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
|
@ -482,6 +485,7 @@
|
||||||
0C794B67289DACB600DD1CC8 /* SourceUpdateButtonView.swift in Sources */,
|
0C794B67289DACB600DD1CC8 /* SourceUpdateButtonView.swift in Sources */,
|
||||||
0CA148E6288903F000DE2211 /* WebView.swift in Sources */,
|
0CA148E6288903F000DE2211 /* WebView.swift in Sources */,
|
||||||
0C4CFC4E28970C8B00AD9FAD /* SourceComplexQuery+CoreDataProperties.swift in Sources */,
|
0C4CFC4E28970C8B00AD9FAD /* SourceComplexQuery+CoreDataProperties.swift in Sources */,
|
||||||
|
0CDCB91828C662640098B513 /* EmptyInstructionView.swift in Sources */,
|
||||||
0CA148E2288903F000DE2211 /* Data.swift in Sources */,
|
0CA148E2288903F000DE2211 /* Data.swift in Sources */,
|
||||||
0C57D4CC289032ED008534E8 /* SearchResultRDView.swift in Sources */,
|
0C57D4CC289032ED008534E8 /* SearchResultRDView.swift in Sources */,
|
||||||
0C7D11FC28AA01E900ED92DB /* DynamicAccentColor.swift in Sources */,
|
0C7D11FC28AA01E900ED92DB /* DynamicAccentColor.swift in Sources */,
|
||||||
|
|
|
||||||
|
|
@ -5,14 +5,14 @@
|
||||||
// Created by Brian Dashore on 8/15/22.
|
// Created by Brian Dashore on 8/15/22.
|
||||||
//
|
//
|
||||||
|
|
||||||
import SwiftUI
|
|
||||||
import Introspect
|
import Introspect
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
extension View {
|
extension View {
|
||||||
// MARK: Custom introspect functions
|
// MARK: Custom introspect functions
|
||||||
|
|
||||||
func introspectCollectionView(customize: @escaping (UICollectionView) -> ()) -> some View {
|
func introspectCollectionView(customize: @escaping (UICollectionView) -> Void) -> some View {
|
||||||
return inject(UIKitIntrospectionView(
|
inject(UIKitIntrospectionView(
|
||||||
selector: { introspectionView in
|
selector: { introspectionView in
|
||||||
guard let viewHost = Introspect.findViewHost(from: introspectionView) else {
|
guard let viewHost = Introspect.findViewHost(from: introspectionView) else {
|
||||||
return nil
|
return nil
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ struct AboutView: View {
|
||||||
Image("AppImage")
|
Image("AppImage")
|
||||||
.resizable()
|
.resizable()
|
||||||
.frame(width: 100, height: 100)
|
.frame(width: 100, height: 100)
|
||||||
.clipShape(RoundedRectangle(cornerRadius: 100*0.225, style: .continuous))
|
.clipShape(RoundedRectangle(cornerRadius: 100 * 0.225, style: .continuous))
|
||||||
.padding(.top, 24)
|
.padding(.top, 24)
|
||||||
|
|
||||||
Text("Ferrite is a free and open source application developed by kingbri under the GNU-GPLv3 license.")
|
Text("Ferrite is a free and open source application developed by kingbri under the GNU-GPLv3 license.")
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,7 @@ struct BatchChoiceView: View {
|
||||||
|
|
||||||
presentationMode.wrappedValue.dismiss()
|
presentationMode.wrappedValue.dismiss()
|
||||||
}
|
}
|
||||||
|
.dynamicAccentColor(.primary)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.listStyle(.insetGrouped)
|
.listStyle(.insetGrouped)
|
||||||
|
|
|
||||||
27
Ferrite/Views/CommonViews/EmptyInstructionView.swift
Normal file
27
Ferrite/Views/CommonViews/EmptyInstructionView.swift
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
//
|
||||||
|
// EmptyInstructionView.swift
|
||||||
|
// Ferrite
|
||||||
|
//
|
||||||
|
// Created by Brian Dashore on 9/5/22.
|
||||||
|
//
|
||||||
|
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct EmptyInstructionView: View {
|
||||||
|
let title: String
|
||||||
|
let message: String
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
VStack(spacing: 5) {
|
||||||
|
Text(title)
|
||||||
|
.font(.system(size: 25, weight: .semibold))
|
||||||
|
|
||||||
|
Text(message)
|
||||||
|
.padding(.horizontal, 50)
|
||||||
|
}
|
||||||
|
.multilineTextAlignment(.center)
|
||||||
|
.foregroundColor(.secondaryLabel)
|
||||||
|
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
||||||
|
.ignoresSafeArea()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -4,6 +4,8 @@
|
||||||
//
|
//
|
||||||
// Created by Brian Dashore on 9/5/22.
|
// Created by Brian Dashore on 9/5/22.
|
||||||
//
|
//
|
||||||
|
// For iOS 15's weird defaults regarding sectioned list padding
|
||||||
|
//
|
||||||
|
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
|
|
@ -15,16 +17,13 @@ struct InlineHeader: View {
|
||||||
}
|
}
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
Group {
|
if #available(iOS 16, *) {
|
||||||
if #available(iOS 16, *) {
|
Text(title)
|
||||||
Text(title)
|
} else if #available(iOS 15, *) {
|
||||||
.padding(.vertical, 5)
|
Text(title)
|
||||||
} else {
|
.listRowInsets(EdgeInsets(top: 10, leading: 15, bottom: 0, trailing: 0))
|
||||||
Text(title)
|
} else {
|
||||||
.padding(.vertical, 10)
|
Text(title)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
.padding(.horizontal, 20)
|
|
||||||
.listRowInsets(EdgeInsets())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,8 @@
|
||||||
// Use UITableView.appearance().contentInset.top = -20 for iOS 15 and below in the App file
|
// Use UITableView.appearance().contentInset.top = -20 for iOS 15 and below in the App file
|
||||||
//
|
//
|
||||||
|
|
||||||
import SwiftUI
|
|
||||||
import Introspect
|
import Introspect
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
struct InlinedList: ViewModifier {
|
struct InlinedList: ViewModifier {
|
||||||
func body(content: Content) -> some View {
|
func body(content: Content) -> some View {
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,8 @@
|
||||||
// Created by Brian Dashore on 7/11/22.
|
// Created by Brian Dashore on 7/11/22.
|
||||||
//
|
//
|
||||||
|
|
||||||
import SwiftUI
|
|
||||||
import Introspect
|
import Introspect
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
struct SettingsView: View {
|
struct SettingsView: View {
|
||||||
@EnvironmentObject var debridManager: DebridManager
|
@EnvironmentObject var debridManager: DebridManager
|
||||||
|
|
@ -41,11 +41,11 @@ struct SettingsView: View {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Section(header: InlineHeader("Source management")) {
|
Section(header: Text("Source management")) {
|
||||||
NavigationLink("Source lists", destination: SettingsSourceListView())
|
NavigationLink("Source lists", destination: SettingsSourceListView())
|
||||||
}
|
}
|
||||||
|
|
||||||
Section(header: InlineHeader("Default actions")) {
|
Section(header: Text("Default actions")) {
|
||||||
if debridManager.realDebridEnabled {
|
if debridManager.realDebridEnabled {
|
||||||
NavigationLink(
|
NavigationLink(
|
||||||
destination: DebridActionPickerView(),
|
destination: DebridActionPickerView(),
|
||||||
|
|
@ -95,14 +95,14 @@ struct SettingsView: View {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
Section(header: InlineHeader("Updates")) {
|
Section(header: Text("Updates")) {
|
||||||
Toggle(isOn: $autoUpdateNotifs) {
|
Toggle(isOn: $autoUpdateNotifs) {
|
||||||
Text("Show update alerts")
|
Text("Show update alerts")
|
||||||
}
|
}
|
||||||
NavigationLink("Version history", destination: SettingsAppVersionView())
|
NavigationLink("Version history", destination: SettingsAppVersionView())
|
||||||
}
|
}
|
||||||
|
|
||||||
Section(header: InlineHeader("Information")) {
|
Section(header: Text("Information")) {
|
||||||
ListRowLinkView(text: "Donate", link: "https://ko-fi.com/kingbri")
|
ListRowLinkView(text: "Donate", link: "https://ko-fi.com/kingbri")
|
||||||
ListRowLinkView(text: "Report issues", link: "https://github.com/bdashore3/Ferrite/issues")
|
ListRowLinkView(text: "Report issues", link: "https://github.com/bdashore3/Ferrite/issues")
|
||||||
NavigationLink("About", destination: AboutView())
|
NavigationLink("About", destination: AboutView())
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,7 @@ struct SettingsAppVersionView: View {
|
||||||
} catch {
|
} catch {
|
||||||
toastModel.updateToastDescription("Github error: \(error)")
|
toastModel.updateToastDescription("Github error: \(error)")
|
||||||
}
|
}
|
||||||
|
|
||||||
withAnimation {
|
withAnimation {
|
||||||
loadedReleases = true
|
loadedReleases = true
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,58 +21,60 @@ struct SettingsSourceListView: View {
|
||||||
@State private var selectedSourceList: SourceList?
|
@State private var selectedSourceList: SourceList?
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
List {
|
ZStack {
|
||||||
if sourceLists.isEmpty {
|
if sourceLists.isEmpty {
|
||||||
Text("No source lists")
|
EmptyInstructionView(title: "No Lists", message: "Add a source list using the + button in the top-right")
|
||||||
} else {
|
} else {
|
||||||
ForEach(sourceLists, id: \.self) { sourceList in
|
List {
|
||||||
VStack(alignment: .leading, spacing: 5) {
|
ForEach(sourceLists, id: \.self) { sourceList in
|
||||||
Text(sourceList.name)
|
VStack(alignment: .leading, spacing: 5) {
|
||||||
|
Text(sourceList.name)
|
||||||
|
|
||||||
Text(sourceList.author)
|
Text(sourceList.author)
|
||||||
.foregroundColor(.gray)
|
.foregroundColor(.gray)
|
||||||
|
|
||||||
Text("ID: \(sourceList.id)")
|
Text("ID: \(sourceList.id)")
|
||||||
.font(.caption)
|
.font(.caption)
|
||||||
.foregroundColor(.gray)
|
.foregroundColor(.gray)
|
||||||
}
|
|
||||||
.padding(.vertical, 2)
|
|
||||||
.contextMenu {
|
|
||||||
Button {
|
|
||||||
navModel.selectedSourceList = sourceList
|
|
||||||
presentSourceSheet.toggle()
|
|
||||||
} label: {
|
|
||||||
Text("Edit")
|
|
||||||
Image(systemName: "pencil")
|
|
||||||
}
|
}
|
||||||
|
.padding(.vertical, 2)
|
||||||
if #available(iOS 15.0, *) {
|
.contextMenu {
|
||||||
Button(role: .destructive) {
|
|
||||||
PersistenceController.shared.delete(sourceList, context: backgroundContext)
|
|
||||||
} label: {
|
|
||||||
Text("Remove")
|
|
||||||
Image(systemName: "trash")
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Button {
|
Button {
|
||||||
PersistenceController.shared.delete(sourceList, context: backgroundContext)
|
navModel.selectedSourceList = sourceList
|
||||||
|
presentSourceSheet.toggle()
|
||||||
} label: {
|
} label: {
|
||||||
Text("Remove")
|
Text("Edit")
|
||||||
Image(systemName: "trash")
|
Image(systemName: "pencil")
|
||||||
|
}
|
||||||
|
|
||||||
|
if #available(iOS 15.0, *) {
|
||||||
|
Button(role: .destructive) {
|
||||||
|
PersistenceController.shared.delete(sourceList, context: backgroundContext)
|
||||||
|
} label: {
|
||||||
|
Text("Remove")
|
||||||
|
Image(systemName: "trash")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Button {
|
||||||
|
PersistenceController.shared.delete(sourceList, context: backgroundContext)
|
||||||
|
} label: {
|
||||||
|
Text("Remove")
|
||||||
|
Image(systemName: "trash")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.listStyle(.insetGrouped)
|
||||||
|
.inlinedList()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.listStyle(.insetGrouped)
|
|
||||||
.inlinedList()
|
|
||||||
.sheet(isPresented: $presentSourceSheet) {
|
.sheet(isPresented: $presentSourceSheet) {
|
||||||
if #available(iOS 16, *) {
|
if #available(iOS 16, *) {
|
||||||
SourceListEditorView(sourceUrl: navModel.selectedSourceList?.urlString ?? "")
|
SourceListEditorView()
|
||||||
.presentationDetents([.medium])
|
.presentationDetents([.medium])
|
||||||
} else {
|
} else {
|
||||||
SourceListEditorView(sourceUrl: navModel.selectedSourceList?.urlString ?? "")
|
SourceListEditorView()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.navigationTitle("Source Lists")
|
.navigationTitle("Source Lists")
|
||||||
|
|
|
||||||
|
|
@ -15,11 +15,9 @@ struct SourceListEditorView: View {
|
||||||
|
|
||||||
let backgroundContext = PersistenceController.shared.backgroundContext
|
let backgroundContext = PersistenceController.shared.backgroundContext
|
||||||
|
|
||||||
@State private var sourceUrl: String
|
@State private var sourceUrlSet = false
|
||||||
|
|
||||||
init(sourceUrl: String = "") {
|
@State private var sourceUrl: String = ""
|
||||||
_sourceUrl = State(initialValue: sourceUrl)
|
|
||||||
}
|
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
NavView {
|
NavView {
|
||||||
|
|
@ -28,9 +26,11 @@ struct SourceListEditorView: View {
|
||||||
.disableAutocorrection(true)
|
.disableAutocorrection(true)
|
||||||
.keyboardType(.URL)
|
.keyboardType(.URL)
|
||||||
.autocapitalization(.none)
|
.autocapitalization(.none)
|
||||||
|
.conditionalId(sourceUrlSet)
|
||||||
}
|
}
|
||||||
.onAppear {
|
.onAppear {
|
||||||
sourceUrl = navModel.selectedSourceList?.urlString ?? ""
|
sourceUrl = navModel.selectedSourceList?.urlString ?? ""
|
||||||
|
sourceUrlSet = true
|
||||||
}
|
}
|
||||||
.alert(isPresented: $sourceManager.showUrlErrorAlert) {
|
.alert(isPresented: $sourceManager.showUrlErrorAlert) {
|
||||||
Alert(
|
Alert(
|
||||||
|
|
|
||||||
|
|
@ -5,13 +5,11 @@
|
||||||
// Created by Brian Dashore on 7/24/22.
|
// Created by Brian Dashore on 7/24/22.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
import Introspect
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
import SwiftUIX
|
import SwiftUIX
|
||||||
import Introspect
|
|
||||||
|
|
||||||
struct SourcesView: View {
|
struct SourcesView: View {
|
||||||
@Environment(\.verticalSizeClass) var verticalSizeClass: UserInterfaceSizeClass?
|
|
||||||
|
|
||||||
@EnvironmentObject var sourceManager: SourceManager
|
@EnvironmentObject var sourceManager: SourceManager
|
||||||
@EnvironmentObject var navModel: NavigationViewModel
|
@EnvironmentObject var navModel: NavigationViewModel
|
||||||
|
|
||||||
|
|
@ -53,15 +51,8 @@ struct SourcesView: View {
|
||||||
ZStack {
|
ZStack {
|
||||||
if !checkedForSources {
|
if !checkedForSources {
|
||||||
ProgressView()
|
ProgressView()
|
||||||
} else if sources.isEmpty && sourceManager.availableSources.isEmpty {
|
} else if sources.isEmpty, sourceManager.availableSources.isEmpty {
|
||||||
VStack {
|
EmptyInstructionView(title: "No Sources", message: "Add a source list in Settings")
|
||||||
Text("No Sources")
|
|
||||||
.font(.system(size: 25, weight: .semibold))
|
|
||||||
.foregroundColor(.secondaryLabel)
|
|
||||||
Text("Add a source list in Settings")
|
|
||||||
.foregroundColor(.secondaryLabel)
|
|
||||||
}
|
|
||||||
.padding(.top, verticalSizeClass == .regular ? -50 : 0)
|
|
||||||
} else {
|
} else {
|
||||||
List {
|
List {
|
||||||
if !filteredUpdatedSources.isEmpty {
|
if !filteredUpdatedSources.isEmpty {
|
||||||
|
|
@ -80,12 +71,12 @@ struct SourcesView: View {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !filteredAvailableSources.isEmpty && sourceManager.availableSources.contains(where: { availableSource in
|
if !filteredAvailableSources.isEmpty, sourceManager.availableSources.contains(where: { availableSource in
|
||||||
!sources.contains(
|
!sources.contains(
|
||||||
where: {
|
where: {
|
||||||
availableSource.name == $0.name &&
|
availableSource.name == $0.name &&
|
||||||
availableSource.listId == $0.listId &&
|
availableSource.listId == $0.listId &&
|
||||||
availableSource.author == $0.author
|
availableSource.author == $0.author
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}) {
|
}) {
|
||||||
|
|
@ -94,8 +85,8 @@ struct SourcesView: View {
|
||||||
if !sources.contains(
|
if !sources.contains(
|
||||||
where: {
|
where: {
|
||||||
availableSource.name == $0.name &&
|
availableSource.name == $0.name &&
|
||||||
availableSource.listId == $0.listId &&
|
availableSource.listId == $0.listId &&
|
||||||
availableSource.author == $0.author
|
availableSource.author == $0.author
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
SourceCatalogButtonView(availableSource: availableSource)
|
SourceCatalogButtonView(availableSource: availableSource)
|
||||||
|
|
@ -131,7 +122,7 @@ struct SourcesView: View {
|
||||||
searchText = ""
|
searchText = ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.onChange(of: searchText) { newValue in
|
.onChange(of: searchText) { _ in
|
||||||
filteredAvailableSources = sourceManager.availableSources.filter { searchText.isEmpty ? true : $0.name.contains(searchText) }
|
filteredAvailableSources = sourceManager.availableSources.filter { searchText.isEmpty ? true : $0.name.contains(searchText) }
|
||||||
filteredUpdatedSources = updatedSources.filter { searchText.isEmpty ? true : $0.name.contains(searchText) }
|
filteredUpdatedSources = updatedSources.filter { searchText.isEmpty ? true : $0.name.contains(searchText) }
|
||||||
if #available(iOS 15.0, *) {
|
if #available(iOS 15.0, *) {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue