Skip to content

Commit 7905187

Browse files
author
Jon Petersson
committed
List only DAITA enabled entry locations if multihop and DAITA are enabled
1 parent e327f37 commit 7905187

18 files changed

+137
-138
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/MullvadREST/Relay/RelaySelectorWrapper.swift

-5
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,6 @@ public final class RelaySelectorWrapper: RelaySelectorProtocol {
1515
private var tunnelSettings = LatestTunnelSettings()
1616
private var observer: SettingsObserverBlock!
1717

18-
// TODO: Remove, Jon
19-
func setDaita(state: MultihopState) {
20-
daitaState = state
21-
}
22-
2318
deinit {
2419
self.tunnelSettingsUpdater.removeObserver(observer)
2520
}

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 */; };
@@ -1805,6 +1807,7 @@
18051807
7A516C392B7111A700BBD33D /* IPOverrideWrapper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IPOverrideWrapper.swift; sourceTree = "<group>"; };
18061808
7A516C3B2B712F0B00BBD33D /* IPOverrideWrapperTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IPOverrideWrapperTests.swift; sourceTree = "<group>"; };
18071809
7A52F96B2C17450C00B133B9 /* RelaySelectorWrapperTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RelaySelectorWrapperTests.swift; sourceTree = "<group>"; };
1810+
7A5468AB2C6A55B100590086 /* LocationRelays.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationRelays.swift; sourceTree = "<group>"; };
18081811
7A5869942B32E9C700640D27 /* LinkButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LinkButton.swift; sourceTree = "<group>"; };
18091812
7A5869962B32EA4500640D27 /* AppButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppButton.swift; sourceTree = "<group>"; };
18101813
7A58699A2B482FE200640D27 /* UITableViewCell+Disable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UITableViewCell+Disable.swift"; sourceTree = "<group>"; };
@@ -2754,6 +2757,7 @@
27542757
F050AE5D2B739A73003F4EDB /* LocationDataSourceProtocol.swift */,
27552758
7A6652B62BB44B120042D848 /* LocationDiffableDataSourceProtocol.swift */,
27562759
7A6389F72B864CDF008E77E1 /* LocationNode.swift */,
2760+
7A5468AB2C6A55B100590086 /* LocationRelays.swift */,
27572761
F050AE512B70DFC0003F4EDB /* LocationSection.swift */,
27582762
F0BE65362B9F136A005CC385 /* LocationSectionHeaderView.swift */,
27592763
5888AD86227B17950051EB06 /* LocationViewController.swift */,
@@ -5248,6 +5252,7 @@
52485252
A9A5FA422ACB05D90083449F /* DeviceStateAccessorProtocol.swift in Sources */,
52495253
7A5869C32B5820CE00640D27 /* IPOverrideRepositoryTests.swift in Sources */,
52505254
A9A5FA392ACB05910083449F /* UIColor+Palette.swift in Sources */,
5255+
7A5468AD2C6B5E4B00590086 /* LocationRelays.swift in Sources */,
52515256
A9A5FA3A2ACB05910083449F /* UIEdgeInsets+Extensions.swift in Sources */,
52525257
A9A5FA3B2ACB05910083449F /* UIMetrics.swift in Sources */,
52535258
58B07C182AEFDD6C00A09625 /* StoreTransactionLog.swift in Sources */,
@@ -5539,6 +5544,7 @@
55395544
7A9CCCC42A96302800DD6A34 /* TunnelCoordinator.swift in Sources */,
55405545
5827B0A42B0F38FD00CCBBA1 /* EditAccessMethodInteractorProtocol.swift in Sources */,
55415546
586C0D852B03D31E00E7CDD7 /* SocksSectionHandler.swift in Sources */,
5547+
7A5468AC2C6A55B100590086 /* LocationRelays.swift in Sources */,
55425548
58BFA5CC22A7CE1F00A6173D /* ApplicationConfiguration.swift in Sources */,
55435549
5891BF5125E66B1E006D6FB0 /* UIBarButtonItem+KeyboardNavigation.swift in Sources */,
55445550
58E511E628DDDEAC00B0BCDE /* CodingErrors+CustomErrorDescription.swift in Sources */,

ios/MullvadVPN.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
"kind" : "remoteSourceControl",
1616
"location" : "https://github.com/mullvad/wireguard-apple.git",
1717
"state" : {
18-
"revision" : "e3fdc2e95ccd7a30284ec78f3bdf4f9a252a1ed2"
18+
"revision" : "3c55cc305d30a02f87af5d6228ff416d3901d8dd"
1919
}
2020
}
2121
],

ios/MullvadVPN/AppDelegate.swift

+2
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
103103
})
104104
tunnelManager.addObserver(settingsObserver)
105105

