From 31f455a894278c9a4dc1d4aeaed8a2452a183606 Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Mon, 4 Nov 2024 16:34:25 +0100 Subject: [PATCH 01/27] Add cell for proxy-settings to Advanced Settings (#2382) --- .../Settings/AdvancedViewController.swift | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/deltachat-ios/Controller/Settings/AdvancedViewController.swift b/deltachat-ios/Controller/Settings/AdvancedViewController.swift index 1553f1c74..4d0ac50fa 100644 --- a/deltachat-ios/Controller/Settings/AdvancedViewController.swift +++ b/deltachat-ios/Controller/Settings/AdvancedViewController.swift @@ -19,6 +19,7 @@ internal final class AdvancedViewController: UITableViewController { case videoChat case viewLog case accountSettings + case proxySettings } private var dcContext: DcContext @@ -75,6 +76,14 @@ internal final class AdvancedViewController: UITableViewController { return cell }() + private lazy var proxySettingsCell: UITableViewCell = { + let cell = UITableViewCell(style: .default, reuseIdentifier: nil) + cell.textLabel?.text = String.localized("proxy_settings") + cell.accessoryType = .disclosureIndicator + cell.tag = CellTags.proxySettings.rawValue + return cell + }() + lazy var sentboxWatchCell: SwitchCell = { return SwitchCell( textLabel: String.localized("pref_watch_sent_folder"), @@ -242,7 +251,7 @@ internal final class AdvancedViewController: UITableViewController { let serverSection = SectionConfigs( headerTitle: String.localized("pref_server"), footerTitle: nil, - cells: [accountSettingsCell]) + cells: [accountSettingsCell, proxySettingsCell]) return [viewLogSection, experimentalSection, encryptionSection, serverSection] } else { let appAccessSection = SectionConfigs( @@ -256,7 +265,7 @@ internal final class AdvancedViewController: UITableViewController { let serverSection = SectionConfigs( headerTitle: String.localized("pref_server"), footerTitle: String.localized("pref_only_fetch_mvbox_explain"), - cells: [accountSettingsCell, sentboxWatchCell, sendCopyToSelfCell, mvboxMoveCell, onlyFetchMvboxCell]) + cells: [accountSettingsCell, sentboxWatchCell, sendCopyToSelfCell, mvboxMoveCell, onlyFetchMvboxCell, proxySettingsCell]) return [viewLogSection, experimentalSection, appAccessSection, encryptionSection, serverSection] } }() @@ -320,6 +329,9 @@ internal final class AdvancedViewController: UITableViewController { Utils.authenticateDeviceOwner(reason: String.localized("pref_password_and_account_settings")) { [weak self] in self?.showAccountSettingsController() } + case .proxySettings: + //TODO: Show ProxySettingsViewController + break case .defaultTagValue: break } From a4946b41a57cb764d4f9baa1aee587c4ea8bf4bd Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Tue, 5 Nov 2024 13:26:31 +0100 Subject: [PATCH 02/27] Get proxies from core (hopefully, #2382) --- deltachat-ios/DC/DcContext.swift | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/deltachat-ios/DC/DcContext.swift b/deltachat-ios/DC/DcContext.swift index 7efe6548d..86345280a 100644 --- a/deltachat-ios/DC/DcContext.swift +++ b/deltachat-ios/DC/DcContext.swift @@ -741,4 +741,23 @@ public class DcContext { public var isChatmail: Bool { return getConfigInt("is_chatmail") == 1 } + + public var isProxyEnabled: Bool { + get { return getConfigBool("proxy_enabled") } + set { setConfigBool("proxy_enabled", newValue) } + } + + public func getProxies() -> [String] { + guard let proxyURLStrings = getConfig("proxy_url"), + let proxies = proxyURLStrings.split(separator: "\n") as? [String] + else { return [] } + + return proxies + } + + public func setProxies(proxyURLs: [String]) { + let allProxies = proxyURLs.joined(separator: "\n") + + setConfig("proxy_url", allProxies) + } } From 7459f022991121e667e6df86b1b814c3c995e990 Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Tue, 5 Nov 2024 13:26:56 +0100 Subject: [PATCH 03/27] [WIP] Sketch ProxySettings-screen (#2382) --- deltachat-ios.xcodeproj/project.pbxproj | 10 +- .../Settings/AdvancedViewController.swift | 11 +- .../Proxy/ProxySettingsViewController.swift | 155 ++++++++++++++++++ .../Settings/Proxy/ProxyTableViewCell.swift | 9 + deltachat-ios/Helper/Utils.swift | 5 + deltachat-ios/View/SwitchCell.swift | 1 + 6 files changed, 187 insertions(+), 4 deletions(-) create mode 100644 deltachat-ios/Controller/Settings/Proxy/ProxySettingsViewController.swift create mode 100644 deltachat-ios/Controller/Settings/Proxy/ProxyTableViewCell.swift diff --git a/deltachat-ios.xcodeproj/project.pbxproj b/deltachat-ios.xcodeproj/project.pbxproj index 091ae0d7c..7daad59d9 100644 --- a/deltachat-ios.xcodeproj/project.pbxproj +++ b/deltachat-ios.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 54; + objectVersion = 70; objects = { /* Begin PBXBuildFile section */ @@ -615,6 +615,10 @@ E23C80FA36453692862D4A90 /* Pods_deltachat_iosTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_deltachat_iosTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ +/* Begin PBXFileSystemSynchronizedRootGroup section */ + D8F809C52CD93EA1002CAAC2 /* Proxy */ = {isa = PBXFileSystemSynchronizedRootGroup; explicitFileTypes = {}; explicitFolders = (); path = Proxy; sourceTree = ""; }; +/* End PBXFileSystemSynchronizedRootGroup section */ + /* Begin PBXFrameworksBuildPhase section */ 30E8F20D2447285600CE2C90 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; @@ -1097,6 +1101,7 @@ B28D25882913CE8600B9067F /* Settings */ = { isa = PBXGroup; children = ( + D8F809C52CD93EA1002CAAC2 /* Proxy */, 78E45E3921D3CFBC00D4B15E /* SettingsViewController.swift */, B2D4B63A29C38D1900B47DA8 /* ChatsAndMediaViewController.swift */, B2172F3B29C125F2002C289E /* AdvancedViewController.swift */, @@ -1215,6 +1220,9 @@ 30E8F2192447285600CE2C90 /* PBXTargetDependency */, B2D0E4982B93A4B200791949 /* PBXTargetDependency */, ); + fileSystemSynchronizedGroups = ( + D8F809C52CD93EA1002CAAC2 /* Proxy */, + ); name = "deltachat-ios"; productName = "deltachat-ios"; productReference = 7A9FB1401FB061E2001FEA36 /* deltachat-ios.app */; diff --git a/deltachat-ios/Controller/Settings/AdvancedViewController.swift b/deltachat-ios/Controller/Settings/AdvancedViewController.swift index 4d0ac50fa..5fedd1201 100644 --- a/deltachat-ios/Controller/Settings/AdvancedViewController.swift +++ b/deltachat-ios/Controller/Settings/AdvancedViewController.swift @@ -330,9 +330,9 @@ internal final class AdvancedViewController: UITableViewController { self?.showAccountSettingsController() } case .proxySettings: - //TODO: Show ProxySettingsViewController - break - + Utils.authenticateDeviceOwner(reason: String.localized("proxy_settings")) { [weak self] in + self?.showProxySettings() + } case .defaultTagValue: break } } @@ -397,6 +397,11 @@ internal final class AdvancedViewController: UITableViewController { navigationController?.pushViewController(controller, animated: true) } + private func showProxySettings() { + let proxySettingsController = ProxySettingsViewController(dcContext: dcContext) + navigationController?.pushViewController(proxySettingsController, animated: true) + } + private func showManageKeysDialog() { let alert = UIAlertController(title: String.localized("pref_manage_keys"), message: nil, preferredStyle: .safeActionSheet) diff --git a/deltachat-ios/Controller/Settings/Proxy/ProxySettingsViewController.swift b/deltachat-ios/Controller/Settings/Proxy/ProxySettingsViewController.swift new file mode 100644 index 000000000..e73605f84 --- /dev/null +++ b/deltachat-ios/Controller/Settings/Proxy/ProxySettingsViewController.swift @@ -0,0 +1,155 @@ +import UIKit +import DcCore + +enum ProxySettingsSection: Int { + case enableProxies = 1 + case proxies + case add + + var title: String? { + switch self { + case .enableProxies: + return nil + case .proxies: + return "Proxies" + case .add: + return nil + } + } +} + +enum ProxySettingsItem { + case enable + case entry(DcLot) // dcContext.checkQr(proxyUrl); DcLot? URL? + case add +} + +class ProxySettingsViewController: UIViewController { + + let dcContext: DcContext + let tableView: UITableView + let proxies: [String] + + init(dcContext: DcContext) { + + self.dcContext = dcContext + self.proxies = dcContext.getProxies() + tableView = UITableView(frame: .zero, style: .grouped) + tableView.translatesAutoresizingMaskIntoConstraints = false + + tableView.register(SwitchCell.self, forCellReuseIdentifier: SwitchCell.reuseIdentifier) + tableView.register(ActionCell.self, forCellReuseIdentifier: ActionCell.reuseIdentifier) + tableView.register(ProxyTableViewCell.self, forCellReuseIdentifier: ProxyTableViewCell.reuseIdentifier) + + super.init(nibName: nil, bundle: nil) + + tableView.delegate = self + tableView.dataSource = self + + view.addSubview(tableView) + setupConstraints() + } + + required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } + + private func setupConstraints() { + let constraints = [ + tableView.topAnchor.constraint(equalTo: view.topAnchor), + tableView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor), + view.safeAreaLayoutGuide.trailingAnchor.constraint(equalTo: tableView.trailingAnchor), + view.bottomAnchor.constraint(equalTo: tableView.bottomAnchor), + ] + + NSLayoutConstraint.activate(constraints) + } + + private func selectProxy(at indexPath: IndexPath) { + // TODO: set selected proxy + } + + private func addProxy() { + // TODO: Show alert with Textfield (alternative: Dedicated Controller?) to add a new proxy-URL, reloadList afterwards + } + + private func deleteProxy(at indexPath: IndexPath) { + // TODO: Delete Proxy, if proxy was selected: Deselect proxy + } + + private func enableProxies() { + // TODO: Enable Proxies in general + } + + private func disableProxies() { + // TODO: Enable Proxies in general + } +} + +extension ProxySettingsViewController: UITableViewDataSource { + func numberOfSections(in tableView: UITableView) -> Int { + if proxies.isEmpty == false { + return 3 + } else { + return 2 + } + } + + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + if proxies.isEmpty == false { + if section == ProxySettingsSection.enableProxies.rawValue { + return 1 + } else /* if section == ProxySettingsSection.add.rawValue */ { + return 1 + } + } else { + if section == ProxySettingsSection.enableProxies.rawValue { + return 1 + } else if section == ProxySettingsSection.proxies.rawValue { + return proxies.count + } else /*if section == ProxySettingsSection.add.rawValue*/ { + return 1 + } + } + } + + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + if proxies.isEmpty == false { + if indexPath.section == ProxySettingsSection.enableProxies.rawValue { + // SwitchCell with enable/disable + } else /* if indexPath.section == ProxySettingsSection.add.rawValue */ { + // ActionCell with add + } + } else { + if indexPath.section == ProxySettingsSection.enableProxies.rawValue { + // SwitchCell with enable/disable + } else if indexPath.section == ProxySettingsSection.proxies.rawValue { + // ProxyCell with proxies[indexPath.row] + } else /*if indexPath.section == ProxySettingsSection.add.rawValue*/ { + // ActionCell with add + } + } + return UITableViewCell() + } +} + +extension ProxySettingsViewController: UITableViewDelegate { + func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + if proxies.isEmpty == false { + if indexPath.section == ProxySettingsSection.enableProxies.rawValue { + // enable/disable proxy and toggle switch + } else /* if indexPath.section == ProxySettingsSection.add.rawValue */ { + // open dialog to add a new proxy + } + } else { + if indexPath.section == ProxySettingsSection.enableProxies.rawValue { + // enable/disable proxy and toggle switch + } else if indexPath.section == ProxySettingsSection.proxies.rawValue { + // select proxy + } else /*if indexPath.section == ProxySettingsSection.add.rawValue*/ { + // open dialog to add a new proxy + } + } + + tableView.deselectRow(at: indexPath, animated: true) + } +} diff --git a/deltachat-ios/Controller/Settings/Proxy/ProxyTableViewCell.swift b/deltachat-ios/Controller/Settings/Proxy/ProxyTableViewCell.swift new file mode 100644 index 000000000..93d0b328a --- /dev/null +++ b/deltachat-ios/Controller/Settings/Proxy/ProxyTableViewCell.swift @@ -0,0 +1,9 @@ +import UIKit + +class ProxyTableViewCell: UITableViewCell { + static let reuseIdentifier = "ProxyTableViewCell" + + // make it look like the Android-version + + +} diff --git a/deltachat-ios/Helper/Utils.swift b/deltachat-ios/Helper/Utils.swift index 7cdde0b21..68740b2d2 100644 --- a/deltachat-ios/Helper/Utils.swift +++ b/deltachat-ios/Helper/Utils.swift @@ -165,6 +165,11 @@ struct Utils { } public static func authenticateDeviceOwner(reason: String, callback: @escaping () -> Void) { + +#if DEBUG + return callback() +#endif + let localAuthenticationContext = LAContext() var error: NSError? if localAuthenticationContext.canEvaluatePolicy(.deviceOwnerAuthentication, error: &error) { diff --git a/deltachat-ios/View/SwitchCell.swift b/deltachat-ios/View/SwitchCell.swift index b71cec0c6..f55c9eac7 100644 --- a/deltachat-ios/View/SwitchCell.swift +++ b/deltachat-ios/View/SwitchCell.swift @@ -4,6 +4,7 @@ class SwitchCell: UITableViewCell { var uiSwitch: UISwitch var action: ((SwitchCell) -> Void)? + static let reuseIdentifier = "SwitchCell" var isOn: Bool { return uiSwitch.isOn From dc03551f85eb277356b3cefac5e6f429993adf35 Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Tue, 5 Nov 2024 17:02:01 +0100 Subject: [PATCH 04/27] Add cells to toggle/add proxies (#2382) --- .../Proxy/ProxySettingsViewController.swift | 61 +++++++++---------- 1 file changed, 30 insertions(+), 31 deletions(-) diff --git a/deltachat-ios/Controller/Settings/Proxy/ProxySettingsViewController.swift b/deltachat-ios/Controller/Settings/Proxy/ProxySettingsViewController.swift index e73605f84..0468d4f47 100644 --- a/deltachat-ios/Controller/Settings/Proxy/ProxySettingsViewController.swift +++ b/deltachat-ios/Controller/Settings/Proxy/ProxySettingsViewController.swift @@ -2,7 +2,7 @@ import UIKit import DcCore enum ProxySettingsSection: Int { - case enableProxies = 1 + case enableProxies = 0 case proxies case add @@ -18,22 +18,22 @@ enum ProxySettingsSection: Int { } } -enum ProxySettingsItem { - case enable - case entry(DcLot) // dcContext.checkQr(proxyUrl); DcLot? URL? - case add -} - class ProxySettingsViewController: UIViewController { let dcContext: DcContext - let tableView: UITableView let proxies: [String] + var selectedProxy: String? + + let tableView: UITableView + let addProxyCell: ActionCell + let toggleProxyCell: SwitchCell init(dcContext: DcContext) { self.dcContext = dcContext self.proxies = dcContext.getProxies() + + tableView = UITableView(frame: .zero, style: .grouped) tableView.translatesAutoresizingMaskIntoConstraints = false @@ -41,6 +41,13 @@ class ProxySettingsViewController: UIViewController { tableView.register(ActionCell.self, forCellReuseIdentifier: ActionCell.reuseIdentifier) tableView.register(ProxyTableViewCell.self, forCellReuseIdentifier: ProxyTableViewCell.reuseIdentifier) + addProxyCell = ActionCell() + addProxyCell.actionTitle = String.localized("proxy_add") + + toggleProxyCell = SwitchCell(textLabel: String.localized("proxy_use_proxy"), on: dcContext.isProxyEnabled, action: { cell in + dcContext.isProxyEnabled = cell.uiSwitch.isOn + }) + super.init(nibName: nil, bundle: nil) tableView.delegate = self @@ -74,27 +81,19 @@ class ProxySettingsViewController: UIViewController { private func deleteProxy(at indexPath: IndexPath) { // TODO: Delete Proxy, if proxy was selected: Deselect proxy } - - private func enableProxies() { - // TODO: Enable Proxies in general - } - - private func disableProxies() { - // TODO: Enable Proxies in general - } } extension ProxySettingsViewController: UITableViewDataSource { func numberOfSections(in tableView: UITableView) -> Int { - if proxies.isEmpty == false { - return 3 - } else { + if proxies.isEmpty { return 2 + } else { + return 3 } } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - if proxies.isEmpty == false { + if proxies.isEmpty { if section == ProxySettingsSection.enableProxies.rawValue { return 1 } else /* if section == ProxySettingsSection.add.rawValue */ { @@ -110,22 +109,22 @@ extension ProxySettingsViewController: UITableViewDataSource { } } } - func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { - if proxies.isEmpty == false { + + if proxies.isEmpty { if indexPath.section == ProxySettingsSection.enableProxies.rawValue { - // SwitchCell with enable/disable + return toggleProxyCell } else /* if indexPath.section == ProxySettingsSection.add.rawValue */ { - // ActionCell with add + return addProxyCell } } else { if indexPath.section == ProxySettingsSection.enableProxies.rawValue { - // SwitchCell with enable/disable + return toggleProxyCell } else if indexPath.section == ProxySettingsSection.proxies.rawValue { // ProxyCell with proxies[indexPath.row] } else /*if indexPath.section == ProxySettingsSection.add.rawValue*/ { - // ActionCell with add + return addProxyCell } } return UITableViewCell() @@ -134,19 +133,19 @@ extension ProxySettingsViewController: UITableViewDataSource { extension ProxySettingsViewController: UITableViewDelegate { func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { - if proxies.isEmpty == false { + if proxies.isEmpty { if indexPath.section == ProxySettingsSection.enableProxies.rawValue { - // enable/disable proxy and toggle switch + toggleProxyCell.uiSwitch.isOn.toggle() } else /* if indexPath.section == ProxySettingsSection.add.rawValue */ { - // open dialog to add a new proxy + addProxy() } } else { if indexPath.section == ProxySettingsSection.enableProxies.rawValue { - // enable/disable proxy and toggle switch + toggleProxyCell.uiSwitch.isOn.toggle() } else if indexPath.section == ProxySettingsSection.proxies.rawValue { // select proxy } else /*if indexPath.section == ProxySettingsSection.add.rawValue*/ { - // open dialog to add a new proxy + addProxy() } } From 71ca66a0c2fb71888237755f68976d25fa02324d Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Wed, 6 Nov 2024 16:05:02 +0100 Subject: [PATCH 05/27] Properly separate newline-separated strings into a list (#2382) --- deltachat-ios/DC/DcContext.swift | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/deltachat-ios/DC/DcContext.swift b/deltachat-ios/DC/DcContext.swift index 86345280a..3a11b850f 100644 --- a/deltachat-ios/DC/DcContext.swift +++ b/deltachat-ios/DC/DcContext.swift @@ -748,10 +748,9 @@ public class DcContext { } public func getProxies() -> [String] { - guard let proxyURLStrings = getConfig("proxy_url"), - let proxies = proxyURLStrings.split(separator: "\n") as? [String] - else { return [] } + guard let proxyURLStrings = getConfig("proxy_url") else { return [] } + let proxies = proxyURLStrings.components(separatedBy: "\n") return proxies } From bc2b3aaa7c92cf4ba931a1475109c79ed9fc31e6 Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Wed, 6 Nov 2024 16:09:59 +0100 Subject: [PATCH 06/27] Add and select proxies (#2382) --- .../Settings/AdvancedViewController.swift | 2 +- .../Proxy/ProxySettingsViewController.swift | 74 +++++++++++++++++-- .../Settings/Proxy/ProxyTableViewCell.swift | 6 ++ 3 files changed, 74 insertions(+), 8 deletions(-) diff --git a/deltachat-ios/Controller/Settings/AdvancedViewController.swift b/deltachat-ios/Controller/Settings/AdvancedViewController.swift index 5fedd1201..97da4990c 100644 --- a/deltachat-ios/Controller/Settings/AdvancedViewController.swift +++ b/deltachat-ios/Controller/Settings/AdvancedViewController.swift @@ -398,7 +398,7 @@ internal final class AdvancedViewController: UITableViewController { } private func showProxySettings() { - let proxySettingsController = ProxySettingsViewController(dcContext: dcContext) + let proxySettingsController = ProxySettingsViewController(dcContext: dcContext, dcAccounts: dcAccounts) navigationController?.pushViewController(proxySettingsController, animated: true) } diff --git a/deltachat-ios/Controller/Settings/Proxy/ProxySettingsViewController.swift b/deltachat-ios/Controller/Settings/Proxy/ProxySettingsViewController.swift index 0468d4f47..7ef38d883 100644 --- a/deltachat-ios/Controller/Settings/Proxy/ProxySettingsViewController.swift +++ b/deltachat-ios/Controller/Settings/Proxy/ProxySettingsViewController.swift @@ -21,18 +21,23 @@ enum ProxySettingsSection: Int { class ProxySettingsViewController: UIViewController { let dcContext: DcContext - let proxies: [String] + let dcAccounts: DcAccounts + + var proxies: [String] var selectedProxy: String? let tableView: UITableView let addProxyCell: ActionCell let toggleProxyCell: SwitchCell - init(dcContext: DcContext) { + var addProxyAlert: UIAlertController? + + init(dcContext: DcContext, dcAccounts: DcAccounts) { self.dcContext = dcContext + self.dcAccounts = dcAccounts self.proxies = dcContext.getProxies() - + self.selectedProxy = proxies.first tableView = UITableView(frame: .zero, style: .grouped) tableView.translatesAutoresizingMaskIntoConstraints = false @@ -50,6 +55,7 @@ class ProxySettingsViewController: UIViewController { super.init(nibName: nil, bundle: nil) + title = String.localized("proxy_settings") tableView.delegate = self tableView.dataSource = self @@ -71,11 +77,50 @@ class ProxySettingsViewController: UIViewController { } private func selectProxy(at indexPath: IndexPath) { - // TODO: set selected proxy + // TODO: add alert + let selectedProxyURL = proxies[indexPath.row] + if dcContext.setConfigFromQR(qrCode: selectedProxyURL) { + self.selectedProxy = selectedProxyURL + tableView.reloadData() + dcAccounts.stopIo() + dcAccounts.startIo() + } } private func addProxy() { - // TODO: Show alert with Textfield (alternative: Dedicated Controller?) to add a new proxy-URL, reloadList afterwards + let alertController = UIAlertController( + title: String.localized("proxy_add"), + message: String.localized("proxy_add_explain"), + preferredStyle: .alert + ) + + let addProxyAction = UIAlertAction(title: String.localized("proxy_use_proxy"), style: .default) { [weak self] _ in + guard let self, + let proxyUrlTextfield = self.addProxyAlert?.textFields?.first, + let proxyURL = proxyUrlTextfield.text else { return } + + let parsedProxy = self.dcContext.checkQR(qrCode: proxyURL) + if parsedProxy.state == DC_QR_PROXY, self.dcContext.setConfigFromQR(qrCode: proxyURL) { + self.proxies.insert(proxyURL, at: self.proxies.startIndex) + self.dcContext.setProxies(proxyURLs: self.proxies) + + DispatchQueue.main.async { + self.tableView.reloadData() + } + } else { + // show another alert with "proxy_invalid" + } + } + + let cancelAction = UIAlertAction(title: String.localized("cancel"), style: .cancel) + alertController.addAction(addProxyAction) + alertController.addAction(cancelAction) + alertController.addTextField { textfield in + textfield.placeholder = String.localized("proxy_add_url_hint") + } + + present(alertController, animated: true) + self.addProxyAlert = alertController } private func deleteProxy(at indexPath: IndexPath) { @@ -83,6 +128,8 @@ class ProxySettingsViewController: UIViewController { } } +// MARK: - UITableViewDataSource + extension ProxySettingsViewController: UITableViewDataSource { func numberOfSections(in tableView: UITableView) -> Int { if proxies.isEmpty { @@ -122,15 +169,28 @@ extension ProxySettingsViewController: UITableViewDataSource { if indexPath.section == ProxySettingsSection.enableProxies.rawValue { return toggleProxyCell } else if indexPath.section == ProxySettingsSection.proxies.rawValue { + guard let cell = tableView.dequeueReusableCell(withIdentifier: ProxyTableViewCell.reuseIdentifier, for: indexPath) as? ProxyTableViewCell else { fatalError() } + + let proxy = proxies[indexPath.row] + cell.textLabel?.text = proxy + + if let selectedProxy, selectedProxy == proxy { + cell.accessoryType = .checkmark + } else { + cell.accessoryType = .none + } + + return cell // ProxyCell with proxies[indexPath.row] } else /*if indexPath.section == ProxySettingsSection.add.rawValue*/ { return addProxyCell } } - return UITableViewCell() } } +// MARK: - UITableViewDelegate + extension ProxySettingsViewController: UITableViewDelegate { func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { if proxies.isEmpty { @@ -143,7 +203,7 @@ extension ProxySettingsViewController: UITableViewDelegate { if indexPath.section == ProxySettingsSection.enableProxies.rawValue { toggleProxyCell.uiSwitch.isOn.toggle() } else if indexPath.section == ProxySettingsSection.proxies.rawValue { - // select proxy + selectProxy(at: indexPath) } else /*if indexPath.section == ProxySettingsSection.add.rawValue*/ { addProxy() } diff --git a/deltachat-ios/Controller/Settings/Proxy/ProxyTableViewCell.swift b/deltachat-ios/Controller/Settings/Proxy/ProxyTableViewCell.swift index 93d0b328a..6be8f2cee 100644 --- a/deltachat-ios/Controller/Settings/Proxy/ProxyTableViewCell.swift +++ b/deltachat-ios/Controller/Settings/Proxy/ProxyTableViewCell.swift @@ -5,5 +5,11 @@ class ProxyTableViewCell: UITableViewCell { // make it look like the Android-version + override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { + super.init(style: style, reuseIdentifier: reuseIdentifier) + + textLabel?.numberOfLines = 0 + } + required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } } From c1e56bdf30a3e04754709700aded4f089386dfd9 Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Wed, 6 Nov 2024 20:29:52 +0100 Subject: [PATCH 07/27] Delete proxies (#2382) For whatever reasons this doesn't work in the simulator. Will investigate further, but it took me some time to figure that out. --- .../Proxy/ProxySettingsViewController.swift | 29 +++++++++++++++++-- deltachat-ios/DC/DcAccount.swift | 5 ++++ 2 files changed, 31 insertions(+), 3 deletions(-) diff --git a/deltachat-ios/Controller/Settings/Proxy/ProxySettingsViewController.swift b/deltachat-ios/Controller/Settings/Proxy/ProxySettingsViewController.swift index 7ef38d883..55d24600c 100644 --- a/deltachat-ios/Controller/Settings/Proxy/ProxySettingsViewController.swift +++ b/deltachat-ios/Controller/Settings/Proxy/ProxySettingsViewController.swift @@ -82,8 +82,7 @@ class ProxySettingsViewController: UIViewController { if dcContext.setConfigFromQR(qrCode: selectedProxyURL) { self.selectedProxy = selectedProxyURL tableView.reloadData() - dcAccounts.stopIo() - dcAccounts.startIo() + dcAccounts.restartIO() } } @@ -161,12 +160,14 @@ extension ProxySettingsViewController: UITableViewDataSource { if proxies.isEmpty { if indexPath.section == ProxySettingsSection.enableProxies.rawValue { + toggleProxyCell.uiSwitch.isOn = dcContext.isProxyEnabled return toggleProxyCell } else /* if indexPath.section == ProxySettingsSection.add.rawValue */ { return addProxyCell } } else { if indexPath.section == ProxySettingsSection.enableProxies.rawValue { + toggleProxyCell.uiSwitch.isOn = dcContext.isProxyEnabled return toggleProxyCell } else if indexPath.section == ProxySettingsSection.proxies.rawValue { guard let cell = tableView.dequeueReusableCell(withIdentifier: ProxyTableViewCell.reuseIdentifier, for: indexPath) as? ProxyTableViewCell else { fatalError() } @@ -181,7 +182,6 @@ extension ProxySettingsViewController: UITableViewDataSource { } return cell - // ProxyCell with proxies[indexPath.row] } else /*if indexPath.section == ProxySettingsSection.add.rawValue*/ { return addProxyCell } @@ -211,4 +211,27 @@ extension ProxySettingsViewController: UITableViewDelegate { tableView.deselectRow(at: indexPath, animated: true) } + + func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? { + guard + proxies.isEmpty == false, + indexPath.section == ProxySettingsSection.proxies.rawValue + else { return nil } + + let deleteAction = UIContextualAction(style: .destructive, title: String.localized("proxy_delete")) { [weak self] _, _, completion in + self?.deleteProxy(at: indexPath) + DispatchQueue.main.async { + self?.tableView.reloadData() + completion(true) + } + } + deleteAction.backgroundColor = .red + deleteAction.image = UIImage(named: "ic_trash") + + let configuration = UISwipeActionsConfiguration(actions: [deleteAction]) + configuration.performsFirstActionWithFullSwipe = true + + return configuration + } + } diff --git a/deltachat-ios/DC/DcAccount.swift b/deltachat-ios/DC/DcAccount.swift index ff1cbe9ad..15afca3d9 100644 --- a/deltachat-ios/DC/DcAccount.swift +++ b/deltachat-ios/DC/DcAccount.swift @@ -67,6 +67,11 @@ public class DcAccounts { dc_accounts_stop_io(accountsPointer) } + public func restartIO() { + stopIo() + startIo() + } + public func backgroundFetch(timeout: UInt64) -> Bool { return dc_accounts_background_fetch(accountsPointer, timeout) == 1 } From a0ad9695cd5c2cf95d941a009a175c1b5be1e982 Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Thu, 7 Nov 2024 12:44:06 +0100 Subject: [PATCH 08/27] Properly delete proxies (#2382) --- .../Proxy/ProxySettingsViewController.swift | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/deltachat-ios/Controller/Settings/Proxy/ProxySettingsViewController.swift b/deltachat-ios/Controller/Settings/Proxy/ProxySettingsViewController.swift index 55d24600c..3f3ff0048 100644 --- a/deltachat-ios/Controller/Settings/Proxy/ProxySettingsViewController.swift +++ b/deltachat-ios/Controller/Settings/Proxy/ProxySettingsViewController.swift @@ -123,7 +123,16 @@ class ProxySettingsViewController: UIViewController { } private func deleteProxy(at indexPath: IndexPath) { - // TODO: Delete Proxy, if proxy was selected: Deselect proxy + let proxyToRemove = proxies[indexPath.row] + + if let selectedProxy, proxyToRemove == selectedProxy { + dcContext.isProxyEnabled = false + } + + proxies.remove(at: indexPath.row) + toggleProxyCell.uiSwitch.isEnabled = (proxies.isEmpty == false) + dcContext.setProxies(proxyURLs: proxies) + tableView.reloadData() } } @@ -219,9 +228,8 @@ extension ProxySettingsViewController: UITableViewDelegate { else { return nil } let deleteAction = UIContextualAction(style: .destructive, title: String.localized("proxy_delete")) { [weak self] _, _, completion in - self?.deleteProxy(at: indexPath) DispatchQueue.main.async { - self?.tableView.reloadData() + self?.deleteProxy(at: indexPath) completion(true) } } From 786a29fb8e9b57992c2a6aac915dd8ae8a4e1243 Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Thu, 7 Nov 2024 13:17:43 +0100 Subject: [PATCH 09/27] Use a tableviewcontroller, disable toggle (if needed), show alert when selecting a proxy (#2382) --- .../Proxy/ProxySettingsViewController.swift | 80 +++++++++---------- deltachat-ios/View/SwitchCell.swift | 2 +- 2 files changed, 40 insertions(+), 42 deletions(-) diff --git a/deltachat-ios/Controller/Settings/Proxy/ProxySettingsViewController.swift b/deltachat-ios/Controller/Settings/Proxy/ProxySettingsViewController.swift index 3f3ff0048..74845aa33 100644 --- a/deltachat-ios/Controller/Settings/Proxy/ProxySettingsViewController.swift +++ b/deltachat-ios/Controller/Settings/Proxy/ProxySettingsViewController.swift @@ -18,7 +18,7 @@ enum ProxySettingsSection: Int { } } -class ProxySettingsViewController: UIViewController { +class ProxySettingsViewController: UITableViewController { let dcContext: DcContext let dcAccounts: DcAccounts @@ -26,7 +26,6 @@ class ProxySettingsViewController: UIViewController { var proxies: [String] var selectedProxy: String? - let tableView: UITableView let addProxyCell: ActionCell let toggleProxyCell: SwitchCell @@ -39,51 +38,51 @@ class ProxySettingsViewController: UIViewController { self.proxies = dcContext.getProxies() self.selectedProxy = proxies.first - tableView = UITableView(frame: .zero, style: .grouped) - tableView.translatesAutoresizingMaskIntoConstraints = false + addProxyCell = ActionCell() + addProxyCell.actionTitle = String.localized("proxy_add") + toggleProxyCell = SwitchCell(textLabel: String.localized("proxy_use_proxy"), on: dcContext.isProxyEnabled) + + super.init(style: .grouped) tableView.register(SwitchCell.self, forCellReuseIdentifier: SwitchCell.reuseIdentifier) tableView.register(ActionCell.self, forCellReuseIdentifier: ActionCell.reuseIdentifier) tableView.register(ProxyTableViewCell.self, forCellReuseIdentifier: ProxyTableViewCell.reuseIdentifier) - addProxyCell = ActionCell() - addProxyCell.actionTitle = String.localized("proxy_add") + toggleProxyCell.uiSwitch.isEnabled = (proxies.isEmpty == false) + toggleProxyCell.action = { [weak self] cell in + guard let self, self.proxies.isEmpty == false else { return } - toggleProxyCell = SwitchCell(textLabel: String.localized("proxy_use_proxy"), on: dcContext.isProxyEnabled, action: { cell in dcContext.isProxyEnabled = cell.uiSwitch.isOn - }) - - super.init(nibName: nil, bundle: nil) + } title = String.localized("proxy_settings") - tableView.delegate = self - tableView.dataSource = self - - view.addSubview(tableView) - setupConstraints() } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } - private func setupConstraints() { - let constraints = [ - tableView.topAnchor.constraint(equalTo: view.topAnchor), - tableView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor), - view.safeAreaLayoutGuide.trailingAnchor.constraint(equalTo: tableView.trailingAnchor), - view.bottomAnchor.constraint(equalTo: tableView.bottomAnchor), - ] - - NSLayoutConstraint.activate(constraints) - } - private func selectProxy(at indexPath: IndexPath) { - // TODO: add alert let selectedProxyURL = proxies[indexPath.row] - if dcContext.setConfigFromQR(qrCode: selectedProxyURL) { - self.selectedProxy = selectedProxyURL - tableView.reloadData() - dcAccounts.restartIO() + + let selectAlert = UIAlertController( + title: String.localized("proxy_use_proxy"), + message: String.localized(stringID: "proxy_use_proxy_confirm", parameter: selectedProxyURL), + preferredStyle: .alert + ) + + let cancelAction = UIAlertAction(title: String.localized("cancel"), style: .cancel) + let selectAction = UIAlertAction(title: String.localized("proxy_use_proxy"), style: .default) { [weak self] _ in + + guard let self else { return } + if self.dcContext.setConfigFromQR(qrCode: selectedProxyURL) { + self.selectedProxy = selectedProxyURL + self.tableView.reloadData() + self.dcAccounts.restartIO() + } } + selectAlert.addAction(cancelAction) + selectAlert.addAction(selectAction) + + present(selectAlert, animated: true) } private func addProxy() { @@ -104,6 +103,7 @@ class ProxySettingsViewController: UIViewController { self.dcContext.setProxies(proxyURLs: self.proxies) DispatchQueue.main.async { + self.toggleProxyCell.uiSwitch.isEnabled = (self.proxies.isEmpty == false) self.tableView.reloadData() } } else { @@ -138,8 +138,8 @@ class ProxySettingsViewController: UIViewController { // MARK: - UITableViewDataSource -extension ProxySettingsViewController: UITableViewDataSource { - func numberOfSections(in tableView: UITableView) -> Int { +extension ProxySettingsViewController { + override func numberOfSections(in tableView: UITableView) -> Int { if proxies.isEmpty { return 2 } else { @@ -147,7 +147,7 @@ extension ProxySettingsViewController: UITableViewDataSource { } } - func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { if proxies.isEmpty { if section == ProxySettingsSection.enableProxies.rawValue { return 1 @@ -165,7 +165,7 @@ extension ProxySettingsViewController: UITableViewDataSource { } } - func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { if proxies.isEmpty { if indexPath.section == ProxySettingsSection.enableProxies.rawValue { @@ -200,11 +200,11 @@ extension ProxySettingsViewController: UITableViewDataSource { // MARK: - UITableViewDelegate -extension ProxySettingsViewController: UITableViewDelegate { - func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { +extension ProxySettingsViewController { + override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { if proxies.isEmpty { if indexPath.section == ProxySettingsSection.enableProxies.rawValue { - toggleProxyCell.uiSwitch.isOn.toggle() + // do nothing as there are no proxies that could be used } else /* if indexPath.section == ProxySettingsSection.add.rawValue */ { addProxy() } @@ -221,7 +221,7 @@ extension ProxySettingsViewController: UITableViewDelegate { tableView.deselectRow(at: indexPath, animated: true) } - func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? { + override func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? { guard proxies.isEmpty == false, indexPath.section == ProxySettingsSection.proxies.rawValue @@ -234,12 +234,10 @@ extension ProxySettingsViewController: UITableViewDelegate { } } deleteAction.backgroundColor = .red - deleteAction.image = UIImage(named: "ic_trash") let configuration = UISwipeActionsConfiguration(actions: [deleteAction]) configuration.performsFirstActionWithFullSwipe = true return configuration } - } diff --git a/deltachat-ios/View/SwitchCell.swift b/deltachat-ios/View/SwitchCell.swift index f55c9eac7..c67792966 100644 --- a/deltachat-ios/View/SwitchCell.swift +++ b/deltachat-ios/View/SwitchCell.swift @@ -10,7 +10,7 @@ class SwitchCell: UITableViewCell { return uiSwitch.isOn } - init(textLabel: String, on: Bool, action: ((SwitchCell) -> Void)?) { + init(textLabel: String, on: Bool, action: ((SwitchCell) -> Void)? = nil) { self.uiSwitch = UISwitch() self.action = action super.init(style: .value1, reuseIdentifier: nil) From ea9e083b6ef52344439e94c64d2b31040737ce94 Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Thu, 7 Nov 2024 14:32:14 +0100 Subject: [PATCH 10/27] Add an alert to prevent accidental proxy-deletion (#2382) --- .../Proxy/ProxySettingsViewController.swift | 25 ++++++++++++++----- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/deltachat-ios/Controller/Settings/Proxy/ProxySettingsViewController.swift b/deltachat-ios/Controller/Settings/Proxy/ProxySettingsViewController.swift index 74845aa33..d060af3a4 100644 --- a/deltachat-ios/Controller/Settings/Proxy/ProxySettingsViewController.swift +++ b/deltachat-ios/Controller/Settings/Proxy/ProxySettingsViewController.swift @@ -125,14 +125,27 @@ class ProxySettingsViewController: UITableViewController { private func deleteProxy(at indexPath: IndexPath) { let proxyToRemove = proxies[indexPath.row] - if let selectedProxy, proxyToRemove == selectedProxy { - dcContext.isProxyEnabled = false + let deleteAlert = UIAlertController(title: String.localized("proxy_delete"), message: String.localized(stringID: "proxy_delete_explain", parameter: proxyToRemove), preferredStyle: .alert) + + let cancelAction = UIAlertAction(title: String.localized("cancel"), style: .cancel) + let deleteAction = UIAlertAction(title: String.localized("proxy_delete"), style: .destructive) { [weak self] _ in + guard let self else { return } + + if let selectedProxy = self.selectedProxy, proxyToRemove == selectedProxy { + self.dcContext.isProxyEnabled = false + } + + self.proxies.remove(at: indexPath.row) + self.dcContext.setProxies(proxyURLs: proxies) + DispatchQueue.main.async { + self.toggleProxyCell.uiSwitch.isEnabled = (self.proxies.isEmpty == false) + self.tableView.reloadData() + } } - proxies.remove(at: indexPath.row) - toggleProxyCell.uiSwitch.isEnabled = (proxies.isEmpty == false) - dcContext.setProxies(proxyURLs: proxies) - tableView.reloadData() + deleteAlert.addAction(cancelAction) + deleteAlert.addAction(deleteAction) + present(deleteAlert, animated: true) } } From 23df034df2c2df4bd0026eb8c35d56479312d0e1 Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Thu, 7 Nov 2024 16:14:54 +0100 Subject: [PATCH 11/27] Try to fix build (#2382) Xcode 16 broke something here so that Github Actions decided not to build any longer --- deltachat-ios.xcodeproj/project.pbxproj | 26 ++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/deltachat-ios.xcodeproj/project.pbxproj b/deltachat-ios.xcodeproj/project.pbxproj index 7daad59d9..d2bde3013 100644 --- a/deltachat-ios.xcodeproj/project.pbxproj +++ b/deltachat-ios.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 70; + objectVersion = 54; objects = { /* Begin PBXBuildFile section */ @@ -224,6 +224,8 @@ D8C19DD02C1C9FFE00B32F6D /* ContactCardPreview.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8C19DCF2C1C95A900B32F6D /* ContactCardPreview.swift */; }; D8CDEFE02C087CDA00146773 /* ContactCardCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8CDEFDF2C087CDA00146773 /* ContactCardCell.swift */; }; D8CDEFE22C087D1000146773 /* ContactCardView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8CDEFE12C087D1000146773 /* ContactCardView.swift */; }; + D8CF2DDC2CDD110F001C2352 /* ProxySettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8CF2DD92CDD110F001C2352 /* ProxySettingsViewController.swift */; }; + D8CF2DDD2CDD110F001C2352 /* ProxyTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8CF2DDA2CDD110F001C2352 /* ProxyTableViewCell.swift */; }; D8FB03FD2B4EF20700A355F8 /* ReactionsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8FB03FC2B4EF20700A355F8 /* ReactionsView.swift */; }; D8FB04002B4F0CF100A355F8 /* EmojiView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D8FB03FF2B4F0CF000A355F8 /* EmojiView.swift */; }; /* End PBXBuildFile section */ @@ -609,16 +611,14 @@ D8C19DCF2C1C95A900B32F6D /* ContactCardPreview.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContactCardPreview.swift; sourceTree = ""; }; D8CDEFDF2C087CDA00146773 /* ContactCardCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContactCardCell.swift; sourceTree = ""; }; D8CDEFE12C087D1000146773 /* ContactCardView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContactCardView.swift; sourceTree = ""; }; + D8CF2DD92CDD110F001C2352 /* ProxySettingsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProxySettingsViewController.swift; sourceTree = ""; }; + D8CF2DDA2CDD110F001C2352 /* ProxyTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProxyTableViewCell.swift; sourceTree = ""; }; D8FB03FC2B4EF20700A355F8 /* ReactionsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReactionsView.swift; sourceTree = ""; }; D8FB03FF2B4F0CF000A355F8 /* EmojiView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmojiView.swift; sourceTree = ""; }; DFBB6227B203C9B6FB5F4321 /* Pods-DcShare.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-DcShare.debug.xcconfig"; path = "Target Support Files/Pods-DcShare/Pods-DcShare.debug.xcconfig"; sourceTree = ""; }; E23C80FA36453692862D4A90 /* Pods_deltachat_iosTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_deltachat_iosTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ -/* Begin PBXFileSystemSynchronizedRootGroup section */ - D8F809C52CD93EA1002CAAC2 /* Proxy */ = {isa = PBXFileSystemSynchronizedRootGroup; explicitFileTypes = {}; explicitFolders = (); path = Proxy; sourceTree = ""; }; -/* End PBXFileSystemSynchronizedRootGroup section */ - /* Begin PBXFrameworksBuildPhase section */ 30E8F20D2447285600CE2C90 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; @@ -1101,7 +1101,7 @@ B28D25882913CE8600B9067F /* Settings */ = { isa = PBXGroup; children = ( - D8F809C52CD93EA1002CAAC2 /* Proxy */, + D8CF2DDB2CDD110F001C2352 /* Proxy */, 78E45E3921D3CFBC00D4B15E /* SettingsViewController.swift */, B2D4B63A29C38D1900B47DA8 /* ChatsAndMediaViewController.swift */, B2172F3B29C125F2002C289E /* AdvancedViewController.swift */, @@ -1170,6 +1170,15 @@ path = "Send Contact"; sourceTree = ""; }; + D8CF2DDB2CDD110F001C2352 /* Proxy */ = { + isa = PBXGroup; + children = ( + D8CF2DD92CDD110F001C2352 /* ProxySettingsViewController.swift */, + D8CF2DDA2CDD110F001C2352 /* ProxyTableViewCell.swift */, + ); + path = Proxy; + sourceTree = ""; + }; D8FB03FE2B4F0CE500A355F8 /* Reactions */ = { isa = PBXGroup; children = ( @@ -1220,9 +1229,6 @@ 30E8F2192447285600CE2C90 /* PBXTargetDependency */, B2D0E4982B93A4B200791949 /* PBXTargetDependency */, ); - fileSystemSynchronizedGroups = ( - D8F809C52CD93EA1002CAAC2 /* Proxy */, - ); name = "deltachat-ios"; productName = "deltachat-ios"; productReference = 7A9FB1401FB061E2001FEA36 /* deltachat-ios.app */; @@ -1713,6 +1719,8 @@ AED423D3249F578B00B6B2BB /* AddGroupMembersViewController.swift in Sources */, 3011E8052787365D00214221 /* KeychainManager.swift in Sources */, AE851AC5227C755A00ED86F0 /* Protocols.swift in Sources */, + D8CF2DDC2CDD110F001C2352 /* ProxySettingsViewController.swift in Sources */, + D8CF2DDD2CDD110F001C2352 /* ProxyTableViewCell.swift in Sources */, AE728F15229D5C390047565B /* PhotoPickerAlertAction.swift in Sources */, AECEF03E244F2D55006C90DA /* QrPageController.swift in Sources */, AEACE2E31FB32B5C00DCDD78 /* Constants.swift in Sources */, From ebe04faccc8e075a76482069fb16394484ad27e6 Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Thu, 7 Nov 2024 17:26:26 +0100 Subject: [PATCH 12/27] Show host and protocol instead of entire proxy-URL (#2382) --- .../Settings/Proxy/ProxySettingsViewController.swift | 12 +++++++----- .../Settings/Proxy/ProxyTableViewCell.swift | 12 +++++++++++- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/deltachat-ios/Controller/Settings/Proxy/ProxySettingsViewController.swift b/deltachat-ios/Controller/Settings/Proxy/ProxySettingsViewController.swift index d060af3a4..a566922b6 100644 --- a/deltachat-ios/Controller/Settings/Proxy/ProxySettingsViewController.swift +++ b/deltachat-ios/Controller/Settings/Proxy/ProxySettingsViewController.swift @@ -62,10 +62,11 @@ class ProxySettingsViewController: UITableViewController { private func selectProxy(at indexPath: IndexPath) { let selectedProxyURL = proxies[indexPath.row] + let host = dcContext.checkQR(qrCode: selectedProxyURL).text1 ?? "" let selectAlert = UIAlertController( title: String.localized("proxy_use_proxy"), - message: String.localized(stringID: "proxy_use_proxy_confirm", parameter: selectedProxyURL), + message: String.localized(stringID: "proxy_use_proxy_confirm", parameter: host), preferredStyle: .alert ) @@ -124,8 +125,9 @@ class ProxySettingsViewController: UITableViewController { private func deleteProxy(at indexPath: IndexPath) { let proxyToRemove = proxies[indexPath.row] + let host = dcContext.checkQR(qrCode: proxyToRemove).text1 ?? "" - let deleteAlert = UIAlertController(title: String.localized("proxy_delete"), message: String.localized(stringID: "proxy_delete_explain", parameter: proxyToRemove), preferredStyle: .alert) + let deleteAlert = UIAlertController(title: String.localized("proxy_delete"), message: String.localized(stringID: "proxy_delete_explain", parameter: host), preferredStyle: .alert) let cancelAction = UIAlertAction(title: String.localized("cancel"), style: .cancel) let deleteAction = UIAlertAction(title: String.localized("proxy_delete"), style: .destructive) { [weak self] _ in @@ -194,10 +196,10 @@ extension ProxySettingsViewController { } else if indexPath.section == ProxySettingsSection.proxies.rawValue { guard let cell = tableView.dequeueReusableCell(withIdentifier: ProxyTableViewCell.reuseIdentifier, for: indexPath) as? ProxyTableViewCell else { fatalError() } - let proxy = proxies[indexPath.row] - cell.textLabel?.text = proxy + let proxyUrl = proxies[indexPath.row] + cell.configure(with: proxyUrl, dcContext: dcContext) - if let selectedProxy, selectedProxy == proxy { + if let selectedProxy, selectedProxy == proxyUrl { cell.accessoryType = .checkmark } else { cell.accessoryType = .none diff --git a/deltachat-ios/Controller/Settings/Proxy/ProxyTableViewCell.swift b/deltachat-ios/Controller/Settings/Proxy/ProxyTableViewCell.swift index 6be8f2cee..cc236d5b1 100644 --- a/deltachat-ios/Controller/Settings/Proxy/ProxyTableViewCell.swift +++ b/deltachat-ios/Controller/Settings/Proxy/ProxyTableViewCell.swift @@ -1,4 +1,5 @@ import UIKit +import DcCore class ProxyTableViewCell: UITableViewCell { static let reuseIdentifier = "ProxyTableViewCell" @@ -6,10 +7,19 @@ class ProxyTableViewCell: UITableViewCell { // make it look like the Android-version override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { - super.init(style: style, reuseIdentifier: reuseIdentifier) + super.init(style: .subtitle, reuseIdentifier: reuseIdentifier) textLabel?.numberOfLines = 0 } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } + + func configure(with proxyUrlString: String, dcContext: DcContext) { + let parsed = dcContext.checkQR(qrCode: proxyUrlString) + + let host = parsed.text1 + let proxyProtocol = proxyUrlString.components(separatedBy: ":").first + textLabel?.text = host + detailTextLabel?.text = proxyProtocol + } } From 91a766761acaf04e445a78b105f83cb04228bd7a Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Fri, 8 Nov 2024 13:20:26 +0100 Subject: [PATCH 13/27] Add title to proxy-section (#2382) --- .../Proxy/ProxySettingsViewController.swift | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/deltachat-ios/Controller/Settings/Proxy/ProxySettingsViewController.swift b/deltachat-ios/Controller/Settings/Proxy/ProxySettingsViewController.swift index a566922b6..fcea06bcc 100644 --- a/deltachat-ios/Controller/Settings/Proxy/ProxySettingsViewController.swift +++ b/deltachat-ios/Controller/Settings/Proxy/ProxySettingsViewController.swift @@ -11,7 +11,7 @@ enum ProxySettingsSection: Int { case .enableProxies: return nil case .proxies: - return "Proxies" + return String.localized("proxy_list_header") case .add: return nil } @@ -211,6 +211,18 @@ extension ProxySettingsViewController { } } } + + override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { + guard proxies.isEmpty == false else { return nil } + + + if section == ProxySettingsSection.proxies.rawValue { + return ProxySettingsSection.proxies.title + } else { + return nil + } + + } } // MARK: - UITableViewDelegate From 5c351380dbf0f487d2c82c1957ad813ed11ae27e Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Fri, 8 Nov 2024 13:28:43 +0100 Subject: [PATCH 14/27] Show an error-alert in case of an invalid proxy (#2382) --- .../Settings/Proxy/ProxySettingsViewController.swift | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/deltachat-ios/Controller/Settings/Proxy/ProxySettingsViewController.swift b/deltachat-ios/Controller/Settings/Proxy/ProxySettingsViewController.swift index fcea06bcc..9c22ac39f 100644 --- a/deltachat-ios/Controller/Settings/Proxy/ProxySettingsViewController.swift +++ b/deltachat-ios/Controller/Settings/Proxy/ProxySettingsViewController.swift @@ -108,7 +108,12 @@ class ProxySettingsViewController: UITableViewController { self.tableView.reloadData() } } else { - // show another alert with "proxy_invalid" + let errorAlert = UIAlertController(title: String.localized("error"), message: String.localized("proxy_invalid"), preferredStyle: .alert) + + let okAction = UIAlertAction(title: String.localized("ok"), style: .default) + errorAlert.addAction(okAction) + + self.present(errorAlert, animated: true) } } From acdd843656eba1a472cc93d51c24250dd4f984b2 Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Fri, 8 Nov 2024 15:49:37 +0100 Subject: [PATCH 15/27] Really enable/disable proxies when tapping the cell (#2382) --- .../Settings/Proxy/ProxySettingsViewController.swift | 4 +++- deltachat-ios/View/SwitchCell.swift | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/deltachat-ios/Controller/Settings/Proxy/ProxySettingsViewController.swift b/deltachat-ios/Controller/Settings/Proxy/ProxySettingsViewController.swift index 9c22ac39f..05d1666b3 100644 --- a/deltachat-ios/Controller/Settings/Proxy/ProxySettingsViewController.swift +++ b/deltachat-ios/Controller/Settings/Proxy/ProxySettingsViewController.swift @@ -52,7 +52,8 @@ class ProxySettingsViewController: UITableViewController { toggleProxyCell.action = { [weak self] cell in guard let self, self.proxies.isEmpty == false else { return } - dcContext.isProxyEnabled = cell.uiSwitch.isOn + self.dcContext.isProxyEnabled = cell.uiSwitch.isOn + self.dcAccounts.restartIO() } title = String.localized("proxy_settings") @@ -243,6 +244,7 @@ extension ProxySettingsViewController { } else { if indexPath.section == ProxySettingsSection.enableProxies.rawValue { toggleProxyCell.uiSwitch.isOn.toggle() + toggleProxyCell.didToggleSwitch(toggleProxyCell.uiSwitch) } else if indexPath.section == ProxySettingsSection.proxies.rawValue { selectProxy(at: indexPath) } else /*if indexPath.section == ProxySettingsSection.add.rawValue*/ { diff --git a/deltachat-ios/View/SwitchCell.swift b/deltachat-ios/View/SwitchCell.swift index c67792966..3616832fa 100644 --- a/deltachat-ios/View/SwitchCell.swift +++ b/deltachat-ios/View/SwitchCell.swift @@ -27,7 +27,7 @@ class SwitchCell: UITableViewCell { } @objc - private func didToggleSwitch(_ sender: UISwitch) { + func didToggleSwitch(_ sender: UISwitch) { action?(self) } } From f6e9629c6dfc546131115ae8011407b2f979a570 Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Fri, 8 Nov 2024 16:32:04 +0100 Subject: [PATCH 16/27] Incorporate Feedback from PR (#2382) --- .../Controller/Settings/AdvancedViewController.swift | 4 +--- deltachat-ios/Helper/Utils.swift | 5 ----- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/deltachat-ios/Controller/Settings/AdvancedViewController.swift b/deltachat-ios/Controller/Settings/AdvancedViewController.swift index 97da4990c..15becad73 100644 --- a/deltachat-ios/Controller/Settings/AdvancedViewController.swift +++ b/deltachat-ios/Controller/Settings/AdvancedViewController.swift @@ -330,9 +330,7 @@ internal final class AdvancedViewController: UITableViewController { self?.showAccountSettingsController() } case .proxySettings: - Utils.authenticateDeviceOwner(reason: String.localized("proxy_settings")) { [weak self] in - self?.showProxySettings() - } + showProxySettings() case .defaultTagValue: break } } diff --git a/deltachat-ios/Helper/Utils.swift b/deltachat-ios/Helper/Utils.swift index 68740b2d2..7cdde0b21 100644 --- a/deltachat-ios/Helper/Utils.swift +++ b/deltachat-ios/Helper/Utils.swift @@ -165,11 +165,6 @@ struct Utils { } public static func authenticateDeviceOwner(reason: String, callback: @escaping () -> Void) { - -#if DEBUG - return callback() -#endif - let localAuthenticationContext = LAContext() var error: NSError? if localAuthenticationContext.canEvaluatePolicy(.deviceOwnerAuthentication, error: &error) { From 864d1c74a01c0000f5054f1da9a5610cf801d199 Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Tue, 12 Nov 2024 12:20:40 +0100 Subject: [PATCH 17/27] Add different labels for different texts (#2382) --- .../DcCore/Extensions/UIView+Extensions.swift | 20 ++++++ .../Settings/Proxy/ProxyTableViewCell.swift | 61 +++++++++++++++++-- 2 files changed, 76 insertions(+), 5 deletions(-) diff --git a/DcCore/DcCore/Extensions/UIView+Extensions.swift b/DcCore/DcCore/Extensions/UIView+Extensions.swift index d55cecef3..7ecd526f1 100644 --- a/DcCore/DcCore/Extensions/UIView+Extensions.swift +++ b/DcCore/DcCore/Extensions/UIView+Extensions.swift @@ -2,6 +2,26 @@ import UIKit public extension UIView { + static func borderedView(around subview: UIView, borderWidth: CGFloat, borderColor: UIColor, cornerRadius: CGFloat, padding: NSDirectionalEdgeInsets) -> UIView { + let borderView = UIView() + + subview.translatesAutoresizingMaskIntoConstraints = false + borderView.addSubview(subview) + + NSLayoutConstraint.activate([ + subview.topAnchor.constraint(equalTo: borderView.topAnchor, constant: padding.top), + subview.leadingAnchor.constraint(equalTo: borderView.leadingAnchor, constant: padding.leading), + borderView.trailingAnchor.constraint(equalTo: subview.trailingAnchor, constant: padding.trailing), + borderView.bottomAnchor.constraint(equalTo: subview.bottomAnchor, constant: padding.bottom), + ]) + + borderView.layer.borderColor = borderColor.cgColor + borderView.layer.borderWidth = borderWidth + borderView.layer.cornerRadius = cornerRadius + + return borderView + } + func makeBorder(color: UIColor = UIColor.systemRed) { self.layer.borderColor = color.cgColor self.layer.borderWidth = 2 diff --git a/deltachat-ios/Controller/Settings/Proxy/ProxyTableViewCell.swift b/deltachat-ios/Controller/Settings/Proxy/ProxyTableViewCell.swift index cc236d5b1..7160d8f44 100644 --- a/deltachat-ios/Controller/Settings/Proxy/ProxyTableViewCell.swift +++ b/deltachat-ios/Controller/Settings/Proxy/ProxyTableViewCell.swift @@ -2,24 +2,75 @@ import UIKit import DcCore class ProxyTableViewCell: UITableViewCell { + static let reuseIdentifier = "ProxyTableViewCell" - // make it look like the Android-version + let hostLabel: UILabel + let protocolLabel: UILabel + let connectionLabel: UILabel + + private let contentStackView: UIStackView + private let subtitleStackView: UIStackView override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { - super.init(style: .subtitle, reuseIdentifier: reuseIdentifier) + hostLabel = UILabel() + protocolLabel = UILabel() + + let detailsColor: UIColor + if #available(iOS 13.0, *) { + detailsColor = .secondaryLabel + } else { + detailsColor = .darkGray + } + protocolLabel.textColor = detailsColor + protocolLabel.font = UIFont.preferredFont(forTextStyle: .footnote) + + connectionLabel = UILabel() + connectionLabel.textColor = detailsColor + connectionLabel.font = UIFont.preferredFont(forTextStyle: .footnote) + + subtitleStackView = UIStackView( + arrangedSubviews: [ + connectionLabel, + UIView.borderedView(around: protocolLabel, borderWidth: 1, borderColor: detailsColor, cornerRadius: 2, padding: NSDirectionalEdgeInsets(top: 2, leading: 2, bottom: 2, trailing: 2)), + UIView() + ] + ) + subtitleStackView.translatesAutoresizingMaskIntoConstraints = false + subtitleStackView.spacing = 4 + + contentStackView = UIStackView(arrangedSubviews: [hostLabel, subtitleStackView]) + contentStackView.translatesAutoresizingMaskIntoConstraints = false + contentStackView.axis = .vertical + contentStackView.spacing = 6 - textLabel?.numberOfLines = 0 + super.init(style: style, reuseIdentifier: reuseIdentifier) + + contentView.addSubview(contentStackView) + + setupConstraints() } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } + private func setupConstraints() { + let constraints = [ + contentStackView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 8), + contentStackView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 8), + contentView.trailingAnchor.constraint(equalTo: contentStackView.trailingAnchor, constant: 8), + contentView.bottomAnchor.constraint(equalTo: contentStackView.bottomAnchor, constant: 8), + ] + + NSLayoutConstraint.activate(constraints) + } + func configure(with proxyUrlString: String, dcContext: DcContext) { let parsed = dcContext.checkQR(qrCode: proxyUrlString) let host = parsed.text1 let proxyProtocol = proxyUrlString.components(separatedBy: ":").first - textLabel?.text = host - detailTextLabel?.text = proxyProtocol + hostLabel.text = host + protocolLabel.text = proxyProtocol + //TODO: Add connectivity } } From 5e4df2fdfe29b44c71adc6bc1b160a290a59d18d Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Tue, 12 Nov 2024 13:01:35 +0100 Subject: [PATCH 18/27] Show connectivity-state (#2382) --- .../Proxy/ProxySettingsViewController.swift | 26 ++++++++++++++++++- .../Settings/Proxy/ProxyTableViewCell.swift | 13 +++++++--- 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/deltachat-ios/Controller/Settings/Proxy/ProxySettingsViewController.swift b/deltachat-ios/Controller/Settings/Proxy/ProxySettingsViewController.swift index 05d1666b3..6bfa0eb1a 100644 --- a/deltachat-ios/Controller/Settings/Proxy/ProxySettingsViewController.swift +++ b/deltachat-ios/Controller/Settings/Proxy/ProxySettingsViewController.swift @@ -57,10 +57,15 @@ class ProxySettingsViewController: UITableViewController { } title = String.localized("proxy_settings") + + NotificationCenter.default.addObserver(self, selector: #selector(ProxySettingsViewController.handleConnectivityChanged(_:)), name: Event.connectivityChanged, object: nil) + } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } + //MARK: - Actions + private func selectProxy(at indexPath: IndexPath) { let selectedProxyURL = proxies[indexPath.row] let host = dcContext.checkQR(qrCode: selectedProxyURL).text1 ?? "" @@ -155,6 +160,16 @@ class ProxySettingsViewController: UITableViewController { deleteAlert.addAction(deleteAction) present(deleteAlert, animated: true) } + + // MARK: - Notifications + + @objc private func handleConnectivityChanged(_ notification: Notification) { + DispatchQueue.main.async { [weak self] in + guard let self else { return } + + self.tableView.reloadData() + } + } } // MARK: - UITableViewDataSource @@ -203,14 +218,23 @@ extension ProxySettingsViewController { guard let cell = tableView.dequeueReusableCell(withIdentifier: ProxyTableViewCell.reuseIdentifier, for: indexPath) as? ProxyTableViewCell else { fatalError() } let proxyUrl = proxies[indexPath.row] - cell.configure(with: proxyUrl, dcContext: dcContext) + + let connectionStateText: String? if let selectedProxy, selectedProxy == proxyUrl { cell.accessoryType = .checkmark + if dcContext.isProxyEnabled { + connectionStateText = DcUtils.getConnectivityString(dcContext: dcContext, connectedString: String.localized("connectivity_connected")) + } else { + connectionStateText = String.localized("connectivity_not_connected") + } } else { cell.accessoryType = .none + connectionStateText = nil } + cell.configure(with: proxyUrl, dcContext: dcContext, connectionStateText: connectionStateText) + return cell } else /*if indexPath.section == ProxySettingsSection.add.rawValue*/ { return addProxyCell diff --git a/deltachat-ios/Controller/Settings/Proxy/ProxyTableViewCell.swift b/deltachat-ios/Controller/Settings/Proxy/ProxyTableViewCell.swift index 7160d8f44..bd4215f4d 100644 --- a/deltachat-ios/Controller/Settings/Proxy/ProxyTableViewCell.swift +++ b/deltachat-ios/Controller/Settings/Proxy/ProxyTableViewCell.swift @@ -31,8 +31,8 @@ class ProxyTableViewCell: UITableViewCell { subtitleStackView = UIStackView( arrangedSubviews: [ - connectionLabel, UIView.borderedView(around: protocolLabel, borderWidth: 1, borderColor: detailsColor, cornerRadius: 2, padding: NSDirectionalEdgeInsets(top: 2, leading: 2, bottom: 2, trailing: 2)), + connectionLabel, UIView() ] ) @@ -64,13 +64,20 @@ class ProxyTableViewCell: UITableViewCell { NSLayoutConstraint.activate(constraints) } - func configure(with proxyUrlString: String, dcContext: DcContext) { + func configure(with proxyUrlString: String, dcContext: DcContext, connectionStateText: String?) { let parsed = dcContext.checkQR(qrCode: proxyUrlString) let host = parsed.text1 let proxyProtocol = proxyUrlString.components(separatedBy: ":").first + hostLabel.text = host protocolLabel.text = proxyProtocol - //TODO: Add connectivity + + if let connectionStateText { + connectionLabel.text = connectionStateText + connectionLabel.isHidden = false + } else { + connectionLabel.isHidden = true + } } } From 53d49329ab7021b1f07be49198bbc073ec4982b2 Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Wed, 13 Nov 2024 10:02:15 +0100 Subject: [PATCH 19/27] No alert when selecting a proxy (#2382) --- .../Proxy/ProxySettingsViewController.swift | 28 ++++--------------- 1 file changed, 5 insertions(+), 23 deletions(-) diff --git a/deltachat-ios/Controller/Settings/Proxy/ProxySettingsViewController.swift b/deltachat-ios/Controller/Settings/Proxy/ProxySettingsViewController.swift index 6bfa0eb1a..06e5d78c2 100644 --- a/deltachat-ios/Controller/Settings/Proxy/ProxySettingsViewController.swift +++ b/deltachat-ios/Controller/Settings/Proxy/ProxySettingsViewController.swift @@ -64,32 +64,15 @@ class ProxySettingsViewController: UITableViewController { required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } - //MARK: - Actions + // MARK: - Actions private func selectProxy(at indexPath: IndexPath) { let selectedProxyURL = proxies[indexPath.row] - let host = dcContext.checkQR(qrCode: selectedProxyURL).text1 ?? "" - - let selectAlert = UIAlertController( - title: String.localized("proxy_use_proxy"), - message: String.localized(stringID: "proxy_use_proxy_confirm", parameter: host), - preferredStyle: .alert - ) - - let cancelAction = UIAlertAction(title: String.localized("cancel"), style: .cancel) - let selectAction = UIAlertAction(title: String.localized("proxy_use_proxy"), style: .default) { [weak self] _ in - - guard let self else { return } - if self.dcContext.setConfigFromQR(qrCode: selectedProxyURL) { - self.selectedProxy = selectedProxyURL - self.tableView.reloadData() - self.dcAccounts.restartIO() - } + if self.dcContext.setConfigFromQR(qrCode: selectedProxyURL) { + self.selectedProxy = selectedProxyURL + self.tableView.reloadData() + self.dcAccounts.restartIO() } - selectAlert.addAction(cancelAction) - selectAlert.addAction(selectAction) - - present(selectAlert, animated: true) } private func addProxy() { @@ -245,7 +228,6 @@ extension ProxySettingsViewController { override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { guard proxies.isEmpty == false else { return nil } - if section == ProxySettingsSection.proxies.rawValue { return ProxySettingsSection.proxies.title } else { From 4e7e8002316a5f0fbd1c49b381bb7ba0a5371e6d Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Wed, 13 Nov 2024 10:28:09 +0100 Subject: [PATCH 20/27] Select proxy after adding it (#2382) --- .../Settings/Proxy/ProxySettingsViewController.swift | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/deltachat-ios/Controller/Settings/Proxy/ProxySettingsViewController.swift b/deltachat-ios/Controller/Settings/Proxy/ProxySettingsViewController.swift index 06e5d78c2..c8d3eed4f 100644 --- a/deltachat-ios/Controller/Settings/Proxy/ProxySettingsViewController.swift +++ b/deltachat-ios/Controller/Settings/Proxy/ProxySettingsViewController.swift @@ -68,10 +68,10 @@ class ProxySettingsViewController: UITableViewController { private func selectProxy(at indexPath: IndexPath) { let selectedProxyURL = proxies[indexPath.row] - if self.dcContext.setConfigFromQR(qrCode: selectedProxyURL) { - self.selectedProxy = selectedProxyURL - self.tableView.reloadData() - self.dcAccounts.restartIO() + if dcContext.setConfigFromQR(qrCode: selectedProxyURL) { + selectedProxy = selectedProxyURL + tableView.reloadData() + dcAccounts.restartIO() } } @@ -90,6 +90,7 @@ class ProxySettingsViewController: UITableViewController { let parsedProxy = self.dcContext.checkQR(qrCode: proxyURL) if parsedProxy.state == DC_QR_PROXY, self.dcContext.setConfigFromQR(qrCode: proxyURL) { self.proxies.insert(proxyURL, at: self.proxies.startIndex) + self.selectedProxy = proxyURL self.dcContext.setProxies(proxyURLs: self.proxies) DispatchQueue.main.async { From 3ee31f684eecdb362788d17962cb3c5fa7ff5700 Mon Sep 17 00:00:00 2001 From: Nathan Mattes Date: Wed, 13 Nov 2024 12:28:44 +0100 Subject: [PATCH 21/27] Restart IO after adding a proxy (#2382) --- .../Controller/Settings/Proxy/ProxySettingsViewController.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/deltachat-ios/Controller/Settings/Proxy/ProxySettingsViewController.swift b/deltachat-ios/Controller/Settings/Proxy/ProxySettingsViewController.swift index c8d3eed4f..b9c272278 100644 --- a/deltachat-ios/Controller/Settings/Proxy/ProxySettingsViewController.swift +++ b/deltachat-ios/Controller/Settings/Proxy/ProxySettingsViewController.swift @@ -92,6 +92,7 @@ class ProxySettingsViewController: UITableViewController { self.proxies.insert(proxyURL, at: self.proxies.startIndex) self.selectedProxy = proxyURL self.dcContext.setProxies(proxyURLs: self.proxies) + self.dcAccounts.restartIO() DispatchQueue.main.async { self.toggleProxyCell.uiSwitch.isEnabled = (self.proxies.isEmpty == false) From a611de228ce10547491828850176731f7e63f7db Mon Sep 17 00:00:00 2001 From: zeitschlag Date: Wed, 13 Nov 2024 13:57:59 +0100 Subject: [PATCH 22/27] Update deltachat-ios/Controller/Settings/Proxy/ProxySettingsViewController.swift Co-authored-by: bjoern --- .../Controller/Settings/Proxy/ProxySettingsViewController.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deltachat-ios/Controller/Settings/Proxy/ProxySettingsViewController.swift b/deltachat-ios/Controller/Settings/Proxy/ProxySettingsViewController.swift index b9c272278..9e6adeda3 100644 --- a/deltachat-ios/Controller/Settings/Proxy/ProxySettingsViewController.swift +++ b/deltachat-ios/Controller/Settings/Proxy/ProxySettingsViewController.swift @@ -123,7 +123,7 @@ class ProxySettingsViewController: UITableViewController { let proxyToRemove = proxies[indexPath.row] let host = dcContext.checkQR(qrCode: proxyToRemove).text1 ?? "" - let deleteAlert = UIAlertController(title: String.localized("proxy_delete"), message: String.localized(stringID: "proxy_delete_explain", parameter: host), preferredStyle: .alert) + let deleteAlert = UIAlertController(title: String.localized("proxy_delete"), message: String.localized(stringID: "proxy_delete_explain", parameter: host), preferredStyle: .safeActionSheet) let cancelAction = UIAlertAction(title: String.localized("cancel"), style: .cancel) let deleteAction = UIAlertAction(title: String.localized("proxy_delete"), style: .destructive) { [weak self] _ in From 77273842dba29eec4d68b409d8737eb50932d0d6 Mon Sep 17 00:00:00 2001 From: zeitschlag Date: Wed, 13 Nov 2024 13:58:12 +0100 Subject: [PATCH 23/27] Update deltachat-ios/Controller/Settings/Proxy/ProxyTableViewCell.swift Co-authored-by: bjoern --- .../Controller/Settings/Proxy/ProxyTableViewCell.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deltachat-ios/Controller/Settings/Proxy/ProxyTableViewCell.swift b/deltachat-ios/Controller/Settings/Proxy/ProxyTableViewCell.swift index bd4215f4d..4ba8d5e3a 100644 --- a/deltachat-ios/Controller/Settings/Proxy/ProxyTableViewCell.swift +++ b/deltachat-ios/Controller/Settings/Proxy/ProxyTableViewCell.swift @@ -31,7 +31,7 @@ class ProxyTableViewCell: UITableViewCell { subtitleStackView = UIStackView( arrangedSubviews: [ - UIView.borderedView(around: protocolLabel, borderWidth: 1, borderColor: detailsColor, cornerRadius: 2, padding: NSDirectionalEdgeInsets(top: 2, leading: 2, bottom: 2, trailing: 2)), + UIView.borderedView(around: protocolLabel, borderWidth: 1, borderColor: detailsColor, cornerRadius: 2, padding: NSDirectionalEdgeInsets(top: 0, leading: 4, bottom: 0, trailing: 4)), connectionLabel, UIView() ] From 913b108907c38dc0901029566b619521ca45d0dd Mon Sep 17 00:00:00 2001 From: zeitschlag Date: Wed, 13 Nov 2024 13:58:23 +0100 Subject: [PATCH 24/27] Update deltachat-ios/Controller/Settings/Proxy/ProxyTableViewCell.swift Co-authored-by: bjoern --- .../Controller/Settings/Proxy/ProxyTableViewCell.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deltachat-ios/Controller/Settings/Proxy/ProxyTableViewCell.swift b/deltachat-ios/Controller/Settings/Proxy/ProxyTableViewCell.swift index 4ba8d5e3a..81421a85c 100644 --- a/deltachat-ios/Controller/Settings/Proxy/ProxyTableViewCell.swift +++ b/deltachat-ios/Controller/Settings/Proxy/ProxyTableViewCell.swift @@ -56,7 +56,7 @@ class ProxyTableViewCell: UITableViewCell { private func setupConstraints() { let constraints = [ contentStackView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 8), - contentStackView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 8), + contentStackView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 16), contentView.trailingAnchor.constraint(equalTo: contentStackView.trailingAnchor, constant: 8), contentView.bottomAnchor.constraint(equalTo: contentStackView.bottomAnchor, constant: 8), ] From f7e520cc4b355a3f16e1a701e6ccbf060b35c825 Mon Sep 17 00:00:00 2001 From: zeitschlag Date: Wed, 13 Nov 2024 15:31:42 +0100 Subject: [PATCH 25/27] Update deltachat-ios/Controller/Settings/Proxy/ProxySettingsViewController.swift Co-authored-by: bjoern --- .../Controller/Settings/Proxy/ProxySettingsViewController.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deltachat-ios/Controller/Settings/Proxy/ProxySettingsViewController.swift b/deltachat-ios/Controller/Settings/Proxy/ProxySettingsViewController.swift index 9e6adeda3..7bfdea8f8 100644 --- a/deltachat-ios/Controller/Settings/Proxy/ProxySettingsViewController.swift +++ b/deltachat-ios/Controller/Settings/Proxy/ProxySettingsViewController.swift @@ -275,7 +275,7 @@ extension ProxySettingsViewController { completion(true) } } - deleteAction.backgroundColor = .red + deleteAction.backgroundColor = .systemRed let configuration = UISwipeActionsConfiguration(actions: [deleteAction]) configuration.performsFirstActionWithFullSwipe = true From 69ac63b43a4e86bfc9772cee0aff4657f0238553 Mon Sep 17 00:00:00 2001 From: zeitschlag Date: Wed, 13 Nov 2024 15:51:53 +0100 Subject: [PATCH 26/27] Update deltachat-ios/Controller/Settings/Proxy/ProxySettingsViewController.swift Co-authored-by: bjoern --- .../Controller/Settings/Proxy/ProxySettingsViewController.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deltachat-ios/Controller/Settings/Proxy/ProxySettingsViewController.swift b/deltachat-ios/Controller/Settings/Proxy/ProxySettingsViewController.swift index 7bfdea8f8..22c5df3a9 100644 --- a/deltachat-ios/Controller/Settings/Proxy/ProxySettingsViewController.swift +++ b/deltachat-ios/Controller/Settings/Proxy/ProxySettingsViewController.swift @@ -269,7 +269,7 @@ extension ProxySettingsViewController { indexPath.section == ProxySettingsSection.proxies.rawValue else { return nil } - let deleteAction = UIContextualAction(style: .destructive, title: String.localized("proxy_delete")) { [weak self] _, _, completion in + let deleteAction = UIContextualAction(style: .destructive, title: String.localized("delete")) { [weak self] _, _, completion in DispatchQueue.main.async { self?.deleteProxy(at: indexPath) completion(true) From b588f394ee0c8bc1f62219344bccb0946c2c450c Mon Sep 17 00:00:00 2001 From: "B. Petersen" Date: Wed, 13 Nov 2024 16:05:11 +0100 Subject: [PATCH 27/27] show icon+text on swipe --- .../Settings/Proxy/ProxySettingsViewController.swift | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/deltachat-ios/Controller/Settings/Proxy/ProxySettingsViewController.swift b/deltachat-ios/Controller/Settings/Proxy/ProxySettingsViewController.swift index 22c5df3a9..9c616548d 100644 --- a/deltachat-ios/Controller/Settings/Proxy/ProxySettingsViewController.swift +++ b/deltachat-ios/Controller/Settings/Proxy/ProxySettingsViewController.swift @@ -269,13 +269,20 @@ extension ProxySettingsViewController { indexPath.section == ProxySettingsSection.proxies.rawValue else { return nil } - let deleteAction = UIContextualAction(style: .destructive, title: String.localized("delete")) { [weak self] _, _, completion in + let deleteAction = UIContextualAction(style: .destructive, title: nil) { [weak self] _, _, completion in DispatchQueue.main.async { self?.deleteProxy(at: indexPath) completion(true) } } deleteAction.backgroundColor = .systemRed + deleteAction.accessibilityLabel = String.localized("delete") + if #available(iOS 13.0, *) { + deleteAction.image = Utils.makeImageWithText(image: UIImage(systemName: "trash"), text: String.localized("delete")) + } else { + deleteAction.title = String.localized("delete") + } + let configuration = UISwipeActionsConfiguration(actions: [deleteAction]) configuration.performsFirstActionWithFullSwipe = true