diff --git a/android/src/main/java/org/ergoplatform/android/tokens/TokenInformationDialogFragment.kt b/android/src/main/java/org/ergoplatform/android/tokens/TokenInformationDialogFragment.kt index 6dbd6886c..87965e6e6 100644 --- a/android/src/main/java/org/ergoplatform/android/tokens/TokenInformationDialogFragment.kt +++ b/android/src/main/java/org/ergoplatform/android/tokens/TokenInformationDialogFragment.kt @@ -52,7 +52,7 @@ class TokenInformationDialogFragment : BottomSheetDialogFragment() { binding.labelTokenName.text = if (displayName.isBlank()) getString(R.string.label_unnamed_token) else displayName - binding.labelTokenName.setCompoundDrawablesWithIntrinsicBounds( + binding.labelTokenName.setCompoundDrawablesRelativeWithIntrinsicBounds( 0, 0, getGenuineDrawableId(), 0 ) diff --git a/android/src/main/java/org/ergoplatform/android/tokens/TokenUtils.kt b/android/src/main/java/org/ergoplatform/android/tokens/TokenUtils.kt index eacc33731..66fcd125f 100644 --- a/android/src/main/java/org/ergoplatform/android/tokens/TokenUtils.kt +++ b/android/src/main/java/org/ergoplatform/android/tokens/TokenUtils.kt @@ -1,18 +1,15 @@ package org.ergoplatform.android.tokens import android.view.LayoutInflater -import android.view.View import android.widget.LinearLayout +import org.ergoplatform.TokenAmount import org.ergoplatform.android.R import org.ergoplatform.android.databinding.EntryWalletTokenBinding -import org.ergoplatform.android.databinding.EntryWalletTokenDetailsBinding import org.ergoplatform.android.databinding.FragmentChooseTokenDialogItemBinding import org.ergoplatform.persistance.GENUINE_SUSPICIOUS import org.ergoplatform.persistance.GENUINE_VERIFIED import org.ergoplatform.persistance.TokenInformation import org.ergoplatform.persistance.WalletToken -import org.ergoplatform.tokens.isSingularToken -import org.ergoplatform.utils.formatTokenAmounts fun inflateAndBindTokenView( walletToken: WalletToken, @@ -29,10 +26,10 @@ fun inflateAndBindTokenView( itemBinding.labelTokenName.text = walletToken.name ?: layoutInflater.context.getString(R.string.label_unnamed_token) itemBinding.labelTokenVal.text = - formatTokenAmounts( + TokenAmount( walletToken.amount ?: 0, walletToken.decimals, - ) + ).toStringPrettified() } fun FragmentChooseTokenDialogItemBinding.bind(token: WalletToken) { @@ -40,7 +37,9 @@ fun FragmentChooseTokenDialogItemBinding.bind(token: WalletToken) { labelTokenId.text = token.tokenId } -fun TokenInformation.getGenuineDrawableId(): Int { +fun TokenInformation.getGenuineDrawableId() = getGenuineDrawableId(genuineFlag) + +fun getGenuineDrawableId(genuineFlag: Int): Int { return when (genuineFlag) { GENUINE_VERIFIED -> R.drawable.ic_verified_24 GENUINE_SUSPICIOUS -> R.drawable.ic_suspicious_24 diff --git a/android/src/main/java/org/ergoplatform/android/tokens/WalletDetailsView.kt b/android/src/main/java/org/ergoplatform/android/tokens/WalletDetailsView.kt deleted file mode 100644 index 8713b174e..000000000 --- a/android/src/main/java/org/ergoplatform/android/tokens/WalletDetailsView.kt +++ /dev/null @@ -1,41 +0,0 @@ -package org.ergoplatform.android.tokens - -import android.view.View -import org.ergoplatform.android.R -import org.ergoplatform.android.databinding.EntryWalletTokenDetailsBinding -import org.ergoplatform.persistance.TokenInformation -import org.ergoplatform.persistance.WalletToken -import org.ergoplatform.tokens.isSingularToken -import org.ergoplatform.utils.formatTokenAmounts - -class WalletDetailsView(val binding: EntryWalletTokenDetailsBinding) { - private var walletToken: WalletToken? = null - private var tokenInformation: TokenInformation? = null - val tokenId get() = walletToken?.tokenId - - fun bind(walletToken: WalletToken, tokenInformation: TokenInformation? = null) { - this.walletToken = walletToken - this.tokenInformation = tokenInformation - - binding.labelTokenName.text = - walletToken.name ?: binding.root.context.getString(R.string.label_unnamed_token) - binding.labelTokenId.text = walletToken.tokenId - binding.labelTokenVal.text = - formatTokenAmounts( - walletToken.amount ?: 0, - walletToken.decimals, - ) - binding.labelTokenVal.visibility = - if (walletToken.isSingularToken()) View.GONE else View.VISIBLE - - // TODO genuine: don't show ID - // TODO show thumbnail (also in detail screen) - // TODO show price - } - - fun addTokenInfo(tokenInformation: TokenInformation) { - if (this.tokenInformation == null || this.tokenInformation!!.updatedMs != tokenInformation.updatedMs) { - bind(walletToken!!, tokenInformation) - } - } -} \ No newline at end of file diff --git a/android/src/main/java/org/ergoplatform/android/tokens/WalletEntryView.kt b/android/src/main/java/org/ergoplatform/android/tokens/WalletEntryView.kt new file mode 100644 index 000000000..038bf8e48 --- /dev/null +++ b/android/src/main/java/org/ergoplatform/android/tokens/WalletEntryView.kt @@ -0,0 +1,40 @@ +package org.ergoplatform.android.tokens + +import org.ergoplatform.android.databinding.EntryWalletTokenDetailsBinding +import org.ergoplatform.android.ui.AndroidStringProvider +import org.ergoplatform.android.ui.setTextAndVisibility +import org.ergoplatform.persistance.WalletToken +import org.ergoplatform.uilogic.StringProvider +import org.ergoplatform.uilogic.tokens.WalletEntryViewUiLogic + +class WalletEntryView(val binding: EntryWalletTokenDetailsBinding, walletToken: WalletToken) : + WalletEntryViewUiLogic(walletToken) { + override val texts: StringProvider + get() = AndroidStringProvider(binding.root.context) + + override fun setDisplayedTokenName(tokenName: String) { + binding.labelTokenName.text = tokenName + } + + override fun setGenuineFlag(genuineFlag: Int) { + binding.labelTokenName.setCompoundDrawablesRelativeWithIntrinsicBounds( + 0, + 0, + getGenuineDrawableId(genuineFlag), + 0 + ) + } + + override fun setDisplayedTokenId(tokenId: String?) { + binding.labelTokenId.setTextAndVisibility(tokenId) + } + + override fun setDisplayedBalance(value: String?) { + binding.labelTokenVal.setTextAndVisibility(value) + } + + override fun setDisplayedPrice(price: String?) { + binding.labelBalanceValue.setTextAndVisibility(price) + } + +} \ No newline at end of file diff --git a/android/src/main/java/org/ergoplatform/android/ui/UiUtils.kt b/android/src/main/java/org/ergoplatform/android/ui/UiUtils.kt index 4e37b5f19..5f2738900 100644 --- a/android/src/main/java/org/ergoplatform/android/ui/UiUtils.kt +++ b/android/src/main/java/org/ergoplatform/android/ui/UiUtils.kt @@ -154,4 +154,11 @@ fun BottomSheetDialogFragment.expandBottomSheetOnShow() { fun postDelayed(delayMs: Long, r: Runnable) { Handler(Looper.getMainLooper()).postDelayed(r, delayMs) +} + +fun TextView.setTextAndVisibility(newText: String?) { + newText?.let { + visibility = View.VISIBLE + text = it + } ?: run { visibility = View.GONE } } \ No newline at end of file diff --git a/android/src/main/java/org/ergoplatform/android/wallet/WalletDetailsFragment.kt b/android/src/main/java/org/ergoplatform/android/wallet/WalletDetailsFragment.kt index 9e442c647..6ff0f6dbd 100644 --- a/android/src/main/java/org/ergoplatform/android/wallet/WalletDetailsFragment.kt +++ b/android/src/main/java/org/ergoplatform/android/wallet/WalletDetailsFragment.kt @@ -25,7 +25,7 @@ import org.ergoplatform.android.Preferences import org.ergoplatform.android.R import org.ergoplatform.android.databinding.EntryWalletTokenDetailsBinding import org.ergoplatform.android.databinding.FragmentWalletDetailsBinding -import org.ergoplatform.android.tokens.WalletDetailsView +import org.ergoplatform.android.tokens.WalletEntryView import org.ergoplatform.android.ui.AndroidStringProvider import org.ergoplatform.android.ui.navigateSafe import org.ergoplatform.android.ui.openUrlWithBrowser @@ -216,8 +216,8 @@ class WalletDetailsFragment : Fragment(), AddressChooserCallback { this, true ) - val walletDetailsView = WalletDetailsView(itemBinding) - walletDetailsView.bind(token) + val walletDetailsView = WalletEntryView(itemBinding, token) + walletDetailsView.bind() tokensViewList.add(walletDetailsView) walletDetailsView.binding.root.setOnClickListener { @@ -248,7 +248,7 @@ class WalletDetailsFragment : Fragment(), AddressChooserCallback { } // list of token views currently in view - private val tokensViewList = ArrayList() + private val tokensViewList = ArrayList() private fun onTokenInfoChanged(tokenInfoHashMap: HashMap) { // token info changed, or we have the last call from another view instance diff --git a/android/src/main/res/layout/entry_wallet_token_details.xml b/android/src/main/res/layout/entry_wallet_token_details.xml index 90ea9cfd1..7b46742e5 100644 --- a/android/src/main/res/layout/entry_wallet_token_details.xml +++ b/android/src/main/res/layout/entry_wallet_token_details.xml @@ -1,10 +1,11 @@ - @@ -12,41 +13,63 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" - android:orientation="horizontal"> + android:orientation="vertical" + tools:ignore="UselessParent"> + + + + + + + + + android:textColor="@color/darkgrey" + tools:text="ba5856162d6342d2a0072f464a5a8b62b4ac4dd77195bec18c6bf268c2def831" /> + android:gravity="center" + android:maxLines="5" + android:textColor="@color/lightgrey" + tools:text="904.2 ERG" /> - - - - - \ No newline at end of file + \ No newline at end of file diff --git a/android/src/main/res/layout/fragment_token_information.xml b/android/src/main/res/layout/fragment_token_information.xml index c6cd47567..8f06b227a 100644 --- a/android/src/main/res/layout/fragment_token_information.xml +++ b/android/src/main/res/layout/fragment_token_information.xml @@ -77,7 +77,7 @@ android:layout_gravity="center" android:ellipsize="end" android:gravity="center" - android:maxLines="5" + android:maxLines="1" android:textColor="@color/lightgrey" tools:text="904.2 ERG" /> diff --git a/common-jvm/src/main/java/org/ergoplatform/TokenAmount.kt b/common-jvm/src/main/java/org/ergoplatform/TokenAmount.kt index f45fadc98..e22aa2c2d 100644 --- a/common-jvm/src/main/java/org/ergoplatform/TokenAmount.kt +++ b/common-jvm/src/main/java/org/ergoplatform/TokenAmount.kt @@ -1,5 +1,7 @@ package org.ergoplatform +import org.ergoplatform.persistance.WalletToken +import org.ergoplatform.utils.formatDoubleWithPrettyReduction import java.math.BigDecimal import java.math.RoundingMode import java.text.NumberFormat @@ -43,6 +45,20 @@ class TokenAmount(val rawValue: Long, val decimals: Int) { return numberInstance.format(toBigDecimal()) } + /** + * Formats token (asset) amounts, always formatted US-style. + * For larger amounts, 1,120.00 becomes 1.1K, useful for displaying with less space + */ + fun toStringPrettified(): String { + val doubleValue: Double = toDouble() + val preciseString = toString() + return if (doubleValue < 1000 && preciseString.length < 8 || doubleValue < 1) { + toStringUsFormatted(false) + } else { + formatDoubleWithPrettyReduction(doubleValue) + } + } + fun toBigDecimal() = rawValue.toBigDecimal().movePointLeft(decimals) fun toDouble(): Double { @@ -60,4 +76,9 @@ fun String.toTokenAmount(decimals: Int): TokenAmount? { } catch (t: Throwable) { return null } -} \ No newline at end of file +} + +fun WalletToken.toTokenAmount(): TokenAmount = TokenAmount( + amount ?: 0, + decimals +) \ No newline at end of file diff --git a/common-jvm/src/main/java/org/ergoplatform/uilogic/tokens/WalletEntryViewUiLogic.kt b/common-jvm/src/main/java/org/ergoplatform/uilogic/tokens/WalletEntryViewUiLogic.kt new file mode 100644 index 000000000..f93d66d83 --- /dev/null +++ b/common-jvm/src/main/java/org/ergoplatform/uilogic/tokens/WalletEntryViewUiLogic.kt @@ -0,0 +1,63 @@ +package org.ergoplatform.uilogic.tokens + +import org.ergoplatform.WalletStateSyncManager +import org.ergoplatform.persistance.GENUINE_UNKNOWN +import org.ergoplatform.persistance.GENUINE_VERIFIED +import org.ergoplatform.persistance.TokenInformation +import org.ergoplatform.persistance.WalletToken +import org.ergoplatform.toTokenAmount +import org.ergoplatform.tokens.isSingularToken +import org.ergoplatform.uilogic.STRING_LABEL_UNNAMED_TOKEN +import org.ergoplatform.uilogic.StringProvider +import org.ergoplatform.utils.formatTokenPriceToString + +abstract class WalletEntryViewUiLogic(val walletToken: WalletToken) { + abstract val texts: StringProvider + + private var tokenInformation: TokenInformation? = null + val tokenId get() = walletToken.tokenId + + abstract fun setDisplayedTokenName(tokenName: String) + abstract fun setDisplayedTokenId(tokenId: String?) + abstract fun setDisplayedBalance(value: String?) + abstract fun setDisplayedPrice(price: String?) + abstract fun setGenuineFlag(genuineFlag: Int) + + fun bind(tokenInformation: TokenInformation? = null) { + this.tokenInformation = tokenInformation + + val textProvider = this.texts + val balanceAmount = walletToken.toTokenAmount() + val singularToken = (tokenInformation?.isSingularToken() ?: walletToken.isSingularToken()) + val genuineFlag = tokenInformation?.genuineFlag ?: GENUINE_UNKNOWN + + setDisplayedTokenName( + walletToken.name ?: textProvider.getString(STRING_LABEL_UNNAMED_TOKEN) + ) + setGenuineFlag(genuineFlag) + setDisplayedTokenId(if (genuineFlag == GENUINE_VERIFIED) null else walletToken.tokenId) + setDisplayedBalance(if (singularToken) null else balanceAmount.toStringPrettified()) + + setDisplayedPrice(if (!singularToken) { + val walletSyncManager = WalletStateSyncManager.getInstance() + val tokenPrice = walletSyncManager.tokenPrices.get(tokenId) + tokenPrice?.let { + formatTokenPriceToString( + balanceAmount, + it.ergValue, + walletSyncManager, + textProvider + ) + " [${it.priceSource}]" + } + } else null) + + // TODO show thumbnail (also in detail screen) + + } + + fun addTokenInfo(tokenInformation: TokenInformation) { + if (this.tokenInformation == null || this.tokenInformation!!.updatedMs != tokenInformation.updatedMs) { + bind(tokenInformation) + } + } +} \ No newline at end of file diff --git a/common-jvm/src/main/java/org/ergoplatform/utils/UiUtils.kt b/common-jvm/src/main/java/org/ergoplatform/utils/UiUtils.kt index 9e13d3d2b..1c1c7f12e 100644 --- a/common-jvm/src/main/java/org/ergoplatform/utils/UiUtils.kt +++ b/common-jvm/src/main/java/org/ergoplatform/utils/UiUtils.kt @@ -47,24 +47,6 @@ fun formatFiatToString(amount: Double, currency: String, text: StringProvider): " " + currency.uppercase(Locale.getDefault()) } -/** - * Formats token (asset) amounts, always formatted US-style. - * For larger amounts, 1,120.00 becomes 1.1K, useful for displaying with less space - */ -fun formatTokenAmounts( - amount: Long, - decimals: Int, -): String { - val tokenAmount = TokenAmount(amount, decimals) - val doubleValue: Double = tokenAmount.toDouble() - val preciseString = tokenAmount.toString() - return if (doubleValue < 1000 && preciseString.length < 8 || doubleValue < 1) { - tokenAmount.toStringUsFormatted(false) - } else { - formatDoubleWithPrettyReduction(doubleValue) - } -} - fun formatDoubleWithPrettyReduction(amount: Double): String { val suffixChars = "KMGTPE" val formatter = DecimalFormat("###.#", DecimalFormatSymbols(Locale.US)) diff --git a/ios/src/main/java/org/ergoplatform/ios/tokens/TokenEntryView.kt b/ios/src/main/java/org/ergoplatform/ios/tokens/TokenEntryView.kt index d572be7f0..fe9a616b7 100644 --- a/ios/src/main/java/org/ergoplatform/ios/tokens/TokenEntryView.kt +++ b/ios/src/main/java/org/ergoplatform/ios/tokens/TokenEntryView.kt @@ -1,11 +1,11 @@ package org.ergoplatform.ios.tokens import com.badlogic.gdx.utils.I18NBundle +import org.ergoplatform.TokenAmount import org.ergoplatform.ios.ui.* import org.ergoplatform.persistance.WalletToken import org.ergoplatform.uilogic.STRING_LABEL_MORE_TOKENS import org.ergoplatform.uilogic.STRING_LABEL_UNNAMED_TOKEN -import org.ergoplatform.utils.formatTokenAmounts import org.robovm.apple.coregraphics.CGRect import org.robovm.apple.uikit.UILayoutConstraintAxis import org.robovm.apple.uikit.UIStackView @@ -35,10 +35,10 @@ class TokenEntryView : UIStackView(CGRect.Zero()) { fun bindWalletToken(walletToken: WalletToken, texts: I18NBundle): TokenEntryView { labelTokenName.text = walletToken.name ?: texts.get(STRING_LABEL_UNNAMED_TOKEN) labelTokenVal.text = - formatTokenAmounts( + TokenAmount( walletToken.amount ?: 0, walletToken.decimals, - ) + ).toStringPrettified() return this }