diff options
| author | David Göransson <david.goransson@mullvad.net> | 2024-08-21 10:30:22 +0200 |
|---|---|---|
| committer | Jonatan Rhodin <jonatan.rhodin@mullvad.net> | 2024-08-21 11:05:02 +0200 |
| commit | d1e33486cf2b4c027f1a87a1700891c7cd6bcbab (patch) | |
| tree | e8eb7b98bb54a0b8ce20e3b958f40c3eae2ad55d /android | |
| parent | 5d38db0855f8e48cf43795b73488121dd4810b1b (diff) | |
| download | mullvadvpn-d1e33486cf2b4c027f1a87a1700891c7cd6bcbab.tar.xz mullvadvpn-d1e33486cf2b4c027f1a87a1700891c7cd6bcbab.zip | |
Add error for voucher code looks like an account number
Diffstat (limited to 'android')
6 files changed, 43 insertions, 6 deletions
diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/RedeemVoucherDialog.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/RedeemVoucherDialog.kt index 093dc7ce97..6d3d134e1d 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/RedeemVoucherDialog.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/dialog/RedeemVoucherDialog.kt @@ -274,10 +274,23 @@ private fun EnterVoucherBody( ) } } + if ( + state.voucherState is VoucherDialogState.Error && + state.voucherState.error is RedeemVoucherError.EnteredAccountNumber + ) { + Text( + modifier = Modifier.padding(top = Dimens.smallPadding), + text = stringResource(id = R.string.voucher_is_account_number), + color = MaterialTheme.colorScheme.onPrimary, + style = MaterialTheme.typography.bodySmall + ) + } } private fun RedeemVoucherError.message(): Int = when (this) { + RedeemVoucherError.TooShortVoucher, + RedeemVoucherError.EnteredAccountNumber, RedeemVoucherError.InvalidVoucher -> R.string.invalid_voucher RedeemVoucherError.VoucherAlreadyUsed -> R.string.voucher_already_used RedeemVoucherError.RpcError, diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/VoucherDialogViewModel.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/VoucherDialogViewModel.kt index 3d67b42bd1..857953f28b 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/VoucherDialogViewModel.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/VoucherDialogViewModel.kt @@ -2,6 +2,7 @@ package net.mullvad.mullvadvpn.viewmodel import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope +import arrow.core.raise.either import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.combine @@ -11,7 +12,9 @@ import kotlinx.coroutines.launch import net.mullvad.mullvadvpn.compose.state.VoucherDialogState import net.mullvad.mullvadvpn.compose.state.VoucherDialogUiState import net.mullvad.mullvadvpn.constant.VOUCHER_LENGTH +import net.mullvad.mullvadvpn.lib.model.ParseVoucherCodeError import net.mullvad.mullvadvpn.lib.model.RedeemVoucherError +import net.mullvad.mullvadvpn.lib.model.VoucherCode import net.mullvad.mullvadvpn.lib.shared.VoucherRepository import net.mullvad.mullvadvpn.util.VoucherRegexHelper @@ -26,11 +29,23 @@ class VoucherDialogViewModel(private val voucherRepository: VoucherRepository) : } .stateIn(viewModelScope, SharingStarted.WhileSubscribed(), VoucherDialogUiState.INITIAL) - fun onRedeem(voucherCode: String) { + fun onRedeem(voucherInput: String) { vmState.update { VoucherDialogState.Verifying } viewModelScope.launch { - voucherRepository - .submitVoucher(voucherCode) + either { + val voucherCode = + VoucherCode.fromString(voucherInput) + .mapLeft { + when (it) { + is ParseVoucherCodeError.AllDigit -> + RedeemVoucherError.EnteredAccountNumber + is ParseVoucherCodeError.TooShort -> + RedeemVoucherError.TooShortVoucher + } + } + .bind() + voucherRepository.submitVoucher(voucherCode).bind() + } .fold( { error -> setError(error) }, { success -> handleAddedTime(success.timeAdded) } diff --git a/android/lib/daemon-grpc/src/main/kotlin/net/mullvad/mullvadvpn/lib/daemon/grpc/ManagementService.kt b/android/lib/daemon-grpc/src/main/kotlin/net/mullvad/mullvadvpn/lib/daemon/grpc/ManagementService.kt index 95679cb43d..36460ae1fa 100644 --- a/android/lib/daemon-grpc/src/main/kotlin/net/mullvad/mullvadvpn/lib/daemon/grpc/ManagementService.kt +++ b/android/lib/daemon-grpc/src/main/kotlin/net/mullvad/mullvadvpn/lib/daemon/grpc/ManagementService.kt @@ -116,6 +116,7 @@ import net.mullvad.mullvadvpn.lib.model.UnknownApiAccessMethodError import net.mullvad.mullvadvpn.lib.model.UnknownCustomListError import net.mullvad.mullvadvpn.lib.model.UpdateApiAccessMethodError import net.mullvad.mullvadvpn.lib.model.UpdateCustomListError +import net.mullvad.mullvadvpn.lib.model.VoucherCode import net.mullvad.mullvadvpn.lib.model.WebsiteAuthToken import net.mullvad.mullvadvpn.lib.model.WireguardConstraints as ModelWireguardConstraints import net.mullvad.mullvadvpn.lib.model.WireguardEndpointData as ModelWireguardEndpointData @@ -575,8 +576,10 @@ class ManagementService( .mapLeft(SetWireguardConstraintsError::Unknown) .mapEmpty() - suspend fun submitVoucher(voucher: String): Either<RedeemVoucherError, RedeemVoucherSuccess> = - Either.catch { grpc.submitVoucher(StringValue.of(voucher)).toDomain() } + suspend fun submitVoucher( + voucher: VoucherCode + ): Either<RedeemVoucherError, RedeemVoucherSuccess> = + Either.catch { grpc.submitVoucher(StringValue.of(voucher.value)).toDomain() } .mapLeftStatus { when (it.status.code) { Status.Code.INVALID_ARGUMENT, diff --git a/android/lib/model/src/main/kotlin/net/mullvad/mullvadvpn/lib/model/RedeemVoucherError.kt b/android/lib/model/src/main/kotlin/net/mullvad/mullvadvpn/lib/model/RedeemVoucherError.kt index d14a2f236b..6df604c4a6 100644 --- a/android/lib/model/src/main/kotlin/net/mullvad/mullvadvpn/lib/model/RedeemVoucherError.kt +++ b/android/lib/model/src/main/kotlin/net/mullvad/mullvadvpn/lib/model/RedeemVoucherError.kt @@ -5,6 +5,10 @@ sealed class RedeemVoucherError { data object VoucherAlreadyUsed : RedeemVoucherError() + data object TooShortVoucher : RedeemVoucherError() + + data object EnteredAccountNumber : RedeemVoucherError() + data object RpcError : RedeemVoucherError() data class Unknown(val error: Throwable) : RedeemVoucherError() diff --git a/android/lib/resource/src/main/res/values/strings.xml b/android/lib/resource/src/main/res/values/strings.xml index ef6b0bce7a..c43acdb496 100644 --- a/android/lib/resource/src/main/res/values/strings.xml +++ b/android/lib/resource/src/main/res/values/strings.xml @@ -33,6 +33,7 @@ <string name="redeem">Redeem</string> <string name="invalid_voucher">Voucher code is invalid.</string> <string name="voucher_already_used">Voucher code has already been used.</string> + <string name="voucher_is_account_number">It looks like you’ve entered an account number instead of a voucher code. If you would like to change the active account, please log out first.</string> <string name="error_occurred">An error occurred.</string> <string name="settings">Settings</string> <string name="no_internet_connection">No internet connection</string> diff --git a/android/lib/shared/src/main/kotlin/net/mullvad/mullvadvpn/lib/shared/VoucherRepository.kt b/android/lib/shared/src/main/kotlin/net/mullvad/mullvadvpn/lib/shared/VoucherRepository.kt index a5783a832e..3ea55ccd9d 100644 --- a/android/lib/shared/src/main/kotlin/net/mullvad/mullvadvpn/lib/shared/VoucherRepository.kt +++ b/android/lib/shared/src/main/kotlin/net/mullvad/mullvadvpn/lib/shared/VoucherRepository.kt @@ -1,12 +1,13 @@ package net.mullvad.mullvadvpn.lib.shared import net.mullvad.mullvadvpn.lib.daemon.grpc.ManagementService +import net.mullvad.mullvadvpn.lib.model.VoucherCode class VoucherRepository( private val managementService: ManagementService, private val accountRepository: AccountRepository ) { - suspend fun submitVoucher(voucher: String) = + suspend fun submitVoucher(voucher: VoucherCode) = managementService.submitVoucher(voucher).onRight { accountRepository.onVoucherRedeemed(it.newExpiryDate) } |
