Skip to content

Commit e24edab

Browse files
committed
Add daita grpc and ui
1 parent fc50853 commit e24edab

File tree

40 files changed

+481
-133
lines changed

40 files changed

+481
-133
lines changed

android/app/src/androidTest/kotlin/net/mullvad/mullvadvpn/compose/data/DummyRelayItems.kt

+4-2
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ private val DUMMY_RELAY_1 =
2424
Provider(
2525
providerId = ProviderId("PROVIDER RENTED"),
2626
ownership = Ownership.Rented,
27-
)
27+
),
28+
daita = false
2829
)
2930
private val DUMMY_RELAY_2 =
3031
RelayItem.Location.Relay(
@@ -35,7 +36,8 @@ private val DUMMY_RELAY_2 =
3536
),
3637
active = true,
3738
provider =
38-
Provider(providerId = ProviderId("PROVIDER OWNED"), ownership = Ownership.MullvadOwned)
39+
Provider(providerId = ProviderId("PROVIDER OWNED"), ownership = Ownership.MullvadOwned),
40+
daita = false
3941
)
4042
private val DUMMY_RELAY_CITY_1 =
4143
RelayItem.Location.City(

android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/cell/FilterRow.kt

+14-2
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ fun FilterRow(
5959
is FilterChip.Ownership ->
6060
OwnershipFilterChip(it.ownership, onRemoveOwnershipFilter)
6161
is FilterChip.Provider -> ProviderFilterChip(it.count, onRemoveProviderFilter)
62+
is FilterChip.Daita -> DaitaFilterChip()
6263
}
6364
}
6465
}
@@ -68,15 +69,26 @@ fun FilterRow(
6869
fun ProviderFilterChip(providers: Int, onRemoveClick: () -> Unit) {
6970
MullvadFilterChip(
7071
text = stringResource(id = R.string.number_of_providers, providers),
71-
onRemoveClick = onRemoveClick
72+
onRemoveClick = onRemoveClick,
73+
showIcon = true
7274
)
7375
}
7476

7577
@Composable
7678
fun OwnershipFilterChip(ownership: Ownership, onRemoveClick: () -> Unit) {
7779
MullvadFilterChip(
7880
text = stringResource(ownership.stringResources()),
79-
onRemoveClick = onRemoveClick
81+
onRemoveClick = onRemoveClick,
82+
showIcon = true
83+
)
84+
}
85+
86+
@Composable
87+
fun DaitaFilterChip() {
88+
MullvadFilterChip(
89+
text = stringResource(id = R.string.setting_chip, stringResource(id = R.string.daita)),
90+
onRemoveClick = {},
91+
showIcon = false
8092
)
8193
}
8294

android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/FilterChip.kt

+11-7
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@ private fun PreviewMullvadFilterChip() {
2323
AppTheme {
2424
MullvadFilterChip(
2525
text = stringResource(id = R.string.number_of_providers),
26-
onRemoveClick = {}
26+
onRemoveClick = {},
27+
showIcon = true
2728
)
2829
}
2930
}
@@ -35,7 +36,8 @@ fun MullvadFilterChip(
3536
labelColor: Color = MaterialTheme.colorScheme.onPrimary,
3637
iconColor: Color = MaterialTheme.colorScheme.onPrimary,
3738
text: String,
38-
onRemoveClick: () -> Unit
39+
onRemoveClick: () -> Unit,
40+
showIcon: Boolean
3941
) {
4042
InputChip(
4143
shape = MaterialTheme.shapes.chipShape,
@@ -55,11 +57,13 @@ fun MullvadFilterChip(
5557
onClick = onRemoveClick,
5658
label = { Text(text = text, style = MaterialTheme.typography.labelMedium) },
5759
trailingIcon = {
58-
Icon(
59-
painter = painterResource(id = R.drawable.icon_close),
60-
contentDescription = null,
61-
modifier = Modifier.size(Dimens.smallIconSize)
62-
)
60+
if (showIcon) {
61+
Icon(
62+
painter = painterResource(id = R.drawable.icon_close),
63+
contentDescription = null,
64+
modifier = Modifier.size(Dimens.smallIconSize)
65+
)
66+
}
6367
}
6468
)
6569
}

android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/LocationInfo.kt

+43-9
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ private fun PreviewLocationInfo() {
3333
isVisible = true,
3434
isExpanded = true,
3535
location = null,
36+
isUsingDaita = false,
3637
inAddress = null,
3738
outAddress = ""
3839
)
@@ -48,6 +49,7 @@ fun LocationInfo(
4849
isVisible: Boolean,
4950
isExpanded: Boolean,
5051
location: GeoIpLocation?,
52+
isUsingDaita: Boolean,
5153
inAddress: Triple<String, Int, TransportProtocol>?,
5254
outAddress: String
5355
) {
@@ -61,15 +63,12 @@ fun LocationInfo(
6163
.then(modifier)
6264
) {
6365
Row(verticalAlignment = Alignment.CenterVertically) {
64-
Text(
65-
text = location?.hostname ?: "",
66-
color =
67-
if (isExpanded) {
68-
colorExpanded
69-
} else {
70-
colorCollapsed
71-
},
72-
style = MaterialTheme.typography.labelLarge.copy(fontWeight = FontWeight.SemiBold)
66+
RelayHostname(
67+
hostname = location?.hostname,
68+
isUsingDaita = isUsingDaita,
69+
isExpanded = isExpanded,
70+
colorExpanded = colorExpanded,
71+
colorCollapsed = colorCollapsed,
7372
)
7473
Chevron(
7574
isExpanded = isExpanded,
@@ -119,3 +118,38 @@ fun LocationInfo(
119118
)
120119
}
121120
}
121+
122+
@Composable
123+
private fun RelayHostname(
124+
hostname: String?,
125+
isUsingDaita: Boolean,
126+
isExpanded: Boolean,
127+
colorExpanded: Color,
128+
colorCollapsed: Color
129+
) {
130+
val hostnameTitle =
131+
when {
132+
hostname != null && isUsingDaita -> {
133+
stringResource(
134+
id = R.string.connected_using_daita,
135+
hostname,
136+
stringResource(
137+
id = R.string.daita,
138+
)
139+
)
140+
}
141+
hostname != null -> hostname
142+
else -> ""
143+
}
144+
145+
Text(
146+
text = hostnameTitle,
147+
color =
148+
if (isExpanded) {
149+
colorExpanded
150+
} else {
151+
colorCollapsed
152+
},
153+
style = MaterialTheme.typography.labelLarge.copy(fontWeight = FontWeight.SemiBold),
154+
)
155+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
package net.mullvad.mullvadvpn.compose.dialog
2+
3+
import androidx.compose.foundation.layout.Arrangement
4+
import androidx.compose.foundation.layout.Column
5+
import androidx.compose.foundation.layout.Spacer
6+
import androidx.compose.foundation.layout.fillMaxWidth
7+
import androidx.compose.foundation.layout.height
8+
import androidx.compose.foundation.rememberScrollState
9+
import androidx.compose.foundation.verticalScroll
10+
import androidx.compose.material3.AlertDialog
11+
import androidx.compose.material3.Icon
12+
import androidx.compose.material3.MaterialTheme
13+
import androidx.compose.material3.Text
14+
import androidx.compose.runtime.Composable
15+
import androidx.compose.ui.Alignment
16+
import androidx.compose.ui.Modifier
17+
import androidx.compose.ui.res.painterResource
18+
import androidx.compose.ui.res.stringResource
19+
import androidx.compose.ui.tooling.preview.Preview
20+
import androidx.lifecycle.compose.dropUnlessResumed
21+
import com.ramcosta.composedestinations.annotation.Destination
22+
import com.ramcosta.composedestinations.annotation.RootGraph
23+
import com.ramcosta.composedestinations.result.EmptyResultBackNavigator
24+
import com.ramcosta.composedestinations.result.ResultBackNavigator
25+
import com.ramcosta.composedestinations.spec.DestinationStyle
26+
import net.mullvad.mullvadvpn.R
27+
import net.mullvad.mullvadvpn.compose.button.PrimaryButton
28+
import net.mullvad.mullvadvpn.compose.component.drawVerticalScrollbar
29+
import net.mullvad.mullvadvpn.lib.theme.AppTheme
30+
import net.mullvad.mullvadvpn.lib.theme.Dimens
31+
import net.mullvad.mullvadvpn.lib.theme.color.AlphaScrollbar
32+
33+
@Preview
34+
@Composable
35+
private fun PreviewDaitaConfirmationDialog() {
36+
AppTheme { DaitaConfirmation(EmptyResultBackNavigator()) }
37+
}
38+
39+
@Destination<RootGraph>(style = DestinationStyle.Dialog::class)
40+
@Composable
41+
fun DaitaConfirmation(navigator: ResultBackNavigator<Boolean>) {
42+
AlertDialog(
43+
onDismissRequest = dropUnlessResumed { navigator.navigateBack(false) },
44+
icon = {
45+
Icon(
46+
modifier = Modifier.fillMaxWidth().height(Dimens.dialogIconHeight),
47+
painter = painterResource(id = R.drawable.icon_alert),
48+
contentDescription = "",
49+
tint = MaterialTheme.colorScheme.onSurface
50+
)
51+
},
52+
text = {
53+
val scrollState = rememberScrollState()
54+
Column(
55+
Modifier.drawVerticalScrollbar(
56+
scrollState,
57+
MaterialTheme.colorScheme.onPrimary.copy(alpha = AlphaScrollbar)
58+
)
59+
.verticalScroll(scrollState),
60+
horizontalAlignment = Alignment.CenterHorizontally,
61+
) {
62+
Text(
63+
text = stringResource(id = R.string.daita_relay_subset_warning),
64+
color = MaterialTheme.colorScheme.onSurface,
65+
style = MaterialTheme.typography.bodySmall,
66+
modifier = Modifier.fillMaxWidth(),
67+
)
68+
69+
Spacer(modifier = Modifier.height(Dimens.verticalSpace))
70+
71+
Text(
72+
text =
73+
stringResource(
74+
id = R.string.daita_warning,
75+
stringResource(
76+
id = R.string.daita,
77+
),
78+
),
79+
color = MaterialTheme.colorScheme.onSurface,
80+
style = MaterialTheme.typography.bodySmall,
81+
modifier = Modifier.fillMaxWidth(),
82+
)
83+
}
84+
},
85+
confirmButton = {
86+
Column(verticalArrangement = Arrangement.spacedBy(Dimens.buttonSpacing)) {
87+
PrimaryButton(
88+
modifier = Modifier.fillMaxWidth(),
89+
text = stringResource(R.string.enable_anyway),
90+
onClick = { navigator.navigateBack(true) },
91+
)
92+
93+
PrimaryButton(
94+
modifier = Modifier.fillMaxWidth(),
95+
text = stringResource(R.string.back),
96+
onClick = dropUnlessResumed { navigator.navigateBack(false) },
97+
)
98+
}
99+
},
100+
containerColor = MaterialTheme.colorScheme.surface,
101+
titleContentColor = MaterialTheme.colorScheme.onSurface,
102+
)
103+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package net.mullvad.mullvadvpn.compose.dialog
2+
3+
import androidx.compose.runtime.Composable
4+
import androidx.compose.ui.res.stringResource
5+
import androidx.compose.ui.tooling.preview.Preview
6+
import androidx.lifecycle.compose.dropUnlessResumed
7+
import com.ramcosta.composedestinations.annotation.Destination
8+
import com.ramcosta.composedestinations.annotation.RootGraph
9+
import com.ramcosta.composedestinations.navigation.DestinationsNavigator
10+
import com.ramcosta.composedestinations.navigation.EmptyDestinationsNavigator
11+
import com.ramcosta.composedestinations.spec.DestinationStyle
12+
import net.mullvad.mullvadvpn.R
13+
import net.mullvad.mullvadvpn.lib.theme.AppTheme
14+
15+
@Preview
16+
@Composable
17+
private fun PreviewDaitaInfoDialog() {
18+
AppTheme { DaitaInfo(EmptyDestinationsNavigator) }
19+
}
20+
21+
@Destination<RootGraph>(style = DestinationStyle.Dialog::class)
22+
@Composable
23+
fun DaitaInfo(navigator: DestinationsNavigator) {
24+
InfoDialog(
25+
message =
26+
stringResource(
27+
id = R.string.daita_info,
28+
stringResource(id = R.string.daita),
29+
stringResource(id = R.string.daita_full),
30+
),
31+
additionalInfo =
32+
stringResource(id = R.string.daita_warning, stringResource(id = R.string.daita)),
33+
onDismiss = dropUnlessResumed { navigator.navigateUp() },
34+
)
35+
}

android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/preview/RelayItemPreviewData.kt

+2
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ private fun generateRelayItemRelay(
5151
cityCode: GeoLocationId.City,
5252
hostName: String,
5353
active: Boolean = true,
54+
daita: Boolean = true,
5455
) =
5556
RelayItem.Location.Relay(
5657
id =
@@ -60,6 +61,7 @@ private fun generateRelayItemRelay(
6061
),
6162
active = active,
6263
provider = Provider(ProviderId("Provider"), Ownership.MullvadOwned),
64+
daita = daita
6365
)
6466

6567
private fun String.generateCountryCode() =

android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/preview/TunnelStatePreviewData.kt

+5-4
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,14 @@ object TunnelStatePreviewData {
1818

1919
fun generateConnectingState(featureIndicators: Int, quantumResistant: Boolean) =
2020
TunnelState.Connecting(
21-
endpoint = generateTunnelEndpoint(quantumResistant = quantumResistant),
21+
endpoint = generateTunnelEndpoint(quantumResistant = quantumResistant, daita = false),
2222
location = generateLocation(),
2323
featureIndicators = generateFeatureIndicators(featureIndicators)
2424
)
2525

2626
fun generateConnectedState(featureIndicators: Int, quantumResistant: Boolean) =
2727
TunnelState.Connected(
28-
endpoint = generateTunnelEndpoint(quantumResistant = quantumResistant),
28+
endpoint = generateTunnelEndpoint(quantumResistant = quantumResistant, daita = true),
2929
location = generateLocation(),
3030
featureIndicators = generateFeatureIndicators(featureIndicators)
3131
)
@@ -39,15 +39,16 @@ object TunnelStatePreviewData {
3939
)
4040
}
4141

42-
private fun generateTunnelEndpoint(quantumResistant: Boolean): TunnelEndpoint =
42+
private fun generateTunnelEndpoint(quantumResistant: Boolean, daita: Boolean): TunnelEndpoint =
4343
TunnelEndpoint(
4444
endpoint = generateEndpoint(TransportProtocol.Udp),
4545
quantumResistant = quantumResistant,
4646
obfuscation =
4747
ObfuscationEndpoint(
4848
endpoint = generateEndpoint(TransportProtocol.Tcp),
4949
ObfuscationType.Udp2Tcp
50-
)
50+
),
51+
daita = daita
5152
)
5253

5354
private fun generateEndpoint(transportProtocol: TransportProtocol) =

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

+1
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,7 @@ private fun ConnectionInfo(state: ConnectUiState) {
365365
isVisible = state.showLocationInfo,
366366
isExpanded = expanded,
367367
location = state.location,
368+
isUsingDaita = state.tunnelState.isUsingDaita(),
368369
inAddress = state.inAddress,
369370
outAddress = state.outAddress,
370371
modifier =

0 commit comments

Comments
 (0)