From f8773cacf1aea1caad673031acdfbb19a3eeb91c Mon Sep 17 00:00:00 2001 From: Davide Date: Mon, 28 Oct 2024 20:53:35 +0100 Subject: [PATCH] Filter countries by selected category (#767) Countries are filtered through the latest servers list. If a country is chosen, the countries picker only lists the currently selected country, because there are no servers from other countries. Update the library to prefetch the available countries per category. --- .../xcshareddata/swiftpm/Package.resolved | 2 +- Passepartout/Library/Package.swift | 2 +- .../CDVPNProviderServerRepositoryV3.swift | 19 +++++++++++++------ .../Views/Provider/VPNFiltersView+Model.swift | 11 ++++++++--- 4 files changed, 23 insertions(+), 11 deletions(-) diff --git a/Passepartout.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Passepartout.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index 7d80fade..b1328c2a 100644 --- a/Passepartout.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/Passepartout.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -41,7 +41,7 @@ "kind" : "remoteSourceControl", "location" : "git@github.com:passepartoutvpn/passepartoutkit-source", "state" : { - "revision" : "db0f5258fdbd5192dd2b87dedc46494494bc7ffb" + "revision" : "31aff403169c7cebe91a07fb8d225ab844a9a9ff" } }, { diff --git a/Passepartout/Library/Package.swift b/Passepartout/Library/Package.swift index ca79dfd6..12745ed7 100644 --- a/Passepartout/Library/Package.swift +++ b/Passepartout/Library/Package.swift @@ -28,7 +28,7 @@ let package = Package( ], dependencies: [ // .package(url: "git@github.com:passepartoutvpn/passepartoutkit-source", from: "0.9.0"), - .package(url: "git@github.com:passepartoutvpn/passepartoutkit-source", revision: "db0f5258fdbd5192dd2b87dedc46494494bc7ffb"), + .package(url: "git@github.com:passepartoutvpn/passepartoutkit-source", revision: "31aff403169c7cebe91a07fb8d225ab844a9a9ff"), // .package(path: "../../../passepartoutkit-source"), .package(url: "git@github.com:passepartoutvpn/passepartoutkit-source-openvpn-openssl", from: "0.9.1"), // .package(url: "git@github.com:passepartoutvpn/passepartoutkit-source-openvpn-openssl", revision: "031863a1cd683962a7dfe68e20b91fa820a1ecce"), diff --git a/Passepartout/Library/Sources/AppDataProviders/CDVPNProviderServerRepositoryV3.swift b/Passepartout/Library/Sources/AppDataProviders/CDVPNProviderServerRepositoryV3.swift index 6e64d88d..21a3830a 100644 --- a/Passepartout/Library/Sources/AppDataProviders/CDVPNProviderServerRepositoryV3.swift +++ b/Passepartout/Library/Sources/AppDataProviders/CDVPNProviderServerRepositoryV3.swift @@ -52,11 +52,18 @@ final class CDVPNProviderServerRepositoryV3: VPNProviderServerRepository { "countryCode" ] let serversResults = try serversRequest.execute() - let categoryNames = serversResults.compactMap { - $0.object(forKey: "categoryName") as? String - } - let countryCodes = serversResults.compactMap { - $0.object(forKey: "countryCode") as? String + + var countriesByCategoryName: [String: Set] = [:] + var countryCodes: Set = [] + serversResults.forEach { + guard let categoryName = $0.object(forKey: "categoryName") as? String, + let countryCode = $0.object(forKey: "countryCode") as? String else { + return + } + var codes: Set = countriesByCategoryName[categoryName] ?? [] + codes.insert(countryCode) + countriesByCategoryName[categoryName] = codes + countryCodes.insert(countryCode) } let presetsRequest = CDVPNPresetV3.fetchRequest() @@ -67,7 +74,7 @@ final class CDVPNProviderServerRepositoryV3: VPNProviderServerRepository { let presetsResults = try presetsRequest.execute() return VPNFilterOptions( - categoryNames: Set(categoryNames), + countriesByCategoryName: countriesByCategoryName, countryCodes: Set(countryCodes), presets: Set(try presetsResults.compactMap { try mapper.preset(from: $0) diff --git a/Passepartout/Library/Sources/AppUI/Views/Provider/VPNFiltersView+Model.swift b/Passepartout/Library/Sources/AppUI/Views/Provider/VPNFiltersView+Model.swift index 9265fc05..8623f755 100644 --- a/Passepartout/Library/Sources/AppUI/Views/Provider/VPNFiltersView+Model.swift +++ b/Passepartout/Library/Sources/AppUI/Views/Provider/VPNFiltersView+Model.swift @@ -63,7 +63,7 @@ extension VPNFiltersView { func load(options: VPNFilterOptions, initialFilters: VPNFilters?) { self.options = options - setCategories(withNames: options.categoryNames) + setCategories(withNames: Set(options.countriesByCategoryName.keys)) setCountries(withCodes: options.countryCodes) setPresets(with: options.presets) @@ -74,8 +74,13 @@ extension VPNFiltersView { func update(with servers: [VPNServer]) { - // only non-empty countries - let knownCountryCodes = Set(servers.map(\.provider.countryCode)) + // only countries that have servers in this category + let knownCountryCodes: Set + if let categoryName = filters.categoryName { + knownCountryCodes = options.countriesByCategoryName[categoryName] ?? [] + } else { + knownCountryCodes = options.countryCodes + } // only presets known in filtered servers var knownPresets = options.presets