106+
tunnelManager.updateSettings([.daita(DAITASettings(state: .on))])
107+
106108
storePaymentManager = StorePaymentManager(
107109
backgroundTaskProvider: application,
108110
queue: .default(),

ios/MullvadVPN/Coordinators/LocationCoordinator.swift

+25-7
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

@@ -57,7 +57,8 @@ class LocationCoordinator: Coordinator, Presentable, Presenting {
5757
let locationViewControllerWrapper = LocationViewControllerWrapper(
5858
customListRepository: customListRepository,
5959
constraints: tunnelManager.settings.relayConstraints,
60-
multihopEnabled: tunnelManager.settings.tunnelMultihopState == .on
60+
multihopEnabled: tunnelManager.settings.tunnelMultihopState == .on,
61+
daitaEnabled: tunnelManager.settings.daita.state == .on
6162
)
6263
locationViewControllerWrapper.delegate = self
6364

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

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

7682
navigationController.pushViewController(locationViewControllerWrapper, animated: false)
@@ -87,7 +93,11 @@ class LocationCoordinator: Coordinator, Presentable, Presenting {
8793
)
8894

8995
relayFilterCoordinator.didFinish = { [weak self] coordinator, filter in
90-
if let cachedRelays = self?.cachedRelays, let filter {
96+
if var cachedRelays = self?.cachedRelays, let filter {
97+
cachedRelays.relays = cachedRelays.relays.filter { relay in
98+
RelaySelector.relayMatchesFilter(relay, filter: filter)
99+
}
100+
91101
self?.locationViewControllerWrapper?.setCachedRelays(cachedRelays, filter: filter)
92102
}
93103

@@ -148,9 +158,13 @@ extension LocationCoordinator: RelayCacheTrackerObserver {
148158
_ tracker: RelayCacheTracker,
149159
didUpdateCachedRelays cachedRelays: CachedRelays
150160
) {
151-
self.cachedRelays = cachedRelays
161+
let locationRelays = LocationRelays(
162+
relays: cachedRelays.relays.wireguard.relays,
163+
locations: cachedRelays.relays.locations
164+
)
165+
self.cachedRelays = locationRelays
152166

153-
locationViewControllerWrapper?.setCachedRelays(cachedRelays, filter: relayFilter)
167+
locationViewControllerWrapper?.setCachedRelays(locationRelays, filter: relayFilter)
154168
}
155169
}
156170

@@ -178,6 +192,10 @@ extension LocationCoordinator: LocationViewControllerWrapperDelegate {
178192
relayConstraints.filter = .only(filter)
179193

180194
tunnelManager.updateSettings([.relayConstraints(relayConstraints)])
195+
196+
if let cachedRelays {
197+
locationViewControllerWrapper?.setCachedRelays(cachedRelays, filter: filter)
198+
}
181199
}
182200

183201
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

+22-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,6 +35,7 @@ class RelayFilterView: UIView {
3435

3536
private let ownershipView = RelayFilterChipView()
3637
private let providersView = RelayFilterChipView()
38+
private let daitaView = RelayFilterChipView()
3739
private var filter: RelayFilter?
3840

3941
var didUpdateFilter: ((RelayFilter) -> Void)?
@@ -71,14 +73,24 @@ class RelayFilterView: UIView {
7173
}
7274
}
7375

76+
func setDaita(_ enabled: Bool) {
77+
daitaView.isHidden = !enabled
78+
}
79+
7480
private func setUpViews() {
81+
daitaView.setTitle(localizedDaitaText())
82+
daitaView.isHidden = true
83+
daitaView.closeButton.isHidden = true
84+
85+
ownershipView.isHidden = true
7586
ownershipView.didTapButton = { [weak self] in
7687
guard var filter = self?.filter else { return }
7788

7889
filter.ownership = .any
7990
self?.didUpdateFilter?(filter)
8091
}
8192

93+
providersView.isHidden = true
8294
providersView.didTapButton = { [weak self] in
8395
guard var filter = self?.filter else { return }
8496

@@ -87,7 +99,7 @@ class RelayFilterView: UIView {
8799
}
88100

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

93105
let contentContainer = UIStackView(arrangedSubviews: [titleLabel, filterContainer])
@@ -99,6 +111,15 @@ class RelayFilterView: UIView {
99111
}
100112
}
101113

114+
private func localizedDaitaText() -> String {
115+
return NSLocalizedString(
116+
"RELAY_FILTER_APPLIED_DAITA",
117+
tableName: "RelayFilter",
118+
value: "Setting: DAITA",
119+
comment: ""
120+
)
121+
}
122+
102123
private func localizedOwnershipText(for string: String) -> String {
103124
return NSLocalizedString(
104125
"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)