Attempt an iOS layout with DisclosureGroup
Also fix missing initial filters based on selection. Fixes #746
This commit is contained in:
parent
2455c5397e
commit
48dc31a1f1
|
@ -130,6 +130,7 @@ private extension OpenVPNView {
|
|||
VPNProviderServerView(
|
||||
providerId: $0,
|
||||
configurationType: OpenVPN.Configuration.self,
|
||||
selectedEntity: providerEntity.wrappedValue,
|
||||
onSelect: onSelectServer
|
||||
)
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ struct VPNProviderServerView<Configuration>: View where Configuration: ProviderC
|
|||
|
||||
let configurationType: Configuration.Type
|
||||
|
||||
var selectedEntity: VPNEntity<Configuration>?
|
||||
let selectedEntity: VPNEntity<Configuration>?
|
||||
|
||||
let onSelect: (_ server: VPNServer, _ preset: VPNPreset<Configuration>) -> 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()
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue