From 48dc31a1f164ad8ee50debca1d035f63d29f01b7 Mon Sep 17 00:00:00 2001 From: Davide Date: Wed, 23 Oct 2024 17:58:04 +0200 Subject: [PATCH] Attempt an iOS layout with DisclosureGroup Also fix missing initial filters based on selection. Fixes #746 --- .../AppUI/Views/Modules/OpenVPNView.swift | 1 + .../Provider/VPNProviderServerView.swift | 9 +-- .../iOS/VPNProviderServerView+iOS.swift | 61 +++++++++++++++++-- .../macOS/VPNProviderServerView+macOS.swift | 15 +++++ 4 files changed, 76 insertions(+), 10 deletions(-) diff --git a/Passepartout/Library/Sources/AppUI/Views/Modules/OpenVPNView.swift b/Passepartout/Library/Sources/AppUI/Views/Modules/OpenVPNView.swift index 13bf1b0f..2a6df1bd 100644 --- a/Passepartout/Library/Sources/AppUI/Views/Modules/OpenVPNView.swift +++ b/Passepartout/Library/Sources/AppUI/Views/Modules/OpenVPNView.swift @@ -130,6 +130,7 @@ private extension OpenVPNView { VPNProviderServerView( providerId: $0, configurationType: OpenVPN.Configuration.self, + selectedEntity: providerEntity.wrappedValue, onSelect: onSelectServer ) } diff --git a/Passepartout/Library/Sources/AppUI/Views/Provider/VPNProviderServerView.swift b/Passepartout/Library/Sources/AppUI/Views/Provider/VPNProviderServerView.swift index a279e0cc..a5b45554 100644 --- a/Passepartout/Library/Sources/AppUI/Views/Provider/VPNProviderServerView.swift +++ b/Passepartout/Library/Sources/AppUI/Views/Provider/VPNProviderServerView.swift @@ -39,7 +39,7 @@ struct VPNProviderServerView: View where Configuration: ProviderC let configurationType: Configuration.Type - var selectedEntity: VPNEntity? + let selectedEntity: VPNEntity? let onSelect: (_ server: VPNServer, _ preset: VPNPreset) -> Void @@ -119,9 +119,10 @@ extension VPNProviderServerView { VPNProviderServerView( apis: [API.bundled], providerId: .protonvpn, - configurationType: OpenVPN.Configuration.self - ) { _, _ in - } + configurationType: OpenVPN.Configuration.self, + selectedEntity: nil, + onSelect: { _, _ in } + ) } .withMockEnvironment() } diff --git a/Passepartout/Library/Sources/AppUI/Views/Provider/iOS/VPNProviderServerView+iOS.swift b/Passepartout/Library/Sources/AppUI/Views/Provider/iOS/VPNProviderServerView+iOS.swift index e2b462fc..6228c502 100644 --- a/Passepartout/Library/Sources/AppUI/Views/Provider/iOS/VPNProviderServerView+iOS.swift +++ b/Passepartout/Library/Sources/AppUI/Views/Provider/iOS/VPNProviderServerView+iOS.swift @@ -55,20 +55,54 @@ extension VPNProviderServerView { private extension VPNProviderServerView.Subview { var listView: some View { List { - // FIXME: #746, providers UI, iOS server rows + country flags if manager.isFiltering { ProgressView() } else { - ForEach(manager.filteredServers, id: \.id) { server in - Button("\(server.hostname ?? server.id) \(server.provider.countryCode)") { - onSelect(server) - } - } + ForEach(countryCodes, id: \.self, content: countryView) } } .themeAnimation(on: manager.isFiltering, category: .providers) } + var countryCodes: [String] { + manager + .allCountryCodes + .sorted { + $0.localizedAsRegionCode! < $1.localizedAsRegionCode! + } + } + + func countryServers(for code: String) -> [VPNServer]? { + manager + .filteredServers + .filter { + $0.provider.countryCode == code + } + .nilIfEmpty + } + + func countryView(for code: String) -> some View { + countryServers(for: code) + .map { servers in + DisclosureGroup { + ForEach(servers, id: \.serverId, content: serverView) + } label: { + HStack { + ThemeCountryFlag(code: code) + Text(code.localizedAsRegionCode!) + } + } + } + } + + func serverView(for server: VPNServer) -> some View { + Button { + onSelect(server) + } label: { + Text(server.hostname ?? server.id) + } + } + var filtersItem: some ToolbarContent { ToolbarItem { Button { @@ -93,4 +127,19 @@ private extension VPNProviderServerView.Subview { } } +// MARK: - Preview + +#Preview { + NavigationStack { + VPNProviderServerView( + apis: [API.bundled], + providerId: .tunnelbear, + configurationType: OpenVPN.Configuration.self, + selectedEntity: nil, + onSelect: { _, _ in } + ) + } + .withMockEnvironment() +} + #endif diff --git a/Passepartout/Library/Sources/AppUI/Views/Provider/macOS/VPNProviderServerView+macOS.swift b/Passepartout/Library/Sources/AppUI/Views/Provider/macOS/VPNProviderServerView+macOS.swift index c44c3785..a03aa455 100644 --- a/Passepartout/Library/Sources/AppUI/Views/Provider/macOS/VPNProviderServerView+macOS.swift +++ b/Passepartout/Library/Sources/AppUI/Views/Provider/macOS/VPNProviderServerView+macOS.swift @@ -82,4 +82,19 @@ private extension VPNProviderServerView.Subview { } } +// MARK: - Preview + +#Preview { + NavigationStack { + VPNProviderServerView( + apis: [API.bundled], + providerId: .tunnelbear, + configurationType: OpenVPN.Configuration.self, + selectedEntity: nil, + onSelect: { _, _ in } + ) + } + .withMockEnvironment() +} + #endif