taler-android

Android apps for GNU Taler (wallet, PoS, cashier)
Log | Files | Refs | README | LICENSE

DepositFragment.kt (7896B)


      1 /*
      2  * This file is part of GNU Taler
      3  * (C) 2022 Taler Systems S.A.
      4  *
      5  * GNU Taler is free software; you can redistribute it and/or modify it under the
      6  * terms of the GNU General Public License as published by the Free Software
      7  * Foundation; either version 3, or (at your option) any later version.
      8  *
      9  * GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
     10  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
     11  * A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
     12  *
     13  * You should have received a copy of the GNU General Public License along with
     14  * GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
     15  */
     16 
     17 package net.taler.wallet.deposit
     18 
     19 import android.os.Bundle
     20 import android.view.LayoutInflater
     21 import android.view.View
     22 import android.view.ViewGroup
     23 import androidx.activity.compose.BackHandler
     24 import androidx.appcompat.app.AppCompatActivity
     25 import androidx.compose.foundation.layout.fillMaxSize
     26 import androidx.compose.foundation.rememberScrollState
     27 import androidx.compose.foundation.verticalScroll
     28 import androidx.compose.runtime.getValue
     29 import androidx.compose.runtime.livedata.observeAsState
     30 import androidx.compose.ui.Modifier
     31 import androidx.compose.ui.platform.ComposeView
     32 import androidx.fragment.app.Fragment
     33 import androidx.fragment.app.activityViewModels
     34 import androidx.lifecycle.Lifecycle
     35 import androidx.lifecycle.lifecycleScope
     36 import androidx.lifecycle.map
     37 import androidx.lifecycle.repeatOnLifecycle
     38 import androidx.navigation.fragment.findNavController
     39 import kotlinx.coroutines.launch
     40 import net.taler.common.Amount
     41 import net.taler.common.showError
     42 import net.taler.wallet.main.MainViewModel
     43 import net.taler.wallet.R
     44 import net.taler.wallet.compose.LoadingScreen
     45 import net.taler.wallet.compose.TalerSurface
     46 import net.taler.wallet.compose.collectAsStateLifecycleAware
     47 import net.taler.wallet.showError
     48 import net.taler.wallet.accounts.ListBankAccountsResult.Success
     49 import net.taler.wallet.compose.ErrorComposable
     50 
     51 class DepositFragment : Fragment() {
     52     private val model: MainViewModel by activityViewModels()
     53     private val depositManager get() = model.depositManager
     54     private val accountManager get() = model.accountManager
     55     private val exchangeManager get() = model.exchangeManager
     56 
     57     override fun onCreateView(
     58         inflater: LayoutInflater,
     59         container: ViewGroup?,
     60         savedInstanceState: Bundle?,
     61     ): View {
     62         val presetAmount = arguments?.getString("amount")?.let { Amount.fromJSONString(it) }
     63         val receiverName = arguments?.getString("receiverName")
     64         val receiverPostalCode = arguments?.getString("receiverPostalCode")
     65         val receiverTown = arguments?.getString("receiverTown")
     66         val iban = arguments?.getString("IBAN")
     67 
     68         if (presetAmount != null && receiverName != null && iban != null) {
     69             val paytoUri = getIbanPayto(receiverName, receiverPostalCode, receiverTown, iban)
     70             depositManager.makeDeposit(presetAmount, paytoUri)
     71         }
     72 
     73         return ComposeView(requireContext()).apply {
     74             setContent {
     75                 TalerSurface {
     76                     val state by depositManager.depositState.collectAsStateLifecycleAware()
     77                     val knownBankAccounts by accountManager.bankAccounts.collectAsStateLifecycleAware()
     78                     val knownCurrencies by model.balanceManager.balances.map {
     79                         it.map { bl -> bl.currency }
     80                     }.observeAsState(emptyList())
     81                     val devMode by model.devMode.observeAsState(false)
     82 
     83                     BackHandler(state is DepositState.AccountSelected) {
     84                         depositManager.resetDepositState()
     85                     }
     86 
     87                     when (val s = state) {
     88                         is DepositState.MakingDeposit, is DepositState.Success -> {
     89                             LoadingScreen()
     90                         }
     91 
     92                         is DepositState.Error -> ErrorComposable(s.error,
     93                             devMode = devMode,
     94                             modifier = Modifier
     95                                 .fillMaxSize()
     96                                 .verticalScroll(rememberScrollState()),
     97                             onClose = {
     98                                 findNavController().popBackStack()
     99                             },
    100                         )
    101 
    102                         is DepositState.Start -> {
    103                             MakeDepositComposable(
    104                                 knownBankAccounts = (knownBankAccounts as? Success)
    105                                     ?.accounts
    106                                     ?: emptyList(),
    107                                 onAccountSelected = { account ->
    108                                     depositManager.selectAccount(account)
    109                                 },
    110                                 onManageBankAccounts = {
    111                                     findNavController().navigate(R.id.action_global_bankAccounts)
    112                                 }
    113                             )
    114                         }
    115 
    116                         is DepositState.AccountSelected -> {
    117                             DepositAmountComposable(
    118                                 state = s,
    119                                 knownCurrencies = knownCurrencies,
    120                                 getCurrencySpec = exchangeManager::getSpecForCurrency,
    121                                 checkDeposit = { a ->
    122                                     depositManager.checkDepositFees(s.account.paytoUri, a)
    123                                 },
    124                                 onMakeDeposit = { amount ->
    125                                     depositManager.makeDeposit(amount, s.account.paytoUri)
    126                                 },
    127                                 onClose = {
    128                                     depositManager.resetDepositState()
    129                                 }
    130                             )
    131                         }
    132                     }
    133                 }
    134             }
    135         }
    136     }
    137 
    138     override fun onCreate(savedInstanceState: Bundle?) {
    139         super.onCreate(savedInstanceState)
    140         val supportActionBar = (requireActivity() as? AppCompatActivity)?.supportActionBar
    141         lifecycleScope.launch {
    142             repeatOnLifecycle(Lifecycle.State.STARTED) {
    143                 depositManager.depositState.collect { state ->
    144                     when (state) {
    145                         is DepositState.Start -> {
    146                             supportActionBar?.setTitle(R.string.send_deposit_select_account_title)
    147                         }
    148 
    149                         is DepositState.AccountSelected -> {
    150                             supportActionBar?.setTitle(R.string.send_deposit_select_amount_title)
    151                         }
    152 
    153                         is DepositState.Error -> {
    154                             if (model.devMode.value == false) {
    155                                 showError(state.error.userFacingMsg)
    156                             } else {
    157                                 showError(state.error)
    158                             }
    159                         }
    160 
    161                         is DepositState.Success -> {
    162                             findNavController().navigate(R.id.action_global_main)
    163                         }
    164 
    165                         else -> {}
    166                     }
    167                 }
    168             }
    169         }
    170 
    171         lifecycleScope.launch {
    172             repeatOnLifecycle(Lifecycle.State.STARTED) {
    173                 accountManager.listBankAccounts()
    174             }
    175         }
    176     }
    177 
    178     override fun onStart() {
    179         super.onStart()
    180         activity?.setTitle(R.string.send_deposit_title)
    181     }
    182 
    183     override fun onDestroy() {
    184         super.onDestroy()
    185         if (!requireActivity().isChangingConfigurations) {
    186             depositManager.resetDepositState()
    187         }
    188     }
    189 }