Skip to content

Commit 4e2bbc6

Browse files
committed
Implement device ip version ui
1 parent 05700e9 commit 4e2bbc6

File tree

5 files changed

+56
-10
lines changed

5 files changed

+56
-10
lines changed

android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/VpnSettingsScreen.kt

+30
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ import net.mullvad.mullvadvpn.compose.util.OnNavResultValue
9393
import net.mullvad.mullvadvpn.compose.util.showSnackbarImmediately
9494
import net.mullvad.mullvadvpn.constant.WIREGUARD_PRESET_PORTS
9595
import net.mullvad.mullvadvpn.lib.model.Constraint
96+
import net.mullvad.mullvadvpn.lib.model.IpVersion
9697
import net.mullvad.mullvadvpn.lib.model.Mtu
9798
import net.mullvad.mullvadvpn.lib.model.ObfuscationMode
9899
import net.mullvad.mullvadvpn.lib.model.Port
@@ -140,6 +141,7 @@ private fun PreviewVpnSettings(
140141
navigateToLocalNetworkSharingInfo = {},
141142
navigateToWireguardPortDialog = {},
142143
navigateToServerIpOverrides = {},
144+
onSelectDeviceIpVersion = {},
143145
)
144146
}
145147
}
@@ -268,6 +270,7 @@ fun VpnSettings(
268270
navigateToUdp2TcpSettings =
269271
dropUnlessResumed { navigator.navigate(Udp2TcpSettingsDestination) },
270272
onToggleAutoStartAndConnectOnBoot = vm::onToggleAutoStartAndConnectOnBoot,
273+
onSelectDeviceIpVersion = vm::onDeviceIpVersionSelected,
271274
)
272275
}
273276

