diff options
| author | Bug Magnet <marco.nikic@mullvad.net> | 2024-10-25 14:17:52 +0200 |
|---|---|---|
| committer | Bug Magnet <marco.nikic@mullvad.net> | 2024-10-28 10:33:32 +0100 |
| commit | c2495e07cd1a2af9c6584d07e59af5acccb353fe (patch) | |
| tree | 94be143e1fda0616695c3cd3f4c6743e5094b16e | |
| parent | 28a284c523283b38c348f1798cfbae7f4a8dc54d (diff) | |
| download | mullvadvpn-dns-settings-swiftui-again.tar.xz mullvadvpn-dns-settings-swiftui-again.zip | |
Try the toggle all logicdns-settings-swiftui-again
4 files changed, 127 insertions, 48 deletions
diff --git a/ios/MullvadVPN.xcodeproj/project.pbxproj b/ios/MullvadVPN.xcodeproj/project.pbxproj index ae3a961c0e..270b56fe08 100644 --- a/ios/MullvadVPN.xcodeproj/project.pbxproj +++ b/ios/MullvadVPN.xcodeproj/project.pbxproj @@ -684,6 +684,7 @@ A90763C32B2858630045ADF0 /* Socks5Configuration.swift in Sources */ = {isa = PBXBuildFile; fileRef = A90763C22B2858630045ADF0 /* Socks5Configuration.swift */; }; A90763C52B2858B40045ADF0 /* AnyIPEndpoint+Socks5.swift in Sources */ = {isa = PBXBuildFile; fileRef = A90763C42B2858B40045ADF0 /* AnyIPEndpoint+Socks5.swift */; }; A90763C72B2858DC0045ADF0 /* CancellableChain.swift in Sources */ = {isa = PBXBuildFile; fileRef = A90763C62B2858DC0045ADF0 /* CancellableChain.swift */; }; + A90BCA3E2CCB96C200769DB1 /* CustomDNSViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A90BCA3D2CCB96C200769DB1 /* CustomDNSViewModel.swift */; }; A90C48672C36BC2600DCB94C /* EphemeralPeerReceiver.swift in Sources */ = {isa = PBXBuildFile; fileRef = A90C48662C36BC2600DCB94C /* EphemeralPeerReceiver.swift */; }; A90C48692C36BF3900DCB94C /* TunnelProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = A90C48682C36BF3900DCB94C /* TunnelProvider.swift */; }; A91614D12B108D1B00F416EB /* TransportLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = A91614D02B108D1B00F416EB /* TransportLayer.swift */; }; @@ -2014,6 +2015,7 @@ A90763C22B2858630045ADF0 /* Socks5Configuration.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Socks5Configuration.swift; sourceTree = "<group>"; }; A90763C42B2858B40045ADF0 /* AnyIPEndpoint+Socks5.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "AnyIPEndpoint+Socks5.swift"; sourceTree = "<group>"; }; A90763C62B2858DC0045ADF0 /* CancellableChain.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CancellableChain.swift; sourceTree = "<group>"; }; + A90BCA3D2CCB96C200769DB1 /* CustomDNSViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomDNSViewModel.swift; sourceTree = "<group>"; }; A90C48662C36BC2600DCB94C /* EphemeralPeerReceiver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EphemeralPeerReceiver.swift; sourceTree = "<group>"; }; A90C48682C36BF3900DCB94C /* TunnelProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TunnelProvider.swift; sourceTree = "<group>"; }; A91614D02B108D1B00F416EB /* TransportLayer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TransportLayer.swift; sourceTree = "<group>"; }; @@ -2860,6 +2862,7 @@ A9EBCE052CC2937F00146599 /* CustomDNSSwiftUIViewController.swift */, A9EBCE072CC2945100146599 /* CustomDNSSwiftUIView.swift */, A9EBCE0B2CC2B5DF00146599 /* ToggleStyle.swift */, + A90BCA3D2CCB96C200769DB1 /* CustomDNSViewModel.swift */, ); path = VPNSettings; sourceTree = "<group>"; @@ -5938,6 +5941,7 @@ 7A6F2FAF2AFE36E7006D0856 /* VPNSettingsInfoButtonItem.swift in Sources */, 7A6389DD2B7E3BD6008E77E1 /* CustomListDataSourceConfiguration.swift in Sources */, A9EBCE0A2CC2AB2400146599 /* UIColor+Color.swift in Sources */, + A90BCA3E2CCB96C200769DB1 /* CustomDNSViewModel.swift in Sources */, 5827B0BF2B14B37D00CCBBA1 /* Publisher+PreviousValue.swift in Sources */, 7A9CCCB62A96302800DD6A34 /* OutOfTimeCoordinator.swift in Sources */, 5827B0AA2B0F4C9100CCBBA1 /* EditAccessMethodViewControllerDelegate.swift in Sources */, diff --git a/ios/MullvadVPN/View controllers/VPNSettings/CustomDNSSwiftUIView.swift b/ios/MullvadVPN/View controllers/VPNSettings/CustomDNSSwiftUIView.swift index 81eb45c536..3326fdcdc6 100644 --- a/ios/MullvadVPN/View controllers/VPNSettings/CustomDNSSwiftUIView.swift +++ b/ios/MullvadVPN/View controllers/VPNSettings/CustomDNSSwiftUIView.swift @@ -6,54 +6,9 @@ // Copyright © 2024 Mullvad VPN AB. All rights reserved. // -import MullvadSettings +import Foundation import SwiftUI -class CustomDNSViewModel: ObservableObject { - @Published var blockAll = false - @Published var blockAdvertising = false - @Published var blockTracking = false - @Published var blockMalware = false - @Published var blockAdultContent = false - @Published var blockGambling = false - @Published var blockSocialMedia = false - @Published var enableCustomDNS = false - @Published var customDNSDomains: [DNSServerEntry] = [] - - @Published var isEditing = false - @Published var isExpanded = false - - lazy var contentBlockers: [DNSRowViewModel] = [ - DNSRowViewModel(name: "All", isEnabled: blockAll), - DNSRowViewModel(name: DNSBlockingOptions.blockAdvertising.name, isEnabled: blockAdvertising), - DNSRowViewModel(name: DNSBlockingOptions.blockTracking.name, isEnabled: blockTracking), - DNSRowViewModel( - name: DNSBlockingOptions.blockMalware.name, - isEnabled: blockMalware, - action: showMalwareInformation - ), - DNSRowViewModel(name: DNSBlockingOptions.blockAdultContent.name, isEnabled: blockAdultContent), - DNSRowViewModel(name: DNSBlockingOptions.blockGambling.name, isEnabled: blockGambling), - DNSRowViewModel(name: DNSBlockingOptions.blockSocialMedia.name, isEnabled: blockSocialMedia), - ] - - func showMalwareInformation() { - print("show a popup here") - } -} - -class DNSRowViewModel: ObservableObject, Identifiable { - let name: String - @Published var isEnabled: Bool - let infoButtonAction: (() -> Void)? - - init(name: String, isEnabled: Bool, action: (() -> Void)? = nil) { - self.name = name - self.isEnabled = isEnabled - self.infoButtonAction = action - } -} - struct CustomDNSSwiftUIView: View { @ObservedObject var viewModel: CustomDNSViewModel @@ -61,7 +16,7 @@ struct CustomDNSSwiftUIView: View { GeometryReader { _ in ScrollView { Section { - DisclosureGroup("DNS content blockers", isExpanded: $viewModel.isExpanded) { + DisclosureGroup(viewModel.headerTitle, isExpanded: $viewModel.isExpanded) { ForEach(viewModel.contentBlockers) { singleSetting in DNSItemRow(viewModel: singleSetting) .background(Color.Cell.Background.normal) diff --git a/ios/MullvadVPN/View controllers/VPNSettings/CustomDNSSwiftUIViewController.swift b/ios/MullvadVPN/View controllers/VPNSettings/CustomDNSSwiftUIViewController.swift index 2e5e60f2c5..6c4cb4af1c 100644 --- a/ios/MullvadVPN/View controllers/VPNSettings/CustomDNSSwiftUIViewController.swift +++ b/ios/MullvadVPN/View controllers/VPNSettings/CustomDNSSwiftUIViewController.swift @@ -24,7 +24,7 @@ class CustomDNSSwiftUIViewController: UIViewController { } override func viewDidLoad() { - let rootView = CustomDNSSwiftUIView(viewModel: CustomDNSViewModel()) + let rootView = CustomDNSSwiftUIView(viewModel: self.interactor.tunnelSettings.dnsSettings.viewModel()) let hostingController = UIHostingController(rootView: rootView) diff --git a/ios/MullvadVPN/View controllers/VPNSettings/CustomDNSViewModel.swift b/ios/MullvadVPN/View controllers/VPNSettings/CustomDNSViewModel.swift new file mode 100644 index 0000000000..0691e8c076 --- /dev/null +++ b/ios/MullvadVPN/View controllers/VPNSettings/CustomDNSViewModel.swift @@ -0,0 +1,120 @@ +// +// CustomDNSViewModel.swift +// MullvadVPN +// +// Created by Marco Nikic on 2024-10-25. +// Copyright © 2024 Mullvad VPN AB. All rights reserved. +// + +import Foundation +import MullvadSettings +import SwiftUI +import Combine + +class CustomDNSViewModel: ObservableObject { + @Published var blockAll = false + @Published var blockAdvertising = false + @Published var blockTracking = false + @Published var blockMalware = false + @Published var blockAdultContent = false + @Published var blockGambling = false + @Published var blockSocialMedia = false + + @Published var isEditing = false + @Published var isExpanded = false + var bucket: AnyCancellable? + + var headerTitle: String { + "DNS content blockers \(enabledSettingsCount())" + } + + func enabledSettingsCount() -> String { + let enabledSettingsCount = selfFields.filter { $0 == true }.count + return enabledSettingsCount == 0 ? "" : "(\(enabledSettingsCount))" + } + + lazy var selfFields: [Bool] = [ + blockAdvertising, + blockTracking, + blockMalware, + blockAdultContent, + blockGambling, + blockSocialMedia, + ] + + lazy var contentBlockers: [DNSRowViewModel] = [ + DNSRowViewModel(name: "All", isEnabled: blockAll, action: toggleAll), + DNSRowViewModel(name: DNSBlockingOptions.blockAdvertising.name, isEnabled: blockAdvertising), + DNSRowViewModel(name: DNSBlockingOptions.blockTracking.name, isEnabled: blockTracking), + DNSRowViewModel( + name: DNSBlockingOptions.blockMalware.name, + isEnabled: blockMalware, + action: showMalwareInformation + ), + DNSRowViewModel(name: DNSBlockingOptions.blockAdultContent.name, isEnabled: blockAdultContent), + DNSRowViewModel(name: DNSBlockingOptions.blockGambling.name, isEnabled: blockGambling), + DNSRowViewModel(name: DNSBlockingOptions.blockSocialMedia.name, isEnabled: blockSocialMedia), + ] + + func toggleAll() { + blockAll.toggle() + contentBlockers.forEach { $0.isEnabled = blockAll } + contentBlockers.forEach { print($0) } + } + + func showMalwareInformation() { + print("show a popup here") + } + + init( + blockAdvertising: Bool = false, + blockTracking: Bool = false, + blockMalware: Bool = false, + blockAdultContent: Bool = false, + blockGambling: Bool = false, + blockSocialMedia: Bool = false + ) { + self.blockAll = false + self.blockAdvertising = blockAdvertising + self.blockTracking = blockTracking + self.blockMalware = blockMalware + self.blockAdultContent = blockAdultContent + self.blockGambling = blockGambling + self.blockSocialMedia = blockSocialMedia + + contentBlockers.forEach { print($0) } + + bucket = $blockAll.sink { newvalue in + self.contentBlockers.forEach { $0.isEnabled = newvalue } + } + } +} + +extension DNSSettings { + func viewModel() -> CustomDNSViewModel { + CustomDNSViewModel( + blockAdvertising: blockingOptions.contains(.blockAdvertising), + blockTracking: blockingOptions.contains(.blockTracking), + blockMalware: blockingOptions.contains(.blockMalware), + blockAdultContent: blockingOptions.contains(.blockAdultContent), + blockGambling: blockingOptions.contains(.blockGambling), + blockSocialMedia: blockingOptions.contains(.blockSocialMedia) + ) + } +} + +class DNSRowViewModel: ObservableObject, Identifiable, CustomDebugStringConvertible { + let name: String + @Published var isEnabled: Bool + let infoButtonAction: (() -> Void)? + + init(name: String, isEnabled: Bool, action: (() -> Void)? = nil) { + self.name = name + self.isEnabled = isEnabled + self.infoButtonAction = action + } + + var debugDescription: String { + "\(Unmanaged.passUnretained(self).toOpaque()), name: \(name) isEnabled: \(isEnabled)" + } +} |
