-
Notifications
You must be signed in to change notification settings - Fork 356
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add the multihop page to the root of the settings page
- Loading branch information
Showing
61 changed files
with
955 additions
and
59 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
33 changes: 33 additions & 0 deletions
33
ios/MullvadVPN/Coordinators/Settings/DAITA/DAITATunnelSettingsObserver.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
// | ||
// DAITATunnelSettingsObserver.swift | ||
// MullvadVPN | ||
// | ||
// Created by Jon Petersson on 2024-11-21. | ||
// Copyright © 2024 Mullvad VPN AB. All rights reserved. | ||
// | ||
|
||
import Foundation | ||
import MullvadSettings | ||
|
||
class DAITATunnelSettingsObserver: ObservableObject { | ||
private let tunnelManager: TunnelManager | ||
private var tunnelObserver: TunnelObserver? | ||
|
||
var value: DAITASettings { | ||
willSet(newValue) { | ||
guard newValue != self.value else { return } | ||
|
||
objectWillChange.send() | ||
tunnelManager.updateSettings([.daita(newValue)]) | ||
} | ||
} | ||
|
||
init(tunnelManager: TunnelManager) { | ||
self.tunnelManager = tunnelManager | ||
value = tunnelManager.settings.daita | ||
|
||
tunnelObserver = TunnelBlockObserver(didUpdateTunnelSettings: { [weak self] _, newSettings in | ||
self?.value = newSettings.daita | ||
}) | ||
} | ||
} |
24 changes: 24 additions & 0 deletions
24
ios/MullvadVPN/Coordinators/Settings/DAITA/DAITATunnelSettingsViewModel.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
// | ||
// DAITATunnelSettingsObservable.swift | ||
// MullvadVPN | ||
// | ||
// Created by Jon Petersson on 2024-11-21. | ||
// Copyright © 2024 Mullvad VPN AB. All rights reserved. | ||
// | ||
|
||
import Foundation | ||
import MullvadSettings | ||
|
||
protocol DAITATunnelSettingsObservable: ObservableObject { | ||
var value: DAITASettings { get set } | ||
} | ||
|
||
class MockDAITATunnelSettingsViewModel: DAITATunnelSettingsObservable { | ||
@Published var value: DAITASettings | ||
|
||
init(daitaSettings: DAITASettings = DAITASettings()) { | ||
value = daitaSettings | ||
} | ||
} | ||
|
||
class DAITATunnelSettingsViewModel: DAITATunnelSettingsObserver, DAITATunnelSettingsObservable {} |
106 changes: 106 additions & 0 deletions
106
ios/MullvadVPN/Coordinators/Settings/DAITA/SettingsDAITAView.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
// | ||
// SettingsDAITAView.swift | ||
// MullvadVPN | ||
// | ||
// Created by Jon Petersson on 2024-11-14. | ||
// Copyright © 2024 Mullvad VPN AB. All rights reserved. | ||
// | ||
|
||
import SwiftUI | ||
|
||
struct SettingsDAITAView<VM>: View where VM: DAITATunnelSettingsObservable { | ||
@StateObject var tunnelViewModel: VM | ||
|
||
private let dataViewModel = SettingsInfoViewModel( | ||
pages: [ | ||
SettingsInfoViewModelPage( | ||
body: NSLocalizedString( | ||
"SETTINGS_INFO_DAITA_PAGE_1", | ||
tableName: "Settings", | ||
value: """ | ||
DAITA (Defense against AI-guided Traffic Analysis) hides patterns in \ | ||
your encrypted VPN traffic. | ||
By using sophisticated AI it’s possible to analyze the traffic of data \ | ||
packets going in and out of your device (even if the traffic is encrypted). | ||
If an observer monitors these data packets, DAITA makes it significantly \ | ||
harder for them to identify which websites you are visiting or with whom \ | ||
you are communicating. | ||
""", | ||
comment: "" | ||
), | ||
image: .daitaOffIllustration | ||
), | ||
SettingsInfoViewModelPage( | ||
body: NSLocalizedString( | ||
"SETTINGS_INFO_DAITA_PAGE_2", | ||
tableName: "Settings", | ||
value: """ | ||
DAITA does this by carefully adding network noise and making all network \ | ||
packets the same size. | ||
Not all our servers are DAITA-enabled. Therefore, we use multihop \ | ||
automatically to enable DAITA with any server. | ||
Attention: Be cautious if you have a limited data plan as this feature \ | ||
will increase your network traffic. | ||
""", | ||
comment: "" | ||
), | ||
image: .daitaOnIllustration | ||
) | ||
] | ||
) | ||
|
||
var body: some View { | ||
SettingsInfoContainerView { | ||
VStack(alignment: .leading, spacing: 8) { | ||
SettingsInfoView(viewModel: dataViewModel) | ||
|
||
VStack { | ||
GroupedRowView { | ||
SwitchRowView( | ||
enabled: $tunnelViewModel.value.daitaState.isEnabled, | ||
text: NSLocalizedString( | ||
"SETTINGS_SWITCH_DAITA_ENABLE", | ||
tableName: "Settings", | ||
value: "Enable", | ||
comment: "" | ||
) | ||
) | ||
RowSeparator() | ||
SwitchRowView( | ||
enabled: $tunnelViewModel.value.directOnlyState.isEnabled, | ||
text: NSLocalizedString( | ||
"SETTINGS_SWITCH_DAITA_DIRECT_ONLY", | ||
tableName: "Settings", | ||
value: "Direct only", | ||
comment: "" | ||
) | ||
) | ||
} | ||
|
||
SettingsRowViewFooter( | ||
text: NSLocalizedString( | ||
"SETTINGS_SWITCH_DAITA_ENABLE", | ||
tableName: "Settings", | ||
value: """ | ||
By enabling "Direct only" you will have to manually select a server that \ | ||
is DAITA-enabled. Multihop won't automatically be used to enable DAITA with \ | ||
any server. | ||
""", | ||
comment: "" | ||
) | ||
) | ||
} | ||
.padding(.leading, UIMetrics.contentInsets.left) | ||
.padding(.trailing, UIMetrics.contentInsets.right) | ||
} | ||
} | ||
} | ||
} | ||
|
||
#Preview { | ||
SettingsDAITAView(tunnelViewModel: MockDAITATunnelSettingsViewModel()) | ||
} |
33 changes: 33 additions & 0 deletions
33
ios/MullvadVPN/Coordinators/Settings/Multihop/MultihopTunnelSettingsObserver.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
// | ||
// MultihopTunnelSettingsObserver.swift | ||
// MullvadVPN | ||
// | ||
// Created by Jon Petersson on 2024-11-21. | ||
// Copyright © 2024 Mullvad VPN AB. All rights reserved. | ||
// | ||
|
||
import Foundation | ||
import MullvadSettings | ||
|
||
class MultihopTunnelSettingsObserver: ObservableObject { | ||
private let tunnelManager: TunnelManager | ||
private var tunnelObserver: TunnelObserver? | ||
|
||
var value: MultihopState { | ||
willSet(newValue) { | ||
guard newValue != value else { return } | ||
|
||
objectWillChange.send() | ||
tunnelManager.updateSettings([.multihop(newValue)]) | ||
} | ||
} | ||
|
||
init(tunnelManager: TunnelManager) { | ||
self.tunnelManager = tunnelManager | ||
value = tunnelManager.settings.tunnelMultihopState | ||
|
||
tunnelObserver = TunnelBlockObserver(didUpdateTunnelSettings: { [weak self] _, newSettings in | ||
self?.value = newSettings.tunnelMultihopState | ||
}) | ||
} | ||
} |
24 changes: 24 additions & 0 deletions
24
ios/MullvadVPN/Coordinators/Settings/Multihop/MultihopTunnelSettingsViewModel.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
// | ||
// MultihopTunnelSettingsViewModel.swift | ||
// MullvadVPN | ||
// | ||
// Created by Jon Petersson on 2024-11-21. | ||
// Copyright © 2024 Mullvad VPN AB. All rights reserved. | ||
// | ||
|
||
import Foundation | ||
import MullvadSettings | ||
|
||
protocol MultihopTunnelSettingsObservable: ObservableObject { | ||
var value: MultihopState { get set } | ||
} | ||
|
||
class MockMultihopTunnelSettingsViewModel: MultihopTunnelSettingsObservable { | ||
@Published var value: MultihopState | ||
|
||
init(multihopState: MultihopState = .off) { | ||
value = multihopState | ||
} | ||
} | ||
|
||
class MultihopTunnelSettingsViewModel: MultihopTunnelSettingsObserver, MultihopTunnelSettingsObservable {} |
55 changes: 55 additions & 0 deletions
55
ios/MullvadVPN/Coordinators/Settings/Multihop/SettingsMultihopView.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
// | ||
// SettingsMultihopView.swift | ||
// MullvadVPN | ||
// | ||
// Created by Jon Petersson on 2024-11-14. | ||
// Copyright © 2024 Mullvad VPN AB. All rights reserved. | ||
// | ||
|
||
import Combine | ||
import SwiftUI | ||
|
||
struct SettingsMultihopView<VM>: View where VM: MultihopTunnelSettingsObservable { | ||
@StateObject var tunnelViewModel: VM | ||
|
||
private let viewModel = SettingsInfoViewModel( | ||
pages: [ | ||
SettingsInfoViewModelPage( | ||
body: NSLocalizedString( | ||
"SETTINGS_INFO_MULTIHOP", | ||
tableName: "Settings", | ||
value: """ | ||
Multihop routes your traffic into one WireGuard server and out another, making it \ | ||
harder to trace. This results in increased latency but increases anonymity online. | ||
""", | ||
comment: "" | ||
), | ||
image: .multihopIllustration | ||
) | ||
] | ||
) | ||
|
||
var body: some View { | ||
SettingsInfoContainerView { | ||
VStack(alignment: .leading, spacing: 8) { | ||
SettingsInfoView(viewModel: viewModel) | ||
|
||
SwitchRowView( | ||
enabled: $tunnelViewModel.value.isEnabled, | ||
text: NSLocalizedString( | ||
"SETTINGS_SWITCH_MULTIHOP", | ||
tableName: "Settings", | ||
value: "Enable", | ||
comment: "" | ||
) | ||
) | ||
.padding(.leading, UIMetrics.contentInsets.left) | ||
.padding(.trailing, UIMetrics.contentInsets.right) | ||
} | ||
} | ||
} | ||
} | ||
|
||
#Preview { | ||
SettingsMultihopView(tunnelViewModel: MockMultihopTunnelSettingsViewModel()) | ||
} |
Oops, something went wrong.