summaryrefslogtreecommitdiffhomepage
path: root/android/app/src
diff options
context:
space:
mode:
authorJonatan Rhodin <jonatan.rhodin@mullvad.net>2023-10-25 14:03:36 +0200
committerJonatan Rhodin <jonatan.rhodin@mullvad.net>2023-10-25 14:03:36 +0200
commit78ed10bb270c915157f8ca3e8bbb9fd1f381a8b3 (patch)
tree174e5c9cd9c210347b367827ac42290b28541d6f /android/app/src
parentc0cfd41987eac1ba5c8701c8e166dd13f9537406 (diff)
parente8e1762498bc537a71397a8fd5791af1618ec791 (diff)
downloadmullvadvpn-78ed10bb270c915157f8ca3e8bbb9fd1f381a8b3.tar.xz
mullvadvpn-78ed10bb270c915157f8ca3e8bbb9fd1f381a8b3.zip
Merge branch 'show-popup-when-enabling-custom-dns-server-and-server-list-droid-320'
Diffstat (limited to 'android/app/src')
-rw-r--r--android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/VpnSettingsScreenTest.kt201
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/VpnSettingsScreen.kt36
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/state/VpnSettingsUiState.kt205
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/VpnSettingsFragment.kt2
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/VpnSettingsViewModel.kt20
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/VpnSettingsViewModelState.kt198
-rw-r--r--android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/VpnSettingsViewModelTest.kt6
7 files changed, 264 insertions, 404 deletions
diff --git a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/VpnSettingsScreenTest.kt b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/VpnSettingsScreenTest.kt
index e5b7ebedb0..3eee07e2e6 100644
--- a/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/VpnSettingsScreenTest.kt
+++ b/android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/screen/VpnSettingsScreenTest.kt
@@ -16,6 +16,7 @@ import io.mockk.verify
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.asSharedFlow
import net.mullvad.mullvadvpn.compose.setContentWithTheme
+import net.mullvad.mullvadvpn.compose.state.VpnSettingsDialog
import net.mullvad.mullvadvpn.compose.state.VpnSettingsUiState
import net.mullvad.mullvadvpn.compose.test.CUSTOM_PORT_DIALOG_INPUT_TEST_TAG
import net.mullvad.mullvadvpn.compose.test.LAZY_LIST_LAST_ITEM_TEST_TAG
@@ -49,7 +50,7 @@ class VpnSettingsScreenTest {
// Arrange
composeTestRule.setContentWithTheme {
VpnSettingsScreen(
- uiState = VpnSettingsUiState.DefaultUiState(),
+ uiState = VpnSettingsUiState.createDefault(),
toastMessagesSharedFlow = MutableSharedFlow<String>().asSharedFlow()
)
}
@@ -75,7 +76,7 @@ class VpnSettingsScreenTest {
// Arrange
composeTestRule.setContentWithTheme {
VpnSettingsScreen(
- uiState = VpnSettingsUiState.DefaultUiState(mtu = VALID_DUMMY_MTU_VALUE),
+ uiState = VpnSettingsUiState.createDefault(mtu = VALID_DUMMY_MTU_VALUE),
toastMessagesSharedFlow = MutableSharedFlow<String>().asSharedFlow()
)
}
@@ -90,7 +91,7 @@ class VpnSettingsScreenTest {
val mockedClickHandler: () -> Unit = mockk(relaxed = true)
composeTestRule.setContentWithTheme {
VpnSettingsScreen(
- uiState = VpnSettingsUiState.DefaultUiState(),
+ uiState = VpnSettingsUiState.createDefault(),
onMtuCellClick = mockedClickHandler,
toastMessagesSharedFlow = MutableSharedFlow<String>().asSharedFlow()
)
@@ -108,7 +109,10 @@ class VpnSettingsScreenTest {
// Arrange
composeTestRule.setContentWithTheme {
VpnSettingsScreen(
- uiState = VpnSettingsUiState.MtuDialogUiState(mtuEditValue = EMPTY_STRING),
+ uiState =
+ VpnSettingsUiState.createDefault(
+ dialog = VpnSettingsDialog.Mtu(mtuEditValue = EMPTY_STRING),
+ ),
toastMessagesSharedFlow = MutableSharedFlow<String>().asSharedFlow()
)
}
@@ -122,7 +126,7 @@ class VpnSettingsScreenTest {
// Arrange
composeTestRule.setContentWithTheme {
VpnSettingsScreen(
- uiState = VpnSettingsUiState.MtuDialogUiState(mtuEditValue = VALID_DUMMY_MTU_VALUE),
+ uiState = VpnSettingsUiState.createDefault(mtu = VALID_DUMMY_MTU_VALUE),
toastMessagesSharedFlow = MutableSharedFlow<String>().asSharedFlow()
)
}
@@ -136,7 +140,10 @@ class VpnSettingsScreenTest {
// Arrange
composeTestRule.setContentWithTheme {
VpnSettingsScreen(
- uiState = VpnSettingsUiState.MtuDialogUiState(mtuEditValue = EMPTY_STRING),
+ uiState =
+ VpnSettingsUiState.createDefault(
+ dialog = VpnSettingsDialog.Mtu(mtuEditValue = EMPTY_STRING)
+ ),
toastMessagesSharedFlow = MutableSharedFlow<String>().asSharedFlow()
)
}
@@ -154,7 +161,10 @@ class VpnSettingsScreenTest {
val mockedSubmitHandler: (Int) -> Unit = mockk(relaxed = true)
composeTestRule.setContentWithTheme {
VpnSettingsScreen(
- uiState = VpnSettingsUiState.MtuDialogUiState(mtuEditValue = VALID_DUMMY_MTU_VALUE),
+ uiState =
+ VpnSettingsUiState.createDefault(
+ dialog = VpnSettingsDialog.Mtu(mtuEditValue = VALID_DUMMY_MTU_VALUE)
+ ),
onSaveMtuClick = mockedSubmitHandler,
toastMessagesSharedFlow = MutableSharedFlow<String>().asSharedFlow()
)
@@ -173,7 +183,9 @@ class VpnSettingsScreenTest {
composeTestRule.setContentWithTheme {
VpnSettingsScreen(
uiState =
- VpnSettingsUiState.MtuDialogUiState(mtuEditValue = INVALID_DUMMY_MTU_VALUE),
+ VpnSettingsUiState.createDefault(
+ dialog = VpnSettingsDialog.Mtu(mtuEditValue = INVALID_DUMMY_MTU_VALUE)
+ ),
toastMessagesSharedFlow = MutableSharedFlow<String>().asSharedFlow()
)
}
@@ -188,7 +200,10 @@ class VpnSettingsScreenTest {
val mockedClickHandler: () -> Unit = mockk(relaxed = true)
composeTestRule.setContentWithTheme {
VpnSettingsScreen(
- uiState = VpnSettingsUiState.MtuDialogUiState(mtuEditValue = EMPTY_STRING),
+ uiState =
+ VpnSettingsUiState.createDefault(
+ dialog = VpnSettingsDialog.Mtu(mtuEditValue = EMPTY_STRING)
+ ),
onRestoreMtuClick = mockedClickHandler,
toastMessagesSharedFlow = MutableSharedFlow<String>().asSharedFlow()
)
@@ -207,7 +222,10 @@ class VpnSettingsScreenTest {
val mockedClickHandler: () -> Unit = mockk(relaxed = true)
composeTestRule.setContentWithTheme {
VpnSettingsScreen(
- uiState = VpnSettingsUiState.MtuDialogUiState(mtuEditValue = EMPTY_STRING),
+ uiState =
+ VpnSettingsUiState.createDefault(
+ dialog = VpnSettingsDialog.Mtu(mtuEditValue = EMPTY_STRING)
+ ),
onCancelMtuDialogClick = mockedClickHandler,
toastMessagesSharedFlow = MutableSharedFlow<String>().asSharedFlow()
)
@@ -226,7 +244,7 @@ class VpnSettingsScreenTest {
composeTestRule.setContentWithTheme {
VpnSettingsScreen(
uiState =
- VpnSettingsUiState.DefaultUiState(
+ VpnSettingsUiState.createDefault(
isCustomDnsEnabled = true,
isAllowLanEnabled = false,
customDnsItems =
@@ -257,7 +275,7 @@ class VpnSettingsScreenTest {
composeTestRule.setContentWithTheme {
VpnSettingsScreen(
uiState =
- VpnSettingsUiState.DefaultUiState(
+ VpnSettingsUiState.createDefault(
isCustomDnsEnabled = false,
customDnsItems = listOf(CustomDnsItem(address = DUMMY_DNS_ADDRESS, false))
),
@@ -278,7 +296,7 @@ class VpnSettingsScreenTest {
composeTestRule.setContentWithTheme {
VpnSettingsScreen(
uiState =
- VpnSettingsUiState.DefaultUiState(
+ VpnSettingsUiState.createDefault(
isCustomDnsEnabled = true,
isAllowLanEnabled = true,
customDnsItems =
@@ -298,7 +316,7 @@ class VpnSettingsScreenTest {
composeTestRule.setContentWithTheme {
VpnSettingsScreen(
uiState =
- VpnSettingsUiState.DefaultUiState(
+ VpnSettingsUiState.createDefault(
isCustomDnsEnabled = true,
isAllowLanEnabled = false,
customDnsItems =
@@ -318,7 +336,7 @@ class VpnSettingsScreenTest {
composeTestRule.setContentWithTheme {
VpnSettingsScreen(
uiState =
- VpnSettingsUiState.DefaultUiState(
+ VpnSettingsUiState.createDefault(
isCustomDnsEnabled = true,
isAllowLanEnabled = true,
customDnsItems =
@@ -338,7 +356,7 @@ class VpnSettingsScreenTest {
composeTestRule.setContentWithTheme {
VpnSettingsScreen(
uiState =
- VpnSettingsUiState.DefaultUiState(
+ VpnSettingsUiState.createDefault(
isCustomDnsEnabled = true,
isAllowLanEnabled = false,
customDnsItems =
@@ -363,7 +381,7 @@ class VpnSettingsScreenTest {
val mockedClickHandler: (Int?) -> Unit = mockk(relaxed = true)
composeTestRule.setContentWithTheme {
VpnSettingsScreen(
- uiState = VpnSettingsUiState.DefaultUiState(isCustomDnsEnabled = true),
+ uiState = VpnSettingsUiState.createDefault(isCustomDnsEnabled = true),
onDnsClick = mockedClickHandler,
toastMessagesSharedFlow = MutableSharedFlow<String>().asSharedFlow()
)
@@ -385,11 +403,14 @@ class VpnSettingsScreenTest {
composeTestRule.setContentWithTheme {
VpnSettingsScreen(
uiState =
- VpnSettingsUiState.DnsDialogUiState(
- stagedDns =
- StagedDns.NewDns(
- item = CustomDnsItem(DUMMY_DNS_ADDRESS, isLocal = false)
- ),
+ VpnSettingsUiState.createDefault(
+ dialog =
+ VpnSettingsDialog.Dns(
+ stagedDns =
+ StagedDns.NewDns(
+ item = CustomDnsItem(DUMMY_DNS_ADDRESS, isLocal = false)
+ ),
+ )
),
toastMessagesSharedFlow = MutableSharedFlow<String>().asSharedFlow()
)
@@ -405,11 +426,14 @@ class VpnSettingsScreenTest {
composeTestRule.setContentWithTheme {
VpnSettingsScreen(
uiState =
- VpnSettingsUiState.DnsDialogUiState(
- stagedDns =
- StagedDns.EditDns(
- item = CustomDnsItem(DUMMY_DNS_ADDRESS, isLocal = false),
- index = 0
+ VpnSettingsUiState.createDefault(
+ dialog =
+ VpnSettingsDialog.Dns(
+ stagedDns =
+ StagedDns.EditDns(
+ item = CustomDnsItem(DUMMY_DNS_ADDRESS, isLocal = false),
+ index = 0
+ )
)
),
toastMessagesSharedFlow = MutableSharedFlow<String>().asSharedFlow()
@@ -426,11 +450,14 @@ class VpnSettingsScreenTest {
composeTestRule.setContentWithTheme {
VpnSettingsScreen(
uiState =
- VpnSettingsUiState.DnsDialogUiState(
- stagedDns =
- StagedDns.NewDns(
- item = CustomDnsItem(DUMMY_DNS_ADDRESS, isLocal = true),
- validationResult = StagedDns.ValidationResult.Success
+ VpnSettingsUiState.createDefault(
+ dialog =
+ VpnSettingsDialog.Dns(
+ stagedDns =
+ StagedDns.NewDns(
+ item = CustomDnsItem(DUMMY_DNS_ADDRESS, isLocal = true),
+ validationResult = StagedDns.ValidationResult.Success
+ ),
),
isAllowLanEnabled = false
),
@@ -448,11 +475,14 @@ class VpnSettingsScreenTest {
composeTestRule.setContentWithTheme {
VpnSettingsScreen(
uiState =
- VpnSettingsUiState.DnsDialogUiState(
- stagedDns =
- StagedDns.NewDns(
- item = CustomDnsItem(DUMMY_DNS_ADDRESS, isLocal = true),
- validationResult = StagedDns.ValidationResult.Success
+ VpnSettingsUiState.createDefault(
+ dialog =
+ VpnSettingsDialog.Dns(
+ stagedDns =
+ StagedDns.NewDns(
+ item = CustomDnsItem(DUMMY_DNS_ADDRESS, isLocal = true),
+ validationResult = StagedDns.ValidationResult.Success
+ ),
),
isAllowLanEnabled = true
),
@@ -470,11 +500,14 @@ class VpnSettingsScreenTest {
composeTestRule.setContentWithTheme {
VpnSettingsScreen(
uiState =
- VpnSettingsUiState.DnsDialogUiState(
- stagedDns =
- StagedDns.NewDns(
- item = CustomDnsItem(DUMMY_DNS_ADDRESS, isLocal = false),
- validationResult = StagedDns.ValidationResult.Success
+ VpnSettingsUiState.createDefault(
+ dialog =
+ VpnSettingsDialog.Dns(
+ stagedDns =
+ StagedDns.NewDns(
+ item = CustomDnsItem(DUMMY_DNS_ADDRESS, isLocal = false),
+ validationResult = StagedDns.ValidationResult.Success
+ ),
),
isAllowLanEnabled = true
),
@@ -492,11 +525,14 @@ class VpnSettingsScreenTest {
composeTestRule.setContentWithTheme {
VpnSettingsScreen(
uiState =
- VpnSettingsUiState.DnsDialogUiState(
- stagedDns =
- StagedDns.NewDns(
- item = CustomDnsItem(DUMMY_DNS_ADDRESS, isLocal = false),
- validationResult = StagedDns.ValidationResult.Success
+ VpnSettingsUiState.createDefault(
+ dialog =
+ VpnSettingsDialog.Dns(
+ stagedDns =
+ StagedDns.NewDns(
+ item = CustomDnsItem(DUMMY_DNS_ADDRESS, isLocal = false),
+ validationResult = StagedDns.ValidationResult.Success
+ ),
),
isAllowLanEnabled = false
),
@@ -514,11 +550,14 @@ class VpnSettingsScreenTest {
composeTestRule.setContentWithTheme {
VpnSettingsScreen(
uiState =
- VpnSettingsUiState.DnsDialogUiState(
- stagedDns =
- StagedDns.NewDns(
- item = CustomDnsItem(DUMMY_DNS_ADDRESS, isLocal = false),
- validationResult = StagedDns.ValidationResult.InvalidAddress
+ VpnSettingsUiState.createDefault(
+ dialog =
+ VpnSettingsDialog.Dns(
+ stagedDns =
+ StagedDns.NewDns(
+ item = CustomDnsItem(DUMMY_DNS_ADDRESS, isLocal = false),
+ validationResult = StagedDns.ValidationResult.InvalidAddress
+ )
)
),
toastMessagesSharedFlow = MutableSharedFlow<String>().asSharedFlow()
@@ -535,12 +574,16 @@ class VpnSettingsScreenTest {
composeTestRule.setContentWithTheme {
VpnSettingsScreen(
uiState =
- VpnSettingsUiState.DnsDialogUiState(
- stagedDns =
- StagedDns.NewDns(
- item = CustomDnsItem(DUMMY_DNS_ADDRESS, isLocal = false),
- validationResult = StagedDns.ValidationResult.DuplicateAddress
- )
+ VpnSettingsUiState.createDefault(
+ dialog =
+ VpnSettingsDialog.Dns(
+ stagedDns =
+ StagedDns.NewDns(
+ item = CustomDnsItem(DUMMY_DNS_ADDRESS, isLocal = false),
+ validationResult =
+ StagedDns.ValidationResult.DuplicateAddress
+ )
+ ),
),
toastMessagesSharedFlow = MutableSharedFlow<String>().asSharedFlow()
)
@@ -556,7 +599,7 @@ class VpnSettingsScreenTest {
composeTestRule.setContentWithTheme {
VpnSettingsScreen(
uiState =
- VpnSettingsUiState.DefaultUiState(quantumResistant = QuantumResistantState.On),
+ VpnSettingsUiState.createDefault(quantumResistant = QuantumResistantState.On),
toastMessagesSharedFlow = MutableSharedFlow<String>().asSharedFlow()
)
}
@@ -578,7 +621,7 @@ class VpnSettingsScreenTest {
composeTestRule.setContentWithTheme {
VpnSettingsScreen(
uiState =
- VpnSettingsUiState.DefaultUiState(
+ VpnSettingsUiState.createDefault(
quantumResistant = QuantumResistantState.Auto,
),
onSelectQuantumResistanceSetting = mockSelectQuantumResistantSettingListener,
@@ -603,7 +646,10 @@ class VpnSettingsScreenTest {
// Arrange
composeTestRule.setContentWithTheme {
VpnSettingsScreen(
- uiState = VpnSettingsUiState.QuantumResistanceInfoDialogUiState(),
+ uiState =
+ VpnSettingsUiState.createDefault(
+ dialog = VpnSettingsDialog.QuantumResistanceInfo
+ ),
toastMessagesSharedFlow = MutableSharedFlow<String>().asSharedFlow()
)
}
@@ -618,7 +664,7 @@ class VpnSettingsScreenTest {
composeTestRule.setContentWithTheme {
VpnSettingsScreen(
uiState =
- VpnSettingsUiState.DefaultUiState(
+ VpnSettingsUiState.createDefault(
selectedWireguardPort = Constraint.Only(Port(53))
),
toastMessagesSharedFlow = MutableSharedFlow<String>().asSharedFlow()
@@ -649,7 +695,7 @@ class VpnSettingsScreenTest {
composeTestRule.setContentWithTheme {
VpnSettingsScreen(
uiState =
- VpnSettingsUiState.DefaultUiState(
+ VpnSettingsUiState.createDefault(
selectedWireguardPort = Constraint.Only(Port(53))
),
onWireguardPortSelected = mockSelectWireguardPortSelectionListener,
@@ -682,8 +728,11 @@ class VpnSettingsScreenTest {
composeTestRule.setContentWithTheme {
VpnSettingsScreen(
uiState =
- VpnSettingsUiState.WireguardPortInfoDialogUiState(
- availablePortRanges = listOf(PortRange(53, 53), PortRange(120, 121))
+ VpnSettingsUiState.createDefault(
+ dialog =
+ VpnSettingsDialog.WireguardPortInfo(
+ availablePortRanges = listOf(PortRange(53, 53), PortRange(120, 121))
+ )
),
toastMessagesSharedFlow = MutableSharedFlow<String>().asSharedFlow()
)
@@ -703,8 +752,11 @@ class VpnSettingsScreenTest {
composeTestRule.setContentWithTheme {
VpnSettingsScreen(
uiState =
- VpnSettingsUiState.CustomPortDialogUiState(
- availablePortRanges = listOf(PortRange(53, 53), PortRange(120, 121))
+ VpnSettingsUiState.createDefault(
+ dialog =
+ VpnSettingsDialog.CustomPort(
+ availablePortRanges = listOf(PortRange(53, 53), PortRange(120, 121))
+ )
),
toastMessagesSharedFlow = MutableSharedFlow<String>().asSharedFlow()
)
@@ -720,7 +772,7 @@ class VpnSettingsScreenTest {
composeTestRule.setContentWithTheme {
VpnSettingsScreen(
uiState =
- VpnSettingsUiState.DefaultUiState(
+ VpnSettingsUiState.createDefault(
selectedWireguardPort = Constraint.Only(Port(4000))
),
toastMessagesSharedFlow = MutableSharedFlow<String>().asSharedFlow()
@@ -742,7 +794,7 @@ class VpnSettingsScreenTest {
val mockOnShowCustomPortDialog: () -> Unit = mockk(relaxed = true)
composeTestRule.setContentWithTheme {
VpnSettingsScreen(
- uiState = VpnSettingsUiState.DefaultUiState(),
+ uiState = VpnSettingsUiState.createDefault(),
onShowCustomPortDialog = mockOnShowCustomPortDialog,
toastMessagesSharedFlow = MutableSharedFlow<String>().asSharedFlow()
)
@@ -765,7 +817,7 @@ class VpnSettingsScreenTest {
composeTestRule.setContentWithTheme {
VpnSettingsScreen(
uiState =
- VpnSettingsUiState.DefaultUiState(
+ VpnSettingsUiState.createDefault(
selectedWireguardPort = Constraint.Only(Port(4000))
),
onShowCustomPortDialog = mockOnShowCustomPortDialog,
@@ -792,7 +844,7 @@ class VpnSettingsScreenTest {
composeTestRule.setContentWithTheme {
VpnSettingsScreen(
uiState =
- VpnSettingsUiState.DefaultUiState(
+ VpnSettingsUiState.createDefault(
selectedWireguardPort = Constraint.Only(Port(4000))
),
onWireguardPortSelected = onWireguardPortSelected,
@@ -821,8 +873,11 @@ class VpnSettingsScreenTest {
composeTestRule.setContentWithTheme {
VpnSettingsScreen(
uiState =
- VpnSettingsUiState.CustomPortDialogUiState(
- availablePortRanges = listOf(PortRange(53, 53), PortRange(120, 121))
+ VpnSettingsUiState.createDefault(
+ dialog =
+ VpnSettingsDialog.CustomPort(
+ availablePortRanges = listOf(PortRange(53, 53), PortRange(120, 121))
+ )
),
toastMessagesSharedFlow = MutableSharedFlow<String>().asSharedFlow()
)
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/VpnSettingsScreen.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/VpnSettingsScreen.kt
index c65710f17b..4e08e06a1d 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/VpnSettingsScreen.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/VpnSettingsScreen.kt
@@ -61,6 +61,7 @@ import net.mullvad.mullvadvpn.compose.dialog.ObfuscationInfoDialog
import net.mullvad.mullvadvpn.compose.dialog.QuantumResistanceInfoDialog
import net.mullvad.mullvadvpn.compose.dialog.WireguardPortInfoDialog
import net.mullvad.mullvadvpn.compose.extensions.itemWithDivider
+import net.mullvad.mullvadvpn.compose.state.VpnSettingsDialog
import net.mullvad.mullvadvpn.compose.state.VpnSettingsUiState
import net.mullvad.mullvadvpn.compose.test.LAZY_LIST_LAST_ITEM_TEST_TAG
import net.mullvad.mullvadvpn.compose.test.LAZY_LIST_QUANTUM_ITEM_OFF_TEST_TAG
@@ -87,7 +88,7 @@ private fun PreviewVpnSettings() {
AppTheme {
VpnSettingsScreen(
uiState =
- VpnSettingsUiState.DefaultUiState(
+ VpnSettingsUiState.createDefault(
isAutoConnectEnabled = true,
mtu = "1337",
isCustomDnsEnabled = true,
@@ -175,18 +176,18 @@ fun VpnSettingsScreen(
) {
val savedCustomPort = rememberSaveable { mutableStateOf<Constraint<Port>>(Constraint.Any()) }
- when (uiState) {
- is VpnSettingsUiState.MtuDialogUiState -> {
+ when (val dialog = uiState.dialog) {
+ is VpnSettingsDialog.Mtu -> {
MtuDialog(
- mtuInitial = uiState.mtuEditValue.toIntOrNull(),
+ mtuInitial = dialog.mtuEditValue.toIntOrNull(),
onSave = { onSaveMtuClick(it) },
onRestoreDefaultValue = { onRestoreMtuClick() },
onDismiss = { onCancelMtuDialogClick() }
)
}
- is VpnSettingsUiState.DnsDialogUiState -> {
+ is VpnSettingsDialog.Dns -> {
DnsDialog(
- stagedDns = uiState.stagedDns,
+ stagedDns = dialog.stagedDns,
isAllowLanEnabled = uiState.isAllowLanEnabled,
onIpAddressChanged = { onDnsInputChange(it) },
onAttemptToSave = { onSaveDnsClick() },
@@ -194,31 +195,31 @@ fun VpnSettingsScreen(
onDismiss = { onCancelDnsDialogClick() }
)
}
- is VpnSettingsUiState.LocalNetworkSharingInfoDialogUiState -> {
+ is VpnSettingsDialog.LocalNetworkSharingInfo -> {
LocalNetworkSharingInfoDialog(onDismissInfoClick)
}
- is VpnSettingsUiState.ContentBlockersInfoDialogUiState -> {
+ is VpnSettingsDialog.ContentBlockersInfo -> {
ContentBlockersInfoDialog(onDismissInfoClick)
}
- is VpnSettingsUiState.CustomDnsInfoDialogUiState -> {
+ is VpnSettingsDialog.CustomDnsInfo -> {
CustomDnsInfoDialog(onDismissInfoClick)
}
- is VpnSettingsUiState.MalwareInfoDialogUiState -> {
+ is VpnSettingsDialog.MalwareInfo -> {
MalwareInfoDialog(onDismissInfoClick)
}
- is VpnSettingsUiState.ObfuscationInfoDialogUiState -> {
+ is VpnSettingsDialog.ObfuscationInfo -> {
ObfuscationInfoDialog(onDismissInfoClick)
}
- is VpnSettingsUiState.QuantumResistanceInfoDialogUiState -> {
+ is VpnSettingsDialog.QuantumResistanceInfo -> {
QuantumResistanceInfoDialog(onDismissInfoClick)
}
- is VpnSettingsUiState.WireguardPortInfoDialogUiState -> {
- WireguardPortInfoDialog(uiState.availablePortRanges, onDismissInfoClick)
+ is VpnSettingsDialog.WireguardPortInfo -> {
+ WireguardPortInfoDialog(dialog.availablePortRanges, onDismissInfoClick)
}
- is VpnSettingsUiState.CustomPortDialogUiState -> {
+ is VpnSettingsDialog.CustomPort -> {
CustomPortDialog(
customPort = savedCustomPort.value.toDisplayCustomPort(),
- allowedPortRanges = uiState.availablePortRanges,
+ allowedPortRanges = dialog.availablePortRanges,
onSave = { customPortString ->
onWireguardPortSelected(Constraint.Only(Port(customPortString.toInt())))
},
@@ -233,9 +234,6 @@ fun VpnSettingsScreen(
onDismissRequest = { onCancelCustomPortDialogClick() }
)
}
- else -> {
- // NOOP
- }
}
var expandContentBlockersState by rememberSaveable { mutableStateOf(false) }
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/state/VpnSettingsUiState.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/state/VpnSettingsUiState.kt
index d6c9625668..e78d2e9f43 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/state/VpnSettingsUiState.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/state/VpnSettingsUiState.kt
@@ -9,162 +9,73 @@ import net.mullvad.mullvadvpn.model.SelectedObfuscation
import net.mullvad.mullvadvpn.viewmodel.CustomDnsItem
import net.mullvad.mullvadvpn.viewmodel.StagedDns
-sealed interface VpnSettingsUiState {
- val mtu: String
- val isAutoConnectEnabled: Boolean
- val isLocalNetworkSharingEnabled: Boolean
- val isCustomDnsEnabled: Boolean
- val customDnsItems: List<CustomDnsItem>
- val contentBlockersOptions: DefaultDnsOptions
- val isAllowLanEnabled: Boolean
- val selectedObfuscation: SelectedObfuscation
- val quantumResistant: QuantumResistantState
- val selectedWireguardPort: Constraint<Port>
+data class VpnSettingsUiState(
+ val mtu: String,
+ val isAutoConnectEnabled: Boolean,
+ val isLocalNetworkSharingEnabled: Boolean,
+ val isCustomDnsEnabled: Boolean,
+ val customDnsItems: List<CustomDnsItem>,
+ val contentBlockersOptions: DefaultDnsOptions,
+ val isAllowLanEnabled: Boolean,
+ val selectedObfuscation: SelectedObfuscation,
+ val quantumResistant: QuantumResistantState,
+ val selectedWireguardPort: Constraint<Port>,
+ val availablePortRanges: List<PortRange>,
+ val dialog: VpnSettingsDialog?
+) {
- data class DefaultUiState(
- override val mtu: String = "",
- override val isAutoConnectEnabled: Boolean = false,
- override val isLocalNetworkSharingEnabled: Boolean = false,
- override val isCustomDnsEnabled: Boolean = false,
- override val isAllowLanEnabled: Boolean = false,
- override val customDnsItems: List<CustomDnsItem> = listOf(),
- override val contentBlockersOptions: DefaultDnsOptions = DefaultDnsOptions(),
- override val selectedObfuscation: SelectedObfuscation = SelectedObfuscation.Off,
- override val quantumResistant: QuantumResistantState = QuantumResistantState.Off,
- override val selectedWireguardPort: Constraint<Port> = Constraint.Any()
- ) : VpnSettingsUiState
+ companion object {
+ fun createDefault(
+ mtu: String = "",
+ isAutoConnectEnabled: Boolean = false,
+ isLocalNetworkSharingEnabled: Boolean = false,
+ isCustomDnsEnabled: Boolean = false,
+ customDnsItems: List<CustomDnsItem> = emptyList(),
+ contentBlockersOptions: DefaultDnsOptions = DefaultDnsOptions(),
+ isAllowLanEnabled: Boolean = false,
+ selectedObfuscation: SelectedObfuscation = SelectedObfuscation.Off,
+ quantumResistant: QuantumResistantState = QuantumResistantState.Off,
+ selectedWireguardPort: Constraint<Port> = Constraint.Any(),
+ availablePortRanges: List<PortRange> = emptyList(),
+ dialog: VpnSettingsDialog? = null
+ ) =
+ VpnSettingsUiState(
+ mtu,
+ isAutoConnectEnabled,
+ isLocalNetworkSharingEnabled,
+ isCustomDnsEnabled,
+ customDnsItems,
+ contentBlockersOptions,
+ isAllowLanEnabled,
+ selectedObfuscation,
+ quantumResistant,
+ selectedWireguardPort,
+ availablePortRanges,
+ dialog
+ )
+ }
+}
- data class MtuDialogUiState(
- override val mtu: String = "",
- override val isAutoConnectEnabled: Boolean = false,
- override val isLocalNetworkSharingEnabled: Boolean = false,
- override val isCustomDnsEnabled: Boolean = false,
- override val isAllowLanEnabled: Boolean = false,
- override val customDnsItems: List<CustomDnsItem> = listOf(),
- override val contentBlockersOptions: DefaultDnsOptions = DefaultDnsOptions(),
- val mtuEditValue: String,
- override val selectedObfuscation: SelectedObfuscation = SelectedObfuscation.Off,
- override val quantumResistant: QuantumResistantState = QuantumResistantState.Off,
- override val selectedWireguardPort: Constraint<Port> = Constraint.Any()
- ) : VpnSettingsUiState
+interface VpnSettingsDialog {
+ data class Mtu(val mtuEditValue: String) : VpnSettingsDialog
- data class DnsDialogUiState(
- override val mtu: String = "",
- override val isAutoConnectEnabled: Boolean = false,
- override val isLocalNetworkSharingEnabled: Boolean = false,
- override val isCustomDnsEnabled: Boolean = false,
- override val isAllowLanEnabled: Boolean = false,
- override val customDnsItems: List<CustomDnsItem> = listOf(),
- override val contentBlockersOptions: DefaultDnsOptions = DefaultDnsOptions(),
- val stagedDns: StagedDns,
- override val selectedObfuscation: SelectedObfuscation = SelectedObfuscation.Off,
- override val quantumResistant: QuantumResistantState = QuantumResistantState.Off,
- override val selectedWireguardPort: Constraint<Port> = Constraint.Any()
- ) : VpnSettingsUiState
+ data class Dns(val stagedDns: StagedDns) : VpnSettingsDialog
- data class LocalNetworkSharingInfoDialogUiState(
- override val mtu: String = "",
- override val isAutoConnectEnabled: Boolean = false,
- override val isLocalNetworkSharingEnabled: Boolean = false,
- override val isCustomDnsEnabled: Boolean = false,
- override val isAllowLanEnabled: Boolean = false,
- override val customDnsItems: List<CustomDnsItem> = listOf(),
- override val contentBlockersOptions: DefaultDnsOptions = DefaultDnsOptions(),
- override val selectedObfuscation: SelectedObfuscation = SelectedObfuscation.Off,
- override val quantumResistant: QuantumResistantState = QuantumResistantState.Off,
- override val selectedWireguardPort: Constraint<Port> = Constraint.Any()
- ) : VpnSettingsUiState
+ data object LocalNetworkSharingInfo : VpnSettingsDialog
- data class ContentBlockersInfoDialogUiState(
- override val mtu: String = "",
- override val isAutoConnectEnabled: Boolean = false,
- override val isLocalNetworkSharingEnabled: Boolean = false,
- override val isCustomDnsEnabled: Boolean = false,
- override val isAllowLanEnabled: Boolean = false,
- override val customDnsItems: List<CustomDnsItem> = listOf(),
- override val contentBlockersOptions: DefaultDnsOptions = DefaultDnsOptions(),
- override val selectedObfuscation: SelectedObfuscation = SelectedObfuscation.Off,
- override val quantumResistant: QuantumResistantState = QuantumResistantState.Off,
- override val selectedWireguardPort: Constraint<Port> = Constraint.Any()
- ) : VpnSettingsUiState
+ data object ContentBlockersInfo : VpnSettingsDialog
- data class CustomDnsInfoDialogUiState(
- override val mtu: String = "",
- override val isAutoConnectEnabled: Boolean = false,
- override val isLocalNetworkSharingEnabled: Boolean = false,
- override val isCustomDnsEnabled: Boolean = false,
- override val isAllowLanEnabled: Boolean = false,
- override val customDnsItems: List<CustomDnsItem> = listOf(),
- override val contentBlockersOptions: DefaultDnsOptions = DefaultDnsOptions(),
- override val selectedObfuscation: SelectedObfuscation = SelectedObfuscation.Off,
- override val quantumResistant: QuantumResistantState = QuantumResistantState.Off,
- override val selectedWireguardPort: Constraint<Port> = Constraint.Any()
- ) : VpnSettingsUiState
+ data object CustomDnsInfo : VpnSettingsDialog
- data class MalwareInfoDialogUiState(
- override val mtu: String = "",
- override val isAutoConnectEnabled: Boolean = false,
- override val isLocalNetworkSharingEnabled: Boolean = false,
- override val isCustomDnsEnabled: Boolean = false,
- override val isAllowLanEnabled: Boolean = false,
- override val customDnsItems: List<CustomDnsItem> = listOf(),
- override val contentBlockersOptions: DefaultDnsOptions = DefaultDnsOptions(),
- override val selectedObfuscation: SelectedObfuscation = SelectedObfuscation.Off,
- override val quantumResistant: QuantumResistantState = QuantumResistantState.Off,
- override val selectedWireguardPort: Constraint<Port> = Constraint.Any()
- ) : VpnSettingsUiState
+ data object MalwareInfo : VpnSettingsDialog
- data class ObfuscationInfoDialogUiState(
- override val mtu: String = "",
- override val isAutoConnectEnabled: Boolean = false,
- override val isLocalNetworkSharingEnabled: Boolean = false,
- override val isCustomDnsEnabled: Boolean = false,
- override val isAllowLanEnabled: Boolean = false,
- override val customDnsItems: List<CustomDnsItem> = listOf(),
- override val contentBlockersOptions: DefaultDnsOptions = DefaultDnsOptions(),
- override val selectedObfuscation: SelectedObfuscation = SelectedObfuscation.Off,
- override val quantumResistant: QuantumResistantState = QuantumResistantState.Off,
- override val selectedWireguardPort: Constraint<Port> = Constraint.Any()
- ) : VpnSettingsUiState
+ data object ObfuscationInfo : VpnSettingsDialog
- data class QuantumResistanceInfoDialogUiState(
- override val mtu: String = "",
- override val isAutoConnectEnabled: Boolean = false,
- override val isLocalNetworkSharingEnabled: Boolean = false,
- override val isCustomDnsEnabled: Boolean = false,
- override val isAllowLanEnabled: Boolean = false,
- override val customDnsItems: List<CustomDnsItem> = listOf(),
- override val contentBlockersOptions: DefaultDnsOptions = DefaultDnsOptions(),
- override val selectedObfuscation: SelectedObfuscation = SelectedObfuscation.Off,
- override val quantumResistant: QuantumResistantState = QuantumResistantState.Off,
- override val selectedWireguardPort: Constraint<Port> = Constraint.Any()
- ) : VpnSettingsUiState
+ data object QuantumResistanceInfo : VpnSettingsDialog
- data class WireguardPortInfoDialogUiState(
- override val mtu: String = "",
- override val isAutoConnectEnabled: Boolean = false,
- override val isLocalNetworkSharingEnabled: Boolean = false,
- override val isCustomDnsEnabled: Boolean = false,
- override val isAllowLanEnabled: Boolean = false,
- override val customDnsItems: List<CustomDnsItem> = listOf(),
- override val contentBlockersOptions: DefaultDnsOptions = DefaultDnsOptions(),
- override val selectedObfuscation: SelectedObfuscation = SelectedObfuscation.Off,
- override val quantumResistant: QuantumResistantState = QuantumResistantState.Off,
- override val selectedWireguardPort: Constraint<Port> = Constraint.Any(),
- val availablePortRanges: List<PortRange> = emptyList()
- ) : VpnSettingsUiState
+ data class WireguardPortInfo(val availablePortRanges: List<PortRange> = emptyList()) :
+ VpnSettingsDialog
- data class CustomPortDialogUiState(
- override val mtu: String = "",
- override val isAutoConnectEnabled: Boolean = false,
- override val isLocalNetworkSharingEnabled: Boolean = false,
- override val isCustomDnsEnabled: Boolean = false,
- override val isAllowLanEnabled: Boolean = false,
- override val customDnsItems: List<CustomDnsItem> = listOf(),
- override val contentBlockersOptions: DefaultDnsOptions = DefaultDnsOptions(),
- override val selectedObfuscation: SelectedObfuscation = SelectedObfuscation.Off,
- override val quantumResistant: QuantumResistantState = QuantumResistantState.Off,
- override val selectedWireguardPort: Constraint<Port> = Constraint.Any(),
- val availablePortRanges: List<PortRange> = emptyList()
- ) : VpnSettingsUiState
+ data class CustomPort(val availablePortRanges: List<PortRange> = emptyList()) :
+ VpnSettingsDialog
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/VpnSettingsFragment.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/VpnSettingsFragment.kt
index e3ed6c469d..49d43e6b27 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/VpnSettingsFragment.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/fragment/VpnSettingsFragment.kt
@@ -43,7 +43,7 @@ class VpnSettingsFragment : BaseFragment() {
onDnsInputChange = vm::onDnsInputChange,
onSaveDnsClick = vm::onSaveDnsClick,
onRemoveDnsClick = vm::onRemoveDnsClick,
- onCancelDnsDialogClick = vm::onCancelDialogClick,
+ onCancelDnsDialogClick = vm::onCancelDns,
onLocalNetworkSharingInfoClick = vm::onLocalNetworkSharingInfoClick,
onContentsBlockersInfoClick = vm::onContentsBlockerInfoClick,
onCustomDnsInfoClick = vm::onCustomDnsInfoClick,
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/VpnSettingsViewModel.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/VpnSettingsViewModel.kt
index 9c25fe824f..0827c81e99 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/VpnSettingsViewModel.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/VpnSettingsViewModel.kt
@@ -54,8 +54,7 @@ class VpnSettingsViewModel(
@Suppress("konsist.ensure public properties use permitted names")
val toastMessages = _toastMessages.asSharedFlow()
- private val dialogState =
- MutableStateFlow<VpnSettingsDialogState>(VpnSettingsDialogState.NoDialog)
+ private val dialogState = MutableStateFlow<VpnSettingsDialogState?>(null)
private val vmState =
serviceConnectionManager.connectionState
@@ -103,7 +102,7 @@ class VpnSettingsViewModel(
.stateIn(
viewModelScope,
SharingStarted.WhileSubscribed(),
- VpnSettingsUiState.DefaultUiState()
+ VpnSettingsUiState.createDefault()
)
fun onMtuCellClick() {
@@ -252,6 +251,9 @@ class VpnSettingsViewModel(
fun onToggleDnsClick(isEnabled: Boolean) {
updateCustomDnsState(isEnabled)
+ if (isEnabled && vmState.value.customDnsList.isEmpty()) {
+ onDnsClick(null)
+ }
showApplySettingChangesWarningToast()
}
@@ -374,7 +376,17 @@ class VpnSettingsViewModel(
}
private fun hideDialog() {
- dialogState.update { VpnSettingsDialogState.NoDialog }
+ dialogState.update { null }
+ }
+
+ fun onCancelDns() {
+ if (
+ vmState.value.dialogState is VpnSettingsDialogState.DnsDialog &&
+ vmState.value.customDnsList.isEmpty()
+ ) {
+ onToggleDnsClick(false)
+ }
+ hideDialog()
}
private fun String.isDuplicateDns(stagedIndex: Int? = null): Boolean {
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/VpnSettingsViewModelState.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/VpnSettingsViewModelState.kt
index aba6dd7e36..2ebc2b397c 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/VpnSettingsViewModelState.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/VpnSettingsViewModelState.kt
@@ -1,5 +1,6 @@
package net.mullvad.mullvadvpn.viewmodel
+import net.mullvad.mullvadvpn.compose.state.VpnSettingsDialog
import net.mullvad.mullvadvpn.compose.state.VpnSettingsUiState
import net.mullvad.mullvadvpn.model.Constraint
import net.mullvad.mullvadvpn.model.DefaultDnsOptions
@@ -17,165 +18,26 @@ data class VpnSettingsViewModelState(
val customDnsList: List<CustomDnsItem>,
val contentBlockersOptions: DefaultDnsOptions,
val selectedObfuscation: SelectedObfuscation,
- val dialogState: VpnSettingsDialogState,
val quantumResistant: QuantumResistantState,
val selectedWireguardPort: Constraint<Port>,
- val availablePortRanges: List<PortRange>
+ val availablePortRanges: List<PortRange>,
+ val dialogState: VpnSettingsDialogState?,
) {
- fun toUiState(): VpnSettingsUiState {
- return when (dialogState) {
- is VpnSettingsDialogState.MtuDialog ->
- VpnSettingsUiState.MtuDialogUiState(
- mtu = mtuValue,
- isAutoConnectEnabled = isAutoConnectEnabled,
- isLocalNetworkSharingEnabled = isLocalNetworkSharingEnabled,
- isCustomDnsEnabled = isCustomDnsEnabled,
- isAllowLanEnabled = isAllowLanEnabled,
- customDnsItems = customDnsList,
- contentBlockersOptions = contentBlockersOptions,
- mtuEditValue = dialogState.mtuEditValue,
- selectedObfuscation = selectedObfuscation,
- quantumResistant = quantumResistant,
- selectedWireguardPort = selectedWireguardPort
- )
- is VpnSettingsDialogState.DnsDialog ->
- VpnSettingsUiState.DnsDialogUiState(
- mtu = mtuValue,
- isAutoConnectEnabled = isAutoConnectEnabled,
- isLocalNetworkSharingEnabled = isLocalNetworkSharingEnabled,
- isCustomDnsEnabled = isCustomDnsEnabled,
- isAllowLanEnabled = isAllowLanEnabled,
- customDnsItems = customDnsList,
- contentBlockersOptions = contentBlockersOptions,
- stagedDns = dialogState.stagedDns,
- selectedObfuscation = selectedObfuscation,
- quantumResistant = quantumResistant,
- selectedWireguardPort = selectedWireguardPort
- )
- is VpnSettingsDialogState.LocalNetworkSharingInfoDialog ->
- VpnSettingsUiState.LocalNetworkSharingInfoDialogUiState(
- mtu = mtuValue,
- isAutoConnectEnabled = isAutoConnectEnabled,
- isLocalNetworkSharingEnabled = isLocalNetworkSharingEnabled,
- isCustomDnsEnabled = isCustomDnsEnabled,
- isAllowLanEnabled = isAllowLanEnabled,
- customDnsItems = customDnsList,
- contentBlockersOptions = contentBlockersOptions,
- selectedObfuscation = selectedObfuscation,
- quantumResistant = quantumResistant,
- selectedWireguardPort = selectedWireguardPort
- )
- is VpnSettingsDialogState.ContentBlockersInfoDialog ->
- VpnSettingsUiState.ContentBlockersInfoDialogUiState(
- mtu = mtuValue,
- isAutoConnectEnabled = isAutoConnectEnabled,
- isLocalNetworkSharingEnabled = isLocalNetworkSharingEnabled,
- isCustomDnsEnabled = isCustomDnsEnabled,
- isAllowLanEnabled = isAllowLanEnabled,
- customDnsItems = customDnsList,
- contentBlockersOptions = contentBlockersOptions,
- selectedObfuscation = selectedObfuscation,
- quantumResistant = quantumResistant,
- selectedWireguardPort = selectedWireguardPort
- )
- is VpnSettingsDialogState.CustomDnsInfoDialog ->
- VpnSettingsUiState.CustomDnsInfoDialogUiState(
- mtu = mtuValue,
- isAutoConnectEnabled = isAutoConnectEnabled,
- isLocalNetworkSharingEnabled = isLocalNetworkSharingEnabled,
- isCustomDnsEnabled = isCustomDnsEnabled,
- isAllowLanEnabled = isAllowLanEnabled,
- customDnsItems = customDnsList,
- contentBlockersOptions = contentBlockersOptions,
- selectedObfuscation = selectedObfuscation,
- quantumResistant = quantumResistant,
- selectedWireguardPort = selectedWireguardPort
- )
- is VpnSettingsDialogState.MalwareInfoDialog ->
- VpnSettingsUiState.MalwareInfoDialogUiState(
- mtu = mtuValue,
- isAutoConnectEnabled = isAutoConnectEnabled,
- isLocalNetworkSharingEnabled = isLocalNetworkSharingEnabled,
- isCustomDnsEnabled = isCustomDnsEnabled,
- isAllowLanEnabled = isAllowLanEnabled,
- customDnsItems = customDnsList,
- contentBlockersOptions = contentBlockersOptions,
- selectedObfuscation = selectedObfuscation,
- quantumResistant = quantumResistant,
- selectedWireguardPort = selectedWireguardPort
- )
- is VpnSettingsDialogState.ObfuscationInfoDialog ->
- VpnSettingsUiState.ObfuscationInfoDialogUiState(
- mtu = mtuValue,
- isAutoConnectEnabled = isAutoConnectEnabled,
- isLocalNetworkSharingEnabled = isLocalNetworkSharingEnabled,
- isCustomDnsEnabled = isCustomDnsEnabled,
- isAllowLanEnabled = isAllowLanEnabled,
- customDnsItems = customDnsList,
- contentBlockersOptions = contentBlockersOptions,
- selectedObfuscation = selectedObfuscation,
- quantumResistant = quantumResistant,
- selectedWireguardPort = selectedWireguardPort
- )
- is VpnSettingsDialogState.QuantumResistanceInfoDialog -> {
- VpnSettingsUiState.QuantumResistanceInfoDialogUiState(
- mtu = mtuValue,
- isAutoConnectEnabled = isAutoConnectEnabled,
- isLocalNetworkSharingEnabled = isLocalNetworkSharingEnabled,
- isCustomDnsEnabled = isCustomDnsEnabled,
- isAllowLanEnabled = isAllowLanEnabled,
- customDnsItems = customDnsList,
- contentBlockersOptions = contentBlockersOptions,
- selectedObfuscation = selectedObfuscation,
- quantumResistant = quantumResistant,
- selectedWireguardPort = selectedWireguardPort
- )
- }
- is VpnSettingsDialogState.WireguardPortInfoDialog -> {
- VpnSettingsUiState.WireguardPortInfoDialogUiState(
- mtu = mtuValue,
- isAutoConnectEnabled = isAutoConnectEnabled,
- isLocalNetworkSharingEnabled = isLocalNetworkSharingEnabled,
- isCustomDnsEnabled = isCustomDnsEnabled,
- isAllowLanEnabled = isAllowLanEnabled,
- customDnsItems = customDnsList,
- contentBlockersOptions = contentBlockersOptions,
- selectedObfuscation = selectedObfuscation,
- quantumResistant = quantumResistant,
- selectedWireguardPort = selectedWireguardPort,
- availablePortRanges = availablePortRanges
- )
- }
- is VpnSettingsDialogState.CustomPortDialog -> {
- VpnSettingsUiState.CustomPortDialogUiState(
- mtu = mtuValue,
- isAutoConnectEnabled = isAutoConnectEnabled,
- isLocalNetworkSharingEnabled = isLocalNetworkSharingEnabled,
- isCustomDnsEnabled = isCustomDnsEnabled,
- isAllowLanEnabled = isAllowLanEnabled,
- customDnsItems = customDnsList,
- contentBlockersOptions = contentBlockersOptions,
- selectedObfuscation = selectedObfuscation,
- quantumResistant = quantumResistant,
- selectedWireguardPort = selectedWireguardPort,
- availablePortRanges = availablePortRanges
- )
- }
- else ->
- VpnSettingsUiState.DefaultUiState(
- mtu = mtuValue,
- isAutoConnectEnabled = isAutoConnectEnabled,
- isLocalNetworkSharingEnabled = isLocalNetworkSharingEnabled,
- isCustomDnsEnabled = isCustomDnsEnabled,
- isAllowLanEnabled = isAllowLanEnabled,
- customDnsItems = customDnsList,
- contentBlockersOptions = contentBlockersOptions,
- selectedObfuscation = selectedObfuscation,
- quantumResistant = quantumResistant,
- selectedWireguardPort = selectedWireguardPort
- )
- }
- }
+ fun toUiState(): VpnSettingsUiState =
+ VpnSettingsUiState(
+ mtuValue,
+ isAutoConnectEnabled,
+ isLocalNetworkSharingEnabled,
+ isCustomDnsEnabled,
+ customDnsList,
+ contentBlockersOptions,
+ isAllowLanEnabled,
+ selectedObfuscation,
+ quantumResistant,
+ selectedWireguardPort,
+ availablePortRanges,
+ dialogState.toUi(this@VpnSettingsViewModelState)
+ )
companion object {
private const val EMPTY_STRING = ""
@@ -189,7 +51,7 @@ data class VpnSettingsViewModelState(
customDnsList = listOf(),
contentBlockersOptions = DefaultDnsOptions(),
isAllowLanEnabled = false,
- dialogState = VpnSettingsDialogState.NoDialog,
+ dialogState = null,
selectedObfuscation = SelectedObfuscation.Auto,
quantumResistant = QuantumResistantState.Off,
selectedWireguardPort = Constraint.Any(),
@@ -198,8 +60,28 @@ data class VpnSettingsViewModelState(
}
}
+private fun VpnSettingsDialogState?.toUi(
+ vpnSettingsViewModelState: VpnSettingsViewModelState
+): VpnSettingsDialog? =
+ when (this) {
+ VpnSettingsDialogState.ContentBlockersInfoDialog -> VpnSettingsDialog.ContentBlockersInfo
+ VpnSettingsDialogState.CustomDnsInfoDialog -> VpnSettingsDialog.CustomDnsInfo
+ VpnSettingsDialogState.CustomPortDialog ->
+ VpnSettingsDialog.CustomPort(vpnSettingsViewModelState.availablePortRanges)
+ is VpnSettingsDialogState.DnsDialog -> VpnSettingsDialog.Dns(stagedDns)
+ VpnSettingsDialogState.LocalNetworkSharingInfoDialog ->
+ VpnSettingsDialog.LocalNetworkSharingInfo
+ VpnSettingsDialogState.MalwareInfoDialog -> VpnSettingsDialog.MalwareInfo
+ is VpnSettingsDialogState.MtuDialog -> VpnSettingsDialog.Mtu(mtuEditValue)
+ VpnSettingsDialogState.ObfuscationInfoDialog -> VpnSettingsDialog.ObfuscationInfo
+ VpnSettingsDialogState.QuantumResistanceInfoDialog ->
+ VpnSettingsDialog.QuantumResistanceInfo
+ VpnSettingsDialogState.WireguardPortInfoDialog ->
+ VpnSettingsDialog.WireguardPortInfo(vpnSettingsViewModelState.availablePortRanges)
+ null -> null
+ }
+
sealed class VpnSettingsDialogState {
- data object NoDialog : VpnSettingsDialogState()
data class MtuDialog(val mtuEditValue: String) : VpnSettingsDialogState()
diff --git a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/VpnSettingsViewModelTest.kt b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/VpnSettingsViewModelTest.kt
index 4e02f1f703..66d301d903 100644
--- a/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/VpnSettingsViewModelTest.kt
+++ b/android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/VpnSettingsViewModelTest.kt
@@ -10,10 +10,12 @@ import io.mockk.unmockkAll
import io.mockk.verify
import kotlin.test.assertEquals
import kotlin.test.assertIs
+import kotlin.test.assertTrue
import kotlinx.coroutines.cancel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.test.UnconfinedTestDispatcher
import kotlinx.coroutines.test.runTest
+import net.mullvad.mullvadvpn.compose.state.VpnSettingsDialog
import net.mullvad.mullvadvpn.compose.state.VpnSettingsUiState
import net.mullvad.mullvadvpn.lib.common.test.TestCoroutineRule
import net.mullvad.mullvadvpn.lib.common.test.assertLists
@@ -180,14 +182,14 @@ class VpnSettingsViewModelTest {
// Act, Assert
viewModel.uiState.test {
- assertIs<VpnSettingsUiState.DefaultUiState>(awaitItem())
+ assertIs<VpnSettingsUiState>(awaitItem())
mockSettingsUpdate.value = mockSettings
viewModel.onWireguardPortInfoClicked()
mockConnectionState.value =
ServiceConnectionState.ConnectedReady(mockServiceConnectionContainer)
portRangeSlot.captured.invoke(expectedPortRange)
val state = awaitItem()
- assertIs<VpnSettingsUiState.WireguardPortInfoDialogUiState>(state)
+ assertTrue { state.dialog is VpnSettingsDialog.WireguardPortInfo }
assertLists(expectedPortRange, state.availablePortRanges)
}
}