Skip to content

Commit 2272c98

Browse files
author
Jon Petersson
committed
List only DAITA enabled entry locations if multihop and DAITA are enabled
1 parent c5fe10c commit 2272c98

14 files changed

+127
-60
lines changed

ios/MullvadREST/ApiHandlers/ServerRelaysResponse.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ extension REST {
3434
public let ipv4AddrIn: IPv4Address
3535
public let weight: UInt64
3636
public let includeInCountry: Bool
37-
public var daita: Bool? = nil
37+
public var daita: Bool?
3838

3939
public func override(ipv4AddrIn: IPv4Address?) -> Self {
4040
return BridgeRelay(

ios/MullvadVPN.xcodeproj/project.pbxproj

+6
Original file line numberDiff line numberDiff line change
@@ -489,6 +489,8 @@
489489
7A516C3C2B712F0B00BBD33D /* IPOverrideWrapperTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A516C3B2B712F0B00BBD33D /* IPOverrideWrapperTests.swift */; };
490490
7A52F96A2C1735AE00B133B9 /* RelaySelectorStub.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58FE25EF2AA77664003D1918 /* RelaySelectorStub.swift */; };
491491
7A52F96C2C17450C00B133B9 /* RelaySelectorWrapperTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A52F96B2C17450C00B133B9 /* RelaySelectorWrapperTests.swift */; };
492+
7A5468AC2C6A55B100590086 /* LocationRelays.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A5468AB2C6A55B100590086 /* LocationRelays.swift */; };
493+
7A5468AD2C6B5E4B00590086 /* LocationRelays.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A5468AB2C6A55B100590086 /* LocationRelays.swift */; };
492494
7A5869952B32E9C700640D27 /* LinkButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A5869942B32E9C700640D27 /* LinkButton.swift */; };
493495
7A5869972B32EA4500640D27 /* AppButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A5869962B32EA4500640D27 /* AppButton.swift */; };
494496
7A58699B2B482FE200640D27 /* UITableViewCell+Disable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A58699A2B482FE200640D27 /* UITableViewCell+Disable.swift */; };
@@ -1803,6 +1805,7 @@
18031805
7A516C392B7111A700BBD33D /* IPOverrideWrapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IPOverrideWrapper.swift; sourceTree = "<group>"; };
18041806
7A516C3B2B712F0B00BBD33D /* IPOverrideWrapperTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IPOverrideWrapperTests.swift; sourceTree = "<group>"; };
18051807
7A52F96B2C17450C00B133B9 /* RelaySelectorWrapperTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RelaySelectorWrapperTests.swift; sourceTree = "<group>"; };
1808+
7A5468AB2C6A55B100590086 /* LocationRelays.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationRelays.swift; sourceTree = "<group>"; };
18061809
7A5869942B32E9C700640D27 /* LinkButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LinkButton.swift; sourceTree = "<group>"; };
18071810
7A5869962B32EA4500640D27 /* AppButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppButton.swift; sourceTree = "<group>"; };
18081811
7A58699A2B482FE200640D27 /* UITableViewCell+Disable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UITableViewCell+Disable.swift"; sourceTree = "<group>"; };
@@ -2749,6 +2752,7 @@
27492752
F050AE5D2B739A73003F4EDB /* LocationDataSourceProtocol.swift */,
27502753
7A6652B62BB44B120042D848 /* LocationDiffableDataSourceProtocol.swift */,
27512754
7A6389F72B864CDF008E77E1 /* LocationNode.swift */,
2755+
7A5468AB2C6A55B100590086 /* LocationRelays.swift */,
27522756
F050AE512B70DFC0003F4EDB /* LocationSection.swift */,
27532757
F0BE65362B9F136A005CC385 /* LocationSectionHeaderView.swift */,
27542758
5888AD86227B17950051EB06 /* LocationViewController.swift */,
@@ -5211,6 +5215,7 @@
52115215
A9A5FA422ACB05D90083449F /* DeviceStateAccessorProtocol.swift in Sources */,
52125216
7A5869C32B5820CE00640D27 /* IPOverrideRepositoryTests.swift in Sources */,
52135217
A9A5FA392ACB05910083449F /* UIColor+Palette.swift in Sources */,
5218+
7A5468AD2C6B5E4B00590086 /* LocationRelays.swift in Sources */,
52145219
A9A5FA3A2ACB05910083449F /* UIEdgeInsets+Extensions.swift in Sources */,
52155220
A9A5FA3B2ACB05910083449F /* UIMetrics.swift in Sources */,
52165221
58B07C182AEFDD6C00A09625 /* StoreTransactionLog.swift in Sources */,
@@ -5498,6 +5503,7 @@
54985503
7A9CCCC42A96302800DD6A34 /* TunnelCoordinator.swift in Sources */,
54995504
5827B0A42B0F38FD00CCBBA1 /* EditAccessMethodInteractorProtocol.swift in Sources */,
55005505
586C0D852B03D31E00E7CDD7 /* SocksSectionHandler.swift in Sources */,
5506+
7A5468AC2C6A55B100590086 /* LocationRelays.swift in Sources */,
55015507
58BFA5CC22A7CE1F00A6173D /* ApplicationConfiguration.swift in Sources */,
55025508
5891BF5125E66B1E006D6FB0 /* UIBarButtonItem+KeyboardNavigation.swift in Sources */,
55035509
58E511E628DDDEAC00B0BCDE /* CodingErrors+CustomErrorDescription.swift in Sources */,

