summaryrefslogtreecommitdiff
path: root/wallet/src/main/java/net/taler/wallet/exchanges
diff options
context:
space:
mode:
Diffstat (limited to 'wallet/src/main/java/net/taler/wallet/exchanges')
-rw-r--r--wallet/src/main/java/net/taler/wallet/exchanges/ExchangeAdapter.kt17
-rw-r--r--wallet/src/main/java/net/taler/wallet/exchanges/ExchangeFeesFragment.kt146
-rw-r--r--wallet/src/main/java/net/taler/wallet/exchanges/ExchangeListFragment.kt20
-rw-r--r--wallet/src/main/java/net/taler/wallet/exchanges/SelectExchangeFragment.kt135
4 files changed, 193 insertions, 125 deletions
diff --git a/wallet/src/main/java/net/taler/wallet/exchanges/ExchangeAdapter.kt b/wallet/src/main/java/net/taler/wallet/exchanges/ExchangeAdapter.kt
index 17ac50f..e315632 100644
--- a/wallet/src/main/java/net/taler/wallet/exchanges/ExchangeAdapter.kt
+++ b/wallet/src/main/java/net/taler/wallet/exchanges/ExchangeAdapter.kt
@@ -18,6 +18,8 @@ package net.taler.wallet.exchanges
import android.view.LayoutInflater
import android.view.View
+import android.view.View.GONE
+import android.view.View.VISIBLE
import android.view.ViewGroup
import android.widget.ImageButton
import android.widget.TextView
@@ -39,11 +41,14 @@ data class ExchangeItem(
}
interface ExchangeClickListener {
+ fun onExchangeSelected(item: ExchangeItem)
fun onManualWithdraw(item: ExchangeItem)
}
-internal class ExchangeAdapter(private val listener: ExchangeClickListener) :
- Adapter<ExchangeItemViewHolder>() {
+internal class ExchangeAdapter(
+ private val selectOnly: Boolean,
+ private val listener: ExchangeClickListener,
+) : Adapter<ExchangeItemViewHolder>() {
private val items = ArrayList<ExchangeItem>()
@@ -74,6 +79,14 @@ internal class ExchangeAdapter(private val listener: ExchangeClickListener) :
fun bind(item: ExchangeItem) {
urlView.text = item.name
currencyView.text = context.getString(R.string.exchange_list_currency, item.currency)
+ if (selectOnly) {
+ itemView.setOnClickListener { listener.onExchangeSelected(item) }
+ overflowIcon.visibility = GONE
+ } else {
+ itemView.setOnClickListener(null)
+ itemView.isClickable = false
+ overflowIcon.visibility = VISIBLE
+ }
overflowIcon.setOnClickListener { openMenu(overflowIcon, item) }
}
diff --git a/wallet/src/main/java/net/taler/wallet/exchanges/ExchangeFeesFragment.kt b/wallet/src/main/java/net/taler/wallet/exchanges/ExchangeFeesFragment.kt
new file mode 100644
index 0000000..c59fffe
--- /dev/null
+++ b/wallet/src/main/java/net/taler/wallet/exchanges/ExchangeFeesFragment.kt
@@ -0,0 +1,146 @@
+/*
+ * This file is part of GNU Taler
+ * (C) 2020 Taler Systems S.A.
+ *
+ * GNU Taler is free software; you can redistribute it and/or modify it under the
+ * terms of the GNU General Public License as published by the Free Software
+ * Foundation; either version 3, or (at your option) any later version.
+ *
+ * GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+
+package net.taler.wallet.exchanges
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.View.GONE
+import android.view.ViewGroup
+import android.widget.TextView
+import androidx.core.content.ContextCompat.getColor
+import androidx.fragment.app.Fragment
+import androidx.fragment.app.activityViewModels
+import androidx.recyclerview.widget.RecyclerView.Adapter
+import androidx.recyclerview.widget.RecyclerView.ViewHolder
+import net.taler.common.toRelativeTime
+import net.taler.common.toShortDate
+import net.taler.lib.common.Amount
+import net.taler.wallet.MainViewModel
+import net.taler.wallet.R
+import net.taler.wallet.databinding.FragmentExchangeFeesBinding
+import net.taler.wallet.exchanges.CoinFeeAdapter.CoinFeeViewHolder
+import net.taler.wallet.exchanges.WireFeeAdapter.WireFeeViewHolder
+
+class ExchangeFeesFragment : Fragment() {
+
+ private val model: MainViewModel by activityViewModels()
+ private val withdrawManager by lazy { model.withdrawManager }
+
+ private lateinit var ui: FragmentExchangeFeesBinding
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View? {
+ ui = FragmentExchangeFeesBinding.inflate(inflater, container, false)
+ return ui.root
+ }
+
+ override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+ val fees = withdrawManager.exchangeFees ?: throw IllegalStateException()
+ if (fees.withdrawFee.isZero()) {
+ ui.withdrawFeeLabel.visibility = GONE
+ ui.withdrawFeeView.visibility = GONE
+ } else ui.withdrawFeeView.setAmount(fees.withdrawFee)
+ if (fees.overhead.isZero()) {
+ ui.overheadLabel.visibility = GONE
+ ui.overheadView.visibility = GONE
+ } else ui.overheadView.setAmount(fees.overhead)
+ ui.expirationView.text = fees.earliestDepositExpiration.ms.toRelativeTime(requireContext())
+ ui.coinFeesList.adapter = CoinFeeAdapter(fees.coinFees)
+ ui.wireFeesList.adapter = WireFeeAdapter(fees.wireFees)
+ }
+
+ private fun TextView.setAmount(amount: Amount) {
+ if (amount.isZero()) text = amount.toString()
+ else {
+ text = getString(R.string.amount_negative, amount)
+ setTextColor(getColor(context, R.color.red))
+ }
+ }
+
+}
+
+private class CoinFeeAdapter(private val items: List<CoinFee>) : Adapter<CoinFeeViewHolder>() {
+ override fun getItemCount() = items.size
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CoinFeeViewHolder {
+ val v =
+ LayoutInflater.from(parent.context).inflate(R.layout.list_item_coin_fee, parent, false)
+ return CoinFeeViewHolder(v)
+ }
+
+ override fun onBindViewHolder(holder: CoinFeeViewHolder, position: Int) {
+ holder.bind(items[position])
+ }
+
+ private class CoinFeeViewHolder(private val v: View) : ViewHolder(v) {
+ private val res = v.context.resources
+ private val coinView: TextView = v.findViewById(R.id.coinView)
+ private val withdrawFeeView: TextView = v.findViewById(R.id.withdrawFeeView)
+ private val depositFeeView: TextView = v.findViewById(R.id.depositFeeView)
+ private val refreshFeeView: TextView = v.findViewById(R.id.refreshFeeView)
+ private val refundFeeView: TextView = v.findViewById(R.id.refundFeeView)
+ fun bind(item: CoinFee) {
+ coinView.text = res.getQuantityString(
+ R.plurals.exchange_fee_coin,
+ item.quantity,
+ item.coin,
+ item.quantity
+ )
+ withdrawFeeView.text =
+ v.context.getString(R.string.exchange_fee_withdraw_fee, item.feeWithdraw)
+ depositFeeView.text =
+ v.context.getString(R.string.exchange_fee_deposit_fee, item.feeDeposit)
+ refreshFeeView.text =
+ v.context.getString(R.string.exchange_fee_refresh_fee, item.feeRefresh)
+ refundFeeView.text =
+ v.context.getString(R.string.exchange_fee_refund_fee, item.feeRefresh)
+ }
+ }
+}
+
+private class WireFeeAdapter(private val items: List<WireFee>) : Adapter<WireFeeViewHolder>() {
+ override fun getItemCount() = items.size
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): WireFeeViewHolder {
+ val v =
+ LayoutInflater.from(parent.context).inflate(R.layout.list_item_wire_fee, parent, false)
+ return WireFeeViewHolder(v)
+ }
+
+ override fun onBindViewHolder(holder: WireFeeViewHolder, position: Int) {
+ holder.bind(items[position])
+ }
+
+ private class WireFeeViewHolder(private val v: View) : ViewHolder(v) {
+ private val validityView: TextView = v.findViewById(R.id.validityView)
+ private val wireFeeView: TextView = v.findViewById(R.id.wireFeeView)
+ private val closingFeeView: TextView = v.findViewById(R.id.closingFeeView)
+ fun bind(item: WireFee) {
+ validityView.text = v.context.getString(
+ R.string.exchange_fee_wire_fee_timespan,
+ item.start.ms.toShortDate(v.context),
+ item.end.ms.toShortDate(v.context)
+ )
+ wireFeeView.text =
+ v.context.getString(R.string.exchange_fee_wire_fee_wire_fee, item.wireFee)
+ closingFeeView.text =
+ v.context.getString(R.string.exchange_fee_wire_fee_closing_fee, item.closingFee)
+ }
+ }
+}
diff --git a/wallet/src/main/java/net/taler/wallet/exchanges/ExchangeListFragment.kt b/wallet/src/main/java/net/taler/wallet/exchanges/ExchangeListFragment.kt
index 86b2519..9a96b59 100644
--- a/wallet/src/main/java/net/taler/wallet/exchanges/ExchangeListFragment.kt
+++ b/wallet/src/main/java/net/taler/wallet/exchanges/ExchangeListFragment.kt
@@ -34,17 +34,19 @@ import net.taler.wallet.MainViewModel
import net.taler.wallet.R
import net.taler.wallet.databinding.FragmentExchangeListBinding
-class ExchangeListFragment : Fragment(), ExchangeClickListener {
+open class ExchangeListFragment : Fragment(), ExchangeClickListener {
- private val model: MainViewModel by activityViewModels()
+ protected val model: MainViewModel by activityViewModels()
private val exchangeManager by lazy { model.exchangeManager }
- private lateinit var ui: FragmentExchangeListBinding
- private val exchangeAdapter by lazy { ExchangeAdapter(this) }
+ protected lateinit var ui: FragmentExchangeListBinding
+ protected open val isSelectOnly = false
+ private val exchangeAdapter by lazy { ExchangeAdapter(isSelectOnly, this) }
override fun onCreateView(
- inflater: LayoutInflater, container: ViewGroup?,
- savedInstanceState: Bundle?
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?,
): View? {
ui = FragmentExchangeListBinding.inflate(inflater, container, false)
return ui.root
@@ -70,7 +72,7 @@ class ExchangeListFragment : Fragment(), ExchangeClickListener {
})
}
- private fun onExchangeUpdate(exchanges: List<ExchangeItem>) {
+ protected open fun onExchangeUpdate(exchanges: List<ExchangeItem>) {
exchangeAdapter.update(exchanges)
if (exchanges.isEmpty()) {
ui.emptyState.fadeIn()
@@ -85,6 +87,10 @@ class ExchangeListFragment : Fragment(), ExchangeClickListener {
Toast.makeText(requireContext(), R.string.exchange_add_error, LENGTH_LONG).show()
}
+ override fun onExchangeSelected(item: ExchangeItem) {
+ throw AssertionError("must not get triggered here")
+ }
+
override fun onManualWithdraw(item: ExchangeItem) {
exchangeManager.withdrawalExchange = item
findNavController().navigate(R.id.action_nav_settings_exchanges_to_nav_exchange_manual_withdrawal)
diff --git a/wallet/src/main/java/net/taler/wallet/exchanges/SelectExchangeFragment.kt b/wallet/src/main/java/net/taler/wallet/exchanges/SelectExchangeFragment.kt
index a95a51c..61e0db5 100644
--- a/wallet/src/main/java/net/taler/wallet/exchanges/SelectExchangeFragment.kt
+++ b/wallet/src/main/java/net/taler/wallet/exchanges/SelectExchangeFragment.kt
@@ -16,130 +16,33 @@
package net.taler.wallet.exchanges
-import android.os.Bundle
-import android.view.LayoutInflater
-import android.view.View
-import android.view.View.GONE
-import android.view.ViewGroup
-import android.widget.TextView
-import androidx.core.content.ContextCompat.getColor
-import androidx.fragment.app.Fragment
-import androidx.fragment.app.activityViewModels
-import androidx.recyclerview.widget.RecyclerView.Adapter
-import androidx.recyclerview.widget.RecyclerView.ViewHolder
-import net.taler.common.toRelativeTime
-import net.taler.common.toShortDate
-import net.taler.lib.common.Amount
-import net.taler.wallet.MainViewModel
-import net.taler.wallet.R
-import net.taler.wallet.databinding.FragmentSelectExchangeBinding
-import net.taler.wallet.exchanges.CoinFeeAdapter.CoinFeeViewHolder
-import net.taler.wallet.exchanges.WireFeeAdapter.WireFeeViewHolder
+import androidx.navigation.fragment.findNavController
+import net.taler.common.fadeOut
-class SelectExchangeFragment : Fragment() {
+class SelectExchangeFragment : ExchangeListFragment() {
- private val model: MainViewModel by activityViewModels()
private val withdrawManager by lazy { model.withdrawManager }
- private lateinit var ui: FragmentSelectExchangeBinding
-
- override fun onCreateView(
- inflater: LayoutInflater, container: ViewGroup?,
- savedInstanceState: Bundle?
- ): View? {
- ui = FragmentSelectExchangeBinding.inflate(inflater, container, false)
- return ui.root
- }
-
- override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
- val fees = withdrawManager.exchangeFees ?: throw IllegalStateException()
- if (fees.withdrawFee.isZero()) {
- ui.withdrawFeeLabel.visibility = GONE
- ui.withdrawFeeView.visibility = GONE
- } else ui.withdrawFeeView.setAmount(fees.withdrawFee)
- if (fees.overhead.isZero()) {
- ui.overheadLabel.visibility = GONE
- ui.overheadView.visibility = GONE
- } else ui.overheadView.setAmount(fees.overhead)
- ui.expirationView.text = fees.earliestDepositExpiration.ms.toRelativeTime(requireContext())
- ui.coinFeesList.adapter = CoinFeeAdapter(fees.coinFees)
- ui.wireFeesList.adapter = WireFeeAdapter(fees.wireFees)
- }
-
- private fun TextView.setAmount(amount: Amount) {
- if (amount.isZero()) text = amount.toString()
- else {
- text = getString(R.string.amount_negative, amount)
- setTextColor(getColor(context, R.color.red))
- }
+ override val isSelectOnly = true
+ private val exchangeSelection by lazy {
+ requireNotNull(withdrawManager.exchangeSelection.value?.getEvenIfConsumedAlready())
}
-}
-
-private class CoinFeeAdapter(private val items: List<CoinFee>) : Adapter<CoinFeeViewHolder>() {
- override fun getItemCount() = items.size
- override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CoinFeeViewHolder {
- val v =
- LayoutInflater.from(parent.context).inflate(R.layout.list_item_coin_fee, parent, false)
- return CoinFeeViewHolder(v)
+ override fun onExchangeUpdate(exchanges: List<ExchangeItem>) {
+ ui.progressBar.fadeOut()
+ super.onExchangeUpdate(exchanges.filter { exchangeItem ->
+ exchangeItem.currency == exchangeSelection.amount.currency
+ })
}
- override fun onBindViewHolder(holder: CoinFeeViewHolder, position: Int) {
- holder.bind(items[position])
+ override fun onExchangeSelected(item: ExchangeItem) {
+ withdrawManager.getWithdrawalDetails(
+ exchangeBaseUrl = item.exchangeBaseUrl,
+ amount = exchangeSelection.amount,
+ showTosImmediately = true,
+ uri = exchangeSelection.talerWithdrawUri,
+ )
+ findNavController().navigateUp()
}
- private class CoinFeeViewHolder(private val v: View) : ViewHolder(v) {
- private val res = v.context.resources
- private val coinView: TextView = v.findViewById(R.id.coinView)
- private val withdrawFeeView: TextView = v.findViewById(R.id.withdrawFeeView)
- private val depositFeeView: TextView = v.findViewById(R.id.depositFeeView)
- private val refreshFeeView: TextView = v.findViewById(R.id.refreshFeeView)
- private val refundFeeView: TextView = v.findViewById(R.id.refundFeeView)
- fun bind(item: CoinFee) {
- coinView.text = res.getQuantityString(
- R.plurals.exchange_fee_coin,
- item.quantity,
- item.coin,
- item.quantity
- )
- withdrawFeeView.text =
- v.context.getString(R.string.exchange_fee_withdraw_fee, item.feeWithdraw)
- depositFeeView.text =
- v.context.getString(R.string.exchange_fee_deposit_fee, item.feeDeposit)
- refreshFeeView.text =
- v.context.getString(R.string.exchange_fee_refresh_fee, item.feeRefresh)
- refundFeeView.text =
- v.context.getString(R.string.exchange_fee_refund_fee, item.feeRefresh)
- }
- }
-}
-
-private class WireFeeAdapter(private val items: List<WireFee>) : Adapter<WireFeeViewHolder>() {
- override fun getItemCount() = items.size
- override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): WireFeeViewHolder {
- val v =
- LayoutInflater.from(parent.context).inflate(R.layout.list_item_wire_fee, parent, false)
- return WireFeeViewHolder(v)
- }
-
- override fun onBindViewHolder(holder: WireFeeViewHolder, position: Int) {
- holder.bind(items[position])
- }
-
- private class WireFeeViewHolder(private val v: View) : ViewHolder(v) {
- private val validityView: TextView = v.findViewById(R.id.validityView)
- private val wireFeeView: TextView = v.findViewById(R.id.wireFeeView)
- private val closingFeeView: TextView = v.findViewById(R.id.closingFeeView)
- fun bind(item: WireFee) {
- validityView.text = v.context.getString(
- R.string.exchange_fee_wire_fee_timespan,
- item.start.ms.toShortDate(v.context),
- item.end.ms.toShortDate(v.context)
- )
- wireFeeView.text =
- v.context.getString(R.string.exchange_fee_wire_fee_wire_fee, item.wireFee)
- closingFeeView.text =
- v.context.getString(R.string.exchange_fee_wire_fee_closing_fee, item.closingFee)
- }
- }
}