Skip to content

Commit

Permalink
Add cencel button for test method
Browse files Browse the repository at this point in the history
  • Loading branch information
Pururun committed Jun 12, 2024
1 parent 609accb commit f1e291a
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ private fun LazyListScope.currentAccessMethod(
color = MaterialTheme.colorScheme.onBackground,
text =
stringResource(
id = R.string.current_x,
id = R.string.current_method,
currentApiAccessMethodName?.value ?: "-",
),
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,10 @@ fun ApiAccessMethodDetails(
if (state.testingAccessMethod()) {
launch {
snackbarHostState.showSnackbarImmediately(
message = context.getString(R.string.testing),
duration = SnackbarDuration.Indefinite
message = context.getString(R.string.testing_name, state.name()),
duration = SnackbarDuration.Indefinite,
actionLabel = context.getString(R.string.cancel),
onAction = viewModel::cancelTestMethod
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,9 @@ fun EditApiAccessMethod(
launch {
snackbarHostState.showSnackbarImmediately(
message = context.getString(R.string.testing),
duration = SnackbarDuration.Indefinite
duration = SnackbarDuration.Indefinite,
actionLabel = context.getString(R.string.cancel),
onAction = viewModel::cancelTestMethod
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package net.mullvad.mullvadvpn.viewmodel
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import arrow.core.Either
import kotlinx.coroutines.Job
import kotlinx.coroutines.cancel
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
Expand All @@ -20,6 +22,8 @@ class ApiAccessMethodDetailsViewModel(
private val apiAccessMethodId: ApiAccessMethodId,
private val apiAccessRepository: ApiAccessRepository
) : ViewModel() {
private var testingJob: Job? = null

private val _uiSideEffect = Channel<ApiAccessMethodDetailsSideEffect>(Channel.BUFFERED)
val uiSideEffect = _uiSideEffect.receiveAsFlow()
private val isTestingApiAccessMethodState = MutableStateFlow(false)
Expand Down Expand Up @@ -52,17 +56,20 @@ class ApiAccessMethodDetailsViewModel(
)

fun setCurrentMethod() {
viewModelScope.launch {
testMethodWithStatus().onRight {
apiAccessRepository
.setApiAccessMethod(apiAccessMethodId = apiAccessMethodId)
.onLeft { _uiSideEffect.send(ApiAccessMethodDetailsSideEffect.GenericError) }
testingJob =
viewModelScope.launch {
testMethodWithStatus().onRight {
apiAccessRepository
.setApiAccessMethod(apiAccessMethodId = apiAccessMethodId)
.onLeft {
_uiSideEffect.send(ApiAccessMethodDetailsSideEffect.GenericError)
}
}
}
}
}

fun testMethod() {
viewModelScope.launch { testMethodWithStatus() }
testingJob = viewModelScope.launch { testMethodWithStatus() }
}

fun setEnableMethod(enable: Boolean) {
Expand All @@ -79,6 +86,13 @@ class ApiAccessMethodDetailsViewModel(
}
}

fun cancelTestMethod() {
if (testingJob?.isActive == true) {
testingJob?.cancel("User cancelled job")
isTestingApiAccessMethodState.value = false
}
}

private suspend fun testMethodWithStatus(): Either<TestApiAccessMethodError, Unit> {
isTestingApiAccessMethodState.value = true
return apiAccessRepository
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import arrow.core.getOrElse
import arrow.core.nel
import arrow.core.raise.either
import arrow.core.raise.ensure
import kotlinx.coroutines.Job
import kotlinx.coroutines.cancel
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
Expand Down Expand Up @@ -37,6 +39,8 @@ class EditApiAccessMethodViewModel(
private val apiAccessRepository: ApiAccessRepository,
private val inetAddressValidator: InetAddressValidator
) : ViewModel() {
private var testingJob: Job? = null

private val _uiSideEffect = Channel<EditApiAccessSideEffect>(Channel.BUFFERED)
val uiSideEffect = _uiSideEffect.receiveAsFlow()
private val isTestingApiAccessMethod = MutableStateFlow(false)
Expand Down Expand Up @@ -92,31 +96,32 @@ class EditApiAccessMethodViewModel(
}

fun testMethod() {
viewModelScope.launch {
formData.value
.parseConnectionFormData()
.fold(
{ errors -> formData.update { it.updateWithErrors(errors) } },
{ customProxy ->
isTestingApiAccessMethod.value = true
apiAccessRepository
.testCustomApiAccessMethod(customProxy)
.fold(
{
_uiSideEffect.send(
EditApiAccessSideEffect.TestApiAccessMethodResult(false)
)
},
{
_uiSideEffect.send(
EditApiAccessSideEffect.TestApiAccessMethodResult(true)
)
},
)
isTestingApiAccessMethod.value = false
}
)
}
testingJob =
viewModelScope.launch {
formData.value
.parseConnectionFormData()
.fold(
{ errors -> formData.update { it.updateWithErrors(errors) } },
{ customProxy ->
isTestingApiAccessMethod.value = true
apiAccessRepository
.testCustomApiAccessMethod(customProxy)
.fold(
{
_uiSideEffect.send(
EditApiAccessSideEffect.TestApiAccessMethodResult(false)
)
},
{
_uiSideEffect.send(
EditApiAccessSideEffect.TestApiAccessMethodResult(true)
)
},
)
isTestingApiAccessMethod.value = false
}
)
}
}

fun trySave() {
Expand All @@ -138,6 +143,13 @@ class EditApiAccessMethodViewModel(
}
}

fun cancelTestMethod() {
if (testingJob?.isActive == true) {
testingJob?.cancel("User cancelled test")
isTestingApiAccessMethod.value = false
}
}

private fun initialData(): EditApiAccessFormData =
if (apiAccessMethodId == null) {
EditApiAccessFormData.empty()
Expand Down
4 changes: 2 additions & 2 deletions android/lib/resource/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,7 @@
<string name="settings_api_access">API access</string>
<string name="add">Add</string>
<string name="api_access_description">Manage and add custom methods to access the Mullvad API.</string>
<string name="current_x">Current: %s</string>
<string name="current_method">Current: %s</string>
<string name="api_access_method_info_first_line">The app needs to communicate with a Mullvad API server to log you in, fetch server lists, and other critical operations.</string>
<string name="api_access_method_info_second_line">On some networks, where various types of censorship are being used, the API servers might not be directly reachable.</string>
<string name="api_access_method_info_third_line">This feature allows you to circumvent that censorship by adding custom ways to access the API via proxies and similar methods.</string>
Expand All @@ -364,7 +364,6 @@
<string name="server">Server</string>
<string name="please_enter_a_valid_ip_address">Please enter a valid IPv4 or IPv6 address</string>
<string name="please_enter_a_valid_remote_server_port">Please enter a valid remote server port</string>
<string name="please_enter_a_valid_localhost_port">Please enter a valid localhost port</string>
<string name="password_optional">Password (optional)</string>
<string name="cipher">Cipher</string>
<string name="authentication">Authentication</string>
Expand All @@ -374,6 +373,7 @@
<string name="test_method">Test method</string>
<string name="api_reachable">API reachable</string>
<string name="api_unreachable">API unreachable</string>
<string name="testing_name">Testing %s...</string>
<string name="testing">Testing...</string>
<string name="verifying_api_method">Verifying API method...</string>
<string name="api_reachable_adding_method">API reachable, adding method...</string>
Expand Down

0 comments on commit f1e291a

Please sign in to comment.