ios/MullvadVPN/Coordinators/LocationCoordinator.swift

+23-6
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ class LocationCoordinator: Coordinator, Presentable, Presenting {
1616
private let tunnelManager: TunnelManager
1717
private let relayCacheTracker: RelayCacheTracker
1818
private let customListRepository: CustomListRepositoryProtocol
19-
private var cachedRelays: CachedRelays?
19+
private var cachedRelays: LocationRelays?
2020

2121
let navigationController: UINavigationController
2222

@@ -69,8 +69,13 @@ class LocationCoordinator: Coordinator, Presentable, Presenting {
6969
relayCacheTracker.addObserver(self)
7070

7171
if let cachedRelays = try? relayCacheTracker.getCachedRelays() {
72-
self.cachedRelays = cachedRelays
73-
locationViewControllerWrapper.setCachedRelays(cachedRelays, filter: relayFilter)
72+
let locationRelays = LocationRelays(
73+
relays: cachedRelays.relays.wireguard.relays,
74+
locations: cachedRelays.relays.locations
75+
)
76+
self.cachedRelays = locationRelays
77+
78+
locationViewControllerWrapper.setCachedRelays(locationRelays, filter: relayFilter)
7479
}
7580

7681
navigationController.pushViewController(locationViewControllerWrapper, animated: false)
@@ -87,7 +92,11 @@ class LocationCoordinator: Coordinator, Presentable, Presenting {
8792
)
8893

8994
relayFilterCoordinator.didFinish = { [weak self] coordinator, filter in
90-
if let cachedRelays = self?.cachedRelays, let filter {
95+
if var cachedRelays = self?.cachedRelays, let filter {
96+
cachedRelays.relays = cachedRelays.relays.filter { relay in
97+
RelaySelector.relayMatchesFilter(relay, filter: filter)
98+
}
99+
91100
self?.locationViewControllerWrapper?.setCachedRelays(cachedRelays, filter: filter)
92101
}
93102

@@ -148,9 +157,13 @@ extension LocationCoordinator: RelayCacheTrackerObserver {
148157
_ tracker: RelayCacheTracker,
149158
didUpdateCachedRelays cachedRelays: CachedRelays
150159
) {
151-
self.cachedRelays = cachedRelays
160+
let locationRelays = LocationRelays(
161+
relays: cachedRelays.relays.wireguard.relays,
162+
locations: cachedRelays.relays.locations
163+
)
164+
self.cachedRelays = locationRelays
152165

153-
locationViewControllerWrapper?.setCachedRelays(cachedRelays, filter: relayFilter)
166+
locationViewControllerWrapper?.setCachedRelays(locationRelays, filter: relayFilter)
154167
}
155168
}
156169

@@ -178,6 +191,10 @@ extension LocationCoordinator: LocationViewControllerWrapperDelegate {
178191
relayConstraints.filter = .only(filter)
179192

180193
tunnelManager.updateSettings([.relayConstraints(relayConstraints)])
194+
195+
if let cachedRelays {
196+
locationViewControllerWrapper?.setCachedRelays(cachedRelays, filter: filter)
197+
}
181198
}
182199

183200
func navigateToFilter() {

ios/MullvadVPN/View controllers/RelayFilter/RelayFilterChipView.swift

+10-6
Original file line numberDiff line numberDiff line change
@@ -18,19 +18,23 @@ class RelayFilterChipView: UIView {
1818
return label
1919
}()
2020

21+
let closeButton: IncreasedHitButton = {
22+
let button = IncreasedHitButton()
23+
button.setImage(
24+
UIImage(named: "IconCloseSml")?.withTintColor(.white.withAlphaComponent(0.6)),
25+
for: .normal
26+
)
27+
button.accessibilityIdentifier = .relayFilterChipCloseButton
28+
return button
29+
}()
30+
2131
var didTapButton: (() -> Void)?
2232

2333
init() {
2434
super.init(frame: .zero)
2535

2636
self.accessibilityIdentifier = .relayFilterChipView
2737

28-
let closeButton = IncreasedHitButton()
29-
closeButton.setImage(
30-
UIImage(named: "IconCloseSml")?.withTintColor(.white.withAlphaComponent(0.6)),
31-
for: .normal
32-
)
33-
closeButton.accessibilityIdentifier = .relayFilterChipCloseButton
3438
closeButton.addTarget(self, action: #selector(didTapButton(_:)), for: .touchUpInside)
3539

3640
let container = UIStackView(arrangedSubviews: [titleLabel, closeButton])

ios/MullvadVPN/View controllers/RelayFilter/RelayFilterView.swift

+24-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
//
88

99
import MullvadTypes
10+
import MullvadSettings
1011
import UIKit
1112

1213
class RelayFilterView: UIView {
@@ -34,7 +35,9 @@ class RelayFilterView: UIView {
3435

3536
private let ownershipView = RelayFilterChipView()
3637
private let providersView = RelayFilterChipView()
38+
private let daitaView = RelayFilterChipView()
3739
private var filter: RelayFilter?
40+
private var daitaState: MultihopState = .off
3841

3942
var didUpdateFilter: ((RelayFilter) -> Void)?
4043

@@ -71,14 +74,25 @@ class RelayFilterView: UIView {
7174
}
7275
}
7376

77+
func setDaita(_ state: MultihopState) {
78+
daitaState = state
79+
daitaView.isHidden = state == .off
80+
}
81+
7482
private func setUpViews() {
83+
daitaView.setTitle(localizedDaitaText())
84+
daitaView.isHidden = true
85+
daitaView.closeButton.isHidden = true
86+
87+
ownershipView.isHidden = true
7588
ownershipView.didTapButton = { [weak self] in
7689
guard var filter = self?.filter else { return }
7790

7891
filter.ownership = .any
7992
self?.didUpdateFilter?(filter)
8093
}
8194

95+
providersView.isHidden = true
8296
providersView.didTapButton = { [weak self] in
8397
guard var filter = self?.filter else { return }
8498

@@ -87,7 +101,7 @@ class RelayFilterView: UIView {
87101
}
88102

89103
// Add a dummy view at the end to push content to the left.
90-
let filterContainer = UIStackView(arrangedSubviews: [ownershipView, providersView, UIView()])
104+
let filterContainer = UIStackView(arrangedSubviews: [daitaView, ownershipView, providersView, UIView()])
91105
filterContainer.spacing = UIMetrics.FilterView.interChipViewSpacing
92106

93107
let contentContainer = UIStackView(arrangedSubviews: [titleLabel, filterContainer])
@@ -99,6 +113,15 @@ class RelayFilterView: UIView {
99113
}
100114
}
101115

116+
private func localizedDaitaText() -> String {
117+
return NSLocalizedString(
118+
"RELAY_FILTER_APPLIED_DAITA",
119+
tableName: "RelayFilter",
120+
value: "Setting: DAITA",
121+
comment: ""
122+
)
123+
}
124+
102125
private func localizedOwnershipText(for string: String) -> String {
103126
return NSLocalizedString(
104127
"RELAY_FILTER_APPLIED_OWNERSHIP",

ios/MullvadVPN/View controllers/SelectLocation/AllLocationDataSource.swift

+3-3
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,13 @@ class AllLocationDataSource: LocationDataSourceProtocol {
2020
/// Constructs a collection of node trees from relays fetched from the API.
2121
/// ``RelayLocation.city`` is of special import since we use it to get country
2222
/// and city names.
23-
func reload(_ response: REST.ServerRelaysResponse, relays: [REST.ServerRelay]) {
23+
func reload(_ relays: LocationRelays) {
2424
let rootNode = RootLocationNode()
2525

26-
for relay in relays {
26+
for relay in relays.relays {
2727
guard case
2828
let .city(countryCode, cityCode) = RelayLocation(dashSeparatedString: relay.location),
29-
let serverLocation = response.locations[relay.location]
29+
let serverLocation = relays.locations[relay.location]
3030
else { continue }
3131

3232
let relayLocation = RelayLocation.hostname(countryCode, cityCode, relay.hostname)

ios/MullvadVPN/View controllers/SelectLocation/LocationCellViewModel.swift

+9-9
Original file line numberDiff line numberDiff line change
@@ -62,17 +62,17 @@ extension [LocationCellViewModel] {
6262
}
6363

6464
extension LocationCellViewModel {
65-
/* Exclusion of other locations in the same node tree as the currently excluded location
65+
/* Exclusion of other locations in the same node tree (as the currently excluded location)
6666
happens when there are no more hosts in that tree that can be selected.
6767
We check this by doing the following, in order:
6868

69-
1. Count host names in the tree. More than one means that there are other locations than
69+
1. Count hostnames in the tree. More than one means that there are other locations than
7070
the excluded one for the relay selector to choose from. No exlusion.
7171

72-
2. Count host names in the excluded node. More than one means that there are multiple
73-
locations for the relay selector to choose from. No exlusion.
72+
2. Count hostnames in the excluded node. More than one means that there are multiple
73+
locations for the relay selector to choose from. No exclusion.
7474

75-
3. Check existance of a location in the tree that match the currently excluded location.
75+
3. Check existance of a location in the tree that matches the currently excluded location.
7676
No match means no exclusion.
7777
*/
7878
func shouldExcludeLocation(_ excludedLocation: LocationCellViewModel?) -> Bool {
@@ -86,8 +86,8 @@ extension LocationCellViewModel {
8686
if case .hostname = location { true } else { false }
8787
}.count
8888

89-
// If the there are more than one selectable relay in the current node we don't need
90-
// show this in the location tree and can return early.
89+
// If the there's more than one selectable relay in the current node we don't need
90+
// to show this in the location tree and can return early.
9191
guard hostCount == 1 else { return false }
9292

9393
let proxyExcludedNode = RootLocationNode(children: [excludedLocation.node])
@@ -96,8 +96,8 @@ extension LocationCellViewModel {
9696
if case .hostname = location { true } else { false }
9797
}.count
9898

99-
// If the there are more than one selectable relay in the excluded node we don't need
100-
// show this in the location tree and can return early.
99+
// If the there's more than one selectable relay in the excluded node we don't need
100+
// to show this in the location tree and can return early.
101101
guard excludedHostCount == 1 else { return false }
102102

103103
var containsExcludedLocation = false

ios/MullvadVPN/View controllers/SelectLocation/LocationDataSource.swift

+2-12
Original file line numberDiff line numberDiff line change
@@ -54,18 +54,14 @@ final class LocationDataSource:
5454
defaultRowAnimation = .fade
5555
}
5656

57-
func setRelays(_ response: REST.ServerRelaysResponse, selectedRelays: RelaySelection, filter: RelayFilter) {
57+
func setRelays(_ cachedRelays: LocationRelays, selectedRelays: RelaySelection) {
5858
let allLocationsDataSource =
5959
dataSources.first(where: { $0 is AllLocationDataSource }) as? AllLocationDataSource
6060

6161
let customListsDataSource =
6262
dataSources.first(where: { $0 is CustomListsDataSource }) as? CustomListsDataSource
6363

64-
let relays = response.wireguard.relays.filter { relay in
65-
RelaySelector.relayMatchesFilter(relay, filter: filter)
66-
}
67-
68-
allLocationsDataSource?.reload(response, relays: relays)
64+
allLocationsDataSource?.reload(cachedRelays)
6965
customListsDataSource?.reload(allLocationNodes: allLocationsDataSource?.nodes ?? [])
7066

7167
setSelectedRelays(selectedRelays)
@@ -237,12 +233,6 @@ final class LocationDataSource:
237233
)
238234
}
239235

240-
private func nodeMatchesExcludedLocation(_ node: LocationNode) -> Bool {
241-
// Compare nodes on name rather than whole node in order to match all items in both .customLists
242-
// and .allLocations.
243-
node.name == excludedLocation?.node.name
244-
}
245-
246236
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
247237
let cell = super.tableView(tableView, cellForRowAt: indexPath)
248238
guard let cell = cell as? LocationCell, let item = itemIdentifier(for: indexPath) else {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
//
2+
// LocationRelays.swift
3+
// MullvadVPN
4+
//
5+
// Created by Jon Petersson on 2024-08-12.
6+
// Copyright © 2024 Mullvad VPN AB. All rights reserved.
7+
//
8+
9+
import MullvadREST
10+
11+
struct LocationRelays {
12+
var relays: [REST.ServerRelay]
13+
var locations: [String: REST.ServerLocation]
14+
}

0 commit comments

Comments
 (0)