summaryrefslogtreecommitdiffhomepage
path: root/android/app/src/main
diff options
context:
space:
mode:
authorAlbin <albin@mullvad.net>2023-08-01 12:00:27 +0200
committerAlbin <albin@mullvad.net>2023-08-01 12:00:27 +0200
commitddd2ed9858c7a1aa47884a44b1a653c3f3af8df3 (patch)
tree338416e3b07235dc6116bcf11e1b03326227a172 /android/app/src/main
parent9f76fd36507ef03e1c72ec432c05ddaf52ae2634 (diff)
parentfd6464f0568ad087e3669ae444434768c2a9e50f (diff)
downloadmullvadvpn-ddd2ed9858c7a1aa47884a44b1a653c3f3af8df3.tar.xz
mullvadvpn-ddd2ed9858c7a1aa47884a44b1a653c3f3af8df3.zip
Merge branch 'reduce-location-flickering-droid-219'
Diffstat (limited to 'android/app/src/main')
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/button/ConnectionButton.kt28
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/ConnectScreen.kt20
-rw-r--r--android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/ConnectViewModel.kt27
3 files changed, 43 insertions, 32 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 ad483165f8..e6424a1674 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
@@ -28,7 +28,6 @@ import net.mullvad.mullvadvpn.compose.theme.AlphaInactive
import net.mullvad.mullvadvpn.compose.theme.AppTheme
import net.mullvad.mullvadvpn.compose.theme.Dimens
import net.mullvad.mullvadvpn.model.TunnelState
-import net.mullvad.talpid.tunnel.ActionAfterDisconnect
@Composable
fun ConnectionButton(
@@ -43,26 +42,13 @@ fun ConnectionButton(
when (state) {
is TunnelState.Disconnected -> ConnectButton(modifier = modifier, onClick = connectClick)
is TunnelState.Disconnecting -> {
- when (state.actionAfterDisconnect) {
- ActionAfterDisconnect.Nothing ->
- ConnectButton(modifier = modifier, onClick = connectClick)
- ActionAfterDisconnect.Block ->
- DisconnectButton(
- modifier = modifier,
- text = stringResource(id = R.string.disconnect),
- mainClick = connectClick,
- reconnectClick = reconnectClick,
- reconnectButtonTestTag = reconnectButtonTestTag
- )
- ActionAfterDisconnect.Reconnect ->
- DisconnectButton(
- modifier = modifier,
- text = stringResource(id = R.string.disconnect),
- mainClick = connectClick,
- reconnectClick = reconnectClick,
- reconnectButtonTestTag = reconnectButtonTestTag
- )
- }
+ DisconnectButton(
+ modifier = modifier,
+ text = stringResource(id = R.string.disconnect),
+ mainClick = connectClick,
+ reconnectClick = reconnectClick,
+ reconnectButtonTestTag = reconnectButtonTestTag
+ )
}
is TunnelState.Connecting ->
DisconnectButton(
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/ConnectScreen.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/ConnectScreen.kt
index 50c0005a96..384c92d590 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/ConnectScreen.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/ConnectScreen.kt
@@ -15,6 +15,10 @@ import androidx.compose.material3.CircularProgressIndicator
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.testTag
@@ -36,6 +40,8 @@ import net.mullvad.mullvadvpn.compose.theme.Dimens
import net.mullvad.mullvadvpn.model.TunnelState
import net.mullvad.talpid.tunnel.ActionAfterDisconnect
+private const val CONNECT_BUTTON_THROTTLE_MILLIS = 1000
+
@Preview
@Composable
fun PreviewConnectScreen() {
@@ -54,6 +60,16 @@ fun ConnectScreen(
onToggleTunnelInfo: () -> Unit = {}
) {
val scrollState = rememberScrollState()
+ var lastConnectionActionTimestamp by remember { mutableStateOf(0L) }
+
+ fun handleThrottledAction(action: () -> Unit) {
+ val currentTime = System.currentTimeMillis()
+ if ((currentTime - lastConnectionActionTimestamp) > CONNECT_BUTTON_THROTTLE_MILLIS) {
+ lastConnectionActionTimestamp = currentTime
+ action.invoke()
+ }
+ }
+
Column(
verticalArrangement = Arrangement.Bottom,
horizontalAlignment = Alignment.Start,
@@ -126,9 +142,9 @@ fun ConnectScreen(
.height(Dimens.connectButtonHeight)
.testTag(CONNECT_BUTTON_TEST_TAG),
disconnectClick = onDisconnectClick,
- reconnectClick = onReconnectClick,
+ reconnectClick = { handleThrottledAction(onReconnectClick) },
cancelClick = onCancelClick,
- connectClick = onConnectClick,
+ connectClick = { handleThrottledAction(onConnectClick) },
reconnectButtonTestTag = RECONNECT_BUTTON_TEST_TAG
)
}
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/ConnectViewModel.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/ConnectViewModel.kt
index 826376ad9f..37aa06a7c9 100644
--- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/ConnectViewModel.kt
+++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/ConnectViewModel.kt
@@ -11,6 +11,7 @@ import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.callbackFlow
import kotlinx.coroutines.flow.debounce
import kotlinx.coroutines.flow.emptyFlow
+import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.shareIn
@@ -64,7 +65,13 @@ class ConnectViewModel(private val serviceConnectionManager: ServiceConnectionMa
tunnelRealState,
isTunnelInfoExpanded ->
ConnectUiState(
- location = location,
+ location =
+ when (tunnelRealState) {
+ is TunnelState.Connected -> tunnelRealState.location
+ is TunnelState.Connecting -> tunnelRealState.location
+ else -> null
+ }
+ ?: location,
relayLocation = relayLocation,
versionInfo = versionInfo,
tunnelUiState = tunnelUiState,
@@ -82,7 +89,7 @@ class ConnectViewModel(private val serviceConnectionManager: ServiceConnectionMa
is TunnelState.Disconnected -> true
is TunnelState.Disconnecting -> {
when (tunnelUiState.actionAfterDisconnect) {
- ActionAfterDisconnect.Nothing -> true
+ ActionAfterDisconnect.Nothing -> false
ActionAfterDisconnect.Block -> true
ActionAfterDisconnect.Reconnect -> false
}
@@ -94,12 +101,16 @@ class ConnectViewModel(private val serviceConnectionManager: ServiceConnectionMa
)
}
}
+ .debounce(UI_STATE_DEBOUNCE_DURATION_MILLIS)
.stateIn(viewModelScope, SharingStarted.WhileSubscribed(), ConnectUiState.INITIAL)
- private fun LocationInfoCache.locationCallbackFlow() = callbackFlow {
- onNewLocation = { this.trySend(it) }
- awaitClose { onNewLocation = null }
- }
+ private fun LocationInfoCache.locationCallbackFlow() =
+ callbackFlow {
+ onNewLocation = { this.trySend(it) }
+ awaitClose { onNewLocation = null }
+ }
+ // Filter out empty or short-name country representations.
+ .filter { it?.let { location -> location.country.length > 2 } ?: false }
private fun RelayListListener.relayListCallbackFlow() = callbackFlow {
onRelayCountriesChange = { _, item -> this.trySend(item) }
@@ -108,11 +119,9 @@ class ConnectViewModel(private val serviceConnectionManager: ServiceConnectionMa
private fun ConnectionProxy.tunnelUiStateFlow(): Flow<TunnelState> =
callbackFlowFromNotifier(this.onUiStateChange)
- .debounce(TUNNEL_STATE_UPDATE_DEBOUNCE_DURATION_MILLIS)
private fun ConnectionProxy.tunnelRealStateFlow(): Flow<TunnelState> =
callbackFlowFromNotifier(this.onStateChange)
- .debounce(TUNNEL_STATE_UPDATE_DEBOUNCE_DURATION_MILLIS)
fun toggleTunnelInfoExpansion() {
_isTunnelInfoExpanded.value = _isTunnelInfoExpanded.value.not()
@@ -132,6 +141,6 @@ class ConnectViewModel(private val serviceConnectionManager: ServiceConnectionMa
}
companion object {
- const val TUNNEL_STATE_UPDATE_DEBOUNCE_DURATION_MILLIS: Long = 200
+ const val UI_STATE_DEBOUNCE_DURATION_MILLIS: Long = 100
}
}