diff options
Diffstat (limited to 'android/app/src')
7 files changed, 63 insertions, 24 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 43c5559a38..13ef28dd23 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 @@ -411,7 +411,11 @@ class VpnSettingsScreenTest { // Arrange val mockedClickHandler: (Int?, String?) -> Unit = mockk(relaxed = true) initScreen( - state = VpnSettingsUiState.createDefault(isCustomDnsEnabled = true), + state = + VpnSettingsUiState.createDefault( + isCustomDnsEnabled = true, + customDnsItems = listOf(CustomDnsItem("1.1.1.1", false)), + ), navigateToDns = mockedClickHandler, ) diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/communication/DnsDialogResult.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/communication/DnsDialogResult.kt index 45eb76cc85..b95c3ef72e 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/communication/DnsDialogResult.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/communication/DnsDialogResult.kt @@ -4,7 +4,7 @@ import android.os.Parcelable import kotlinx.parcelize.Parcelize interface DnsDialogResult : Parcelable { - @Parcelize data object Success : DnsDialogResult + @Parcelize data class Success(val isDnsListEmpty: Boolean) : DnsDialogResult @Parcelize data object Error : DnsDialogResult diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/DnsDialog.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/DnsDialog.kt index c2e94ded5b..6f9c8126c0 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/DnsDialog.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/DnsDialog.kt @@ -51,8 +51,8 @@ fun Dns(resultNavigator: ResultBackNavigator<DnsDialogResult>) { CollectSideEffectWithLifecycle(viewModel.uiSideEffect) { when (it) { - DnsDialogSideEffect.Complete -> - resultNavigator.navigateBack(result = DnsDialogResult.Success) + is DnsDialogSideEffect.Complete -> + resultNavigator.navigateBack(result = DnsDialogResult.Success(it.isDnsListEmpty)) DnsDialogSideEffect.Error -> resultNavigator.navigateBack(result = DnsDialogResult.Error) } 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 d900f8e879..0de30c408a 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 @@ -158,7 +158,12 @@ fun VpnSettings( dnsDialogResult.OnNavResultValue { result -> when (result) { - DnsDialogResult.Success -> vm.showApplySettingChangesWarningToast() + is DnsDialogResult.Success -> { + vm.showApplySettingChangesWarningToast() + if (result.isDnsListEmpty) { + vm.onToggleCustomDns(false) + } + } DnsDialogResult.Cancel -> vm.onDnsDialogDismissed() DnsDialogResult.Error -> { vm.showGenericErrorToast() @@ -466,19 +471,21 @@ fun VpnSettingsScreen( ) } - itemWithDivider { - BaseCell( - onCellClicked = { navigateToDns(null, null) }, - headlineContent = { - Text( - text = stringResource(id = R.string.add_a_server), - color = MaterialTheme.colorScheme.onSurface, - ) - }, - bodyView = {}, - background = MaterialTheme.colorScheme.surfaceContainerLow, - startPadding = biggerPadding, - ) + if (state.customDnsItems.isNotEmpty()) { + itemWithDivider { + BaseCell( + onCellClicked = { navigateToDns(null, null) }, + headlineContent = { + Text( + text = stringResource(id = R.string.add_a_server), + color = MaterialTheme.colorScheme.onSurface, + ) + }, + bodyView = {}, + background = MaterialTheme.colorScheme.surfaceContainerLow, + startPadding = biggerPadding, + ) + } } } diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/di/UiModule.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/di/UiModule.kt index a56541ee1a..5c147379b2 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/di/UiModule.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/di/UiModule.kt @@ -38,6 +38,7 @@ import net.mullvad.mullvadvpn.ui.MainActivity import net.mullvad.mullvadvpn.ui.serviceconnection.AppVersionInfoRepository import net.mullvad.mullvadvpn.ui.serviceconnection.ServiceConnectionManager import net.mullvad.mullvadvpn.usecase.AccountExpiryInAppNotificationUseCase +import net.mullvad.mullvadvpn.usecase.DeleteCustomDnsUseCase import net.mullvad.mullvadvpn.usecase.EmptyPaymentUseCase import net.mullvad.mullvadvpn.usecase.FilterChipUseCase import net.mullvad.mullvadvpn.usecase.FilteredRelayListUseCase @@ -167,6 +168,7 @@ val uiModule = module { single { LastKnownLocationUseCase(get()) } single { SelectedLocationUseCase(get(), get()) } single { FilterChipUseCase(get(), get(), get(), get()) } + single { DeleteCustomDnsUseCase(get()) } single { InAppNotificationController(get(), get(), get(), get(), get(), MainScope()) } @@ -214,7 +216,7 @@ val uiModule = module { viewModel { DeviceListViewModel(get(), get()) } viewModel { DeviceRevokedViewModel(get(), get()) } viewModel { MtuDialogViewModel(get(), get()) } - viewModel { DnsDialogViewModel(get(), get(), get()) } + viewModel { DnsDialogViewModel(get(), get(), get(), get()) } viewModel { WireguardCustomPortDialogViewModel(get()) } viewModel { LoginViewModel(get(), get(), get()) } viewModel { PrivacyDisclaimerViewModel(get(), IS_PLAY_BUILD) } diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/usecase/DeleteCustomDnsUseCase.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/usecase/DeleteCustomDnsUseCase.kt new file mode 100644 index 0000000000..fffa841306 --- /dev/null +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/usecase/DeleteCustomDnsUseCase.kt @@ -0,0 +1,24 @@ +package net.mullvad.mullvadvpn.usecase + +import arrow.core.raise.either +import arrow.core.raise.ensure +import net.mullvad.mullvadvpn.lib.model.SetDnsOptionsError +import net.mullvad.mullvadvpn.repository.SettingsRepository + +class DeleteCustomDnsUseCase(private val settingsRepository: SettingsRepository) { + suspend operator fun invoke(index: Int) = + either<SetDnsOptionsError, Int> { + val sizePriorToDeletion = + settingsRepository.settingsUpdates.value + ?.tunnelOptions + ?.dnsOptions + ?.customOptions + ?.addresses + ?.size ?: 0 + ensure(sizePriorToDeletion > 0) { + SetDnsOptionsError.Unknown(IllegalStateException("No custom DNS entries")) + } + settingsRepository.deleteCustomDns(index).bind() + sizePriorToDeletion - 1 + } +} diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/DnsDialogViewModel.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/DnsDialogViewModel.kt index a009210318..ab067e8145 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/DnsDialogViewModel.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/DnsDialogViewModel.kt @@ -22,10 +22,11 @@ import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.launch import net.mullvad.mullvadvpn.lib.model.Settings import net.mullvad.mullvadvpn.repository.SettingsRepository +import net.mullvad.mullvadvpn.usecase.DeleteCustomDnsUseCase import org.apache.commons.validator.routines.InetAddressValidator sealed interface DnsDialogSideEffect { - data object Complete : DnsDialogSideEffect + data class Complete(val isDnsListEmpty: Boolean) : DnsDialogSideEffect data object Error : DnsDialogSideEffect } @@ -52,6 +53,7 @@ class DnsDialogViewModel( private val repository: SettingsRepository, private val inetAddressValidator: InetAddressValidator, savedStateHandle: SavedStateHandle, + private val deleteCustomDnsUseCase: DeleteCustomDnsUseCase, private val dispatcher: CoroutineDispatcher = Dispatchers.IO, ) : ViewModel() { private val navArgs = DnsDestination.argsFrom(savedStateHandle) @@ -127,17 +129,17 @@ class DnsDialogViewModel( result.fold( { _uiSideEffect.send(DnsDialogSideEffect.Error) }, - { _uiSideEffect.send(DnsDialogSideEffect.Complete) }, + { _uiSideEffect.send(DnsDialogSideEffect.Complete(false)) }, ) } fun onRemoveDnsClick(index: Int) = viewModelScope.launch(dispatcher) { - repository - .deleteCustomDns(index) + deleteCustomDnsUseCase + .invoke(index) .fold( { _uiSideEffect.send(DnsDialogSideEffect.Error) }, - { _uiSideEffect.send(DnsDialogSideEffect.Complete) }, + { _uiSideEffect.send(DnsDialogSideEffect.Complete(it == 0)) }, ) } |
