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:
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>