Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add trailing status indicators for daita and multihop cells #7272

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 16 additions & 2 deletions ios/MullvadVPN/View controllers/Settings/SettingsCellFactory.swift
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,14 @@ final class SettingsCellFactory: CellFactoryProtocol {
value: "DAITA",
comment: ""
)
cell.detailTitleLabel.text = nil

cell.detailTitleLabel.text = NSLocalizedString(
"DAITA_CELL_DETAIL_LABEL",
tableName: "Settings",
value: viewModel.daitaSettings.daitaState.isEnabled ? "On" : "Off",
comment: ""
)

cell.accessibilityIdentifier = item.accessibilityIdentifier
cell.disclosureType = .chevron

Expand All @@ -124,7 +131,14 @@ final class SettingsCellFactory: CellFactoryProtocol {
value: "Multihop",
comment: ""
)
cell.detailTitleLabel.text = nil

cell.detailTitleLabel.text = NSLocalizedString(
"MULTIHOP_CELL_DETAIL_LABEL",
tableName: "Settings",
value: viewModel.multihopState.isEnabled ? "On" : "Off",
comment: ""
)

cell.accessibilityIdentifier = item.accessibilityIdentifier
cell.disclosureType = .chevron
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,14 @@ final class SettingsDataSource: UITableViewDiffableDataSource<SettingsDataSource
storedAccountData = interactor.deviceState.accountData
}

func reload(from tunnelSettings: LatestTunnelSettings) {
settingsCellFactory.viewModel = SettingsViewModel(from: tunnelSettings)

var snapshot = snapshot()
snapshot.reconfigureItems(snapshot.itemIdentifiers)
apply(snapshot, animatingDifferences: false)
}

// MARK: - UITableViewDelegate

