diff options
| author | Jonatan Rhodin <jonatan.rhodin@mullvad.net> | 2024-08-26 10:35:29 +0200 |
|---|---|---|
| committer | Albin <albin@mullvad.net> | 2024-08-26 12:44:32 +0200 |
| commit | 4cefa1584d102d47110606b9797f78801103f35f (patch) | |
| tree | ea679771695dc63c0d6b4a6906d90998c2eaabcd /android/app/src/main | |
| parent | ec2098841f78621b31708ab6427c740f7e42ce5a (diff) | |
| download | mullvadvpn-4cefa1584d102d47110606b9797f78801103f35f.tar.xz mullvadvpn-4cefa1584d102d47110606b9797f78801103f35f.zip | |
Add support for feature indicators for tunnel state
Diffstat (limited to 'android/app/src/main')
6 files changed, 157 insertions, 101 deletions
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/button/ConnectionButton.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/button/ConnectionButton.kt index eda1b86690..dd8eec57d2 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/button/ConnectionButton.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/button/ConnectionButton.kt @@ -29,16 +29,34 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.dp import androidx.constraintlayout.compose.ConstraintLayout import androidx.constraintlayout.compose.Dimension import net.mullvad.mullvadvpn.R +import net.mullvad.mullvadvpn.compose.preview.TunnelStatePreviewParameterProvider import net.mullvad.mullvadvpn.lib.model.TunnelState import net.mullvad.mullvadvpn.lib.theme.AppTheme import net.mullvad.mullvadvpn.lib.theme.Dimens import net.mullvad.mullvadvpn.lib.theme.color.AlphaDisconnectButton @Composable +@Preview +private fun PreviewConnectionButton( + @PreviewParameter(TunnelStatePreviewParameterProvider::class) tunnelState: TunnelState +) { + AppTheme { + ConnectionButton( + state = tunnelState, + disconnectClick = {}, + reconnectClick = {}, + cancelClick = {}, + connectClick = {} + ) + } +} + +@Composable fun ConnectionButton( modifier: Modifier = Modifier, reconnectButtonTestTag: String = "", @@ -106,21 +124,6 @@ fun ConnectionButton( ) } -@Preview -@Composable -private fun PreviewConnectionButton() { - AppTheme { - ConnectionButton( - text = "Disconnect", - mainClick = {}, - containerColor = MaterialTheme.colorScheme.error.copy(alpha = AlphaDisconnectButton), - contentColor = MaterialTheme.colorScheme.onError, - reconnectClick = {}, - isReconnectButtonEnabled = true - ) - } -} - @OptIn(ExperimentalMaterial3Api::class) @Composable private fun ConnectionButton( diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/ConnectionStatusText.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/ConnectionStatusText.kt index b4d6b0d60c..0b155953e3 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/ConnectionStatusText.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/component/ConnectionStatusText.kt @@ -1,66 +1,29 @@ package net.mullvad.mullvadvpn.compose.component import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Column import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.tooling.preview.Preview -import java.net.InetSocketAddress +import androidx.compose.ui.tooling.preview.PreviewParameter import net.mullvad.mullvadvpn.R +import net.mullvad.mullvadvpn.compose.preview.TunnelStatePreviewParameterProvider import net.mullvad.mullvadvpn.lib.model.ActionAfterDisconnect -import net.mullvad.mullvadvpn.lib.model.Endpoint -import net.mullvad.mullvadvpn.lib.model.ErrorState -import net.mullvad.mullvadvpn.lib.model.ErrorStateCause -import net.mullvad.mullvadvpn.lib.model.TransportProtocol -import net.mullvad.mullvadvpn.lib.model.TunnelEndpoint import net.mullvad.mullvadvpn.lib.model.TunnelState import net.mullvad.mullvadvpn.lib.theme.AppTheme import net.mullvad.mullvadvpn.lib.theme.typeface.connectionStatus @Preview @Composable -private fun PreviewConnectionStatusText() { +private fun PreviewConnectionStatusText( + @PreviewParameter(TunnelStatePreviewParameterProvider::class) tunnelState: TunnelState +) { AppTheme { - SpacedColumn(modifier = Modifier.background(MaterialTheme.colorScheme.surface)) { - ConnectionStatusText(TunnelState.Disconnected()) - ConnectionStatusText(TunnelState.Connecting(null, null)) - ConnectionStatusText( - state = TunnelState.Error(ErrorState(ErrorStateCause.Ipv6Unavailable, true)) - ) - ConnectionStatusText( - state = - TunnelState.Connected( - endpoint = - TunnelEndpoint( - endpoint = - Endpoint( - address = InetSocketAddress(10), - protocol = TransportProtocol.Tcp - ), - quantumResistant = false, - obfuscation = null - ), - location = null - ) - ) - ConnectionStatusText( - state = - TunnelState.Connected( - endpoint = - TunnelEndpoint( - endpoint = - Endpoint( - address = InetSocketAddress(10), - protocol = TransportProtocol.Tcp - ), - quantumResistant = true, - obfuscation = null - ), - location = null - ) - ) + Column(modifier = Modifier.background(MaterialTheme.colorScheme.surface)) { + ConnectionStatusText(state = tunnelState) } } } diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/preview/OutOfTimeScreenPreviewParameterProvider.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/preview/OutOfTimeScreenPreviewParameterProvider.kt new file mode 100644 index 0000000000..efe8ac2fa5 --- /dev/null +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/preview/OutOfTimeScreenPreviewParameterProvider.kt @@ -0,0 +1,29 @@ +package net.mullvad.mullvadvpn.compose.preview + +import androidx.compose.ui.tooling.preview.PreviewParameterProvider +import net.mullvad.mullvadvpn.compose.preview.TunnelStatePreviewData.generateConnectingState +import net.mullvad.mullvadvpn.compose.preview.TunnelStatePreviewData.generateDisconnectedState +import net.mullvad.mullvadvpn.compose.preview.TunnelStatePreviewData.generateErrorState +import net.mullvad.mullvadvpn.compose.state.OutOfTimeUiState + +class OutOfTimeScreenPreviewParameterProvider : PreviewParameterProvider<OutOfTimeUiState> { + override val values: Sequence<OutOfTimeUiState> = + sequenceOf( + OutOfTimeUiState( + tunnelState = generateDisconnectedState(), + "Heroic Frog", + showSitePayment = true + ), + OutOfTimeUiState( + tunnelState = + generateConnectingState(featureIndicators = 0, quantumResistant = false), + "Strong Rabbit", + showSitePayment = true + ), + OutOfTimeUiState( + tunnelState = generateErrorState(isBlocking = true), + deviceName = "Stable Horse", + showSitePayment = true + ) + ) +} diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/preview/TunnelStatePreviewData.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/preview/TunnelStatePreviewData.kt new file mode 100644 index 0000000000..7045cc45dc --- /dev/null +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/preview/TunnelStatePreviewData.kt @@ -0,0 +1,70 @@ +package net.mullvad.mullvadvpn.compose.preview + +import java.net.InetSocketAddress +import net.mullvad.mullvadvpn.lib.model.ActionAfterDisconnect +import net.mullvad.mullvadvpn.lib.model.Endpoint +import net.mullvad.mullvadvpn.lib.model.ErrorState +import net.mullvad.mullvadvpn.lib.model.ErrorStateCause +import net.mullvad.mullvadvpn.lib.model.FeatureIndicator +import net.mullvad.mullvadvpn.lib.model.GeoIpLocation +import net.mullvad.mullvadvpn.lib.model.ObfuscationEndpoint +import net.mullvad.mullvadvpn.lib.model.ObfuscationType +import net.mullvad.mullvadvpn.lib.model.TransportProtocol +import net.mullvad.mullvadvpn.lib.model.TunnelEndpoint +import net.mullvad.mullvadvpn.lib.model.TunnelState + +object TunnelStatePreviewData { + fun generateDisconnectedState() = TunnelState.Disconnected() + + fun generateConnectingState(featureIndicators: Int, quantumResistant: Boolean) = + TunnelState.Connecting( + endpoint = generateTunnelEndpoint(quantumResistant = quantumResistant), + location = generateLocation(), + featureIndicators = generateFeatureIndicators(featureIndicators) + ) + + fun generateConnectedState(featureIndicators: Int, quantumResistant: Boolean) = + TunnelState.Connected( + endpoint = generateTunnelEndpoint(quantumResistant = quantumResistant), + location = generateLocation(), + featureIndicators = generateFeatureIndicators(featureIndicators) + ) + + fun generateDisconnectingState(actionAfterDisconnect: ActionAfterDisconnect) = + TunnelState.Disconnecting(actionAfterDisconnect = actionAfterDisconnect) + + fun generateErrorState(isBlocking: Boolean) = + TunnelState.Error( + errorState = ErrorState(cause = ErrorStateCause.DnsError, isBlocking = isBlocking) + ) +} + +private fun generateTunnelEndpoint(quantumResistant: Boolean): TunnelEndpoint = + TunnelEndpoint( + endpoint = generateEndpoint(TransportProtocol.Udp), + quantumResistant = quantumResistant, + obfuscation = + ObfuscationEndpoint( + endpoint = generateEndpoint(TransportProtocol.Tcp), + ObfuscationType.Udp2Tcp + ) + ) + +private fun generateEndpoint(transportProtocol: TransportProtocol) = + Endpoint(address = InetSocketAddress(DEFAULT_ENDPOINT_PORT), protocol = transportProtocol) + +private fun generateLocation(): GeoIpLocation = + GeoIpLocation( + ipv4 = null, + ipv6 = null, + country = "", + city = "", + hostname = "", + latitude = 0.0, + longitude = 0.0, + ) + +private fun generateFeatureIndicators(size: Int): List<FeatureIndicator> = + FeatureIndicator.entries.subList(0, size) + +private const val DEFAULT_ENDPOINT_PORT = 100 diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/preview/TunnelStatePreviewParameterProvider.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/preview/TunnelStatePreviewParameterProvider.kt new file mode 100644 index 0000000000..9cd06ef276 --- /dev/null +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/preview/TunnelStatePreviewParameterProvider.kt @@ -0,0 +1,26 @@ +package net.mullvad.mullvadvpn.compose.preview + +import androidx.compose.ui.tooling.preview.PreviewParameterProvider +import net.mullvad.mullvadvpn.compose.preview.TunnelStatePreviewData.generateConnectedState +import net.mullvad.mullvadvpn.compose.preview.TunnelStatePreviewData.generateConnectingState +import net.mullvad.mullvadvpn.compose.preview.TunnelStatePreviewData.generateDisconnectedState +import net.mullvad.mullvadvpn.compose.preview.TunnelStatePreviewData.generateDisconnectingState +import net.mullvad.mullvadvpn.compose.preview.TunnelStatePreviewData.generateErrorState +import net.mullvad.mullvadvpn.lib.model.ActionAfterDisconnect +import net.mullvad.mullvadvpn.lib.model.TunnelState + +class TunnelStatePreviewParameterProvider : PreviewParameterProvider<TunnelState> { + override val values: Sequence<TunnelState> = + sequenceOf( + generateDisconnectedState(), + generateConnectingState(featureIndicators = 0, quantumResistant = false), + generateConnectingState(featureIndicators = 0, quantumResistant = true), + generateConnectedState(featureIndicators = 0, quantumResistant = false), + generateConnectedState(featureIndicators = 0, quantumResistant = true), + generateDisconnectingState(actionAfterDisconnect = ActionAfterDisconnect.Block), + generateDisconnectingState(actionAfterDisconnect = ActionAfterDisconnect.Nothing), + generateDisconnectingState(actionAfterDisconnect = ActionAfterDisconnect.Reconnect), + generateErrorState(isBlocking = true), + generateErrorState(isBlocking = false) + ) +} diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/OutOfTimeScreen.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/OutOfTimeScreen.kt index 7b5b4bff55..43730ff164 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/OutOfTimeScreen.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/OutOfTimeScreen.kt @@ -24,6 +24,7 @@ import androidx.compose.ui.platform.testTag import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.lifecycle.Lifecycle import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.compose.dropUnlessResumed @@ -48,12 +49,12 @@ import net.mullvad.mullvadvpn.compose.component.ScaffoldWithTopBarAndDeviceName import net.mullvad.mullvadvpn.compose.component.drawVerticalScrollbar import net.mullvad.mullvadvpn.compose.extensions.createOpenAccountPageHook import net.mullvad.mullvadvpn.compose.extensions.dropUnlessResumed +import net.mullvad.mullvadvpn.compose.preview.OutOfTimeScreenPreviewParameterProvider import net.mullvad.mullvadvpn.compose.state.OutOfTimeUiState import net.mullvad.mullvadvpn.compose.test.OUT_OF_TIME_SCREEN_TITLE_TEST_TAG import net.mullvad.mullvadvpn.compose.transitions.HomeTransition import net.mullvad.mullvadvpn.compose.util.CollectSideEffectWithLifecycle import net.mullvad.mullvadvpn.compose.util.showSnackbarImmediately -import net.mullvad.mullvadvpn.lib.model.ErrorState import net.mullvad.mullvadvpn.lib.model.ErrorStateCause import net.mullvad.mullvadvpn.lib.model.TunnelState import net.mullvad.mullvadvpn.lib.payment.model.ProductId @@ -65,48 +66,12 @@ import org.koin.androidx.compose.koinViewModel @Preview @Composable -private fun PreviewOutOfTimeScreenDisconnected() { - AppTheme { - OutOfTimeScreen( - state = - OutOfTimeUiState( - tunnelState = TunnelState.Disconnected(), - "Heroic Frog", - showSitePayment = true - ), - ) - } -} - -@Preview -@Composable -private fun PreviewOutOfTimeScreenConnecting() { - AppTheme { - OutOfTimeScreen( - state = - OutOfTimeUiState( - tunnelState = TunnelState.Connecting(null, null), - "Strong Rabbit", - showSitePayment = true - ), - ) - } -} - -@Preview -@Composable -private fun PreviewOutOfTimeScreenError() { +private fun PreviewOutOfTimeScreen( + @PreviewParameter(OutOfTimeScreenPreviewParameterProvider::class) state: OutOfTimeUiState +) { AppTheme { OutOfTimeScreen( - state = - OutOfTimeUiState( - tunnelState = - TunnelState.Error( - ErrorState(cause = ErrorStateCause.IsOffline, isBlocking = true) - ), - deviceName = "Stable Horse", - showSitePayment = true - ), + state = state, ) } } |
