Skip to content

Commit 4b06a33

Browse files
mojganiirablador
authored andcommitted
Add FeaturesIndicatoresView
1 parent 37e90ed commit 4b06a33

16 files changed

+484
-36
lines changed

ios/MullvadSettings/IPOverrideRepository.swift

+11-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
// Copyright © 2024 Mullvad VPN AB. All rights reserved.
77
//
88

9-
import Foundation
9+
import Combine
1010
import MullvadLogging
1111

1212
public protocol IPOverrideRepositoryProtocol {
@@ -17,10 +17,17 @@ public protocol IPOverrideRepositoryProtocol {
1717
}
1818

1919
public class IPOverrideRepository: IPOverrideRepositoryProtocol {
20+
private let overridesSubject: CurrentValueSubject<[IPOverride], Never> = .init([])
21+
public var overridesPublisher: AnyPublisher<[IPOverride], Never> {
22+
overridesSubject.eraseToAnyPublisher()
23+
}
24+
2025
private let logger = Logger(label: "IPOverrideRepository")
2126
private let readWriteLock = NSLock()
2227

23-
public init() {}
28+
public init() {
29+
overridesSubject.send(fetchAll())
30+
}
2431

2532
public func add(_ overrides: [IPOverride]) {
2633
var storedOverrides = fetchAll()
@@ -58,6 +65,7 @@ public class IPOverrideRepository: IPOverrideRepositoryProtocol {
5865
do {
5966
try readWriteLock.withLock {
6067
try SettingsManager.store.delete(key: .ipOverrides)
68+
overridesSubject.send([])
6169
}
6270
} catch {
6371
logger.error("Could not delete all overrides. \nError: \(error)")
@@ -85,6 +93,7 @@ public class IPOverrideRepository: IPOverrideRepositoryProtocol {
8593

8694
try readWriteLock.withLock {
8795
try SettingsManager.store.write(data, for: .ipOverrides)
96+
overridesSubject.send(overrides)
8897
}
8998
}
9099

ios/MullvadSettings/WireGuardObfuscationSettings.swift

+4
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,10 @@ public enum WireGuardObfuscationState: Codable {
4646
self = .off
4747
}
4848
}
49+
50+
public var isEnabled: Bool {
51+
[.udpOverTcp, .shadowsocks].contains(self)
52+
}
4953
}
5054

5155
public enum WireGuardObfuscationUdpOverTcpPort: Codable, Equatable, CustomStringConvertible {

ios/MullvadVPN.xcodeproj/project.pbxproj

+40-5
Original file line numberDiff line numberDiff line change
@@ -659,10 +659,10 @@
659659
7AF9BE902A39F26000DBFEDB /* Collection+Sorting.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AF9BE8F2A39F26000DBFEDB /* Collection+Sorting.swift */; };
660660
7AF9BE952A40461100DBFEDB /* RelayFilterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AF9BE942A40461100DBFEDB /* RelayFilterView.swift */; };
661661
7AF9BE972A41C71F00DBFEDB /* ChipViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AF9BE962A41C71F00DBFEDB /* ChipViewCell.swift */; };
662-
7AFBE38B2D09AAFF002335FC /* SinglehopPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AFBE38A2D09AAFF002335FC /* SinglehopPicker.swift */; };
663-
7AFBE38D2D09AB2E002335FC /* MultihopPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AFBE38C2D09AB2E002335FC /* MultihopPicker.swift */; };
664662
7AFBE3872D084C9D002335FC /* ActivityIndicator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AFBE3862D084C96002335FC /* ActivityIndicator.swift */; };
665663
7AFBE3892D089163002335FC /* FI_TunnelViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AFBE3882D08915D002335FC /* FI_TunnelViewController.swift */; };
664+
7AFBE38B2D09AAFF002335FC /* SinglehopPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AFBE38A2D09AAFF002335FC /* SinglehopPicker.swift */; };
665+
7AFBE38D2D09AB2E002335FC /* MultihopPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AFBE38C2D09AB2E002335FC /* MultihopPicker.swift */; };
666666
850201DB2B503D7700EF8C96 /* RelayTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 850201DA2B503D7700EF8C96 /* RelayTests.swift */; };
667667
850201DD2B503D8C00EF8C96 /* SelectLocationPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 850201DC2B503D8C00EF8C96 /* SelectLocationPage.swift */; };
668668
850201DF2B5040A500EF8C96 /* TunnelControlPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 850201DE2B5040A500EF8C96 /* TunnelControlPage.swift */; };
@@ -997,7 +997,14 @@
997997
F0ADC3722CD3AD1600A1AD97 /* ChipCollectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F0ADC3712CD3AD1600A1AD97 /* ChipCollectionView.swift */; };
998998
F0ADC3742CD3C47400A1AD97 /* ChipFlowLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = F0ADC3732CD3C47400A1AD97 /* ChipFlowLayout.swift */; };
999999
F0ADF1CD2CFDFF3100299F09 /* StringConversionError.swift in Sources */ = {isa = PBXBuildFile; fileRef = F0ADF1CC2CFDFF3100299F09 /* StringConversionError.swift */; };
1000+
F0ADF1D12D01B55C00299F09 /* ChipModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F0ADF1D02D01B55C00299F09 /* ChipModel.swift */; };
1001+
F0ADF1D32D01B6B400299F09 /* FeatureIndicatorsViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = F0ADF1D22D01B6B400299F09 /* FeatureIndicatorsViewModel.swift */; };
1002+
F0ADF1D52D01DCFD00299F09 /* ChipView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F0ADF1D42D01DCFD00299F09 /* ChipView.swift */; };
10001003
F0B0E6972AFE6E7E001DC66B /* XCTest+Async.swift in Sources */ = {isa = PBXBuildFile; fileRef = F0B0E6962AFE6E7E001DC66B /* XCTest+Async.swift */; };
1004+
F0B495762D02025200CFEC2A /* ChipContainerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F0B495752D02025200CFEC2A /* ChipContainerView.swift */; };
1005+
F0B495782D02038B00CFEC2A /* ChipViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = F0B495772D02038B00CFEC2A /* ChipViewModelProtocol.swift */; };
1006+
F0B4957A2D02F49200CFEC2A /* ChipFeatures.swift in Sources */ = {isa = PBXBuildFile; fileRef = F0B495792D02F41F00CFEC2A /* ChipFeatures.swift */; };
1007+
F0B4957C2D03154200CFEC2A /* FeatureIndicatorsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F0B4957B2D03154200CFEC2A /* FeatureIndicatorsView.swift */; };
10011008
F0B894EF2BF751C500817A42 /* RelayWithLocation.swift in Sources */ = {isa = PBXBuildFile; fileRef = F0B894EE2BF751C500817A42 /* RelayWithLocation.swift */; };
10021009
F0B894F12BF751E300817A42 /* RelayWithDistance.swift in Sources */ = {isa = PBXBuildFile; fileRef = F0B894F02BF751E300817A42 /* RelayWithDistance.swift */; };
10031010
F0B894F32BF7526700817A42 /* RelaySelector+Wireguard.swift in Sources */ = {isa = PBXBuildFile; fileRef = F0B894F22BF7526700817A42 /* RelaySelector+Wireguard.swift */; };
@@ -2020,10 +2027,10 @@
20202027
7AF9BE8F2A39F26000DBFEDB /* Collection+Sorting.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Collection+Sorting.swift"; sourceTree = "<group>"; };
20212028
7AF9BE942A40461100DBFEDB /* RelayFilterView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RelayFilterView.swift; sourceTree = "<group>"; };
20222029
7AF9BE962A41C71F00DBFEDB /* ChipViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChipViewCell.swift; sourceTree = "<group>"; };
2023-
7AFBE38A2D09AAFF002335FC /* SinglehopPicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SinglehopPicker.swift; sourceTree = "<group>"; };
2024-
7AFBE38C2D09AB2E002335FC /* MultihopPicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultihopPicker.swift; sourceTree = "<group>"; };
20252030
7AFBE3862D084C96002335FC /* ActivityIndicator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ActivityIndicator.swift; sourceTree = "<group>"; };
20262031
7AFBE3882D08915D002335FC /* FI_TunnelViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FI_TunnelViewController.swift; sourceTree = "<group>"; };
2032+
7AFBE38A2D09AAFF002335FC /* SinglehopPicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SinglehopPicker.swift; sourceTree = "<group>"; };
2033+
7AFBE38C2D09AB2E002335FC /* MultihopPicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultihopPicker.swift; sourceTree = "<group>"; };
20272034
85006A8E2B73EF67004AD8FB /* MullvadVPNUITestsSmoke.xctestplan */ = {isa = PBXFileReference; lastKnownFileType = text; path = MullvadVPNUITestsSmoke.xctestplan; sourceTree = "<group>"; };
20282035
850201DA2B503D7700EF8C96 /* RelayTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RelayTests.swift; sourceTree = "<group>"; };
20292036
850201DC2B503D8C00EF8C96 /* SelectLocationPage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectLocationPage.swift; sourceTree = "<group>"; };
@@ -2236,7 +2243,14 @@
22362243
F0ADC3712CD3AD1600A1AD97 /* ChipCollectionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChipCollectionView.swift; sourceTree = "<group>"; };
22372244
F0ADC3732CD3C47400A1AD97 /* ChipFlowLayout.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChipFlowLayout.swift; sourceTree = "<group>"; };
22382245
F0ADF1CC2CFDFF3100299F09 /* StringConversionError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StringConversionError.swift; sourceTree = "<group>"; };
2246+
F0ADF1D02D01B55C00299F09 /* ChipModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChipModel.swift; sourceTree = "<group>"; };
2247+
F0ADF1D22D01B6B400299F09 /* FeatureIndicatorsViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeatureIndicatorsViewModel.swift; sourceTree = "<group>"; };
2248+
F0ADF1D42D01DCFD00299F09 /* ChipView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChipView.swift; sourceTree = "<group>"; };
22392249
F0B0E6962AFE6E7E001DC66B /* XCTest+Async.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "XCTest+Async.swift"; sourceTree = "<group>"; };
2250+
F0B495752D02025200CFEC2A /* ChipContainerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChipContainerView.swift; sourceTree = "<group>"; };
2251+
F0B495772D02038B00CFEC2A /* ChipViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChipViewModelProtocol.swift; sourceTree = "<group>"; };
2252+
F0B495792D02F41F00CFEC2A /* ChipFeatures.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChipFeatures.swift; sourceTree = "<group>"; };
2253+
F0B4957B2D03154200CFEC2A /* FeatureIndicatorsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FeatureIndicatorsView.swift; sourceTree = "<group>"; };
22402254
F0B894EE2BF751C500817A42 /* RelayWithLocation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RelayWithLocation.swift; sourceTree = "<group>"; };
22412255
F0B894F02BF751E300817A42 /* RelayWithDistance.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RelayWithDistance.swift; sourceTree = "<group>"; };
22422256
F0B894F22BF7526700817A42 /* RelaySelector+Wireguard.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "RelaySelector+Wireguard.swift"; sourceTree = "<group>"; };
@@ -3928,7 +3942,6 @@
39283942
7A0EAE982D01B29E00D3EB8B /* Recovered References */ = {
39293943
isa = PBXGroup;
39303944
children = (
3931-
7AA1309C2D0072F900640DF9 /* View+Size.swift */,
39323945
);
39333946
name = "Recovered References";
39343947
sourceTree = "<group>";
@@ -4067,9 +4080,13 @@
40674080
7AA130972CFF364F00640DF9 /* FeatureIndicators */ = {
40684081
isa = PBXGroup;
40694082
children = (
4083+
F0ADF1CF2D01B50B00299F09 /* ChipView */,
40704084
7AFBE3862D084C96002335FC /* ActivityIndicator.swift */,
4085+
F0B495792D02F41F00CFEC2A /* ChipFeatures.swift */,
40714086
7AA130982CFF365A00640DF9 /* ConnectionView.swift */,
40724087
7A0EAEA32D06DF8200D3EB8B /* ConnectionViewViewModel.swift */,
4088+
F0B4957B2D03154200CFEC2A /* FeatureIndicatorsView.swift */,
4089+
F0ADF1D22D01B6B400299F09 /* FeatureIndicatorsViewModel.swift */,
40734090
7AFBE3882D08915D002335FC /* FI_TunnelViewController.swift */,
40744091
);
40754092
path = FeatureIndicators;
@@ -4392,6 +4409,17 @@
43924409
path = MullvadTypes;
43934410
sourceTree = "<group>";
43944411
};
4412+
F0ADF1CF2D01B50B00299F09 /* ChipView */ = {
4413+
isa = PBXGroup;
4414+
children = (
4415+
F0B495752D02025200CFEC2A /* ChipContainerView.swift */,
4416+
F0ADF1D02D01B55C00299F09 /* ChipModel.swift */,
4417+
F0ADF1D42D01DCFD00299F09 /* ChipView.swift */,
4418+
F0B495772D02038B00CFEC2A /* ChipViewModelProtocol.swift */,
4419+
);
4420+
path = ChipView;
4421+
sourceTree = "<group>";
4422+
};
43954423
F0DC779F2B2222D20087F09D /* Relay */ = {
43964424
isa = PBXGroup;
43974425
children = (
@@ -5917,6 +5945,7 @@
59175945
5878A27129091CF20096FC88 /* AccountInteractor.swift in Sources */,
59185946
7AF9BE882A30C62100DBFEDB /* SelectableSettingsCell.swift in Sources */,
59195947
58CCA010224249A1004F3011 /* TunnelViewController.swift in Sources */,
5948+
F0B495782D02038B00CFEC2A /* ChipViewModelProtocol.swift in Sources */,
59205949
58CEB30A2AFD584700E6E088 /* CustomCellDisclosureHandling.swift in Sources */,
59215950
58B26E22294351EA00D5980C /* InAppNotificationProvider.swift in Sources */,
59225951
5893716A28817A45004EE76C /* DeviceManagementViewController.swift in Sources */,
@@ -5991,6 +6020,7 @@
59916020
58293FB3251241B4005D0BB5 /* CustomTextView.swift in Sources */,
59926021
586A950E290125F3007BAF2B /* ProductsRequestOperation.swift in Sources */,
59936022
7AF9BE902A39F26000DBFEDB /* Collection+Sorting.swift in Sources */,
6023+
F0B495762D02025200CFEC2A /* ChipContainerView.swift in Sources */,
59946024
58F19E35228C15BA00C7710B /* SpinnerActivityIndicatorView.swift in Sources */,
59956025
7A0EAE9A2D01B41500D3EB8B /* MainButtonStyle.swift in Sources */,
59966026
58CEB3022AFD365600E6E088 /* SwitchCellContentConfiguration.swift in Sources */,
@@ -6100,6 +6130,7 @@
61006130
588D7EDE2AF3A585005DF40A /* ListAccessMethodItem.swift in Sources */,
61016131
5827B0B02B0F4CCD00CCBBA1 /* ListAccessMethodViewControllerDelegate.swift in Sources */,
61026132
588D7EE02AF3A595005DF40A /* ListAccessMethodInteractor.swift in Sources */,
6133+
F0B4957A2D02F49200CFEC2A /* ChipFeatures.swift in Sources */,
61036134
58607A4D2947287800BC467D /* AccountExpiryInAppNotificationProvider.swift in Sources */,
61046135
7A8A18FD2CE4BE8D000BCB5B /* CustomToggleStyle.swift in Sources */,
61056136
58C8191829FAA2C400DEB1B4 /* NotificationConfiguration.swift in Sources */,
@@ -6134,8 +6165,10 @@
61346165
586C0D782B039CC000E7CDD7 /* AccessMethodProtocolPicker.swift in Sources */,
61356166
58677710290975E9006F721F /* SettingsInteractorFactory.swift in Sources */,
61366167
7A9CCCC02A96302800DD6A34 /* ProfileVoucherCoordinator.swift in Sources */,
6168+
F0B4957C2D03154200CFEC2A /* FeatureIndicatorsView.swift in Sources */,
61376169
7A9CCCBC2A96302800DD6A34 /* ChangeLogCoordinator.swift in Sources */,
61386170
58B26E282943527300D5980C /* SystemNotificationProvider.swift in Sources */,
6171+
F0ADF1D52D01DCFD00299F09 /* ChipView.swift in Sources */,
61396172
586C0D932B03D90700E7CDD7 /* ShadowsocksItemIdentifier.swift in Sources */,
61406173
58EFC7712AFB45E500E9F4CB /* SettingsChildCoordinator.swift in Sources */,
61416174
7A8A19102CEE391B000BCB5B /* RowSeparator.swift in Sources */,
@@ -6179,6 +6212,7 @@
61796212
7A9CCCC22A96302800DD6A34 /* SafariCoordinator.swift in Sources */,
61806213
58CEB3082AFD484100E6E088 /* BasicCell.swift in Sources */,
61816214
7A5869C12B57D21A00640D27 /* IPOverrideStatusView.swift in Sources */,
6215+
F0ADF1D32D01B6B400299F09 /* FeatureIndicatorsViewModel.swift in Sources */,
61826216
58CEB2F52AFD0BB500E6E088 /* TextCellContentConfiguration.swift in Sources */,
61836217
58E20771274672CA00DE5D77 /* LaunchViewController.swift in Sources */,
61846218
F0E8CC032A4C753B007ED3B4 /* WelcomeViewController.swift in Sources */,
@@ -6198,6 +6232,7 @@
61986232
A99E5EE02B7628150033F241 /* ProblemReportViewModel.swift in Sources */,
61996233
58FD5BF024238EB300112C88 /* SKProduct+Formatting.swift in Sources */,
62006234
58B43C1925F77DB60002C8C3 /* TunnelControlView.swift in Sources */,
6235+
F0ADF1D12D01B55C00299F09 /* ChipModel.swift in Sources */,
62016236
F09A297B2A9F8A9B00EA3B6F /* LogoutDialogueView.swift in Sources */,
62026237
58CEB2FB2AFD13E600E6E088 /* UIListContentConfiguration+Extensions.swift in Sources */,
62036238
5811DE50239014550011EB53 /* NEVPNStatus+Debug.swift in Sources */,

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

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
{
2+
"originHash" : "c15149b2d59d9e9c72375f65339c04f41a19943e1117e682df27fc9f943fdc56",
23
"pins" : [
34
{
45
"identity" : "swift-log",
@@ -18,5 +19,5 @@
1819
}
1920
}
2021
],
21-
"version" : 2
22+
"version" : 3
2223
}

ios/MullvadVPN/Extensions/View+Size.swift

+2-1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ private struct ViewSizeKey: PreferenceKey {
2828
static var defaultValue: CGSize = .zero
2929

3030
static func reduce(value: inout CGSize, nextValue: () -> CGSize) {
31-
value = nextValue()
31+
value = CGSize(width: value.width + nextValue().width, height: value.height + nextValue().height)
32+
// value = nextValue()
3233
}
3334
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
//
2+
// ChipFeatures.swift
3+
// MullvadVPN
4+
//
5+
// Created by Mojgan on 2024-12-06.
6+
// Copyright © 2024 Mullvad VPN AB. All rights reserved.
7+
//
8+
import Foundation
9+
import MullvadSettings
10+
import SwiftUI
11+
12+
protocol ChipFeature {
13+
var isEnabled: Bool { get }
14+
var name: LocalizedStringKey { get }
15+
}
16+
17+
struct DaitaFeature: ChipFeature {
18+
let settings: LatestTunnelSettings
19+
20+
var isEnabled: Bool {
21+
settings.daita.daitaState.isEnabled
22+
}
23+
24+
var name: LocalizedStringKey {
25+
LocalizedStringKey("DAITA")
26+
}
27+
}
28+
29+
struct QuantumResistanceFeature: ChipFeature {
30+
let settings: LatestTunnelSettings
31+
var isEnabled: Bool {
32+
settings.tunnelQuantumResistance.isEnabled
33+
}
34+
35+
var name: LocalizedStringKey {
36+
LocalizedStringKey("Quantum resistance")
37+
}
38+
}
39+
40+
struct MultihopFeature: ChipFeature {
41+
let settings: LatestTunnelSettings
42+
var isEnabled: Bool {
43+
settings.tunnelMultihopState.isEnabled
44+
}
45+
46+
var name: LocalizedStringKey {
47+
LocalizedStringKey("Multihop")
48+
}
49+
}
50+
51+
struct ObfuscationFeature: ChipFeature {
52+
let settings: LatestTunnelSettings
53+
54+
var isEnabled: Bool {
55+
settings.wireGuardObfuscation.state.isEnabled
56+
}
57+
58+
var name: LocalizedStringKey {
59+
LocalizedStringKey("Obfuscation")
60+
}
61+
}
62+
63+
struct DNSFeature: ChipFeature {
64+
let settings: LatestTunnelSettings
65+
66+
var isEnabled: Bool {
67+
settings.dnsSettings.enableCustomDNS || !settings.dnsSettings.blockingOptions.isEmpty
68+
}
69+
70+
var name: LocalizedStringKey {
71+
if !settings.dnsSettings.blockingOptions.isEmpty {
72+
return LocalizedStringKey("DNS content blockers")
73+
}
74+
return LocalizedStringKey("Custom DNS")
75+
}
76+
}
77+
78+
struct IPOverrideFeature: ChipFeature {
79+
let overrides: [IPOverride]
80+
81+
var isEnabled: Bool {
82+
!overrides.isEmpty
83+
}
84+
85+
var name: LocalizedStringKey {
86+
LocalizedStringKey("Server IP override")
87+
}
88+
}

0 commit comments

Comments
 (0)