Skip to content

Commit 9c6c19a

Browse files
committed
Merge branch 'show-snackbars-for-minimum-duration-droid-1066'
2 parents 6ffbd87 + 953bbdc commit 9c6c19a

File tree

5 files changed

+38
-11
lines changed

5 files changed

+38
-11
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package net.mullvad.mullvadvpn.util
2+
3+
import kotlinx.coroutines.async
4+
import kotlinx.coroutines.coroutineScope
5+
import kotlinx.coroutines.delay
6+
7+
suspend fun <T> delayAtLeast(duration: Long, f: suspend () -> T): T = coroutineScope {
8+
val result = async { f() }
9+
delay(timeMillis = duration)
10+
result.await()
11+
}

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

+5-2
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,12 @@ import kotlinx.coroutines.flow.receiveAsFlow
1414
import kotlinx.coroutines.flow.stateIn
1515
import kotlinx.coroutines.launch
1616
import net.mullvad.mullvadvpn.compose.state.ApiAccessMethodDetailsUiState
17+
import net.mullvad.mullvadvpn.constant.MINIMUM_LOADING_TIME_MILLIS
1718
import net.mullvad.mullvadvpn.lib.model.ApiAccessMethod
1819
import net.mullvad.mullvadvpn.lib.model.ApiAccessMethodId
1920
import net.mullvad.mullvadvpn.lib.model.TestApiAccessMethodError
2021
import net.mullvad.mullvadvpn.repository.ApiAccessRepository
22+
import net.mullvad.mullvadvpn.util.delayAtLeast
2123

