diff options
| author | Jonatan Rhodin <jonatan.rhodin@mullvad.net> | 2023-10-25 14:03:36 +0200 |
|---|---|---|
| committer | Jonatan Rhodin <jonatan.rhodin@mullvad.net> | 2023-10-25 14:03:36 +0200 |
| commit | 78ed10bb270c915157f8ca3e8bbb9fd1f381a8b3 (patch) | |
| tree | 174e5c9cd9c210347b367827ac42290b28541d6f | |
| parent | c0cfd41987eac1ba5c8701c8e166dd13f9537406 (diff) | |
| parent | e8e1762498bc537a71397a8fd5791af1618ec791 (diff) | |
| download | mullvadvpn-78ed10bb270c915157f8ca3e8bbb9fd1f381a8b3.tar.xz mullvadvpn-78ed10bb270c915157f8ca3e8bbb9fd1f381a8b3.zip | |
Merge branch 'show-popup-when-enabling-custom-dns-server-and-server-list-droid-320'
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) } } |
