diff options
Diffstat (limited to 'cashier/src/main/java/net/taler/cashier/withdraw')
3 files changed, 41 insertions, 33 deletions
diff --git a/cashier/src/main/java/net/taler/cashier/withdraw/ErrorFragment.kt b/cashier/src/main/java/net/taler/cashier/withdraw/ErrorFragment.kt index 4f98847..c951bb8 100644 --- a/cashier/src/main/java/net/taler/cashier/withdraw/ErrorFragment.kt +++ b/cashier/src/main/java/net/taler/cashier/withdraw/ErrorFragment.kt @@ -22,7 +22,6 @@ import android.view.View import android.view.ViewGroup import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels -import androidx.lifecycle.Observer import androidx.navigation.fragment.findNavController import net.taler.cashier.MainViewModel import net.taler.cashier.R @@ -37,22 +36,22 @@ class ErrorFragment : Fragment() { override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, - savedInstanceState: Bundle? - ): View? { + savedInstanceState: Bundle?, + ): View { ui = FragmentErrorBinding.inflate(inflater, container, false) return ui.root } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - withdrawManager.withdrawStatus.observe(viewLifecycleOwner, Observer { status -> - if (status == null) return@Observer + withdrawManager.withdrawStatus.observe(viewLifecycleOwner) { status -> + if (status == null) return@observe if (status is WithdrawStatus.Aborted) { ui.textView.setText(R.string.transaction_aborted) } else if (status is WithdrawStatus.Error) { ui.textView.text = status.msg } withdrawManager.completeTransaction() - }) + } ui.backButton.setOnClickListener { findNavController().popBackStack() } diff --git a/cashier/src/main/java/net/taler/cashier/withdraw/TransactionFragment.kt b/cashier/src/main/java/net/taler/cashier/withdraw/TransactionFragment.kt index ffb1539..0f606b8 100644 --- a/cashier/src/main/java/net/taler/cashier/withdraw/TransactionFragment.kt +++ b/cashier/src/main/java/net/taler/cashier/withdraw/TransactionFragment.kt @@ -50,21 +50,21 @@ class TransactionFragment : Fragment() { override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? - ): View? { + ): View { ui = FragmentTransactionBinding.inflate(inflater, container, false) return ui.root } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { - withdrawManager.withdrawAmount.observe(viewLifecycleOwner, { amount -> + withdrawManager.withdrawAmount.observe(viewLifecycleOwner) { amount -> ui.amountView.text = amount?.toString() - }) - withdrawManager.withdrawResult.observe(viewLifecycleOwner, { result -> + } + withdrawManager.withdrawResult.observe(viewLifecycleOwner) { result -> onWithdrawResultReceived(result) - }) - withdrawManager.withdrawStatus.observe(viewLifecycleOwner, { status -> + } + withdrawManager.withdrawStatus.observe(viewLifecycleOwner) { status -> onWithdrawStatusChanged(status) - }) + } // change intro text depending on whether NFC is available or not val hasNfc = NfcManager.hasNfc(requireContext()) diff --git a/cashier/src/main/java/net/taler/cashier/withdraw/WithdrawManager.kt b/cashier/src/main/java/net/taler/cashier/withdraw/WithdrawManager.kt index 5d34bba..487475d 100644 --- a/cashier/src/main/java/net/taler/cashier/withdraw/WithdrawManager.kt +++ b/cashier/src/main/java/net/taler/cashier/withdraw/WithdrawManager.kt @@ -34,21 +34,19 @@ import net.taler.cashier.HttpJsonResult.Error import net.taler.cashier.HttpJsonResult.Success import net.taler.cashier.MainViewModel import net.taler.cashier.R +import net.taler.common.Amount import net.taler.common.QrCodeManager.makeQrCode import net.taler.common.isOnline -import net.taler.lib.common.Amount import org.json.JSONObject -import java.util.concurrent.TimeUnit.MINUTES import java.util.concurrent.TimeUnit.SECONDS private val TAG = WithdrawManager::class.java.simpleName private val INTERVAL = SECONDS.toMillis(1) -private val TIMEOUT = MINUTES.toMillis(2) class WithdrawManager( private val app: Application, - private val viewModel: MainViewModel + private val viewModel: MainViewModel, ) { private val scope get() = viewModel.viewModelScope @@ -73,11 +71,20 @@ class WithdrawManager( private val mLastTransaction = MutableLiveData<LastTransaction>() val lastTransaction: LiveData<LastTransaction> = mLastTransaction + /** + * Returns null if the given [amount] can't be compared to the balance + * e.g. due to mismatching currency. + */ @UiThread - fun hasSufficientBalance(amount: Amount): Boolean { + fun hasSufficientBalance(amount: Amount): Boolean? { val balanceResult = viewModel.balance.value if (balanceResult !is BalanceResult.Success) return false - return balanceResult.amount.positive && amount <= balanceResult.amount.amount + return try { + balanceResult.amount.positive && amount <= balanceResult.amount.amount + } catch (e: IllegalStateException) { + Log.e(TAG, "Error comparing amounts", e) + null + } } @UiThread @@ -119,7 +126,7 @@ class WithdrawManager( } } - private val timer: CountDownTimer = object : CountDownTimer(TIMEOUT, INTERVAL) { + private val timer: CountDownTimer = object : CountDownTimer(Long.MAX_VALUE, INTERVAL) { override fun onTick(millisUntilFinished: Long) { val result = withdrawResult.value if (result is WithdrawResult.Success) { @@ -146,31 +153,32 @@ class WithdrawManager( } private fun checkWithdrawStatus(withdrawalId: String) = scope.launch(Dispatchers.IO) { - val url = "${config.bankUrl}/accounts/${config.username}/withdrawals/${withdrawalId}" + val url = + "${config.bankUrl}/withdrawals/${withdrawalId}" Log.d(TAG, "Checking withdraw status at $url") val response = makeJsonGetRequest(url, config) if (response !is Success) return@launch // ignore errors and continue trying val oldStatus = mWithdrawStatus.value try { - when { - response.json.getBoolean("aborted") -> { + when(response.json.getString("status")) { + "selected" -> { + // only update status, if there's none, yet + // so we don't re-notify or overwrite newer status info + if (oldStatus == null) { + mWithdrawStatus.postValue(WithdrawStatus.SelectionDone(withdrawalId)) + } + } + "aborted" -> { cancelWithdrawStatusCheck() mWithdrawStatus.postValue(WithdrawStatus.Aborted) } - response.json.getBoolean("confirmation_done") -> { + "confirmed" -> { if (oldStatus !is WithdrawStatus.Success) { cancelWithdrawStatusCheck() mWithdrawStatus.postValue(WithdrawStatus.Success) viewModel.getBalance() } } - response.json.getBoolean("selection_done") -> { - // only update status, if there's none, yet - // so we don't re-notify or overwrite newer status info - if (oldStatus == null) { - mWithdrawStatus.postValue(WithdrawStatus.SelectionDone(withdrawalId)) - } - } } } catch (e: Exception) { mWithdrawStatus.postValue(WithdrawStatus.Error(e.toString())) @@ -197,7 +205,8 @@ class WithdrawManager( } private fun abort(withdrawalId: String) = scope.launch(Dispatchers.IO) { - val url = "${config.bankUrl}/accounts/${config.username}/withdrawals/${withdrawalId}/abort" + val url = + "${config.bankUrl}/accounts/${config.username}/withdrawals/${withdrawalId}/abort" Log.d(TAG, "Aborting withdrawal at $url") makeJsonPostRequest(url, JSONObject(), config) } @@ -254,5 +263,5 @@ sealed class WithdrawStatus { data class LastTransaction( val withdrawAmount: Amount, - val withdrawStatus: WithdrawStatus + val withdrawStatus: WithdrawStatus, ) |