mirror of
https://github.com/Ferrite-iOS/Ferrite.git
synced 2026-01-11 20:10:27 +00:00
Plugins: Fix list sync in view
Plugin entries were not syncing properly inside the plugins view. Instead of adding events to update filtered lists, make it so that these filtered lists are updated on state changes. This is the intended method of reactive programming and removes complexity from filtering logic. Signed-off-by: kingbri <bdashore3@proton.me>
This commit is contained in:
parent
f622b7af05
commit
282783c460
4 changed files with 34 additions and 35 deletions
|
|
@ -11,8 +11,4 @@ extension Notification.Name {
|
|||
static var didDeleteBookmark: Notification.Name {
|
||||
Notification.Name("Deleted bookmark")
|
||||
}
|
||||
|
||||
static var didDeletePlugin: Notification.Name {
|
||||
Notification.Name("Deleted plugin")
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -89,12 +89,16 @@ public class PluginManager: ObservableObject {
|
|||
}
|
||||
|
||||
print("Plugin fetch error: \(error)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check if underlying type is Source or Action
|
||||
func fetchFilteredPlugins<P: Plugin, PJ: PluginJson>(installedPlugins: FetchedResults<P>, searchText: String) -> [PJ] {
|
||||
let availablePlugins: [PJ] = fetchCastedPlugins(PJ.self)
|
||||
// forType required to guide generic inferences
|
||||
func fetchFilteredPlugins<P: Plugin, PJ: PluginJson>(
|
||||
forType: PJ.Type,
|
||||
installedPlugins: FetchedResults<P>,
|
||||
searchText: String
|
||||
) -> [PJ] {
|
||||
let availablePlugins: [PJ] = fetchCastedPlugins(forType)
|
||||
|
||||
return availablePlugins
|
||||
.filter { availablePlugin in
|
||||
|
|
@ -112,13 +116,19 @@ public class PluginManager: ObservableObject {
|
|||
}
|
||||
}
|
||||
|
||||
func fetchUpdatedPlugins<P: Plugin, PJ: PluginJson>(installedPlugins: FetchedResults<P>, searchText: String) -> [PJ] {
|
||||
func fetchUpdatedPlugins<P: Plugin, PJ: PluginJson>(
|
||||
forType: PJ.Type,
|
||||
installedPlugins: FetchedResults<P>,
|
||||
searchText: String
|
||||
) -> [PJ] {
|
||||
var updatedPlugins: [PJ] = []
|
||||
let availablePlugins: [PJ] = fetchCastedPlugins(PJ.self)
|
||||
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.listId == $0.listId &&
|
||||
plugin.name == $0.name &&
|
||||
plugin.author == $0.author
|
||||
}),
|
||||
availablePlugin.version > plugin.version
|
||||
{
|
||||
|
|
|
|||
|
|
@ -54,7 +54,6 @@ struct InstalledPluginButtonView<P: Plugin>: View {
|
|||
if #available(iOS 15.0, *) {
|
||||
Button(role: .destructive) {
|
||||
PersistenceController.shared.delete(installedPlugin, context: backgroundContext)
|
||||
NotificationCenter.default.post(name: .didDeletePlugin, object: nil)
|
||||
} label: {
|
||||
Text("Remove")
|
||||
Image(systemName: "trash")
|
||||
|
|
@ -62,7 +61,6 @@ struct InstalledPluginButtonView<P: Plugin>: View {
|
|||
} else {
|
||||
Button {
|
||||
PersistenceController.shared.delete(installedPlugin, context: backgroundContext)
|
||||
NotificationCenter.default.post(name: .didDeletePlugin, object: nil)
|
||||
} label: {
|
||||
Text("Remove")
|
||||
Image(systemName: "trash")
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@
|
|||
//
|
||||
// Created by Brian Dashore on 7/24/22.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
struct PluginListView<P: Plugin, PJ: PluginJson>: View {
|
||||
|
|
@ -20,14 +19,19 @@ struct PluginListView<P: Plugin, PJ: PluginJson>: View {
|
|||
@State private var isEditingSearch = false
|
||||
@State private var isSearching = false
|
||||
|
||||
@State private var filteredUpdatedPlugins: [PJ] = []
|
||||
@State private var filteredAvailablePlugins: [PJ] = []
|
||||
@State private var sourcePredicate: NSPredicate?
|
||||
|
||||
var body: some View {
|
||||
DynamicFetchRequest(predicate: sourcePredicate) { (installedPlugins: FetchedResults<P>) in
|
||||
List {
|
||||
if !filteredUpdatedPlugins.isEmpty {
|
||||
if
|
||||
let filteredUpdatedPlugins = pluginManager.fetchUpdatedPlugins(
|
||||
forType: PJ.self,
|
||||
installedPlugins: installedPlugins,
|
||||
searchText: searchText
|
||||
),
|
||||
!filteredUpdatedPlugins.isEmpty
|
||||
{
|
||||
Section(header: InlineHeader("Updates")) {
|
||||
ForEach(filteredUpdatedPlugins, id: \.self) { (updatedPlugin: PJ) in
|
||||
PluginCatalogButtonView(availablePlugin: updatedPlugin, doUpsert: true)
|
||||
|
|
@ -43,16 +47,17 @@ struct PluginListView<P: Plugin, PJ: PluginJson>: View {
|
|||
}
|
||||
}
|
||||
|
||||
if !filteredAvailablePlugins.isEmpty {
|
||||
if
|
||||
let filteredAvailablePlugins = pluginManager.fetchFilteredPlugins(
|
||||
forType: PJ.self,
|
||||
installedPlugins: installedPlugins,
|
||||
searchText: searchText
|
||||
),
|
||||
!filteredAvailablePlugins.isEmpty
|
||||
{
|
||||
Section(header: InlineHeader("Catalog")) {
|
||||
ForEach(filteredAvailablePlugins, id: \.self) { availablePlugin in
|
||||
if !installedPlugins.contains(where: {
|
||||
availablePlugin.name == $0.name &&
|
||||
availablePlugin.listId == $0.listId &&
|
||||
availablePlugin.author == $0.author
|
||||
}) {
|
||||
PluginCatalogButtonView(availablePlugin: availablePlugin, doUpsert: false)
|
||||
}
|
||||
PluginCatalogButtonView(availablePlugin: availablePlugin, doUpsert: false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -65,18 +70,8 @@ struct PluginListView<P: Plugin, PJ: PluginJson>: View {
|
|||
.environmentObject(navModel)
|
||||
}
|
||||
}
|
||||
.backport.onAppear {
|
||||
filteredAvailablePlugins = pluginManager.fetchFilteredPlugins(installedPlugins: installedPlugins, searchText: searchText)
|
||||
filteredUpdatedPlugins = pluginManager.fetchUpdatedPlugins(installedPlugins: installedPlugins, searchText: searchText)
|
||||
}
|
||||
.onChange(of: searchText) { _ in
|
||||
sourcePredicate = searchText.isEmpty ? nil : NSPredicate(format: "name CONTAINS[cd] %@", searchText)
|
||||
filteredAvailablePlugins = pluginManager.fetchFilteredPlugins(installedPlugins: installedPlugins, searchText: searchText)
|
||||
filteredUpdatedPlugins = pluginManager.fetchUpdatedPlugins(installedPlugins: installedPlugins, searchText: searchText)
|
||||
}
|
||||
.onReceive(NotificationCenter.default.publisher(for: .didDeletePlugin)) { _ in
|
||||
filteredAvailablePlugins = pluginManager.fetchFilteredPlugins(installedPlugins: installedPlugins, searchText: searchText)
|
||||
filteredUpdatedPlugins = pluginManager.fetchUpdatedPlugins(installedPlugins: installedPlugins, searchText: searchText)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue