summaryrefslogtreecommitdiffhomepage
path: root/ios/MullvadVPN/View controllers/VPNSettings/CustomDNSViewController.swift
blob: 29bab0ec633ce8cad1abc27407edef2f425801a3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
//
//  CustomDNSViewController.swift
//  MullvadVPN
//
//  Created by Jon Petersson on 2023-11-09.
//  Copyright © 2025 Mullvad VPN AB. All rights reserved.
//

import MullvadSettings
import UIKit

class CustomDNSViewController: UITableViewController {
    private let interactor: VPNSettingsInteractor
    private var dataSource: CustomDNSDataSource?
    private let alertPresenter: AlertPresenter

    override var preferredStatusBarStyle: UIStatusBarStyle {
        .lightContent
    }

    init(interactor: VPNSettingsInteractor, alertPresenter: AlertPresenter) {
        self.interactor = interactor
        self.alertPresenter = alertPresenter

        super.init(style: .grouped)
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        tableView.setAccessibilityIdentifier(.dnsSettingsTableView)
        tableView.backgroundColor = .secondaryColor
        tableView.separatorColor = .secondaryColor
        tableView.rowHeight = UITableView.automaticDimension
        tableView.estimatedRowHeight = 60
        tableView.estimatedSectionHeaderHeight = tableView.estimatedRowHeight

        dataSource = CustomDNSDataSource(tableView: tableView)
        dataSource?.delegate = self

        navigationItem.title = NSLocalizedString("DNS settings", comment: "")
        if navigationItem.rightBarButtonItem != nil {
            navigationItem.leftBarButtonItem = editButtonItem
            navigationItem.leftBarButtonItem?.setAccessibilityIdentifier(.dnsSettingsEditButton)
        } else {
            navigationItem.rightBarButtonItem = editButtonItem
            navigationItem.rightBarButtonItem?.setAccessibilityIdentifier(.dnsSettingsEditButton)
        }

        interactor.tunnelSettingsDidChange = { [weak self] newSettings in
            self?.dataSource?.update(from: newSettings)
        }
        dataSource?.update(from: interactor.tunnelSettings)

        tableView.tableHeaderView = UIView(
            frame: CGRect(
                origin: .zero,
                size: CGSize(width: 0, height: UIMetrics.TableView.emptyHeaderHeight)
            ))
    }

    override func setEditing(_ editing: Bool, animated: Bool) {
        super.setEditing(editing, animated: animated)

        dataSource?.setEditing(editing, animated: animated)

        navigationItem.setHidesBackButton(editing, animated: animated)
        if navigationItem.rightBarButtonItem != editButtonItem {
            if #available(iOS 16.0, *) {
                navigationItem.rightBarButtonItem?.isHidden = editing
            } else {
                navigationItem.rightBarButtonItem?.isEnabled = !editing
            }
        }

        // Disable swipe to dismiss when editing
        isModalInPresentation = editing
    }

    private func showInfo(with message: NSAttributedString) {
        let presentation = AlertPresentation(
            id: "vpn-settings-content-blockers-alert",
            icon: .info,
            attributedMessage: message,
            buttons: [
                AlertAction(
                    title: NSLocalizedString("Got it!", comment: ""),
                    style: .default
                )
            ]
        )

        alertPresenter.showAlert(presentation: presentation, animated: true)
    }
}

extension CustomDNSViewController: @preconcurrency DNSSettingsDataSourceDelegate {
    func didChangeViewModel(_ viewModel: VPNSettingsViewModel) {
        interactor.updateSettings([.dnsSettings(viewModel.asDNSSettings())])
    }

    func showInfo(for item: VPNSettingsInfoButtonItem) {
        showInfo(
            with: NSAttributedString(
                markdownString: item.description,
                options: MarkdownStylingOptions(font: .preferredFont(forTextStyle: .body))
            ))
    }
}