func tableView(_ tableView: UITableView, shouldHighlightRowAt indexPath: IndexPath) -> Bool {
Expand Down Expand Up @@ -171,10 +179,4 @@ extension SettingsDataSource: SettingsCellEventHandler {
func showInfo(for button: SettingsInfoButtonItem) {
delegate?.showInfo(for: button)
}

private func reloadItem(_ item: Item) {
var snapshot = snapshot()
snapshot.reloadItems([item])
apply(snapshot, animatingDifferences: false)
}
}
41 changes: 9 additions & 32 deletions ios/MullvadVPN/View controllers/Settings/SettingsInteractor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ final class SettingsInteractor {
private var tunnelObserver: TunnelObserver?

var didUpdateDeviceState: ((DeviceState) -> Void)?
var didUpdateTunnelSettings: ((LatestTunnelSettings) -> Void)?

var tunnelSettings: LatestTunnelSettings {
tunnelManager.settings
Expand All @@ -28,41 +29,17 @@ final class SettingsInteractor {
self.tunnelManager = tunnelManager

let tunnelObserver =
TunnelBlockObserver(didUpdateDeviceState: { [weak self] _, deviceState, _ in
self?.didUpdateDeviceState?(deviceState)
})
TunnelBlockObserver(
didUpdateDeviceState: { [weak self] _, deviceState, _ in
self?.didUpdateDeviceState?(deviceState)
},
didUpdateTunnelSettings: { [weak self] _, settings in
self?.didUpdateTunnelSettings?(settings)
}
)

tunnelManager.addObserver(tunnelObserver)

self.tunnelObserver = tunnelObserver
}

func updateDAITASettings(_ settings: DAITASettings) {
tunnelManager.updateSettings([.daita(settings)])
}

func evaluateDaitaSettingsCompatibility(_ settings: DAITASettings) -> DAITASettingsCompatibilityError? {
guard settings.daitaState.isEnabled else { return nil }

var tunnelSettings = tunnelSettings
tunnelSettings.daita = settings

var compatibilityError: DAITASettingsCompatibilityError?

do {
_ = try tunnelManager.selectRelays(tunnelSettings: tunnelSettings)
} catch let error as NoRelaysSatisfyingConstraintsError where error.reason == .noDaitaRelaysFound {
// Return error if no relays could be selected due to DAITA constraints.
compatibilityError = tunnelSettings.tunnelMultihopState.isEnabled ? .multihop : .singlehop
} catch _ as NoRelaysSatisfyingConstraintsError {
// Even if the constraints error is not DAITA specific, if both DAITA and Direct only are enabled,
// we should return a DAITA related error since the current settings would have resulted in the
// relay selector not being able to select a DAITA relay anyway.
if settings.isDirectOnly {
compatibilityError = tunnelSettings.tunnelMultihopState.isEnabled ? .multihop : .singlehop
}
} catch {}

return compatibilityError
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@ class SettingsViewController: UITableViewController {

dataSource = SettingsDataSource(tableView: tableView, interactor: interactor)
dataSource?.delegate = self

interactor.didUpdateTunnelSettings = { [weak self] newSettings in
self?.dataSource?.reload(from: newSettings)
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,10 @@ import MullvadSettings

struct SettingsViewModel {
private(set) var daitaSettings: DAITASettings

mutating func setDAITASettings(_ newSettings: DAITASettings) {
daitaSettings = newSettings
}
private(set) var multihopState: MultihopState

init(from tunnelSettings: LatestTunnelSettings = LatestTunnelSettings()) {
daitaSettings = tunnelSettings.daita
multihopState = tunnelSettings.tunnelMultihopState
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -411,4 +411,4 @@ struct SingleChoiceList<Value>: View where Value: Equatable {
)
}
}
}
} // swiftlint:disable:this file_length
40 changes: 40 additions & 0 deletions ios/MullvadVPNUITests/Pages/SettingsPage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,26 @@ class SettingsPage: Page {
return self
}

@discardableResult func verifyDAITAOn() -> Self {
let textElement = app.tables[AccessibilityIdentifier.settingsTableView]
.cells[AccessibilityIdentifier.daitaCell]
.staticTexts["On"]

XCTAssertTrue(textElement.exists)

return self
}

@discardableResult func verifyDAITAOff() -> Self {
let textElement = app.tables[AccessibilityIdentifier.settingsTableView]
.cells[AccessibilityIdentifier.daitaCell]
.staticTexts["Off"]

XCTAssertTrue(textElement.exists)

return self
}

@discardableResult func tapMultihopCell() -> Self {
app.tables[AccessibilityIdentifier.settingsTableView]
.cells[AccessibilityIdentifier.multihopCell]
Expand All @@ -48,6 +68,26 @@ class SettingsPage: Page {
return self
}

@discardableResult func verifyMultihopOn() -> Self {
let textElement = app.tables[AccessibilityIdentifier.settingsTableView]
.cells[AccessibilityIdentifier.multihopCell]
.staticTexts["On"]

XCTAssertTrue(textElement.exists)

return self
}

@discardableResult func verifyMultihopOff() -> Self {
let textElement = app.tables[AccessibilityIdentifier.settingsTableView]
.cells[AccessibilityIdentifier.multihopCell]
.staticTexts["Off"]

XCTAssertTrue(textElement.exists)

return self
}

@discardableResult func tapVPNSettingsCell() -> Self {
app.tables[AccessibilityIdentifier.settingsTableView]
.cells[AccessibilityIdentifier.vpnSettingsCell]
Expand Down
4 changes: 4 additions & 0 deletions ios/MullvadVPNUITests/RelayTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,7 @@ class RelayTests: LoggedInWithTimeUITestCase {
.tapSettingsButton()

SettingsPage(app)
.verifyDAITAOff()
.tapDAITACell()

DAITAPage(app)
Expand All @@ -313,6 +314,7 @@ class RelayTests: LoggedInWithTimeUITestCase {
.tapBackButton()

SettingsPage(app)
.verifyDAITAOn()
.tapDoneButton()

TunnelControlPage(app)
Expand Down Expand Up @@ -343,6 +345,7 @@ class RelayTests: LoggedInWithTimeUITestCase {
.tapSettingsButton()

SettingsPage(app)
.verifyMultihopOff()
.tapMultihopCell()

MultihopPage(app)
Expand All @@ -351,6 +354,7 @@ class RelayTests: LoggedInWithTimeUITestCase {
.tapBackButton()

SettingsPage(app)
.verifyMultihopOn()
.tapDoneButton()

TunnelControlPage(app)
Expand Down
Loading