taler-android

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

commit b6b5db9b878c517828d39cccca1133be5a09c61b
parent 17b074d7453da4e13cda5c4da38533d7a81d7d48
Author: Iván Ávalos <avalos@disroot.org>
Date:   Sat, 23 Nov 2024 22:26:26 +0100

[wallet] QC: add dev option to set/unset exchange as global

Diffstat:
Mwallet/src/main/java/net/taler/wallet/balances/BalanceManager.kt | 37+++++++++++++++++++++++++++++++++++++
Mwallet/src/main/java/net/taler/wallet/balances/Balances.kt | 14+++++++++-----
Mwallet/src/main/java/net/taler/wallet/exchanges/ExchangeAdapter.kt | 20++++++++++++++++++++
Mwallet/src/main/java/net/taler/wallet/exchanges/ExchangeListFragment.kt | 42+++++++++++++++++++++++++++++++++++++++++-
Mwallet/src/main/java/net/taler/wallet/exchanges/Exchanges.kt | 1+
Mwallet/src/main/res/menu/exchange.xml | 6++++++
Mwallet/src/main/res/values/strings.xml | 4++++
7 files changed, 118 insertions(+), 6 deletions(-)

diff --git a/wallet/src/main/java/net/taler/wallet/balances/BalanceManager.kt b/wallet/src/main/java/net/taler/wallet/balances/BalanceManager.kt @@ -31,6 +31,7 @@ import net.taler.common.CurrencySpecification import net.taler.wallet.TAG import net.taler.wallet.backend.TalerErrorInfo import net.taler.wallet.backend.WalletBackendApi +import net.taler.wallet.exchanges.ExchangeItem import org.json.JSONObject @Serializable @@ -150,6 +151,42 @@ class BalanceManager( return false } + fun addGlobalCurrencyExchange( + currency: String, + exchange: ExchangeItem, + onSuccess: () -> Unit, + onError: (error: TalerErrorInfo) -> Unit, + ) = scope.launch { + api.request<Unit>("addGlobalCurrencyExchange") { + put("currency", currency) + put("exchangeBaseUrl", exchange.exchangeBaseUrl) + put("exchangeMasterPub", exchange.masterPub) + }.onError { error -> + Log.e(TAG, "got addGlobalCurrencyExchange error: $error") + onError(error) + }.onSuccess { + onSuccess() + } + } + + fun removeGlobalCurrencyExchange( + currency: String, + exchange: ExchangeItem, + onSuccess: () -> Unit, + onError: (error: TalerErrorInfo) -> Unit, + ) = scope.launch { + api.request<Unit>("removeGlobalCurrencyExchange") { + put("currency", currency) + put("exchangeBaseUrl", exchange.exchangeBaseUrl) + put("exchangeMasterPub", exchange.masterPub) + }.onError { error -> + Log.e(TAG, "got removeGlobalCurrencyExchange error: $error") + onError(error) + }.onSuccess { + onSuccess() + } + } + fun resetBalances() { mState.value = BalanceState.None } diff --git a/wallet/src/main/java/net/taler/wallet/balances/Balances.kt b/wallet/src/main/java/net/taler/wallet/balances/Balances.kt @@ -69,11 +69,15 @@ sealed class ScopeInfo { else -> null } - return PrefsScopeInfo.newBuilder() - .setType(type) - .setUrl(url) - .setCurrency(currency) - .build() + return PrefsScopeInfo.newBuilder().apply { + setType(type) + setCurrency(currency) + if (url != null) { + setUrl(url) + } else { + clearUrl() + } + }.build() } companion object { diff --git a/wallet/src/main/java/net/taler/wallet/exchanges/ExchangeAdapter.kt b/wallet/src/main/java/net/taler/wallet/exchanges/ExchangeAdapter.kt @@ -28,6 +28,7 @@ import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView.Adapter import net.taler.wallet.R +import net.taler.wallet.balances.ScopeInfo import net.taler.wallet.exchanges.ExchangeAdapter.ExchangeItemViewHolder interface ExchangeClickListener { @@ -39,6 +40,8 @@ interface ExchangeClickListener { fun onExchangeTosAccept(item: ExchangeItem) fun onExchangeTosForget(item: ExchangeItem) fun onExchangeTosView(item: ExchangeItem) + fun onExchangeGlobalCurrencyAdd(item: ExchangeItem) + fun onExchangeGlobalCurrencyDelete(item: ExchangeItem) } internal class ExchangeAdapter( @@ -108,6 +111,15 @@ internal class ExchangeAdapter( menu.findItem(R.id.action_accept_tos).isVisible = true menu.findItem(R.id.action_forget_tos).isVisible = false } + + if (item.scopeInfo is ScopeInfo.Exchange) { + menu.findItem(R.id.action_global_add).isVisible = devMode + menu.findItem(R.id.action_global_delete).isVisible = false + } else if (item.scopeInfo is ScopeInfo.Global) { + menu.findItem(R.id.action_global_add).isVisible = false + menu.findItem(R.id.action_global_delete).isVisible = devMode + } + setOnMenuItemClickListener { menuItem -> when (menuItem.itemId) { R.id.action_manual_withdrawal -> { @@ -134,6 +146,14 @@ internal class ExchangeAdapter( listener.onExchangeTosForget(item) true } + R.id.action_global_add -> { + listener.onExchangeGlobalCurrencyAdd(item) + true + } + R.id.action_global_delete -> { + listener.onExchangeGlobalCurrencyDelete(item) + true + } R.id.action_delete -> { listener.onExchangeDelete(item) true diff --git a/wallet/src/main/java/net/taler/wallet/exchanges/ExchangeListFragment.kt b/wallet/src/main/java/net/taler/wallet/exchanges/ExchangeListFragment.kt @@ -43,6 +43,7 @@ import androidx.navigation.fragment.findNavController import androidx.recyclerview.widget.DividerItemDecoration import androidx.recyclerview.widget.LinearLayoutManager.VERTICAL import com.google.android.material.dialog.MaterialAlertDialogBuilder +import com.google.android.material.snackbar.Snackbar import kotlinx.coroutines.launch import net.taler.common.Amount import net.taler.common.EventObserver @@ -58,7 +59,8 @@ open class ExchangeListFragment : Fragment(), ExchangeClickListener { protected val model: MainViewModel by activityViewModels() private val exchangeManager by lazy { model.exchangeManager } - private val transactionManager get() = model.transactionManager + private val transactionManager by lazy { model.transactionManager } + private val balanceManager by lazy { model.balanceManager } protected lateinit var ui: FragmentExchangeListBinding protected open val isSelectOnly = false @@ -218,6 +220,44 @@ open class ExchangeListFragment : Fragment(), ExchangeClickListener { } } + override fun onExchangeGlobalCurrencyAdd(item: ExchangeItem) { + item.currency?.let { + balanceManager.addGlobalCurrencyExchange( + currency = item.currency, + exchange = item, + onSuccess = { + Snackbar.make( + requireView(), + getString(R.string.exchange_global_add_success), + Snackbar.LENGTH_LONG + ).show() + }, + onError = { error -> + showError(error) + }, + ) + } + } + + override fun onExchangeGlobalCurrencyDelete(item: ExchangeItem) { + item.currency?.let { + balanceManager.removeGlobalCurrencyExchange( + currency = item.currency, + exchange = item, + onSuccess = { + Snackbar.make( + requireView(), + getString(R.string.exchange_global_delete_success), + Snackbar.LENGTH_LONG + ).show() + }, + onError = { error -> + showError(error) + }, + ) + } + } + private fun setupInsets() { ViewCompat.setOnApplyWindowInsetsListener(ui.list) { v, windowInsets -> val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()) diff --git a/wallet/src/main/java/net/taler/wallet/exchanges/Exchanges.kt b/wallet/src/main/java/net/taler/wallet/exchanges/Exchanges.kt @@ -30,6 +30,7 @@ data class BuiltinExchange( @Serializable data class ExchangeItem( val exchangeBaseUrl: String, + val masterPub: String? = null, // can be null before exchange info in wallet-core was fully loaded val currency: String? = null, val paytoUris: List<String>, diff --git a/wallet/src/main/res/menu/exchange.xml b/wallet/src/main/res/menu/exchange.xml @@ -34,6 +34,12 @@ android:id="@+id/action_forget_tos" android:title="@string/exchange_tos_forget" /> <item + android:id="@+id/action_global_add" + android:title="@string/exchange_global_add" /> + <item + android:id="@+id/action_global_delete" + android:title="@string/exchange_global_delete" /> + <item android:id="@+id/action_delete" android:title="@string/transactions_delete" /> </menu> diff --git a/wallet/src/main/res/values/strings.xml b/wallet/src/main/res/values/strings.xml @@ -296,6 +296,10 @@ GNU Taler is immune against many types of fraud, such as phishing of credit card <string name="exchange_fee_wire_fees_label">Wire fees</string> <string name="exchange_fee_withdraw_fee">Withdraw fee: %1$s</string> <string name="exchange_fee_withdrawal_fee_label">Withdrawal fee:</string> + <string name="exchange_global_add">Treat as global</string> + <string name="exchange_global_add_success">Provider now being treated as global</string> + <string name="exchange_global_delete">Stop treating as global</string> + <string name="exchange_global_delete_success">Provider no longer being treated as global</string> <string name="exchange_list_add">Add provider</string> <string name="exchange_list_add_dev">Add development providers</string> <string name="exchange_list_currency">Currency: %1$s</string>