Updated on 2026-08-14
This commit is contained in:
parent
00e47d3988
commit
7bce07d944
12 changed files with 228 additions and 16 deletions
|
|
@ -6,7 +6,6 @@ import com.google.zxing.BarcodeFormat
|
|||
import com.google.zxing.EncodeHintType
|
||||
import com.google.zxing.qrcode.QRCodeWriter
|
||||
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel
|
||||
import com.tangem.blockchain.common.Blockchain
|
||||
import java.math.BigDecimal
|
||||
import java.math.RoundingMode
|
||||
import java.text.DecimalFormat
|
||||
|
|
@ -34,16 +33,16 @@ fun String.toQrCode(): Bitmap {
|
|||
return bmp
|
||||
}
|
||||
|
||||
fun BigDecimal.toFormattedString(blockchain: Blockchain): String {
|
||||
fun BigDecimal.toFormattedString(decimals: Int): String {
|
||||
val symbols = DecimalFormatSymbols(Locale.US)
|
||||
symbols.decimalSeparator = '.'
|
||||
val df = DecimalFormat()
|
||||
df.decimalFormatSymbols = symbols
|
||||
df.maximumFractionDigits = blockchain.decimals()
|
||||
df.maximumFractionDigits = decimals
|
||||
df.minimumFractionDigits = 0
|
||||
df.isGroupingUsed = false
|
||||
val bd = BigDecimal(unscaledValue(), scale())
|
||||
bd.setScale(blockchain.decimals(), BigDecimal.ROUND_DOWN)
|
||||
bd.setScale(decimals, BigDecimal.ROUND_DOWN)
|
||||
return df.format(bd)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,10 @@ fun Fragment.getDrawable(@DrawableRes drawableResId: Int): Drawable? {
|
|||
return ContextCompat.getDrawable(requireContext(), drawableResId)
|
||||
}
|
||||
|
||||
fun Context.getDrawableCompat(@DrawableRes drawableResId: Int): Drawable? {
|
||||
return ContextCompat.getDrawable(this, drawableResId)
|
||||
}
|
||||
|
||||
fun View.show(show: Boolean) {
|
||||
if (show) this.visibility = View.VISIBLE else this.visibility = View.GONE
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,36 @@
|
|||
package com.tangem.tap.features.wallet.models
|
||||
|
||||
import com.tangem.blockchain.common.TransactionData
|
||||
import com.tangem.tap.common.extensions.toFormattedString
|
||||
|
||||
data class PendingTransaction(
|
||||
val address: String,
|
||||
val amount: String,
|
||||
val currency: String,
|
||||
val type: PendingTransactionType
|
||||
)
|
||||
|
||||
enum class PendingTransactionType { Incoming, Outcoming }
|
||||
|
||||
fun TransactionData.toPendingTransaction(walletAddress: String): PendingTransaction {
|
||||
val type: PendingTransactionType = if (this.sourceAddress == walletAddress) {
|
||||
PendingTransactionType.Outcoming
|
||||
} else {
|
||||
PendingTransactionType.Incoming
|
||||
}
|
||||
val address = if (this.sourceAddress == walletAddress) {
|
||||
this.destinationAddress
|
||||
} else {
|
||||
this.sourceAddress
|
||||
}
|
||||
return PendingTransaction(
|
||||
address,
|
||||
this.amount.value?.toFormattedString(amount.decimals) ?: "?",
|
||||
this.amount.currencySymbol,
|
||||
type
|
||||
)
|
||||
}
|
||||
|
||||
fun List<TransactionData>.toPendingTransactions(walletAddress: String): List<PendingTransaction>{
|
||||
return this.map { it.toPendingTransaction(walletAddress) }
|
||||
}
|
||||
|
|
@ -7,6 +7,7 @@ import com.tangem.tap.common.extensions.toFiatString
|
|||
import com.tangem.tap.common.extensions.toFormattedString
|
||||
import com.tangem.tap.common.extensions.toQrCode
|
||||
import com.tangem.tap.common.redux.AppState
|
||||
import com.tangem.tap.features.wallet.models.toPendingTransactions
|
||||
import com.tangem.tap.features.wallet.ui.BalanceStatus
|
||||
import com.tangem.tap.features.wallet.ui.BalanceWidgetData
|
||||
import com.tangem.tap.features.wallet.ui.TokenData
|
||||
|
|
@ -37,7 +38,7 @@ private fun internalReduce(action: Action, state: AppState): WalletState {
|
|||
} else {
|
||||
AddressData(wallet.address, wallet.shareUrl, wallet.exploreUrl)
|
||||
}
|
||||
val currentArtworkId = state.globalState.scanNoteResponse?.verifyResponse?.artworkInfo?.id
|
||||
val currentArtworkId = state.globalState.scanNoteResponse?.verifyResponse?.artworkInfo?.id
|
||||
val cardImage = if (newState.cardImage?.artworkId == currentArtworkId) {
|
||||
newState.cardImage
|
||||
} else {
|
||||
|
|
@ -61,7 +62,7 @@ private fun internalReduce(action: Action, state: AppState): WalletState {
|
|||
val tokenFiatRate = state.globalState.fiatRates.getRateForCryptoCurrency(token.currencySymbol)
|
||||
val tokenFiatAmount = tokenFiatRate?.let { token.value?.toFiatString(it) }
|
||||
TokenData(
|
||||
token.value?.toFormattedString(action.wallet.blockchain) ?: "",
|
||||
token.value?.toFormattedString(token.decimals) ?: "",
|
||||
token.currencySymbol, tokenFiatAmount)
|
||||
} else {
|
||||
null
|
||||
|
|
@ -70,16 +71,20 @@ private fun internalReduce(action: Action, state: AppState): WalletState {
|
|||
val fiatRate = state.globalState.fiatRates.getRateForCryptoCurrency(action.wallet.blockchain.currency)
|
||||
val fiatAmount = fiatRate?.let { amount?.toFiatString(it) }
|
||||
|
||||
val pendingTransactions = action.wallet.transactions
|
||||
.toPendingTransactions(action.wallet.address)
|
||||
|
||||
val sendButtonEnabled = amount?.isZero() == false || token?.value?.isZero() == false
|
||||
newState = newState.copy(
|
||||
state = ProgressState.Done, wallet = action.wallet,
|
||||
currencyData = BalanceWidgetData(
|
||||
BalanceStatus.VerifiedOnline, action.wallet.blockchain.fullName,
|
||||
currencySymbol = action.wallet.blockchain.currency,
|
||||
amount?.toFormattedString(action.wallet.blockchain),
|
||||
amount?.toFormattedString(action.wallet.blockchain.decimals()),
|
||||
token = tokenData,
|
||||
fiatAmount = fiatAmount
|
||||
),
|
||||
pendingTransactions = pendingTransactions,
|
||||
mainButton = WalletMainButton.SendButton(sendButtonEnabled)
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package com.tangem.tap.features.wallet.redux
|
|||
import android.graphics.Bitmap
|
||||
import com.tangem.blockchain.common.Wallet
|
||||
import com.tangem.tap.common.entities.Button
|
||||
import com.tangem.tap.features.wallet.models.PendingTransaction
|
||||
import com.tangem.tap.features.wallet.ui.BalanceWidgetData
|
||||
import org.rekotlin.StateType
|
||||
|
||||
|
|
@ -10,6 +11,7 @@ data class WalletState(
|
|||
val state: ProgressState = ProgressState.Done,
|
||||
val cardImage: Artwork? = null,
|
||||
val wallet: Wallet? = null,
|
||||
val pendingTransactions: List<PendingTransaction> = emptyList(),
|
||||
val addressData: AddressData? = null,
|
||||
val currencyData: BalanceWidgetData = BalanceWidgetData(),
|
||||
val payIdData: PayIdData = PayIdData(),
|
||||
|
|
|
|||
|
|
@ -0,0 +1,62 @@
|
|||
package com.tangem.tap.features.wallet.ui
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.DiffUtil
|
||||
import androidx.recyclerview.widget.ListAdapter
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.tangem.tap.common.extensions.getDrawableCompat
|
||||
import com.tangem.tap.features.wallet.models.PendingTransaction
|
||||
import com.tangem.tap.features.wallet.models.PendingTransactionType
|
||||
import com.tangem.wallet.R
|
||||
import kotlinx.android.synthetic.main.layout_pending_transaction.view.*
|
||||
|
||||
class PendingTransactionsAdapter
|
||||
: ListAdapter<PendingTransaction, PendingTransactionsAdapter.TransactionsViewHolder>(DiffUtilCallback) {
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): TransactionsViewHolder {
|
||||
val layout = LayoutInflater.from(parent.context)
|
||||
.inflate(R.layout.layout_pending_transaction, parent, false)
|
||||
return TransactionsViewHolder(layout)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: TransactionsViewHolder, position: Int) {
|
||||
holder.bind(currentList[position])
|
||||
}
|
||||
|
||||
object DiffUtilCallback : DiffUtil.ItemCallback<PendingTransaction>() {
|
||||
|
||||
|
||||
override fun areContentsTheSame(
|
||||
oldItem: PendingTransaction, newItem: PendingTransaction
|
||||
) = oldItem == newItem
|
||||
|
||||
override fun areItemsTheSame(
|
||||
oldItem: PendingTransaction, newItem: PendingTransaction
|
||||
) = oldItem == newItem
|
||||
|
||||
}
|
||||
|
||||
|
||||
class TransactionsViewHolder(val view: View) :
|
||||
RecyclerView.ViewHolder(view) {
|
||||
|
||||
fun bind(transaction: PendingTransaction) {
|
||||
val transactionDescriptionRes = when (transaction.type) {
|
||||
PendingTransactionType.Incoming -> R.string.wallet_pending_transaction_incoming
|
||||
PendingTransactionType.Outcoming -> R.string.wallet_pending_transaction_outcoming
|
||||
}
|
||||
val image = when (transaction.type) {
|
||||
PendingTransactionType.Incoming -> R.drawable.ic_arrow_down
|
||||
PendingTransactionType.Outcoming -> R.drawable.ic_arrow_right
|
||||
}
|
||||
view.tv_pending_transaction.text = view.context.getString(
|
||||
transactionDescriptionRes, transaction.amount, transaction.currency
|
||||
)
|
||||
view.tv_pending_transaction_address.text = transaction.address
|
||||
view.iv_pending_transaction.setImageDrawable(view.context.getDrawableCompat(image))
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -5,6 +5,7 @@ import android.os.Bundle
|
|||
import android.view.View
|
||||
import androidx.activity.OnBackPressedCallback
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.transition.TransitionInflater
|
||||
import com.tangem.tap.common.extensions.getDrawable
|
||||
import com.tangem.tap.common.extensions.hide
|
||||
|
|
@ -26,6 +27,9 @@ class WalletFragment : Fragment(R.layout.fragment_wallet), StoreSubscriber<Walle
|
|||
private var qrDialog: QrDialog? = null
|
||||
private var payIdDialog: PayIdDialog? = null
|
||||
|
||||
private lateinit var viewAdapter: PendingTransactionsAdapter
|
||||
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
activity?.onBackPressedDispatcher?.addCallback(this, object : OnBackPressedCallback(true) {
|
||||
|
|
@ -55,7 +59,6 @@ class WalletFragment : Fragment(R.layout.fragment_wallet), StoreSubscriber<Walle
|
|||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
|
||||
toolbar.setNavigationOnClickListener {
|
||||
store.dispatch(NavigationAction.PopBackTo())
|
||||
}
|
||||
|
|
@ -63,8 +66,17 @@ class WalletFragment : Fragment(R.layout.fragment_wallet), StoreSubscriber<Walle
|
|||
btn_scan.setOnClickListener {
|
||||
store.dispatch(WalletAction.Scan)
|
||||
}
|
||||
setupTransactionsRecyclerView()
|
||||
}
|
||||
|
||||
|
||||
private fun setupTransactionsRecyclerView() {
|
||||
viewAdapter = PendingTransactionsAdapter()
|
||||
rv_pending_transaction.layoutManager = LinearLayoutManager(context)
|
||||
rv_pending_transaction.adapter = viewAdapter
|
||||
}
|
||||
|
||||
|
||||
override fun newState(state: WalletState) {
|
||||
if (activity == null) return
|
||||
|
||||
|
|
@ -76,6 +88,8 @@ class WalletFragment : Fragment(R.layout.fragment_wallet), StoreSubscriber<Walle
|
|||
setupAddressCard(state)
|
||||
setupCardImage(state.cardImage?.artwork)
|
||||
|
||||
viewAdapter.submitList(state.pendingTransactions)
|
||||
|
||||
if (state.qrCode != null && state.addressData?.shareUrl != null) {
|
||||
if (qrDialog == null) qrDialog = QrDialog(requireContext())
|
||||
qrDialog?.showQr(state.qrCode, state.addressData.shareUrl)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue