Skip to content

Commit

Permalink
Update view model when switching between entry and exit location
Browse files Browse the repository at this point in the history
  • Loading branch information
Jon Petersson committed Jun 14, 2024
1 parent 9cba0d8 commit c79eb5b
Show file tree
Hide file tree
Showing 11 changed files with 283 additions and 91 deletions.
4 changes: 4 additions & 0 deletions ios/MullvadVPN.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,7 @@
7A3353912AAA014400F0A71C /* SimulatorVPNConnection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A3353902AAA014400F0A71C /* SimulatorVPNConnection.swift */; };
7A3353932AAA089000F0A71C /* SimulatorTunnelInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A3353922AAA089000F0A71C /* SimulatorTunnelInfo.swift */; };
7A3353972AAA0F8600F0A71C /* OperationBlockObserverSupport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A3353962AAA0F8600F0A71C /* OperationBlockObserverSupport.swift */; };
7A3EFAAB2BDFDAE800318736 /* RelaySelection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A3EFAAA2BDFDAE800318736 /* RelaySelection.swift */; };
7A3FD1B52AD4465A0042BEA6 /* AppMessageHandlerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A3FD1B42AD4465A0042BEA6 /* AppMessageHandlerTests.swift */; };
7A3FD1B72AD54ABD0042BEA6 /* AnyTransport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58BDEB982A98F4ED00F578F2 /* AnyTransport.swift */; };
7A3FD1B82AD54AE60042BEA6 /* TimeServerProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 58BDEB9A2A98F58600F578F2 /* TimeServerProxy.swift */; };
Expand Down Expand Up @@ -1847,6 +1848,7 @@
7A3353902AAA014400F0A71C /* SimulatorVPNConnection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SimulatorVPNConnection.swift; sourceTree = "<group>"; };
7A3353922AAA089000F0A71C /* SimulatorTunnelInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SimulatorTunnelInfo.swift; sourceTree = "<group>"; };
7A3353962AAA0F8600F0A71C /* OperationBlockObserverSupport.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OperationBlockObserverSupport.swift; sourceTree = "<group>"; };
7A3EFAAA2BDFDAE800318736 /* RelaySelection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RelaySelection.swift; sourceTree = "<group>"; };
7A3FD1B42AD4465A0042BEA6 /* AppMessageHandlerTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppMessageHandlerTests.swift; sourceTree = "<group>"; };
7A42DEC82A05164100B209BE /* SettingsInputCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsInputCell.swift; sourceTree = "<group>"; };
7A45CFC22C05FF2F00D80B21 /* ScreenshotTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScreenshotTests.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -2780,6 +2782,7 @@
F0BE65362B9F136A005CC385 /* LocationSectionHeaderView.swift */,
5888AD86227B17950051EB06 /* LocationViewController.swift */,
7AB3BEB42BD7A6CB00E34384 /* LocationViewControllerWrapper.swift */,
7A3EFAAA2BDFDAE800318736 /* RelaySelection.swift */,
);
path = SelectLocation;
sourceTree = "<group>";
Expand Down Expand Up @@ -5799,6 +5802,7 @@
5878F50029CDA742003D4BE2 /* UIView+AutoLayoutBuilder.swift in Sources */,
7A28826D2BAAC9DE00FD9F20 /* IPOverrideHeaderView.swift in Sources */,
A98502032B627B120061901E /* LocalNetworkProbe.swift in Sources */,
7A3EFAAB2BDFDAE800318736 /* RelaySelection.swift in Sources */,
583FE01029C0F532006E85F9 /* CustomSplitViewController.swift in Sources */,
7A6F2FA92AFD0842006D0856 /* CustomDNSDataSource.swift in Sources */,
58EF580B25D69D7A00AEBA94 /* ProblemReportSubmissionOverlayView.swift in Sources */,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,25 @@ class ListCustomListCoordinator: Coordinator, Presentable, Presenting {

coordinator.didFinish = { [weak self] editCustomListCoordinator, action, list in
guard let self else { return }

popToList()
editCustomListCoordinator.removeFromParent()
self.updateRelayConstraints(for: action, in: list)

var relayConstraints = tunnelManager.settings.relayConstraints
relayConstraints.entryLocations = self.updateRelayConstraint(
relayConstraints.entryLocations,
for: action,
in: list
)
relayConstraints.exitLocations = self.updateRelayConstraint(
relayConstraints.exitLocations,
for: action,
in: list
)

tunnelManager.updateSettings([.relayConstraints(relayConstraints)]) { [weak self] in
self?.tunnelManager.reconnectTunnel(selectNewRelay: true)
}
}

coordinator.didCancel = { [weak self] editCustomListCoordinator in
Expand All @@ -75,38 +91,39 @@ class ListCustomListCoordinator: Coordinator, Presentable, Presenting {
addChild(coordinator)
}

private func updateRelayConstraints(for action: EditCustomListCoordinator.FinishAction, in list: CustomList) {
var relayConstraints = tunnelManager.settings.relayConstraints
private func updateRelayConstraint(
_ relayConstraint: RelayConstraint<UserSelectedRelays>,
for action: EditCustomListCoordinator.FinishAction,
in list: CustomList
) -> RelayConstraint<UserSelectedRelays> {
var relayConstraint = relayConstraint

guard let customListSelection = relayConstraints.exitLocations.value?.customListSelection,
guard let customListSelection = relayConstraint.value?.customListSelection,
customListSelection.listId == list.id
else { return }
else { return relayConstraint }

switch action {
case .save:
// TODO: - Add entry locations
if customListSelection.isList {
let selectedRelays = UserSelectedRelays(
locations: list.locations,
customListSelection: UserSelectedRelays.CustomListSelection(listId: list.id, isList: true)
)
relayConstraints.exitLocations = .only(selectedRelays)
relayConstraint = .only(selectedRelays)
} else {
let selectedConstraintIsRemovedFromList = list.locations.filter {
relayConstraints.exitLocations.value?.locations.contains($0) ?? false
relayConstraint.value?.locations.contains($0) ?? false
}.isEmpty

if selectedConstraintIsRemovedFromList {
relayConstraints.exitLocations = .only(UserSelectedRelays(locations: []))
relayConstraint = .only(UserSelectedRelays(locations: []))
}
}
case .delete:
relayConstraints.exitLocations = .only(UserSelectedRelays(locations: []))
relayConstraint = .only(UserSelectedRelays(locations: []))
}

tunnelManager.updateSettings([.relayConstraints(relayConstraints)]) { [weak self] in
self?.tunnelManager.reconnectTunnel(selectNewRelay: true)
}
return relayConstraint
}

private func popToList() {
Expand Down
17 changes: 12 additions & 5 deletions ios/MullvadVPN/Coordinators/LocationCoordinator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,10 @@ class LocationCoordinator: Coordinator, Presentable, Presenting {
}

func start() {
// TODO: - the location should be defined whether it's Entry or Exit location
let locationViewControllerWrapper = LocationViewControllerWrapper(
customListRepository: customListRepository,
selectedRelays: tunnelManager.settings.relayConstraints.exitLocations.value
constraints: tunnelManager.settings.relayConstraints,
multihopEnabled: tunnelManager.settings.tunnelMultihopState == .on
)
locationViewControllerWrapper.delegate = self

Expand Down Expand Up @@ -155,15 +155,22 @@ extension LocationCoordinator: RelayCacheTrackerObserver {
}

extension LocationCoordinator: LocationViewControllerWrapperDelegate {
func didSelectRelays(relays: UserSelectedRelays) {
func didSelectEntryRelays(relays: UserSelectedRelays) {
var relayConstraints = tunnelManager.settings.relayConstraints
relayConstraints.exitLocations = .only(relays)
relayConstraints.entryLocations = .only(relays)

tunnelManager.updateSettings([.relayConstraints(relayConstraints)]) {
self.tunnelManager.startTunnel()
}
}

func didSelectExitRelays(relays: UserSelectedRelays) {
var relayConstraints = tunnelManager.settings.relayConstraints
relayConstraints.exitLocations = .only(relays)

didFinish?(self)
tunnelManager.updateSettings([.relayConstraints(relayConstraints)]) {
self.tunnelManager.startTunnel()
}
}

func didUpdateFilter(filter: RelayFilter) {
Expand Down
2 changes: 1 addition & 1 deletion ios/MullvadVPN/UI appearance/UIColor+Palette.swift
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ extension UIColor {
}

enum SegmentedControl {
static let backgroundColor = UIColor(red: 0.18, green: 0.33, blue: 0.49, alpha: 1.0)
static let backgroundColor = UIColor(red: 0.14, green: 0.25, blue: 0.38, alpha: 1.0)
static let selectedColor = successColor
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ class RelayFilterView: UIView {
contentContainer.spacing = UIMetrics.FilterView.labelSpacing

addConstrainedSubviews([contentContainer]) {
contentContainer.pinEdges(.init([.top(4), .bottom(0)]), to: self)
contentContainer.pinEdges(.init([.top(7), .bottom(0)]), to: self)
contentContainer.pinEdges(.init([.leading(4), .trailing(4)]), to: layoutMarginsGuide)
}
}
Expand Down
14 changes: 11 additions & 3 deletions ios/MullvadVPN/View controllers/SelectLocation/LocationCell.swift
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ class LocationCell: UITableViewCell {

var isDisabled = false {
didSet {
updateDisabled()
updateDisabled(isDisabled)
updateBackgroundColor()
updateStatusIndicatorColor()
}
Expand Down Expand Up @@ -150,7 +150,7 @@ class LocationCell: UITableViewCell {

updateCollapseImage()
updateAccessibilityCustomActions()
updateDisabled()
updateDisabled(isDisabled)
updateBackgroundColor()
setLayoutMargins()

Expand Down Expand Up @@ -207,7 +207,7 @@ class LocationCell: UITableViewCell {
statusIndicator.backgroundColor = statusIndicatorColor()
}

private func updateDisabled() {
private func updateDisabled(_ isDisabled: Bool) {
locationLabel.alpha = isDisabled ? 0.2 : 1
collapseButton.alpha = isDisabled ? 0.2 : 1

Expand Down Expand Up @@ -339,9 +339,17 @@ extension LocationCell {
}
}

setExcludedRelayTitle(item.excludedRelayTitle)
setBehavior(behavior)
}

func setExcludedRelayTitle(_ title: String?) {
if let title {
locationLabel.text! += " (\(title))"
updateDisabled(true)
}
}

private func setBehavior(_ newBehavior: LocationCellBehavior) {
self.behavior = newBehavior
updateLeadingImage()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,20 @@ struct LocationCellViewModel: Hashable {
let node: LocationNode
var indentationLevel = 0
var isSelected = false
var excludedRelayTitle: String?

func hash(into hasher: inout Hasher) {
hasher.combine(node)
hasher.combine(node.children.count)
hasher.combine(section)
hasher.combine(isSelected)
hasher.combine(indentationLevel)
}

static func == (lhs: Self, rhs: Self) -> Bool {
lhs.node == rhs.node &&
lhs.node.children.count == rhs.node.children.count &&
lhs.section == rhs.section &&
lhs.isSelected == rhs.isSelected &&
lhs.indentationLevel == rhs.indentationLevel
lhs.isSelected == rhs.isSelected
}
}

Expand Down
Loading

0 comments on commit c79eb5b

Please sign in to comment.