From d60c26c9b21253be5ca9f6e9b2bc31dc6800b4e6 Mon Sep 17 00:00:00 2001 From: Nico Verbruggen Date: Sun, 25 Aug 2024 14:34:34 +0200 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20UserDefaults-backed=20storage=20for?= =?UTF-8?q?=20Favorites?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- PHP Monitor.xcodeproj/project.pbxproj | 22 ++++++++--- phpmon/Domain/App/App.swift | 3 ++ .../Valet/Proxies/ValetProxy.swift | 11 ++++++ .../Integrations/Valet/Sites/ValetSite.swift | 9 +++++ phpmon/Modules/Domain List/Favorites.swift | 38 +++++++++++++++++++ .../Domain List/UI/DomainListVC+Actions.swift | 4 +- 6 files changed, 79 insertions(+), 8 deletions(-) create mode 100644 phpmon/Modules/Domain List/Favorites.swift diff --git a/PHP Monitor.xcodeproj/project.pbxproj b/PHP Monitor.xcodeproj/project.pbxproj index 6a9eba4..3643ae3 100644 --- a/PHP Monitor.xcodeproj/project.pbxproj +++ b/PHP Monitor.xcodeproj/project.pbxproj @@ -290,6 +290,10 @@ C469E700294CF7B200A82AB2 /* FakeValetProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = C469E6FD294CF7B200A82AB2 /* FakeValetProxy.swift */; }; C469E701294CF7B200A82AB2 /* FakeValetProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = C469E6FD294CF7B200A82AB2 /* FakeValetProxy.swift */; }; C469E706294CFDF700A82AB2 /* DomainsListTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = C469E702294CFDF700A82AB2 /* DomainsListTest.swift */; }; + C46DC7A42C7B55DC00F19D17 /* Favorites.swift in Sources */ = {isa = PBXBuildFile; fileRef = C46DC7A32C7B55DC00F19D17 /* Favorites.swift */; }; + C46DC7A52C7B5BC900F19D17 /* Favorites.swift in Sources */ = {isa = PBXBuildFile; fileRef = C46DC7A32C7B55DC00F19D17 /* Favorites.swift */; }; + C46DC7A62C7B5BC900F19D17 /* Favorites.swift in Sources */ = {isa = PBXBuildFile; fileRef = C46DC7A32C7B55DC00F19D17 /* Favorites.swift */; }; + C46DC7A72C7B5BCA00F19D17 /* Favorites.swift in Sources */ = {isa = PBXBuildFile; fileRef = C46DC7A32C7B55DC00F19D17 /* Favorites.swift */; }; C46EBC4428DB95F0007ACC74 /* ShellProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = C46EBC4328DB95F0007ACC74 /* ShellProtocol.swift */; }; C46EBC4528DB95F0007ACC74 /* ShellProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = C46EBC4328DB95F0007ACC74 /* ShellProtocol.swift */; }; C46EBC4728DB9644007ACC74 /* RealShell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C46EBC4628DB9644007ACC74 /* RealShell.swift */; }; @@ -1049,6 +1053,7 @@ C464ADB1275A87CA003FCD53 /* DomainListCellProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DomainListCellProtocol.swift; sourceTree = ""; }; C469E6FD294CF7B200A82AB2 /* FakeValetProxy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FakeValetProxy.swift; sourceTree = ""; }; C469E702294CFDF700A82AB2 /* DomainsListTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DomainsListTest.swift; sourceTree = ""; }; + C46DC7A32C7B55DC00F19D17 /* Favorites.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Favorites.swift; sourceTree = ""; }; C46EBC4328DB95F0007ACC74 /* ShellProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShellProtocol.swift; sourceTree = ""; }; C46EBC4628DB9644007ACC74 /* RealShell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RealShell.swift; sourceTree = ""; }; C46EBC4928DB966A007ACC74 /* TestableShell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestableShell.swift; sourceTree = ""; }; @@ -1775,6 +1780,7 @@ isa = PBXGroup; children = ( C44DFA852A67090A00B98ED5 /* UI */, + C46DC7A32C7B55DC00F19D17 /* Favorites.swift */, ); path = "Domain List"; sourceTree = ""; @@ -2686,6 +2692,7 @@ C4BF56AB2949381100379603 /* FakeValetInteractor.swift in Sources */, C4B5635E276AB09000F12CCB /* VersionExtractor.swift in Sources */, C451AFF62969E40F0078E617 /* HelpButton.swift in Sources */, + C46DC7A42C7B55DC00F19D17 /* Favorites.swift in Sources */, 54D9E0B627E4F51E003B9AD9 /* HotKey.swift in Sources */, C4AFC4AE29C4F32F00BF4E0D /* BrewPhpFormula.swift in Sources */, C4D936C927E3EB6100BD69FE /* PhpHelper.swift in Sources */, @@ -2852,6 +2859,7 @@ C4415E8F2B0287E90035F520 /* BrewFormulaeObservable.swift in Sources */, C471E7D828F9BA8F0021E251 /* FileSystemProtocol.swift in Sources */, C471E7F328F9BAC70021E251 /* PhpHelper.swift in Sources */, + C46DC7A62C7B5BC900F19D17 /* Favorites.swift in Sources */, C471E7E728F9BAC20021E251 /* Constants.swift in Sources */, C471E81628F9BAE80021E251 /* DateExtension.swift in Sources */, C469E700294CF7B200A82AB2 /* FakeValetProxy.swift in Sources */, @@ -2999,6 +3007,7 @@ C471E8C628F9BB8F0021E251 /* PMTableView.swift in Sources */, C471E8C728F9BB8F0021E251 /* Warning.swift in Sources */, C471E8C828F9BB8F0021E251 /* WarningManager.swift in Sources */, + C46DC7A72C7B5BCA00F19D17 /* Favorites.swift in Sources */, C471E8C928F9BB8F0021E251 /* PhpDoctorWindowController.swift in Sources */, C41ADCEB2970CCC700120423 /* FSNotifier.swift in Sources */, C471E8CA28F9BB8F0021E251 /* OnboardingWindowController.swift in Sources */, @@ -3206,6 +3215,7 @@ C4F780AE25D80B37000DBC97 /* PhpExtensionTest.swift in Sources */, C456A0C72AA614BD0080144F /* PhpPreference.swift in Sources */, C42106672AFA9FF400DF3732 /* PhpVersionManagerView+Actions.swift in Sources */, + C46DC7A52C7B5BC900F19D17 /* Favorites.swift in Sources */, C4C8E819276F54D8003AC782 /* App+ConfigWatch.swift in Sources */, C4FC21B128391F8E00D368BB /* MainMenu+Actions.swift in Sources */, 54D9E0B927E4F51E003B9AD9 /* KeyCombo.swift in Sources */, @@ -3678,7 +3688,7 @@ CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 1500; + CURRENT_PROJECT_VERSION = 1505; DEAD_CODE_STRIPPING = YES; DEBUG = YES; DEVELOPMENT_TEAM = 8M54J5J787; @@ -3709,7 +3719,7 @@ CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 1500; + CURRENT_PROJECT_VERSION = 1505; DEAD_CODE_STRIPPING = YES; DEBUG = NO; DEVELOPMENT_TEAM = 8M54J5J787; @@ -3950,7 +3960,7 @@ CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 1500; + CURRENT_PROJECT_VERSION = 1505; DEAD_CODE_STRIPPING = YES; DEBUG = NO; DEVELOPMENT_TEAM = 8M54J5J787; @@ -4067,7 +4077,7 @@ CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 1500; + CURRENT_PROJECT_VERSION = 1505; DEAD_CODE_STRIPPING = YES; DEBUG = YES; DEVELOPMENT_TEAM = 8M54J5J787; @@ -4184,7 +4194,7 @@ CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 1500; + CURRENT_PROJECT_VERSION = 1505; DEAD_CODE_STRIPPING = YES; DEBUG = YES; DEVELOPMENT_TEAM = 8M54J5J787; @@ -4367,7 +4377,7 @@ CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 1500; + CURRENT_PROJECT_VERSION = 1505; DEAD_CODE_STRIPPING = YES; DEBUG = NO; DEVELOPMENT_TEAM = 8M54J5J787; diff --git a/phpmon/Domain/App/App.swift b/phpmon/Domain/App/App.swift index 8d6e522..0f65c60 100644 --- a/phpmon/Domain/App/App.swift +++ b/phpmon/Domain/App/App.swift @@ -89,6 +89,9 @@ class App { /** List of detected (installed) applications that PHP Monitor can work with. */ var detectedApplications: [Application] = [] + /** Favorites storage, which keeps track of favorited domains. */ + var favorites = Favorites.shared + /** The warning manager, responsible for keeping track of warnings. */ var warnings = WarningManager.shared diff --git a/phpmon/Domain/Integrations/Valet/Proxies/ValetProxy.swift b/phpmon/Domain/Integrations/Valet/Proxies/ValetProxy.swift index 20c1f8c..d19c449 100644 --- a/phpmon/Domain/Integrations/Valet/Proxies/ValetProxy.swift +++ b/phpmon/Domain/Integrations/Valet/Proxies/ValetProxy.swift @@ -13,7 +13,11 @@ class ValetProxy: ValetListable { var tld: String var target: String var secured: Bool = false + var favorited: Bool = false + var favoriteSignature: String { + "proxy:domain:\(domain).\(tld)|target:\(target)" + } init(domain: String, target: String, secure: Bool, tld: String) { self.domain = domain @@ -29,6 +33,8 @@ class ValetProxy: ValetListable { secure: false, tld: configuration.tld ) + + self.favorited = Favorites.shared.contains(domain: self.domain) self.determineSecured() } @@ -72,6 +78,11 @@ class ValetProxy: ValetListable { self.secured = FileSystem.fileExists("~/.config/valet/Certificates/\(self.domain).\(self.tld).key") } + func toggleFavorite() { + self.favorited.toggle() + Favorites.shared.toggle(domain: self.favoriteSignature) + } + func toggleSecure() async throws { try await ValetInteractor.shared.toggleSecure(proxy: self) } diff --git a/phpmon/Domain/Integrations/Valet/Sites/ValetSite.swift b/phpmon/Domain/Integrations/Valet/Sites/ValetSite.swift index ff3bfa6..834aceb 100644 --- a/phpmon/Domain/Integrations/Valet/Sites/ValetSite.swift +++ b/phpmon/Domain/Integrations/Valet/Sites/ValetSite.swift @@ -62,6 +62,9 @@ class ValetSite: ValetListable { } var favorited: Bool = false + var favoriteSignature: String { + "site:domain:\(name).\(tld)|path:\(absolutePath)" + } init( name: String, @@ -77,6 +80,7 @@ class ValetSite: ValetListable { self.secured = false if makeDeterminations { + self.favorited = Favorites.shared.contains(domain: favoriteSignature) determineSecured() determineIsolated() determineComposerPhpVersion() @@ -317,6 +321,11 @@ class ValetSite: ValetListable { try await ValetInteractor.shared.toggleSecure(site: self) } + func toggleFavorite() { + self.favorited.toggle() + Favorites.shared.toggle(domain: self.favoriteSignature) + } + func isolate(version: String) async throws { try await ValetInteractor.shared.isolate(site: self, version: version) } diff --git a/phpmon/Modules/Domain List/Favorites.swift b/phpmon/Modules/Domain List/Favorites.swift new file mode 100644 index 0000000..8a5bc59 --- /dev/null +++ b/phpmon/Modules/Domain List/Favorites.swift @@ -0,0 +1,38 @@ +// +// Favorites.swift +// PHP Monitor +// +// Created by Nico Verbruggen on 25/08/2024. +// Copyright © 2024 Nico Verbruggen. All rights reserved. +// + +import Foundation + +class Favorites { + static var shared: Favorites = Favorites() + + var items: [String] + + init() { + if let items = UserDefaults.standard.array(forKey: "user_favorites") as? [String] { + self.items = items + } else { + self.items = [] + } + } + + public func contains(domain: String) -> Bool { + return self.items.contains(domain) + } + + public func toggle(domain: String) { + if let index = items.firstIndex(of: domain) { + items.remove(at: index) + } else { + items.append(domain) + } + + UserDefaults.standard.setValue(items, forKey: "user_favorites") + UserDefaults.standard.synchronize() + } +} diff --git a/phpmon/Modules/Domain List/UI/DomainListVC+Actions.swift b/phpmon/Modules/Domain List/UI/DomainListVC+Actions.swift index 01acad5..3d15f65 100644 --- a/phpmon/Modules/Domain List/UI/DomainListVC+Actions.swift +++ b/phpmon/Modules/Domain List/UI/DomainListVC+Actions.swift @@ -106,10 +106,10 @@ extension DomainListVC { waitAndExecute { do { if let site = domain as? ValetSite { - site.favorited.toggle() + site.toggleFavorite() } if let proxy = domain as? ValetProxy { - proxy.favorited.toggle() + proxy.toggleFavorite() } // Reload the entire table as the sorting may be affected