From c5024fa89af1134f6ae6a06cf21def224afb3562 Mon Sep 17 00:00:00 2001 From: polstianka Date: Wed, 29 Jan 2025 16:33:41 -0500 Subject: [PATCH] bug fixeds --- .../data/collectibles/entities/NftEntity.kt | 10 ++ .../entities/NftMetadataEntity.kt | 3 + .../tonkeeper/core/entities/TransferEntity.kt | 10 ++ .../tonapps/tonkeeper/extensions/String.kt | 4 + .../tonkeeper/ui/component/LottieView.kt | 83 +++++++++++++ .../tonkeeper/ui/screen/init/list/Holder.kt | 3 +- .../tonkeeper/ui/screen/nft/NftScreen.kt | 23 ++++ .../tonkeeper/ui/screen/root/RootActivity.kt | 13 +- .../ui/screen/send/main/SendViewModel.kt | 3 + .../wallet/picker/list/holder/WalletHolder.kt | 3 +- .../app/src/main/res/layout/fragment_nft.xml | 27 ++-- .../app/src/main/res/raw/lottie_webview | 116 ++++++++++++++++++ 12 files changed, 282 insertions(+), 16 deletions(-) create mode 100644 apps/wallet/instance/app/src/main/java/com/tonapps/tonkeeper/ui/component/LottieView.kt create mode 100644 apps/wallet/instance/app/src/main/res/raw/lottie_webview diff --git a/apps/wallet/data/collectibles/src/main/java/com/tonapps/wallet/data/collectibles/entities/NftEntity.kt b/apps/wallet/data/collectibles/src/main/java/com/tonapps/wallet/data/collectibles/entities/NftEntity.kt index 1c80772b2..766f575f1 100644 --- a/apps/wallet/data/collectibles/src/main/java/com/tonapps/wallet/data/collectibles/entities/NftEntity.kt +++ b/apps/wallet/data/collectibles/src/main/java/com/tonapps/wallet/data/collectibles/entities/NftEntity.kt @@ -2,11 +2,13 @@ package com.tonapps.wallet.data.collectibles.entities import android.net.Uri import android.os.Parcelable +import androidx.core.net.toUri import com.tonapps.blockchain.ton.extensions.equalsAddress import com.tonapps.blockchain.ton.extensions.toUserFriendly import com.tonapps.wallet.api.entity.AccountEntity import com.tonapps.wallet.data.core.Trust import io.tonapi.models.NftItem +import kotlinx.parcelize.IgnoredOnParcel import kotlinx.parcelize.Parcelize @Parcelize @@ -56,18 +58,26 @@ data class NftEntity( val ownerAddress: String get() = owner?.address ?: address + @IgnoredOnParcel val thumbUri: Uri by lazy { getImageUri(64, 320) ?: previews.first().url.let { Uri.parse(it) } } + @IgnoredOnParcel val mediumUri: Uri by lazy { getImageUri(256, 512) ?: previews.first().url.let { Uri.parse(it) } } + @IgnoredOnParcel val bigUri: Uri by lazy { getImageUri(512, 1024) ?: previews.last().url.let { Uri.parse(it) } } + @IgnoredOnParcel + val lottieUri: Uri? by lazy { + metadata.lottie?.toUri() + } + val isTrusted: Boolean get() = trust == Trust.whitelist diff --git a/apps/wallet/data/collectibles/src/main/java/com/tonapps/wallet/data/collectibles/entities/NftMetadataEntity.kt b/apps/wallet/data/collectibles/src/main/java/com/tonapps/wallet/data/collectibles/entities/NftMetadataEntity.kt index 65fb14428..8a3814c33 100644 --- a/apps/wallet/data/collectibles/src/main/java/com/tonapps/wallet/data/collectibles/entities/NftMetadataEntity.kt +++ b/apps/wallet/data/collectibles/src/main/java/com/tonapps/wallet/data/collectibles/entities/NftMetadataEntity.kt @@ -27,6 +27,9 @@ data class NftMetadataEntity( val description: String? get() = strings["description"] + val lottie: String? + get() = strings["lottie"] + constructor(map: Map) : this( strings = map.filter { it.value is String }.mapValues { it.value as String } as HashMap, buttons = map["buttons"]?.let { buttons -> diff --git a/apps/wallet/instance/app/src/main/java/com/tonapps/tonkeeper/core/entities/TransferEntity.kt b/apps/wallet/instance/app/src/main/java/com/tonapps/tonkeeper/core/entities/TransferEntity.kt index 392b387f9..8ea1677c4 100644 --- a/apps/wallet/instance/app/src/main/java/com/tonapps/tonkeeper/core/entities/TransferEntity.kt +++ b/apps/wallet/instance/app/src/main/java/com/tonapps/tonkeeper/core/entities/TransferEntity.kt @@ -407,5 +407,15 @@ data class TransferEntity( BigInteger.ZERO } } + + fun comment(text: String?): Cell? { + if (text.isNullOrBlank()) { + return null + } + return beginCell() + .storeUInt(0, 32) + .storeStringTail(text) + .endCell() + } } } \ No newline at end of file diff --git a/apps/wallet/instance/app/src/main/java/com/tonapps/tonkeeper/extensions/String.kt b/apps/wallet/instance/app/src/main/java/com/tonapps/tonkeeper/extensions/String.kt index 95d9ba55b..6123b6d0c 100644 --- a/apps/wallet/instance/app/src/main/java/com/tonapps/tonkeeper/extensions/String.kt +++ b/apps/wallet/instance/app/src/main/java/com/tonapps/tonkeeper/extensions/String.kt @@ -76,3 +76,7 @@ fun String.withVerificationIcon(context: Context): CharSequence { fun String.isPrintableAscii(): Boolean { return this.all { it.code in 32..126 } } + +fun String.fixW5Title(): String { + return replace("v5", "w5").replace("v5beta", "w5 beta") +} \ No newline at end of file diff --git a/apps/wallet/instance/app/src/main/java/com/tonapps/tonkeeper/ui/component/LottieView.kt b/apps/wallet/instance/app/src/main/java/com/tonapps/tonkeeper/ui/component/LottieView.kt new file mode 100644 index 000000000..731320ce7 --- /dev/null +++ b/apps/wallet/instance/app/src/main/java/com/tonapps/tonkeeper/ui/component/LottieView.kt @@ -0,0 +1,83 @@ +package com.tonapps.tonkeeper.ui.component + +import android.content.Context +import android.net.Uri +import android.os.Build +import android.util.AttributeSet +import android.webkit.WebSettings +import android.webkit.WebView +import android.webkit.WebViewClient +import com.tonapps.extensions.rawText +import com.tonapps.tonkeeperx.R + +class LottieView @JvmOverloads constructor( + context: Context, + attrs: AttributeSet? = null, + defStyle: Int = 0, +) : WebView(context, attrs, defStyle) { + + var doOnReady: (() -> Unit)? = null + + init { + settings.apply { + javaScriptEnabled = true + allowFileAccess = false + allowContentAccess = false + domStorageEnabled = true + cacheMode = WebSettings.LOAD_NO_CACHE + displayZoomControls = false + builtInZoomControls = false + setSupportZoom(false) + setEnableSmoothTransition(false) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + setRendererPriorityPolicy(RENDERER_PRIORITY_IMPORTANT, true) + } + } + + isVerticalScrollBarEnabled = false + isHorizontalScrollBarEnabled = false + overScrollMode = OVER_SCROLL_NEVER + + setBackgroundColor(0x00000000) + setLayerType(LAYER_TYPE_HARDWARE, null) + + setInitialScale(100) + + webViewClient = object : WebViewClient() { + override fun onPageFinished(view: WebView?, url: String?) { + doOnReady?.invoke() + } + } + } + + fun setUri(uri: Uri) { + val data = loadHtml(context).replace("{lottieUrl}", uri.toString()) + loadDataWithBaseURL(null, data, "text/html", "utf-8", null) + } + + override fun onDetachedFromWindow() { + clearCache(true) + clearHistory() + super.onDetachedFromWindow() + } + + + override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { + super.onMeasure(widthMeasureSpec, widthMeasureSpec) + } + + private companion object { + + @Volatile + private var cachedLottie: String? = null + + private fun loadHtml(context: Context): String { + return cachedLottie ?: synchronized(this) { + cachedLottie ?: context.rawText(R.raw.lottie_webview).also { + cachedLottie = it + } + } + } + } + +} \ No newline at end of file diff --git a/apps/wallet/instance/app/src/main/java/com/tonapps/tonkeeper/ui/screen/init/list/Holder.kt b/apps/wallet/instance/app/src/main/java/com/tonapps/tonkeeper/ui/screen/init/list/Holder.kt index d7ec56f00..9184d8cbf 100644 --- a/apps/wallet/instance/app/src/main/java/com/tonapps/tonkeeper/ui/screen/init/list/Holder.kt +++ b/apps/wallet/instance/app/src/main/java/com/tonapps/tonkeeper/ui/screen/init/list/Holder.kt @@ -8,6 +8,7 @@ import androidx.appcompat.widget.AppCompatTextView import com.tonapps.blockchain.ton.contract.WalletVersion import com.tonapps.icu.CurrencyFormatter.withCustomSymbol import com.tonapps.tonkeeper.api.shortAddress +import com.tonapps.tonkeeper.extensions.fixW5Title import com.tonapps.tonkeeperx.R import com.tonapps.uikit.color.textTertiaryColor import com.tonapps.uikit.list.BaseListHolder @@ -46,7 +47,7 @@ class Holder( private fun setDetails(walletVersion: WalletVersion, balance: CharSequence, tokens: Boolean, collectibles: Boolean, isLedger: Boolean, ledgerAdded: Boolean) { val builder = SpannableStringBuilder() if (!isLedger) { - builder.append(walletVersion.title) + builder.append(walletVersion.title.fixW5Title()) builder.append(DOT) } builder.append(balance.withCustomSymbol(context)) diff --git a/apps/wallet/instance/app/src/main/java/com/tonapps/tonkeeper/ui/screen/nft/NftScreen.kt b/apps/wallet/instance/app/src/main/java/com/tonapps/tonkeeper/ui/screen/nft/NftScreen.kt index dbb10b608..0e4010730 100644 --- a/apps/wallet/instance/app/src/main/java/com/tonapps/tonkeeper/ui/screen/nft/NftScreen.kt +++ b/apps/wallet/instance/app/src/main/java/com/tonapps/tonkeeper/ui/screen/nft/NftScreen.kt @@ -8,6 +8,7 @@ import android.util.Log import android.view.View import android.view.ViewGroup import android.widget.Button +import android.widget.FrameLayout import androidx.appcompat.widget.AppCompatImageView import androidx.appcompat.widget.AppCompatTextView import androidx.core.net.toUri @@ -24,6 +25,7 @@ import com.tonapps.tonkeeper.koin.remoteConfig import com.tonapps.tonkeeper.koin.walletViewModel import com.tonapps.tonkeeper.popup.ActionSheet import com.tonapps.tonkeeper.ui.base.WalletContextScreen +import com.tonapps.tonkeeper.ui.component.LottieView import com.tonapps.tonkeeper.ui.screen.browser.dapp.DAppArgs import com.tonapps.tonkeeper.ui.screen.browser.dapp.DAppScreen import com.tonapps.tonkeeper.ui.screen.root.RootViewModel @@ -48,6 +50,7 @@ import uikit.extensions.dp import uikit.extensions.drawable import uikit.extensions.getDimensionPixelSize import uikit.extensions.inflate +import uikit.extensions.roundTop import uikit.extensions.setRightDrawable import uikit.extensions.topScrolled import uikit.widget.ColumnLayout @@ -73,6 +76,9 @@ class NftScreen(wallet: WalletEntity): WalletContextScreen(R.layout.fragment_nft private lateinit var headerView: HeaderView private lateinit var spamView: View + private lateinit var previewView: FrameLayout + + private var lottieView: LottieView? = null override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) @@ -192,6 +198,17 @@ class NftScreen(wallet: WalletEntity): WalletContextScreen(R.layout.fragment_nft domainRenewButton.visibility = View.GONE transferButton.visibility = View.GONE } + + if (nftEntity.lottieUri != null) { + lottieView = LottieView(requireContext()).apply { + roundTop(16.dp) + setUri(nftEntity.lottieUri!!) + } + previewView.addView(lottieView, FrameLayout.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.WRAP_CONTENT + )) + } } private fun setTrust(trust: Trust) { @@ -379,6 +396,12 @@ class NftScreen(wallet: WalletEntity): WalletContextScreen(R.layout.fragment_nft addressView.text = address.short4 } + override fun onDestroyView() { + super.onDestroyView() + lottieView?.destroy() + lottieView = null + } + companion object { private const val HIDE_NFT_ID = 1L diff --git a/apps/wallet/instance/app/src/main/java/com/tonapps/tonkeeper/ui/screen/root/RootActivity.kt b/apps/wallet/instance/app/src/main/java/com/tonapps/tonkeeper/ui/screen/root/RootActivity.kt index 2721d1d98..b2cbc3042 100644 --- a/apps/wallet/instance/app/src/main/java/com/tonapps/tonkeeper/ui/screen/root/RootActivity.kt +++ b/apps/wallet/instance/app/src/main/java/com/tonapps/tonkeeper/ui/screen/root/RootActivity.kt @@ -23,6 +23,7 @@ import com.tonapps.extensions.toUriOrNull import com.tonapps.tonkeeper.App import com.tonapps.tonkeeper.core.AnalyticsHelper import com.tonapps.tonkeeper.core.DevSettings +import com.tonapps.tonkeeper.core.entities.TransferEntity import com.tonapps.tonkeeper.deeplink.DeepLink import com.tonapps.tonkeeper.extensions.isDarkMode import com.tonapps.tonkeeper.extensions.toast @@ -276,7 +277,8 @@ class RootActivity: BaseWalletActivity() { targetAddress: String, amountNano: Long, bin: Cell?, - initStateBase64: String? + initStateBase64: String?, + comment: String? = null ) { val request = SignRequestEntity.Builder() @@ -286,7 +288,9 @@ class RootActivity: BaseWalletActivity() { addressValue = targetAddress, amount = amountNano, stateInitValue = initStateBase64, - payloadValue = bin?.base64() + payloadValue = bin?.base64() ?: comment?.let { + TransferEntity.comment(it) + }?.base64() )) .setTestnet(wallet.testnet) .build(Uri.parse("tonkeeper://signRaw/")) @@ -310,13 +314,14 @@ class RootActivity: BaseWalletActivity() { return } - if (targetAddress != null && amountNano > 0 && (bin != null || initStateBase64 != null)) { + if (targetAddress != null && amountNano > 0 && nftAddress.isNullOrBlank()) { openSign( wallet = wallet, targetAddress = targetAddress, amountNano = amountNano, bin = bin, - initStateBase64 = initStateBase64 + initStateBase64 = initStateBase64, + comment = text, ) return } diff --git a/apps/wallet/instance/app/src/main/java/com/tonapps/tonkeeper/ui/screen/send/main/SendViewModel.kt b/apps/wallet/instance/app/src/main/java/com/tonapps/tonkeeper/ui/screen/send/main/SendViewModel.kt index e6c2e1407..c8faa7061 100644 --- a/apps/wallet/instance/app/src/main/java/com/tonapps/tonkeeper/ui/screen/send/main/SendViewModel.kt +++ b/apps/wallet/instance/app/src/main/java/com/tonapps/tonkeeper/ui/screen/send/main/SendViewModel.kt @@ -5,6 +5,7 @@ import androidx.lifecycle.viewModelScope import com.google.firebase.crashlytics.FirebaseCrashlytics import com.tonapps.blockchain.ton.contract.WalletFeature import com.tonapps.blockchain.ton.extensions.equalsAddress +import com.tonapps.blockchain.ton.extensions.isTestnetAddress import com.tonapps.extensions.MutableEffectFlow import com.tonapps.extensions.filterList import com.tonapps.extensions.state @@ -130,6 +131,8 @@ class SendViewModel( private val destinationFlow = userInputAddressFlow.map { address -> if (address.isEmpty()) { SendDestination.Empty + } else if (wallet.testnet != address.isTestnetAddress()) { + SendDestination.NotFound } else { getDestinationAccount(address, wallet.testnet) } diff --git a/apps/wallet/instance/app/src/main/java/com/tonapps/tonkeeper/ui/screen/wallet/picker/list/holder/WalletHolder.kt b/apps/wallet/instance/app/src/main/java/com/tonapps/tonkeeper/ui/screen/wallet/picker/list/holder/WalletHolder.kt index 293649a7f..366a4a39b 100644 --- a/apps/wallet/instance/app/src/main/java/com/tonapps/tonkeeper/ui/screen/wallet/picker/list/holder/WalletHolder.kt +++ b/apps/wallet/instance/app/src/main/java/com/tonapps/tonkeeper/ui/screen/wallet/picker/list/holder/WalletHolder.kt @@ -10,6 +10,7 @@ import androidx.appcompat.widget.AppCompatImageView import androidx.appcompat.widget.AppCompatTextView import com.tonapps.emoji.ui.EmojiView import com.tonapps.icu.CurrencyFormatter.withCustomSymbol +import com.tonapps.tonkeeper.extensions.fixW5Title import com.tonapps.tonkeeper.extensions.getWalletBadges import com.tonapps.tonkeeper.koin.accountRepository import com.tonapps.tonkeeper.ui.screen.name.edit.EditNameScreen @@ -42,7 +43,7 @@ class WalletHolder( override fun onBind(item: Item.Wallet) { colorView.backgroundTintList = ColorStateList.valueOf(item.color) emojiView.setEmoji(item.emoji, Color.TRANSPARENT) - nameView.text = item.name + nameView.text = item.name.fixW5Title() typesView.text = context.getWalletBadges(item.wallet.type, item.wallet.version) updatePosition(item) diff --git a/apps/wallet/instance/app/src/main/res/layout/fragment_nft.xml b/apps/wallet/instance/app/src/main/res/layout/fragment_nft.xml index 84be67c88..6eaafd579 100644 --- a/apps/wallet/instance/app/src/main/res/layout/fragment_nft.xml +++ b/apps/wallet/instance/app/src/main/res/layout/fragment_nft.xml @@ -64,17 +64,24 @@ android:background="@drawable/bg_content" android:orientation="vertical"> - + android:layout_height="wrap_content"> + + + + + + + + + Lottie WebView + + + + + + + \ No newline at end of file