@@ -304,6 +307,7 @@ fun VpnSettingsScreen(
304307
navigateToShadowSocksSettings: () -> Unit,
305308
navigateToUdp2TcpSettings: () -> Unit,
306309
onToggleAutoStartAndConnectOnBoot: (Boolean) -> Unit,
310+
onSelectDeviceIpVersion: (ipVersion: Constraint<IpVersion>) -> Unit,
307311
) {
308312
var expandContentBlockersState by rememberSaveable { mutableStateOf(false) }
309313
val biggerPadding = 54.dp
@@ -651,6 +655,32 @@ fun VpnSettingsScreen(
651655
Spacer(modifier = Modifier.height(Dimens.cellVerticalSpacing))
652656
}
653657

658+
itemWithDivider {
659+
InformationComposeCell(title = stringResource(R.string.device_ip_version_title))
660+
}
661+
itemWithDivider {
662+
SelectableCell(
663+
title = stringResource(id = R.string.automatic),
664+
isSelected = state.deviceIpVersion == Constraint.Any,
665+
onCellClicked = { onSelectDeviceIpVersion(Constraint.Any) },
666+
)
667+
}
668+
itemWithDivider {
669+
SelectableCell(
670+
title = stringResource(id = R.string.device_ip_version_ipv4),
671+
isSelected = state.deviceIpVersion.getOrNull() == IpVersion.IPV4,
672+
onCellClicked = { onSelectDeviceIpVersion(Constraint.Only(IpVersion.IPV4)) },
673+
)
674+
}
675+
item {
676+
SelectableCell(
677+
title = stringResource(id = R.string.device_ip_version_ipv6),
678+
isSelected = state.deviceIpVersion.getOrNull() == IpVersion.IPV6,
679+
onCellClicked = { onSelectDeviceIpVersion(Constraint.Only(IpVersion.IPV6)) },
680+
)
681+
Spacer(modifier = Modifier.height(Dimens.cellVerticalSpacing))
682+
}
683+
654684
item {
655685
MtuComposeCell(mtuValue = state.mtu, onEditMtu = { navigateToMtuDialog(state.mtu) })
656686
}

android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/state/VpnSettingsUiState.kt

+4
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package net.mullvad.mullvadvpn.compose.state
22

33
import net.mullvad.mullvadvpn.lib.model.Constraint
44
import net.mullvad.mullvadvpn.lib.model.DefaultDnsOptions
5+
import net.mullvad.mullvadvpn.lib.model.IpVersion
56
import net.mullvad.mullvadvpn.lib.model.Mtu
67
import net.mullvad.mullvadvpn.lib.model.ObfuscationMode
78
import net.mullvad.mullvadvpn.lib.model.Port
@@ -24,6 +25,7 @@ data class VpnSettingsUiState(
2425
val availablePortRanges: List<PortRange>,
2526
val systemVpnSettingsAvailable: Boolean,
2627
val autoStartAndConnectOnBoot: Boolean,
28+
val deviceIpVersion: Constraint<IpVersion>,
2729
) {
2830
val isCustomWireguardPort =
2931
selectedWireguardPort is Constraint.Only &&
@@ -48,6 +50,7 @@ data class VpnSettingsUiState(
4850
availablePortRanges: List<PortRange> = emptyList(),
4951
systemVpnSettingsAvailable: Boolean = false,
5052
autoStartAndConnectOnBoot: Boolean = false,
53+
deviceIpVersion: Constraint<IpVersion> = Constraint.Any,
5154
) =
5255
VpnSettingsUiState(
5356
mtu,
@@ -64,6 +67,7 @@ data class VpnSettingsUiState(
6467
availablePortRanges,
6568
systemVpnSettingsAvailable,
6669
autoStartAndConnectOnBoot,
70+
deviceIpVersion,
6771
)
6872
}
6973
}

android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/VpnSettingsViewModel.kt

+15-10
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import net.mullvad.mullvadvpn.constant.WIREGUARD_PRESET_PORTS
2323
import net.mullvad.mullvadvpn.lib.model.Constraint
2424
import net.mullvad.mullvadvpn.lib.model.DefaultDnsOptions
2525
import net.mullvad.mullvadvpn.lib.model.DnsState
26+
import net.mullvad.mullvadvpn.lib.model.IpVersion
2627
import net.mullvad.mullvadvpn.lib.model.ObfuscationMode
2728
import net.mullvad.mullvadvpn.lib.model.Port
2829
import net.mullvad.mullvadvpn.lib.model.QuantumResistantState
@@ -46,7 +47,7 @@ sealed interface VpnSettingsSideEffect {
4647
@Suppress("TooManyFunctions")
4748
class VpnSettingsViewModel(
4849
private val repository: SettingsRepository,
49-
private val relayListRepository: RelayListRepository,
50+
relayListRepository: RelayListRepository,
5051
private val systemVpnSettingsUseCase: SystemVpnSettingsAvailableUseCase,
5152
private val autoStartAndConnectOnBootRepository: AutoStartAndConnectOnBootRepository,
5253
private val wireguardConstraintsRepository: WireguardConstraintsRepository,
@@ -83,6 +84,7 @@ class VpnSettingsViewModel(
8384
availablePortRanges = portRanges,
8485
systemVpnSettingsAvailable = systemVpnSettingsUseCase(),
8586
autoStartAndConnectOnBoot = autoStartAndConnectOnBoot,
87+
deviceIpVersion = settings?.getDeviceIpVersion() ?: Constraint.Any,
8688
)
8789
}
8890
.stateIn(
@@ -122,14 +124,6 @@ class VpnSettingsViewModel(
122124
}
123125
}
124126

125-
fun onToggleDaita(enable: Boolean) {
126-
viewModelScope.launch(dispatcher) {
127-
repository.setDaitaEnabled(enable).onLeft {
128-
_uiSideEffect.send(VpnSettingsSideEffect.ShowToast.GenericError)
129-
}
130-
}
131-
}
132-
133127
fun onDnsDialogDismissed() {
134128
if (vmState.value.customDnsList.isEmpty()) {
135129
onToggleCustomDns(enable = false)
@@ -251,6 +245,14 @@ class VpnSettingsViewModel(
251245
}
252246
}
253247

248+
fun onDeviceIpVersionSelected(ipVersion: Constraint<IpVersion>) {
249+
viewModelScope.launch(dispatcher) {
250+
wireguardConstraintsRepository.setDeviceIpVersion(ipVersion).onLeft {
251+
_uiSideEffect.send(VpnSettingsSideEffect.ShowToast.GenericError)
252+
}
253+
}
254+
}
255+
254256
private fun updateDefaultDnsOptionsViaRepository(contentBlockersOption: DefaultDnsOptions) =
255257
viewModelScope.launch(dispatcher) {
256258
repository
@@ -265,7 +267,7 @@ class VpnSettingsViewModel(
265267
private fun List<String>.asInetAddressList(): List<InetAddress> {
266268
return try {
267269
map { InetAddress.getByName(it) }
268-
} catch (ex: UnknownHostException) {
270+
} catch (_: UnknownHostException) {
269271
Logger.e("Error parsing the DNS address list.")
270272
emptyList()
271273
}
@@ -290,6 +292,9 @@ class VpnSettingsViewModel(
290292
private fun Settings.getWireguardPort() =
291293
relaySettings.relayConstraints.wireguardConstraints.port
292294

295+
private fun Settings.getDeviceIpVersion() =
296+
relaySettings.relayConstraints.wireguardConstraints.ipVersion
297+
293298
private fun InetAddress.isLocalAddress(): Boolean {
294299
return isLinkLocalAddress || isSiteLocalAddress
295300
}

android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/VpnSettingsViewModelState.kt

+4
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package net.mullvad.mullvadvpn.viewmodel
33
import net.mullvad.mullvadvpn.compose.state.VpnSettingsUiState
44
import net.mullvad.mullvadvpn.lib.model.Constraint
55
import net.mullvad.mullvadvpn.lib.model.DefaultDnsOptions
6+
import net.mullvad.mullvadvpn.lib.model.IpVersion
67
import net.mullvad.mullvadvpn.lib.model.Mtu
78
import net.mullvad.mullvadvpn.lib.model.ObfuscationMode
89
import net.mullvad.mullvadvpn.lib.model.Port
@@ -24,6 +25,7 @@ data class VpnSettingsViewModelState(
2425
val availablePortRanges: List<PortRange>,
2526
val systemVpnSettingsAvailable: Boolean,
2627
val autoStartAndConnectOnBoot: Boolean,
28+
val deviceIpVersion: Constraint<IpVersion>,
2729
) {
2830
val isCustomWireguardPort =
2931
selectedWireguardPort is Constraint.Only &&
@@ -45,6 +47,7 @@ data class VpnSettingsViewModelState(
4547
availablePortRanges,
4648
systemVpnSettingsAvailable,
4749
autoStartAndConnectOnBoot,
50+
deviceIpVersion,
4851
)
4952

5053
companion object {
@@ -64,6 +67,7 @@ data class VpnSettingsViewModelState(
6467
availablePortRanges = emptyList(),
6568
systemVpnSettingsAvailable = false,
6669
autoStartAndConnectOnBoot = false,
70+
deviceIpVersion = Constraint.Any,
6771
)
6872
}
6973
}

android/lib/resource/src/main/res/values/strings.xml

+3
Original file line numberDiff line numberDiff line change
@@ -409,4 +409,7 @@
409409
<string name="see_full_changelog">See full changelog</string>
410410
<string name="changelog_empty">No changelog was added for this version</string>
411411
<string name="wg_port_subtitle">Set %s obfuscation to \"Automatic\" or \"Off\" below to activate this setting.</string>
412+
<string name="device_ip_version_title">Device IP version</string>
413+
<string name="device_ip_version_ipv4">IPv4</string>
414+
<string name="device_ip_version_ipv6">IPv6</string>
412415
</resources>

0 commit comments

Comments
 (0)