diff --git a/core/res/src/main/res/values-de/strings.xml b/core/res/src/main/res/values-de/strings.xml index aabccb9ff7..d3c9f55037 100644 --- a/core/res/src/main/res/values-de/strings.xml +++ b/core/res/src/main/res/values-de/strings.xml @@ -278,7 +278,7 @@ Kann nicht gegen %s ausgetauscht werden Bereitgestellt von Status - Tangem bietet Token-Swaps über Drittanbieter gemäß den jeweiligen Bedingungen des jeweiligen Anbieters an. + Anbieter erleichtern Transaktionen Anbieter Es ist ein Fehler aufgetreten. Code: %s Fehler %1$s. Der ausgewählte Anbieter kann die angegebene Transaktion nicht verarbeiten. Bitte runde den Wert auf %2$s auf oder änder diesen. @@ -319,11 +319,11 @@ Verifizierung erforderlich Wartet auf Transaktions-Hash Liste aller Token, die deiner Wallet hinzugefügt wurden - Beste Preise werden abgerufen … + Aktuelle Preise werden abgerufen ... Variabler Zinssatz Durch die Nutzung der Swap-Funktion erklärst du dich mit den folgenden Bedingungen des Anbieters einverstanden %s Durch die Nutzung der Swap-Funktionalität erklärst du dich mit des Anbieters %1$s und %2$s einverstanden - Weitere Anbieter werden bald folgen.\nBleib dabei! + Weitere Anbieter folgen in Kürze Anbieter Bester Preis Verfügbar bis zu %s @@ -419,6 +419,7 @@ Dieses Asset wird derzeit in der Wallet nicht unterstützt. Dieses Asset ist für dieses Wallet nicht verfügbar Hinzufügen + APY %s Verfügbare Netzwerke Mein Portfolio Markt @@ -448,6 +449,9 @@ Top-Gewinner Top-Verlierer Beliebt + Staking ist der einfachste Weg, um Belohnungen für Deine Kryptowährung zu erhalten. %s + Mehr anzeigen + Verdiene bis zu %s APY Über %s %d börse @@ -530,6 +534,13 @@ Basisinformationen Netzwerk Vertragsadresse + Kontrollabschnitt + Kontrollabschnitt + Kontrollabschnitt + Kontrollabschnitt + Kontrollabschnitt + Kontrollabschnitt + Kontrollabschnitt Letzter Verkaufspreis Raritätsetikett Seltenheitsgrad @@ -1051,6 +1062,8 @@ Validierer: %s Minimum %s Der Mindesttransaktionsbetrag beträgt %1$s. + Die Netzwerkgebühren für beliebte Token im Tron-Netzwerk können höher sein. Das Staking von TRX kann helfen, die Transaktionskosten zu senken. + Spare bei den Tron-Netzwerkgebühren Versuche es erneut Du hast dieselbe Karte oder Ring gescannt. Um ein Zwillings-Wallet zu erstellen, musst du die Karte oder Ring mit der Nummer %d scannen. Du hast die falsche Doppelkarte oder Ring gescannt. Bitte versuche eine andere Karte oder Ring @@ -1237,6 +1250,7 @@ Zeitüberschreitungsfehler. Bitte versuche es später erneut. WalletConnect konnte nicht hergestellt werden Diese Domäne kann nicht verifiziert werden. Überprüfe die Anfrage sorgfältig und bestätige diese dann. + Geh zurück zu Deinem Browser und stell erneut eine Verbindung über WalletConnect her. WalletConnect-Sitzung wurde getrennt Fehlercode: %s. Wenn das Problem weiterhin besteht, wende Dich bitte an unseren Support. Wir haben einen unbekannten Fehler festgestellt. @@ -1244,14 +1258,22 @@ Nicht unterstützte Netzwerke Tangem unterstützt ein erforderliches Netzwerk um %s. Verifizierte Domain + Falsche Karte oder falscher Ring in der Tangem-App ausgewählt Wir haben eine Art Problem + Verbinden Netzwerk Netzwerke Wallet + Verbundene Netzwerke + Anzeige des Kontostands und der Aktivitäten in Deiner Wallet Signiere die Transaktionen ohne eine Vorankündigung Genehmigung für Transaktionen anfordern Wird nicht in der Lage sein, + Möchte + Verbindungsanfrage Verbindungen + Inhalt + Daten kopieren Alle trennen Text über die Trennung aller dApps Alle dApps trennen @@ -1262,6 +1284,11 @@ Keine Sitzungen Diese Domain wird von mehreren Sicherheitsanbietern als unsicher eingestuft. Verlasse diese umgehend, um Dein Vermögen zu schützen. Bekanntes Sicherheitsrisiko + Anfrage von + Art der Signatur + Transaktionsanfrage + Transaktionsanfrage + Wallet verbinden Verwerfen Du hast eine unterbrochene Sicherung. Möchtest du diese fortsetzen? Ja, fortsetzen diff --git a/core/res/src/main/res/values-ja/strings.xml b/core/res/src/main/res/values-ja/strings.xml index 31ae60add2..06e907a6d2 100644 --- a/core/res/src/main/res/values-ja/strings.xml +++ b/core/res/src/main/res/values-ja/strings.xml @@ -527,6 +527,13 @@ 基本情報 チェーン コントラクトアドレス + スタブ + スタブ + スタブ + スタブ + スタブ + スタブ + スタブ 最終販売価格 レアリティ・ラベル レアリティ・ランク @@ -1044,7 +1051,7 @@ バリデーター: %s 最小%s 最小取引金額は%1$sです。 - Tronネットワークの人気トークンの手数料は高めです。TRXをステーキングすると、より安く、あるいは無料で取引できます。 + Tronネットワークの人気トークンの手数料は高い可能性があります。TRXをステーキングすると、取引コストを削減できる可能性があります。 Tronネットワーク手数料を節約 もう一度やり直してください 同じカードをスキャンしました。ツインウォレットを作成するには、番号%dのカードをスキャンする必要があります。 @@ -1237,6 +1244,7 @@ 検証済みドメイン Tangemアプリで誤ったカードまたはリングが選択されました 問題が起きています + アドレス 接続する ネットワーク ネットワーク @@ -1249,6 +1257,8 @@ したい 接続リクエスト 接続 + 内容 + データをコピー すべての接続を解除する すべてのdAppsの接続解除に関するテキスト すべてのdAppを接続解除する @@ -1259,6 +1269,11 @@ セッションなし このドメインは複数のセキュリティプロバイダーから安全でないとの警告を受けています。あなたの資産を守るため、直ちにアクセスを中止してください。 既知のセキュリティリスク + リクエスト元 + 署名タイプ + 宛先 + 取引リクエスト + 取引リクエスト ウォレットコネクト 破棄 バックアップが中断されました。再開しますか? diff --git a/core/res/src/main/res/values/strings.xml b/core/res/src/main/res/values/strings.xml index b4b174998e..2081101d9d 100644 --- a/core/res/src/main/res/values/strings.xml +++ b/core/res/src/main/res/values/strings.xml @@ -1063,7 +1063,7 @@ validator: %s Minimum %s The minimum transaction amount is %1$s. - Tron network fees for popular tokens are higher. Stake some TRX for cheaper or free transactions. + Tron network fees for popular tokens can be higher. Staking TRX may help reduce transaction costs. Save on Tron network fees Try again You\'ve scanned the same card. To create a twin wallet you need to scan the card with number %d @@ -1305,6 +1305,7 @@ Verified domain Wrong card or ring selected in Tangem App We\'ve got some kind of problem + Address Connect Network Networks @@ -1331,6 +1332,7 @@ Known security risk Request from Signature Type + To Transaction request Transaction request Wallet connect diff --git a/core/ui/src/main/res/drawable/ic_fee_new_24.xml b/core/ui/src/main/res/drawable/ic_fee_new_24.xml new file mode 100644 index 0000000000..a644c488cf --- /dev/null +++ b/core/ui/src/main/res/drawable/ic_fee_new_24.xml @@ -0,0 +1,21 @@ + + + + + + diff --git a/core/ui/src/main/res/drawable/ic_user_square_24.xml b/core/ui/src/main/res/drawable/ic_user_square_24.xml new file mode 100644 index 0000000000..655ae700f5 --- /dev/null +++ b/core/ui/src/main/res/drawable/ic_user_square_24.xml @@ -0,0 +1,17 @@ + + + + + diff --git a/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/connections/routing/DefaultWcRoutingComponent.kt b/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/connections/routing/DefaultWcRoutingComponent.kt index 6a424d83be..45ccb328ab 100644 --- a/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/connections/routing/DefaultWcRoutingComponent.kt +++ b/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/connections/routing/DefaultWcRoutingComponent.kt @@ -16,7 +16,7 @@ import com.tangem.core.decompose.model.getOrCreateModel import com.tangem.core.ui.decompose.ComposableContentComponent import com.tangem.features.walletconnect.components.WcRoutingComponent import com.tangem.features.walletconnect.connections.components.WcAppInfoContainerComponent -import com.tangem.features.walletconnect.transaction.components.WcSignTransactionComponent +import com.tangem.features.walletconnect.transaction.components.WcSignTransactionContainerComponent import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject @@ -55,9 +55,9 @@ internal class DefaultWcRoutingComponent @AssistedInject constructor( router = model.innerRouter, ) return when (config) { - is WcInnerRoute.SignMessage -> WcSignTransactionComponent( + is WcInnerRoute.SignMessage -> WcSignTransactionContainerComponent( childContext, - params = WcSignTransactionComponent.Params(config.rawRequest), + params = WcSignTransactionContainerComponent.Params(config.rawRequest), ) is WcInnerRoute.Pair -> WcAppInfoContainerComponent( childContext, diff --git a/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/components/WcSignTransactionComponent.kt b/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/components/WcSignTransactionComponent.kt index 9ec9f43b8f..9ffe0a28d5 100644 --- a/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/components/WcSignTransactionComponent.kt +++ b/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/components/WcSignTransactionComponent.kt @@ -1,37 +1,28 @@ package com.tangem.features.walletconnect.transaction.components import androidx.compose.runtime.Composable -import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.tangem.core.decompose.context.AppComponentContext -import com.tangem.core.decompose.model.getOrCreateModel -import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig import com.tangem.core.ui.decompose.ComposableContentComponent -import com.tangem.domain.walletconnect.model.sdkcopy.WcSdkSessionRequest import com.tangem.features.walletconnect.transaction.model.WcSignTransactionModel -import com.tangem.features.walletconnect.transaction.ui.sign.WcSignTransactionModalBottomSheet +import com.tangem.features.walletconnect.transaction.ui.sign.WcSignTransactionModalBottomSheetContent internal class WcSignTransactionComponent( - appComponentContext: AppComponentContext, - params: Params, + private val appComponentContext: AppComponentContext, + private val model: WcSignTransactionModel, + private val transactionInfoOnClick: () -> Unit, ) : AppComponentContext by appComponentContext, ComposableContentComponent { - private val model: WcSignTransactionModel = getOrCreateModel(params) - @Composable override fun Content(modifier: Modifier) { - val content by model.uiState.collectAsStateWithLifecycle() - content?.let { - WcSignTransactionModalBottomSheet( - config = TangemBottomSheetConfig( - isShown = true, - onDismissRequest = it.actions.onDismiss, - content = it, - ), + val content = model.uiState.collectAsStateWithLifecycle().value + + if (content != null) { + WcSignTransactionModalBottomSheetContent( + state = content, + onClickTransactionRequest = transactionInfoOnClick, ) } } - - data class Params(val rawRequest: WcSdkSessionRequest) } \ No newline at end of file diff --git a/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/components/WcSignTransactionContainerComponent.kt b/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/components/WcSignTransactionContainerComponent.kt new file mode 100644 index 0000000000..7bfc3e7738 --- /dev/null +++ b/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/components/WcSignTransactionContainerComponent.kt @@ -0,0 +1,123 @@ +package com.tangem.features.walletconnect.transaction.components + +import androidx.compose.animation.animateContentSize +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.ui.Modifier +import com.arkivanov.decompose.ComponentContext +import com.arkivanov.decompose.extensions.compose.stack.Children +import com.arkivanov.decompose.extensions.compose.subscribeAsState +import com.arkivanov.decompose.router.stack.StackNavigation +import com.arkivanov.decompose.router.stack.childStack +import com.arkivanov.decompose.router.stack.navigate +import com.tangem.core.decompose.context.AppComponentContext +import com.tangem.core.decompose.context.childByContext +import com.tangem.core.decompose.model.getOrCreateModel +import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig +import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheet +import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheetTitle +import com.tangem.core.ui.decompose.ComposableContentComponent +import com.tangem.core.ui.extensions.resourceReference +import com.tangem.core.ui.res.TangemTheme +import com.tangem.domain.walletconnect.model.sdkcopy.WcSdkSessionRequest +import com.tangem.features.walletconnect.impl.R +import com.tangem.features.walletconnect.transaction.model.WcSignTransactionModel +import com.tangem.features.walletconnect.transaction.routes.WcSignTransactionRoutes + +internal class WcSignTransactionContainerComponent( + private val appComponentContext: AppComponentContext, + params: Params, +) : AppComponentContext by appComponentContext, ComposableContentComponent { + + private val model: WcSignTransactionModel = getOrCreateModel(params = params) + private val contentNavigation = StackNavigation() + private val contentStack = childStack( + source = contentNavigation, + serializer = WcSignTransactionRoutes.serializer(), + initialConfiguration = WcSignTransactionRoutes.Transaction, + childFactory = ::screenChild, + ) + + private fun dismiss() { + model.dismiss() + } + + @Composable + override fun Content(modifier: Modifier) { + val content by contentStack.subscribeAsState() + TangemModalBottomSheet( + config = TangemBottomSheetConfig( + isShown = true, + onDismissRequest = ::dismiss, + content = content.active.configuration, + ), + containerColor = TangemTheme.colors.background.tertiary, + title = { config -> Title(route = config) }, + content = { + Box( + modifier = Modifier + .fillMaxWidth() + .animateContentSize(), + ) { + Children(stack = content) { child -> + child.instance.Content(modifier = Modifier) + } + } + }, + ) + } + + @Composable + private fun Title(route: WcSignTransactionRoutes) { + TangemModalBottomSheetTitle( + title = resourceReference(R.string.wc_wallet_connect), + startIconRes = when (route) { + is WcSignTransactionRoutes.Transaction -> null + else -> R.drawable.ic_back_24 + }, + onStartClick = when (route) { + is WcSignTransactionRoutes.Transaction -> null + else -> ::toTransaction + }, + endIconRes = when (route) { + is WcSignTransactionRoutes.Transaction -> R.drawable.ic_close_24 + else -> null + }, + onEndClick = when (route) { + is WcSignTransactionRoutes.Transaction -> ::dismiss + else -> null + }, + ) + } + + private fun toTransactionRequestInfo() { + contentNavigation.navigate { + listOf(WcSignTransactionRoutes.TransactionRequestInfo) + } + } + + private fun toTransaction() { + contentNavigation.navigate { + listOf(WcSignTransactionRoutes.Transaction) + } + } + + private fun screenChild( + config: WcSignTransactionRoutes, + componentContext: ComponentContext, + ): ComposableContentComponent = when (config) { + is WcSignTransactionRoutes.Transaction -> WcSignTransactionComponent( + appComponentContext = childByContext(componentContext), + model = model, + transactionInfoOnClick = ::toTransactionRequestInfo, + ) + is WcSignTransactionRoutes.TransactionRequestInfo -> WcSignTransactionRequestInfoComponent( + appComponentContext = childByContext(componentContext), + model = model, + ) + } + + data class Params(val rawRequest: WcSdkSessionRequest) +} \ No newline at end of file diff --git a/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/components/WcSignTransactionRequestInfoComponent.kt b/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/components/WcSignTransactionRequestInfoComponent.kt new file mode 100644 index 0000000000..7563b8a646 --- /dev/null +++ b/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/components/WcSignTransactionRequestInfoComponent.kt @@ -0,0 +1,24 @@ +package com.tangem.features.walletconnect.transaction.components + +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.lifecycle.compose.collectAsStateWithLifecycle +import com.tangem.core.decompose.context.AppComponentContext +import com.tangem.core.ui.decompose.ComposableContentComponent +import com.tangem.features.walletconnect.transaction.model.WcSignTransactionModel +import com.tangem.features.walletconnect.transaction.ui.common.TransactionRequestInfoContent + +internal class WcSignTransactionRequestInfoComponent( + private val appComponentContext: AppComponentContext, + private val model: WcSignTransactionModel, +) : AppComponentContext by appComponentContext, ComposableContentComponent { + + @Composable + override fun Content(modifier: Modifier) { + val content = model.uiState.collectAsStateWithLifecycle().value + + if (content != null) { + TransactionRequestInfoContent(content) + } + } +} \ No newline at end of file diff --git a/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/entity/WcSignTransactionUM.kt b/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/entity/WcSignTransactionUM.kt index 3f796ce6b1..77379d44e1 100644 --- a/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/entity/WcSignTransactionUM.kt +++ b/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/entity/WcSignTransactionUM.kt @@ -8,19 +8,10 @@ import kotlinx.collections.immutable.ImmutableList @Immutable internal data class WcSignTransactionUM( - @DrawableRes val startIconRes: Int, - @DrawableRes val endIconRes: Int, - @DrawableRes val transactionIconRes: Int, val actions: WcTransactionActionsUM, - val state: State = State.TRANSACTION, val transaction: WcTransactionUM, val transactionRequestInfo: WcTransactionRequestInfoUM, -) : TangemBottomSheetConfigContent { - - enum class State { - TRANSACTION, TRANSACTION_REQUEST_INFO - } -} +) : TangemBottomSheetConfigContent @Immutable internal data class WcTransactionUM( @@ -30,26 +21,31 @@ internal data class WcTransactionUM( val appSubtitle: String, val walletName: String, val networkInfo: WcNetworkInfoUM, + val addressText: String? = null, + val networkFee: String? = null, val isLoading: Boolean = false, ) @Immutable internal data class WcTransactionRequestInfoUM( + val blocks: ImmutableList, +) + +@Immutable +internal data class WcTransactionRequestBlockUM( val info: ImmutableList, ) @Immutable internal data class WcTransactionRequestInfoItemUM( val title: TextReference, - val description: String, + val description: String = "", ) @Immutable internal data class WcTransactionActionsUM( - val transactionRequestOnClick: () -> Unit, val onDismiss: () -> Unit, val onSign: () -> Unit, - val onBack: () -> Unit, val onCopy: () -> Unit, ) diff --git a/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/model/WcSignTransactionModel.kt b/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/model/WcSignTransactionModel.kt index e5b5c90b30..ed6ea36064 100644 --- a/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/model/WcSignTransactionModel.kt +++ b/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/model/WcSignTransactionModel.kt @@ -10,7 +10,7 @@ import com.tangem.domain.walletconnect.WcRequestUseCaseFactory import com.tangem.domain.walletconnect.usecase.method.WcSignState import com.tangem.domain.walletconnect.usecase.method.WcSignStep import com.tangem.domain.walletconnect.usecase.method.WcSignUseCase -import com.tangem.features.walletconnect.transaction.components.WcSignTransactionComponent +import com.tangem.features.walletconnect.transaction.components.WcSignTransactionContainerComponent import com.tangem.features.walletconnect.transaction.entity.WcSignTransactionUM import com.tangem.features.walletconnect.transaction.entity.WcTransactionActionsUM import com.tangem.features.walletconnect.transaction.utils.toUM @@ -35,7 +35,7 @@ internal class WcSignTransactionModel @Inject constructor( private val _uiState = MutableStateFlow(null) val uiState: StateFlow = _uiState - private val params = paramsContainer.require() + private val params = paramsContainer.require() init { modelScope.launch { @@ -47,10 +47,8 @@ internal class WcSignTransactionModel @Inject constructor( signState = signState, actions = WcTransactionActionsUM( onDismiss = { cancel(useCase) }, - onBack = ::showTransactionState, onSign = useCase::sign, onCopy = { copyData(useCase.rawSdkRequest.request.params) }, - transactionRequestOnClick = ::showTransactionRequestState, ), ) _uiState.emit(signTransactionUM) @@ -59,6 +57,10 @@ internal class WcSignTransactionModel @Inject constructor( } } + fun dismiss() { + _uiState.value?.actions?.onDismiss?.invoke() ?: router.pop() + } + private fun signingIsDone(signState: WcSignState<*>): Boolean { (signState.domainStep as? WcSignStep.Result)?.result?.let { router.pop() @@ -75,12 +77,4 @@ internal class WcSignTransactionModel @Inject constructor( private fun copyData(text: String) { clipboardManager.setText(text = text, isSensitive = true) } - - private fun showTransactionRequestState() { - _uiState.value = _uiState.value?.copy(state = WcSignTransactionUM.State.TRANSACTION_REQUEST_INFO) - } - - private fun showTransactionState() { - _uiState.value = _uiState.value?.copy(state = WcSignTransactionUM.State.TRANSACTION) - } } \ No newline at end of file diff --git a/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/routes/WcSignTransactionRoutes.kt b/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/routes/WcSignTransactionRoutes.kt new file mode 100644 index 0000000000..6c5c1d9fa8 --- /dev/null +++ b/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/routes/WcSignTransactionRoutes.kt @@ -0,0 +1,15 @@ +package com.tangem.features.walletconnect.transaction.routes + +import androidx.compose.runtime.Immutable +import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfigContent +import kotlinx.serialization.Serializable + +@Serializable +@Immutable +internal sealed class WcSignTransactionRoutes : TangemBottomSheetConfigContent { + @Serializable + data object Transaction : WcSignTransactionRoutes() + + @Serializable + data object TransactionRequestInfo : WcSignTransactionRoutes() +} \ No newline at end of file diff --git a/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/ui/common/TransactionRequestInfoContent.kt b/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/ui/common/TransactionRequestInfoContent.kt index d7c61d3af8..382da28e98 100644 --- a/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/ui/common/TransactionRequestInfoContent.kt +++ b/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/ui/common/TransactionRequestInfoContent.kt @@ -1,53 +1,94 @@ package com.tangem.features.walletconnect.transaction.ui.common +import android.content.res.Configuration import androidx.compose.foundation.background import androidx.compose.foundation.layout.* +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip +import androidx.compose.ui.platform.LocalConfiguration +import androidx.compose.ui.tooling.preview.Devices +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.tooling.preview.PreviewParameter +import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider import androidx.compose.ui.unit.dp import com.tangem.core.ui.components.SecondaryButtonIconEnd +import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig +import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheet +import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheetTitle import com.tangem.core.ui.extensions.resolveReference +import com.tangem.core.ui.extensions.resourceReference import com.tangem.core.ui.extensions.stringResourceSafe import com.tangem.core.ui.res.TangemTheme +import com.tangem.core.ui.res.TangemThemePreview import com.tangem.features.walletconnect.impl.R +import com.tangem.features.walletconnect.transaction.entity.* +import com.tangem.features.walletconnect.transaction.entity.WcNetworkInfoUM import com.tangem.features.walletconnect.transaction.entity.WcSignTransactionUM +import com.tangem.features.walletconnect.transaction.entity.WcTransactionActionsUM +import com.tangem.features.walletconnect.transaction.entity.WcTransactionRequestInfoUM +import com.tangem.features.walletconnect.transaction.entity.WcTransactionUM +import kotlinx.collections.immutable.persistentListOf + +private const val MIN_HEIGHT_SCREEN_PERCENT = 0.35f +private const val MAX_HEIGHT_SCREEN_PERCENT = 0.75f @Composable internal fun TransactionRequestInfoContent(state: WcSignTransactionUM) { + val screenHeight = LocalConfiguration.current.screenHeightDp + val minHeight = (screenHeight * MIN_HEIGHT_SCREEN_PERCENT).dp + val maxHeight = (screenHeight * MAX_HEIGHT_SCREEN_PERCENT).dp + Box( modifier = Modifier .fillMaxWidth() - .heightIn(min = 310.dp) + .heightIn(min = minHeight, max = maxHeight) .padding(horizontal = TangemTheme.dimens.spacing16), ) { - Column( + LazyColumn( modifier = Modifier - .fillMaxWidth() - .clip(RoundedCornerShape(TangemTheme.dimens.radius16)) - .background(TangemTheme.colors.background.action) - .padding( - start = TangemTheme.dimens.spacing16, - end = TangemTheme.dimens.spacing16, - bottom = TangemTheme.dimens.spacing20, - ), + .fillMaxWidth(), + contentPadding = PaddingValues(top = TangemTheme.dimens.spacing8, bottom = TangemTheme.dimens.spacing70), ) { - state.transactionRequestInfo.info.forEach { item -> - Text( - text = item.title.resolveReference(), - modifier = Modifier.padding(top = TangemTheme.dimens.spacing20), - style = TangemTheme.typography.subtitle2, - color = TangemTheme.colors.text.tertiary, - ) - Text( - text = item.description, - modifier = Modifier.padding(top = TangemTheme.dimens.spacing4), - style = TangemTheme.typography.body2, - color = TangemTheme.colors.text.primary1, - ) + items(state.transactionRequestInfo.blocks) { block -> + Column( + modifier = Modifier + .fillMaxWidth() + .clip(RoundedCornerShape(TangemTheme.dimens.radius16)) + .background(TangemTheme.colors.background.action) + .padding( + start = TangemTheme.dimens.spacing16, + end = TangemTheme.dimens.spacing16, + top = TangemTheme.dimens.spacing20, + ), + ) { + block.info.forEach { item -> + Text( + text = item.title.resolveReference(), + style = TangemTheme.typography.subtitle2, + color = TangemTheme.colors.text.tertiary, + ) + if (item.description.isNotEmpty()) { + Text( + text = item.description, + modifier = Modifier.padding( + top = TangemTheme.dimens.spacing4, + bottom = TangemTheme.dimens.spacing20, + ), + style = TangemTheme.typography.body2, + color = TangemTheme.colors.text.primary1, + ) + } else { + Spacer(modifier = Modifier.size(TangemTheme.dimens.size12)) + } + } + } + Spacer(modifier = Modifier.size(TangemTheme.dimens.size20)) } } @@ -61,4 +102,118 @@ internal fun TransactionRequestInfoContent(state: WcSignTransactionUM) { iconResId = R.drawable.ic_copy_24, ) } -} \ No newline at end of file +} + +@Composable +@Preview(showBackground = true, device = Devices.PIXEL_7_PRO) +@Preview(showBackground = true, device = Devices.PIXEL_7_PRO, uiMode = Configuration.UI_MODE_NIGHT_YES) +private fun WcSignTransactionRequestInfoBottomSheetPreview( + @PreviewParameter(WcSignTransactionStateProvider::class) state: WcSignTransactionUM, +) { + TangemThemePreview { + TangemModalBottomSheet( + config = TangemBottomSheetConfig( + isShown = true, + onDismissRequest = {}, + content = state, + ), + containerColor = TangemTheme.colors.background.tertiary, + title = { + TangemModalBottomSheetTitle( + title = resourceReference(R.string.wc_transaction_request_title), + endIconRes = null, + onEndClick = {}, + startIconRes = R.drawable.ic_back_24, + onStartClick = {}, + ) + }, + content = { + TransactionRequestInfoContent(state = state) + }, + ) + } +} + +private class WcSignTransactionStateProvider : CollectionPreviewParameterProvider( + listOf( + WcSignTransactionUM( + transaction = WcTransactionUM( + appName = "React App", + appIcon = "", + isVerified = true, + appSubtitle = "react-app.walletconnect.com", + walletName = "Tangem 2.0", + networkInfo = WcNetworkInfoUM(name = "Ethereum", iconRes = R.drawable.img_eth_22), + ), + transactionRequestInfo = WcTransactionRequestInfoUM( + blocks = persistentListOf( + WcTransactionRequestBlockUM( + persistentListOf( + WcTransactionRequestInfoItemUM( + title = resourceReference(R.string.wc_signature_type), + description = "personal_sign", + ), + WcTransactionRequestInfoItemUM( + title = resourceReference(R.string.wc_contents), + description = "Hello! My name is John Dow. test@tange.com", + ), + ), + ), + ), + ), + actions = WcTransactionActionsUM( + onDismiss = {}, + onSign = {}, + onCopy = {}, + ), + ), + WcSignTransactionUM( + transaction = WcTransactionUM( + appName = "React App", + appIcon = "", + isVerified = true, + appSubtitle = "react-app.walletconnect.com", + walletName = "Tangem 2.0", + networkInfo = WcNetworkInfoUM(name = "Ethereum", iconRes = R.drawable.img_eth_22), + addressText = "0x345FF...34FA", + networkFee = "~ 0.22 $", + ), + transactionRequestInfo = WcTransactionRequestInfoUM( + blocks = persistentListOf( + WcTransactionRequestBlockUM( + persistentListOf( + WcTransactionRequestInfoItemUM( + title = resourceReference(R.string.wc_signature_type), + description = "personal_sign", + ), + WcTransactionRequestInfoItemUM( + title = resourceReference(R.string.wc_contents), + description = "Hello! My name is John Dow. test@tange.com", + ), + ), + ), + WcTransactionRequestBlockUM( + persistentListOf( + WcTransactionRequestInfoItemUM( + title = resourceReference(R.string.wc_transaction_info_to_title), + ), + WcTransactionRequestInfoItemUM( + title = resourceReference(R.string.settings_wallet_name_title), + description = "Bob", + ), + WcTransactionRequestInfoItemUM( + title = resourceReference(R.string.wc_common_wallet), + description = "0xCD2a3d9F938E13CD947Ec05AbC7FE734Df8DD826", + ), + ), + ), + ), + ), + actions = WcTransactionActionsUM( + onDismiss = {}, + onSign = {}, + onCopy = {}, + ), + ), + ), +) \ No newline at end of file diff --git a/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/ui/common/WcAddressItem.kt b/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/ui/common/WcAddressItem.kt new file mode 100644 index 0000000000..8e9febc9b2 --- /dev/null +++ b/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/ui/common/WcAddressItem.kt @@ -0,0 +1,44 @@ +package com.tangem.features.walletconnect.transaction.ui.common + +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.material3.Icon +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.text.style.TextAlign +import com.tangem.core.ui.extensions.stringResourceSafe +import com.tangem.core.ui.res.TangemTheme +import com.tangem.features.walletconnect.impl.R + +@Composable +internal fun WcAddressItem(addressText: String, modifier: Modifier = Modifier) { + Row(modifier = modifier, verticalAlignment = Alignment.CenterVertically) { + Icon( + modifier = Modifier.size(TangemTheme.dimens.size24), + painter = painterResource(R.drawable.ic_user_square_24), + contentDescription = null, + tint = TangemTheme.colors.icon.accent, + ) + Text( + modifier = Modifier + .padding(start = TangemTheme.dimens.spacing8) + .weight(1f), + text = stringResourceSafe(R.string.wc_common_address), + style = TangemTheme.typography.body1, + color = TangemTheme.colors.text.primary1, + ) + Text( + modifier = Modifier + .padding(start = TangemTheme.dimens.spacing16) + .weight(1f), + text = addressText, + textAlign = TextAlign.End, + style = TangemTheme.typography.body1, + color = TangemTheme.colors.text.tertiary, + ) + } +} \ No newline at end of file diff --git a/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/ui/common/WcNetworkFeeItem.kt b/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/ui/common/WcNetworkFeeItem.kt new file mode 100644 index 0000000000..bb4c1867c5 --- /dev/null +++ b/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/ui/common/WcNetworkFeeItem.kt @@ -0,0 +1,67 @@ +package com.tangem.features.walletconnect.transaction.ui.common + +import androidx.compose.foundation.layout.* +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.material3.Icon +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.res.painterResource +import com.tangem.core.ui.extensions.stringResourceSafe +import com.tangem.core.ui.res.TangemTheme +import com.tangem.features.walletconnect.impl.R + +@Composable +internal fun WcNetworkFeeItem(networkFeeText: String, modifier: Modifier = Modifier) { + Row( + modifier = modifier, + verticalAlignment = Alignment.CenterVertically, + ) { + Icon( + modifier = Modifier.size(TangemTheme.dimens.size24), + painter = painterResource(R.drawable.ic_fee_new_24), + contentDescription = null, + tint = TangemTheme.colors.icon.accent, + ) + + Text( + modifier = Modifier.padding(start = TangemTheme.dimens.spacing8), + text = stringResourceSafe(R.string.common_network_fee_title), + style = TangemTheme.typography.body1, + color = TangemTheme.colors.text.primary1, + ) + + Icon( + modifier = Modifier + .padding(start = TangemTheme.dimens.spacing6) + .size(TangemTheme.dimens.size16), + painter = painterResource(id = R.drawable.ic_information_24), + tint = TangemTheme.colors.icon.informative, + contentDescription = null, + ) + + Spacer(modifier = Modifier.weight(1f)) + + Row( + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.End, + ) { + Text( + text = networkFeeText, + style = TangemTheme.typography.body1, + color = TangemTheme.colors.text.tertiary, + ) + Spacer(modifier = Modifier.width(TangemTheme.dimens.spacing6)) + Icon( + modifier = Modifier + .clip(CircleShape) + .size(width = TangemTheme.dimens.size18, height = TangemTheme.dimens.size24), + painter = painterResource(id = R.drawable.ic_select_18_24), + tint = TangemTheme.colors.icon.informative, + contentDescription = null, + ) + } + } +} \ No newline at end of file diff --git a/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/ui/common/WcNetworkItem.kt b/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/ui/common/WcNetworkItem.kt index 1f337688aa..58c62d0366 100644 --- a/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/ui/common/WcNetworkItem.kt +++ b/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/ui/common/WcNetworkItem.kt @@ -30,7 +30,7 @@ internal fun WcNetworkItem(networkInfo: WcNetworkInfoUM, modifier: Modifier = Mo ) Text( modifier = Modifier - .padding(start = TangemTheme.dimens.spacing4) + .padding(start = TangemTheme.dimens.spacing8) .weight(1f), text = stringResourceSafe(R.string.wc_common_network), style = TangemTheme.typography.body1, diff --git a/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/ui/common/WcWalletItem.kt b/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/ui/common/WcWalletItem.kt index 63633a22c1..18babacc67 100644 --- a/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/ui/common/WcWalletItem.kt +++ b/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/ui/common/WcWalletItem.kt @@ -25,7 +25,7 @@ internal fun WcWalletItem(walletName: String, modifier: Modifier = Modifier) { ) Text( modifier = Modifier - .padding(start = TangemTheme.dimens.spacing4) + .padding(start = TangemTheme.dimens.spacing8) .weight(1f), text = stringResourceSafe(R.string.manage_tokens_network_selector_wallet), style = TangemTheme.typography.body1, diff --git a/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/ui/sign/WcSignTransactionModalBottomSheet.kt b/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/ui/sign/WcSignTransactionModalBottomSheet.kt deleted file mode 100644 index 665eb497b3..0000000000 --- a/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/ui/sign/WcSignTransactionModalBottomSheet.kt +++ /dev/null @@ -1,154 +0,0 @@ -package com.tangem.features.walletconnect.transaction.ui.sign - -import android.content.res.Configuration -import androidx.compose.animation.animateContentSize -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.runtime.Composable -import androidx.compose.ui.Modifier -import androidx.compose.ui.tooling.preview.Devices -import androidx.compose.ui.tooling.preview.Preview -import androidx.compose.ui.tooling.preview.PreviewParameter -import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider -import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig -import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheet -import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheetTitle -import com.tangem.core.ui.extensions.resourceReference -import com.tangem.core.ui.res.TangemTheme -import com.tangem.core.ui.res.TangemThemePreview -import com.tangem.features.walletconnect.impl.R -import com.tangem.features.walletconnect.transaction.entity.* -import com.tangem.features.walletconnect.transaction.ui.common.TransactionRequestInfoContent -import kotlinx.collections.immutable.persistentListOf - -@Composable -internal fun WcSignTransactionModalBottomSheet(config: TangemBottomSheetConfig) { - TangemModalBottomSheet( - config = config, - containerColor = TangemTheme.colors.background.tertiary, - title = { state -> - TangemModalBottomSheetTitle( - title = when (state.state) { - WcSignTransactionUM.State.TRANSACTION -> { - resourceReference(R.string.wallet_connect_title) - } - WcSignTransactionUM.State.TRANSACTION_REQUEST_INFO -> { - resourceReference(R.string.wc_transaction_request_title) - } - }, - endIconRes = state.endIconRes.takeIf { - state.state == WcSignTransactionUM.State.TRANSACTION - }, - onEndClick = state.actions.onDismiss, - startIconRes = state.startIconRes.takeIf { - state.state == WcSignTransactionUM.State.TRANSACTION_REQUEST_INFO - }, - onStartClick = state.actions.onBack, - ) - }, - content = { state -> - Box( - modifier = Modifier - .fillMaxWidth() - .animateContentSize(), - ) { - when (state.state) { - WcSignTransactionUM.State.TRANSACTION -> { - WcSignTransactionModalBottomSheetContent(state) - } - WcSignTransactionUM.State.TRANSACTION_REQUEST_INFO -> { - TransactionRequestInfoContent(state) - } - } - } - }, - ) -} - -@Composable -@Preview(showBackground = true, device = Devices.PIXEL_7_PRO) -@Preview(showBackground = true, device = Devices.PIXEL_7_PRO, uiMode = Configuration.UI_MODE_NIGHT_YES) -private fun WcSignTransactionBottomSheetPreview( - @PreviewParameter(WcSignTransactionStateProvider::class) state: WcSignTransactionUM, -) { - TangemThemePreview { - WcSignTransactionModalBottomSheet( - config = TangemBottomSheetConfig( - isShown = true, - onDismissRequest = {}, - content = state, - ), - ) - } -} - -private class WcSignTransactionStateProvider : CollectionPreviewParameterProvider( - listOf( - WcSignTransactionUM( - startIconRes = R.drawable.ic_back_24, - endIconRes = R.drawable.ic_close_24, - transactionIconRes = R.drawable.ic_doc_new_24, - state = WcSignTransactionUM.State.TRANSACTION, - transaction = WcTransactionUM( - appName = "React App", - appIcon = "", - isVerified = true, - appSubtitle = "react-app.walletconnect.com", - walletName = "Tangem 2.0", - networkInfo = WcNetworkInfoUM(name = "Ethereum", iconRes = R.drawable.img_eth_22), - ), - transactionRequestInfo = WcTransactionRequestInfoUM( - persistentListOf( - WcTransactionRequestInfoItemUM( - title = resourceReference(R.string.wc_signature_type), - description = "personal_sign", - ), - WcTransactionRequestInfoItemUM( - title = resourceReference(R.string.wc_contents), - description = "Hello! My name is John Dow. test@tange.com", - ), - ), - ), - actions = WcTransactionActionsUM( - onDismiss = {}, - onBack = {}, - onSign = {}, - onCopy = {}, - transactionRequestOnClick = {}, - ), - ), - WcSignTransactionUM( - startIconRes = R.drawable.ic_back_24, - endIconRes = R.drawable.ic_close_24, - transactionIconRes = R.drawable.ic_doc_new_24, - state = WcSignTransactionUM.State.TRANSACTION_REQUEST_INFO, - transaction = WcTransactionUM( - appName = "React App", - appIcon = "", - isVerified = true, - appSubtitle = "react-app.walletconnect.com", - walletName = "Tangem 2.0", - networkInfo = WcNetworkInfoUM(name = "Ethereum", iconRes = R.drawable.img_eth_22), - ), - transactionRequestInfo = WcTransactionRequestInfoUM( - persistentListOf( - WcTransactionRequestInfoItemUM( - title = resourceReference(R.string.wc_signature_type), - description = "personal_sign", - ), - WcTransactionRequestInfoItemUM( - title = resourceReference(R.string.wc_contents), - description = "Hello! My name is John Dow. test@tange.com", - ), - ), - ), - actions = WcTransactionActionsUM( - onDismiss = {}, - onBack = {}, - onSign = {}, - onCopy = {}, - transactionRequestOnClick = {}, - ), - ), - ), -) \ No newline at end of file diff --git a/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/ui/sign/WcSignTransactionModalBottomSheetContent.kt b/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/ui/sign/WcSignTransactionModalBottomSheetContent.kt index 7548486b13..398d71924e 100644 --- a/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/ui/sign/WcSignTransactionModalBottomSheetContent.kt +++ b/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/ui/sign/WcSignTransactionModalBottomSheetContent.kt @@ -1,5 +1,6 @@ package com.tangem.features.walletconnect.transaction.ui.sign +import android.content.res.Configuration import androidx.compose.animation.animateContentSize import androidx.compose.foundation.background import androidx.compose.foundation.clickable @@ -11,18 +12,33 @@ import androidx.compose.material3.HorizontalDivider import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip +import androidx.compose.ui.tooling.preview.Devices +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.tooling.preview.PreviewParameter +import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp +import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig +import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheet +import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheetTitle +import com.tangem.core.ui.extensions.resourceReference import com.tangem.core.ui.res.TangemTheme +import com.tangem.core.ui.res.TangemThemePreview import com.tangem.features.walletconnect.connections.ui.WcAppInfoItem -import com.tangem.features.walletconnect.transaction.entity.WcSignTransactionUM +import com.tangem.features.walletconnect.impl.R +import com.tangem.features.walletconnect.transaction.entity.* import com.tangem.features.walletconnect.transaction.ui.common.* -import com.tangem.features.walletconnect.transaction.ui.common.WcNetworkItem -import com.tangem.features.walletconnect.transaction.ui.common.WcTransactionRequestButtons -import com.tangem.features.walletconnect.transaction.ui.common.WcTransactionRequestItem -import com.tangem.features.walletconnect.transaction.ui.common.WcWalletItem +import kotlinx.collections.immutable.persistentListOf @Composable -internal fun WcSignTransactionModalBottomSheetContent(state: WcSignTransactionUM) { - Column(modifier = Modifier.padding(horizontal = TangemTheme.dimens.spacing16)) { +internal fun WcSignTransactionModalBottomSheetContent( + state: WcSignTransactionUM, + onClickTransactionRequest: () -> Unit, +) { + Column( + modifier = Modifier + .padding(horizontal = TangemTheme.dimens.spacing16), + ) { Column( modifier = Modifier .clip(RoundedCornerShape(TangemTheme.dimens.radius14)) @@ -37,47 +53,17 @@ internal fun WcSignTransactionModalBottomSheetContent(state: WcSignTransactionUM subtitle = state.transaction.appSubtitle, isVerified = state.transaction.isVerified, ) - HorizontalDivider( - thickness = TangemTheme.dimens.size1, - color = TangemTheme.colors.stroke.primary, - ) + DividerWithPadding(start = 0.dp, end = 0.dp) WcTransactionRequestItem( - iconRes = state.transactionIconRes, + iconRes = R.drawable.ic_doc_new_24, modifier = Modifier .fillMaxWidth() - .clickable { state.actions.transactionRequestOnClick() } + .clickable { onClickTransactionRequest() } .padding(TangemTheme.dimens.spacing12), ) } Column(modifier = Modifier.padding(top = TangemTheme.dimens.spacing16)) { - Column( - modifier = Modifier - .clip(RoundedCornerShape(TangemTheme.dimens.radius14)) - .background(color = TangemTheme.colors.background.action) - .fillMaxWidth() - .animateContentSize(), - ) { - val itemsModifier = Modifier - .fillMaxWidth() - .padding(TangemTheme.dimens.spacing12) - - HorizontalDivider( - thickness = TangemTheme.dimens.size1, - color = TangemTheme.colors.stroke.primary, - ) - WcWalletItem( - modifier = itemsModifier, - walletName = state.transaction.walletName, - ) - HorizontalDivider( - thickness = TangemTheme.dimens.size1, - color = TangemTheme.colors.stroke.primary, - ) - WcNetworkItem( - modifier = itemsModifier, - networkInfo = state.transaction.networkInfo, - ) - } + WcSignTransactionItems(state) WcTransactionRequestButtons( modifier = Modifier.padding(vertical = TangemTheme.dimens.spacing16), onDismiss = state.actions.onDismiss, @@ -86,4 +72,125 @@ internal fun WcSignTransactionModalBottomSheetContent(state: WcSignTransactionUM ) } } -} \ No newline at end of file +} + +@Composable +private fun WcSignTransactionItems(state: WcSignTransactionUM) { + Column( + modifier = Modifier + .clip(RoundedCornerShape(TangemTheme.dimens.radius14)) + .background(color = TangemTheme.colors.background.action) + .fillMaxWidth() + .animateContentSize(), + ) { + val itemsModifier = Modifier + .fillMaxWidth() + .padding(TangemTheme.dimens.spacing12) + + DividerWithPadding(start = 0.dp, end = 0.dp) + WcWalletItem( + modifier = itemsModifier, + walletName = state.transaction.walletName, + ) + DividerWithPadding(start = TangemTheme.dimens.spacing40, end = TangemTheme.dimens.spacing12) + WcNetworkItem( + modifier = itemsModifier, + networkInfo = state.transaction.networkInfo, + ) + if (!state.transaction.addressText.isNullOrEmpty()) { + DividerWithPadding(start = TangemTheme.dimens.spacing40, end = TangemTheme.dimens.spacing12) + WcAddressItem( + modifier = itemsModifier, + addressText = state.transaction.addressText, + ) + } + if (!state.transaction.networkFee.isNullOrEmpty()) { + DividerWithPadding(start = TangemTheme.dimens.spacing40, end = TangemTheme.dimens.spacing12) + WcNetworkFeeItem( + modifier = itemsModifier, + networkFeeText = state.transaction.networkFee, + ) + } + } +} + +@Composable +private fun DividerWithPadding(start: Dp, end: Dp) { + HorizontalDivider( + modifier = Modifier.padding( + start = start, + end = end, + ), + thickness = TangemTheme.dimens.size1, + color = TangemTheme.colors.stroke.primary, + ) +} + +@Composable +@Preview(showBackground = true, device = Devices.PIXEL_7_PRO) +@Preview(showBackground = true, device = Devices.PIXEL_7_PRO, uiMode = Configuration.UI_MODE_NIGHT_YES) +private fun WcSignTransactionBottomSheetPreview( + @PreviewParameter(WcSignTransactionStateProvider::class) state: WcSignTransactionUM, +) { + TangemThemePreview { + TangemModalBottomSheet( + config = TangemBottomSheetConfig( + isShown = true, + onDismissRequest = {}, + content = state, + ), + containerColor = TangemTheme.colors.background.tertiary, + title = { + TangemModalBottomSheetTitle( + title = resourceReference(R.string.wallet_connect_title), + endIconRes = R.drawable.ic_close_24, + onEndClick = {}, + startIconRes = null, + onStartClick = {}, + ) + }, + content = { + WcSignTransactionModalBottomSheetContent(state = state, onClickTransactionRequest = {}) + }, + ) + } +} + +private class WcSignTransactionStateProvider : CollectionPreviewParameterProvider( + listOf( + WcSignTransactionUM( + transaction = WcTransactionUM( + appName = "React App", + appIcon = "", + isVerified = true, + appSubtitle = "react-app.walletconnect.com", + walletName = "Tangem 2.0", + networkInfo = WcNetworkInfoUM(name = "Ethereum", iconRes = R.drawable.img_eth_22), + ), + transactionRequestInfo = WcTransactionRequestInfoUM(persistentListOf()), + actions = WcTransactionActionsUM( + onDismiss = {}, + onSign = {}, + onCopy = {}, + ), + ), + WcSignTransactionUM( + transaction = WcTransactionUM( + appName = "React App", + appIcon = "", + isVerified = true, + appSubtitle = "react-app.walletconnect.com", + walletName = "Tangem 2.0", + networkInfo = WcNetworkInfoUM(name = "Ethereum", iconRes = R.drawable.img_eth_22), + addressText = "0x345FF...34FA", + networkFee = "~ 0.22 $", + ), + transactionRequestInfo = WcTransactionRequestInfoUM(persistentListOf()), + actions = WcTransactionActionsUM( + onDismiss = {}, + onSign = {}, + onCopy = {}, + ), + ), + ), +) \ No newline at end of file diff --git a/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/utils/WalletAddressUtils.kt b/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/utils/WalletAddressUtils.kt new file mode 100644 index 0000000000..a51a5d82f7 --- /dev/null +++ b/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/utils/WalletAddressUtils.kt @@ -0,0 +1,7 @@ +package com.tangem.features.walletconnect.transaction.utils + +const val ADDRESS_FIRST_PART_LENGTH = 7 +const val ADDRESS_SECOND_PART_LENGTH = 4 + +internal fun String.toShortAddressText() = + "${take(ADDRESS_FIRST_PART_LENGTH)}...${takeLast(ADDRESS_SECOND_PART_LENGTH)}" \ No newline at end of file diff --git a/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/utils/WcSignTransactionUtils.kt b/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/utils/WcSignTransactionUtils.kt index 5eba6dcc9f..0442435782 100644 --- a/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/utils/WcSignTransactionUtils.kt +++ b/features/walletconnect/impl/src/main/kotlin/com/tangem/features/walletconnect/transaction/utils/WcSignTransactionUtils.kt @@ -3,6 +3,9 @@ package com.tangem.features.walletconnect.transaction.utils import com.domain.blockaid.models.dapp.CheckDAppResult import com.tangem.core.ui.extensions.getActiveIconRes import com.tangem.core.ui.extensions.resourceReference +import com.tangem.domain.walletconnect.model.WcEthMethod +import com.tangem.domain.walletconnect.model.WcSolanaMethod +import com.tangem.domain.walletconnect.model.sdkcopy.WcSdkSessionRequest import com.tangem.domain.walletconnect.usecase.method.WcMessageSignUseCase import com.tangem.domain.walletconnect.usecase.method.WcSignState import com.tangem.domain.walletconnect.usecase.method.WcSignStep @@ -11,33 +14,84 @@ import com.tangem.features.walletconnect.impl.R import com.tangem.features.walletconnect.transaction.entity.WcNetworkInfoUM import com.tangem.features.walletconnect.transaction.entity.WcSignTransactionUM import com.tangem.features.walletconnect.transaction.entity.WcTransactionActionsUM +import com.tangem.features.walletconnect.transaction.entity.WcTransactionRequestBlockUM import com.tangem.features.walletconnect.transaction.entity.WcTransactionRequestInfoItemUM import com.tangem.features.walletconnect.transaction.entity.WcTransactionRequestInfoUM import com.tangem.features.walletconnect.transaction.entity.WcTransactionUM import kotlinx.collections.immutable.persistentListOf +import kotlinx.collections.immutable.toImmutableList internal fun WcSignUseCase.toUM(signState: WcSignState<*>, actions: WcTransactionActionsUM): WcSignTransactionUM? { return when (this) { is WcMessageSignUseCase -> { - ethMessageSignToUM( - signState = signState, - signModel = signState.signModel as WcMessageSignUseCase.SignModel, - actions = actions, - ) + when (method) { + is WcEthMethod.SignTypedData -> signTypedDataToUM( + signState = signState, + signModel = signState.signModel as WcMessageSignUseCase.SignModel, + actions = actions, + ) + is WcEthMethod.MessageSign, is WcSolanaMethod.SignMessage -> messageSignToUM( + signState = signState, + signModel = signState.signModel as WcMessageSignUseCase.SignModel, + actions = actions, + ) + else -> null + } } else -> null } } -private fun WcMessageSignUseCase.ethMessageSignToUM( +private fun WcMessageSignUseCase.signTypedDataToUM( + signState: WcSignState<*>, + signModel: WcMessageSignUseCase.SignModel, + actions: WcTransactionActionsUM, +) = WcSignTransactionUM( + actions = actions, + transaction = WcTransactionUM( + appName = session.sdkModel.appMetaData.name, + appIcon = session.sdkModel.appMetaData.url, + isVerified = session.securityStatus == CheckDAppResult.SAFE, + appSubtitle = session.sdkModel.appMetaData.description, + walletName = session.wallet.name, + networkInfo = WcNetworkInfoUM( + name = network.name, + iconRes = getActiveIconRes(network.id.value), + ), + addressText = walletAddress.toShortAddressText(), + isLoading = signState.domainStep == WcSignStep.Signing, + ), + transactionRequestInfo = WcTransactionRequestInfoUM( + buildList { + add(createInfoBlockUM(rawSdkRequest, signModel)) + (method as? WcEthMethod.SignTypedData)?.params?.message?.to?.let { to -> + add( + WcTransactionRequestBlockUM( + persistentListOf( + WcTransactionRequestInfoItemUM( + title = resourceReference(R.string.wc_transaction_info_to_title), + ), + WcTransactionRequestInfoItemUM( + title = resourceReference(R.string.settings_wallet_name_title), + description = to.name, + ), + WcTransactionRequestInfoItemUM( + title = resourceReference(R.string.wc_common_wallet), + description = to.wallet, + ), + ), + ), + ) + } + }.toImmutableList(), + ), +) + +private fun WcMessageSignUseCase.messageSignToUM( signState: WcSignState<*>, signModel: WcMessageSignUseCase.SignModel, actions: WcTransactionActionsUM, ) = WcSignTransactionUM( - startIconRes = R.drawable.ic_back_24, - endIconRes = R.drawable.ic_close_24, - transactionIconRes = R.drawable.ic_doc_new_24, - state = WcSignTransactionUM.State.TRANSACTION, actions = actions, transaction = WcTransactionUM( appName = session.sdkModel.appMetaData.name, @@ -52,6 +106,15 @@ private fun WcMessageSignUseCase.ethMessageSignToUM( isLoading = signState.domainStep == WcSignStep.Signing, ), transactionRequestInfo = WcTransactionRequestInfoUM( + persistentListOf(createInfoBlockUM(rawSdkRequest, signModel)), + ), +) + +private fun createInfoBlockUM( + rawSdkRequest: WcSdkSessionRequest, + signModel: WcMessageSignUseCase.SignModel, +): WcTransactionRequestBlockUM { + return WcTransactionRequestBlockUM( persistentListOf( WcTransactionRequestInfoItemUM( title = resourceReference(R.string.wc_signature_type), @@ -62,5 +125,5 @@ private fun WcMessageSignUseCase.ethMessageSignToUM( description = signModel.humanMsg, ), ), - ), -) \ No newline at end of file + ) +} \ No newline at end of file