diff --git a/Delta/Database/Cheats/CheatBaseView.swift b/Delta/Database/Cheats/CheatBaseView.swift index d9d4d6f..3ff60e2 100644 --- a/Delta/Database/Cheats/CheatBaseView.swift +++ b/Delta/Database/Cheats/CheatBaseView.swift @@ -14,10 +14,17 @@ extension CheatBaseView private class ViewModel: ObservableObject { @Published - private(set) var database: CheatBase? - - @Published - private(set) var allCheats: [CheatMetadata]? + var allCheats: [CheatMetadata]? { + didSet { + guard let cheats = allCheats else { + self.cheatsByCategory = nil + return + } + + let cheatsByCategory = Dictionary(grouping: cheats, by: { $0.category }).sorted { $0.key.id < $1.key.id } + self.cheatsByCategory = cheatsByCategory + } + } @Published private(set) var cheatsByCategory: [(CheatCategory, [CheatMetadata])]? @@ -42,14 +49,9 @@ extension CheatBaseView do { - let database = try CheatBase() - self.database = database - + let database = try CheatBase() let cheats = try await database.cheats(for: game) ?? [] self.allCheats = cheats - - let cheatsByCategory = Dictionary(grouping: cheats, by: { $0.category }).sorted { $0.key.id < $1.key.id } - self.cheatsByCategory = cheatsByCategory } catch { @@ -239,6 +241,15 @@ struct CheatBaseView: View .foregroundColor(.gray) .padding() } + + init(game: Game, cheats: [CheatMetadata]? = nil) + { + self.game = game + + let viewModel = ViewModel() + viewModel.allCheats = cheats + self._viewModel = StateObject(wrappedValue: viewModel) + } } @available(iOS 14, *) diff --git a/Delta/Pause Menu/Cheats/CheatsViewController.swift b/Delta/Pause Menu/Cheats/CheatsViewController.swift index 7df1aea..f53e95e 100644 --- a/Delta/Pause Menu/Cheats/CheatsViewController.swift +++ b/Delta/Pause Menu/Cheats/CheatsViewController.swift @@ -31,6 +31,8 @@ class CheatsViewController: UITableViewController weak var delegate: CheatsViewControllerDelegate? private let dataSource = RSTFetchedResultsTableViewDataSource(fetchedResultsController: NSFetchedResultsController()) + + private var cheatBaseCheats: [CheatMetadata]? } extension CheatsViewController @@ -65,20 +67,17 @@ extension CheatsViewController if #available(iOS 14, *) { - let addCheatMenu = UIMenu(children: [ - UIAction(title: NSLocalizedString("New Cheat Code", comment: ""), image: UIImage(systemName: "square.and.pencil")) { [weak self] _ in - self?.addCheat() - }, - - UIAction(title: NSLocalizedString("Search CheatBase", comment: ""), image: UIImage(systemName: "magnifyingglass")) { [weak self] _ in - self?.searchCheatBase() - }, - ]) - - self.navigationItem.rightBarButtonItem?.target = nil - self.navigationItem.rightBarButtonItem?.action = nil - - self.navigationItem.rightBarButtonItem?.menu = addCheatMenu + self.updateAddCheatMenu() + } + } + + override func viewWillAppear(_ animated: Bool) + { + super.viewWillAppear(animated) + + if #available(iOS 14, *), self.cheatBaseCheats == nil + { + self.fetchCheatBaseCheats() } } @@ -110,6 +109,34 @@ private extension CheatsViewController self.dataSource.fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: DatabaseManager.shared.viewContext, sectionNameKeyPath: nil, cacheName: nil) } + + @available(iOS 14, *) @MainActor + func updateAddCheatMenu() + { + var searchCheatBaseTitle = NSLocalizedString("Search CheatBase", comment: "") + var attributes: UIMenuElement.Attributes = [] + + if let cheats = self.cheatBaseCheats, cheats.isEmpty + { + searchCheatBaseTitle = NSLocalizedString("No Cheats in CheatBase", comment: "") + attributes = [.disabled] + } + + let addCheatMenu = UIMenu(children: [ + UIAction(title: NSLocalizedString("New Cheat Code", comment: ""), image: UIImage(systemName: "square.and.pencil")) { [weak self] _ in + self?.addCheat() + }, + + UIAction(title: searchCheatBaseTitle, image: UIImage(systemName: "magnifyingglass"), attributes: attributes) { [weak self] _ in + self?.searchCheatBase() + }, + ]) + + self.navigationItem.rightBarButtonItem?.target = nil + self.navigationItem.rightBarButtonItem?.action = nil + + self.navigationItem.rightBarButtonItem?.menu = addCheatMenu + } } //MARK: - Managing Cheats - @@ -122,10 +149,29 @@ private extension CheatsViewController editCheatViewController.presentWithPresentingViewController(self) } + @available(iOS 14, *) + func fetchCheatBaseCheats() + { + Task { + do + { + let cheatBase = try CheatBase() + let cheats = try await cheatBase.cheats(for: self.game) ?? [] + self.cheatBaseCheats = cheats + + self.updateAddCheatMenu() + } + catch + { + print("[RSTLog] Failed to prefetch cheats from CheatBase:", error) + } + } + } + @available(iOS 14, *) func searchCheatBase() { - var rootView = CheatBaseView(game: self.game) + var rootView = CheatBaseView(game: self.game, cheats: self.cheatBaseCheats) rootView.cancellationHandler = { [weak self] in self?.presentedViewController?.dismiss(animated: true) }