2224
class ApiAccessMethodDetailsViewModel(
2325
private val apiAccessMethodId: ApiAccessMethodId,
@@ -107,8 +109,9 @@ class ApiAccessMethodDetailsViewModel(
107109

108110
private suspend fun testMethodById(): Either<TestApiAccessMethodError, Unit> {
109111
isTestingApiAccessMethodState.value = true
110-
return apiAccessRepository
111-
.testApiAccessMethodById(apiAccessMethodId)
112+
return delayAtLeast(MINIMUM_LOADING_TIME_MILLIS) {
113+
apiAccessRepository.testApiAccessMethodById(apiAccessMethodId)
114+
}
112115
.onLeft { isTestingApiAccessMethodState.value = false }
113116
.onRight { isTestingApiAccessMethodState.value = false }
114117
}

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

+6-1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import kotlinx.coroutines.launch
2323
import net.mullvad.mullvadvpn.compose.state.ApiAccessMethodTypes
2424
import net.mullvad.mullvadvpn.compose.state.EditApiAccessFormData
2525
import net.mullvad.mullvadvpn.compose.state.EditApiAccessMethodUiState
26+
import net.mullvad.mullvadvpn.constant.MINIMUM_LOADING_TIME_MILLIS
2627
import net.mullvad.mullvadvpn.lib.model.ApiAccessMethod
2728
import net.mullvad.mullvadvpn.lib.model.ApiAccessMethodId
2829
import net.mullvad.mullvadvpn.lib.model.ApiAccessMethodName
@@ -32,6 +33,7 @@ import net.mullvad.mullvadvpn.lib.model.ParsePortError
3233
import net.mullvad.mullvadvpn.lib.model.Port
3334
import net.mullvad.mullvadvpn.lib.model.SocksAuth
3435
import net.mullvad.mullvadvpn.repository.ApiAccessRepository
36+
import net.mullvad.mullvadvpn.util.delayAtLeast
3537
import org.apache.commons.validator.routines.InetAddressValidator
3638

3739
class EditApiAccessMethodViewModel(
@@ -104,7 +106,10 @@ class EditApiAccessMethodViewModel(
104106
{ errors -> formData.update { it.updateWithErrors(errors) } },
105107
{ customProxy ->
106108
isTestingApiAccessMethod.value = true
107-
val result = apiAccessRepository.testCustomApiAccessMethod(customProxy)
109+
val result =
110+
delayAtLeast(MINIMUM_LOADING_TIME_MILLIS) {
111+
apiAccessRepository.testCustomApiAccessMethod(customProxy)
112+
}
108113
_uiSideEffect.send(
109114
EditApiAccessSideEffect.TestApiAccessMethodResult(result.isRight())
110115
)

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

+6-8
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import net.mullvad.mullvadvpn.lib.model.LoginAccountError
2929
import net.mullvad.mullvadvpn.lib.shared.AccountRepository
3030
import net.mullvad.mullvadvpn.repository.NewDeviceRepository
3131
import net.mullvad.mullvadvpn.usecase.InternetAvailableUseCase
32+
import net.mullvad.mullvadvpn.util.delayAtLeast
3233
import net.mullvad.mullvadvpn.util.getOrDefault
3334

3435
private const val MINIMUM_LOADING_SPINNER_TIME_MILLIS = 500L
@@ -101,15 +102,12 @@ class LoginViewModel(
101102
}
102103
_loginState.value = Loading.LoggingIn
103104
viewModelScope.launch(dispatcher) {
104-
// Ensure we always take at least MINIMUM_LOADING_SPINNER_TIME_MILLIS to show the
105-
// loading indicator
106-
val result = async { accountRepository.login(AccountNumber(accountNumber)) }
107-
108-
delay(MINIMUM_LOADING_SPINNER_TIME_MILLIS)
109-
110105
val uiState =
111-
result
112-
.await()
106+
// Ensure we always take at least MINIMUM_LOADING_SPINNER_TIME_MILLIS to show the
107+
// loading indicator
108+
delayAtLeast(MINIMUM_LOADING_SPINNER_TIME_MILLIS) {
109+
accountRepository.login(AccountNumber(accountNumber))
110+
}
113111
.fold(
114112
{ it.toUiState() },
115113
{

android/app/src/test/kotlin/net/mullvad/mullvadvpn/viewmodel/ApiAccessMethodDetailsViewModelTest.kt

+10
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
package net.mullvad.mullvadvpn.viewmodel
22

33
import app.cash.turbine.test
4+
import arrow.core.Either
45
import arrow.core.left
56
import arrow.core.right
67
import io.mockk.coEvery
78
import io.mockk.coVerify
89
import io.mockk.every
910
import io.mockk.mockk
11+
import io.mockk.mockkStatic
1012
import java.time.Duration
1113
import kotlin.test.assertIs
1214
import kotlinx.coroutines.flow.MutableStateFlow
@@ -20,6 +22,7 @@ import net.mullvad.mullvadvpn.lib.model.ApiAccessMethodSetting
2022
import net.mullvad.mullvadvpn.lib.model.TestApiAccessMethodError
2123
import net.mullvad.mullvadvpn.lib.model.UnknownApiAccessMethodError
2224
import net.mullvad.mullvadvpn.repository.ApiAccessRepository
25+
import net.mullvad.mullvadvpn.util.delayAtLeast
2326
import org.junit.jupiter.api.Assertions.assertEquals
2427
import org.junit.jupiter.api.BeforeEach
2528
import org.junit.jupiter.api.Test
@@ -38,6 +41,7 @@ class ApiAccessMethodDetailsViewModelTest {
3841

3942
@BeforeEach
4043
fun setUp() {
44+
mockkStatic(DELAY_UTIL)
4145
every { mockApiAccessRepository.apiAccessMethodSettingById(apiAccessMethodId) } returns
4246
accessMethodFlow
4347
every { mockApiAccessRepository.enabledApiAccessMethods() } returns enabledMethodsFlow
@@ -58,6 +62,8 @@ class ApiAccessMethodDetailsViewModelTest {
5862
Unit.right()
5963
coEvery { mockApiAccessRepository.setCurrentApiAccessMethod(any()) } returns
6064
Unit.right()
65+
coEvery { delayAtLeast<Either<TestApiAccessMethodError, Unit>>(any(), any()) } returns
66+
Unit.right()
6167

6268
// Act
6369
apiAccessMethodDetailsViewModel.setCurrentMethod()
@@ -177,4 +183,8 @@ class ApiAccessMethodDetailsViewModelTest {
177183
)
178184
}
179185
}
186+
187+
companion object {
188+
private const val DELAY_UTIL = "net.mullvad.mullvadvpn.util.DelayKt"
189+
}
180190
}

0 commit comments

Comments
 (0)