Updated on 2026-08-14

This commit is contained in:
Tangem 2025-05-28 22:45:52 +04:00
parent 3e4e8c8f90
commit f7fb784a5b
15 changed files with 367 additions and 353 deletions

View file

@ -17,8 +17,8 @@ import com.tangem.core.ui.decompose.ComposableContentComponent
import com.tangem.features.walletconnect.components.WcRoutingComponent
import com.tangem.features.walletconnect.connections.components.WcPairComponent
import com.tangem.features.walletconnect.connections.components.AlertsComponent
import com.tangem.features.walletconnect.transaction.components.WcAddNetworkContainerComponent
import com.tangem.features.walletconnect.transaction.components.WcSignTransactionContainerComponent
import com.tangem.features.walletconnect.transaction.components.chain.WcAddNetworkContainerComponent
import com.tangem.features.walletconnect.transaction.components.sign.WcSignTransactionContainerComponent
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject

View file

@ -1,100 +0,0 @@
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.pushNew
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.decompose.ComposableContentComponent
import com.tangem.core.ui.res.TangemTheme
import com.tangem.domain.walletconnect.model.sdkcopy.WcSdkSessionRequest
import com.tangem.features.walletconnect.transaction.model.WcAddNetworkModel
import com.tangem.features.walletconnect.transaction.routes.WcTransactionRoutes
import com.tangem.features.walletconnect.transaction.ui.common.WcTransactionCommonBottomSheetTitle
internal class WcAddNetworkContainerComponent(
private val appComponentContext: AppComponentContext,
params: Params,
) : AppComponentContext by appComponentContext, ComposableContentComponent {
private val model: WcAddNetworkModel = getOrCreateModel(params = params)
private val contentNavigation = StackNavigation<WcTransactionRoutes>()
private val contentStack = childStack(
source = contentNavigation,
serializer = WcTransactionRoutes.serializer(),
initialConfiguration = WcTransactionRoutes.Transaction,
childFactory = ::screenChild,
)
private fun dismiss() {
model.dismiss()
}
@Composable
override fun Content(modifier: Modifier) {
val content by contentStack.subscribeAsState()
TangemModalBottomSheet<WcTransactionRoutes>(
config = TangemBottomSheetConfig(
isShown = true,
onDismissRequest = ::dismiss,
content = content.active.configuration,
),
containerColor = TangemTheme.colors.background.tertiary,
title = { config ->
WcTransactionCommonBottomSheetTitle(
route = config,
onStartClick = ::toTransaction,
onEndClick = ::dismiss,
)
},
content = {
Box(
modifier = Modifier
.fillMaxWidth()
.animateContentSize(),
) {
Children(stack = content) { child ->
child.instance.Content(modifier = Modifier)
}
}
},
)
}
private fun toTransactionRequestInfo() {
contentNavigation.pushNew(WcTransactionRoutes.TransactionRequestInfo)
}
private fun toTransaction() {
contentNavigation.pushNew(WcTransactionRoutes.Transaction)
}
private fun screenChild(
config: WcTransactionRoutes,
componentContext: ComponentContext,
): ComposableContentComponent = when (config) {
is WcTransactionRoutes.Transaction -> WcAddNetworkComponent(
appComponentContext = childByContext(componentContext),
model = model,
transactionInfoOnClick = ::toTransactionRequestInfo,
)
is WcTransactionRoutes.TransactionRequestInfo -> WcTransactionRequestInfoComponent(
appComponentContext = childByContext(componentContext),
model = model.uiState.value?.transactionRequestInfo,
)
}
data class Params(val rawRequest: WcSdkSessionRequest)
}

View file

@ -1,104 +0,0 @@
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.decompose.ComposableContentComponent
import com.tangem.core.ui.res.TangemTheme
import com.tangem.domain.walletconnect.model.sdkcopy.WcSdkSessionRequest
import com.tangem.features.walletconnect.transaction.model.WcSignTransactionModel
import com.tangem.features.walletconnect.transaction.routes.WcTransactionRoutes
import com.tangem.features.walletconnect.transaction.ui.common.WcTransactionCommonBottomSheetTitle
internal class WcSignTransactionContainerComponent(
private val appComponentContext: AppComponentContext,
params: Params,
) : AppComponentContext by appComponentContext, ComposableContentComponent {
private val model: WcSignTransactionModel = getOrCreateModel(params = params)
private val contentNavigation = StackNavigation<WcTransactionRoutes>()
private val contentStack = childStack(
source = contentNavigation,
serializer = WcTransactionRoutes.serializer(),
initialConfiguration = WcTransactionRoutes.Transaction,
childFactory = ::screenChild,
)
private fun dismiss() {
model.dismiss()
}
@Composable
override fun Content(modifier: Modifier) {
val content by contentStack.subscribeAsState()
TangemModalBottomSheet<WcTransactionRoutes>(
config = TangemBottomSheetConfig(
isShown = true,
onDismissRequest = ::dismiss,
content = content.active.configuration,
),
containerColor = TangemTheme.colors.background.tertiary,
title = { config ->
WcTransactionCommonBottomSheetTitle(
route = config,
onStartClick = ::toTransaction,
onEndClick = ::dismiss,
)
},
content = {
Box(
modifier = Modifier
.fillMaxWidth()
.animateContentSize(),
) {
Children(stack = content) { child ->
child.instance.Content(modifier = Modifier)
}
}
},
)
}
private fun toTransactionRequestInfo() {
contentNavigation.navigate {
listOf(WcTransactionRoutes.TransactionRequestInfo)
}
}
private fun toTransaction() {
contentNavigation.navigate {
listOf(WcTransactionRoutes.Transaction)
}
}
private fun screenChild(
config: WcTransactionRoutes,
componentContext: ComponentContext,
): ComposableContentComponent = when (config) {
is WcTransactionRoutes.Transaction -> WcSignTransactionComponent(
appComponentContext = childByContext(componentContext),
model = model,
transactionInfoOnClick = ::toTransactionRequestInfo,
)
is WcTransactionRoutes.TransactionRequestInfo -> WcTransactionRequestInfoComponent(
appComponentContext = childByContext(componentContext),
model = model.uiState.value?.transactionRequestInfo,
)
}
data class Params(val rawRequest: WcSdkSessionRequest)
}

View file

@ -1,11 +1,10 @@
package com.tangem.features.walletconnect.transaction.components
package com.tangem.features.walletconnect.transaction.components.chain
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.ui.decompose.ComposableContentComponent
import com.tangem.core.ui.decompose.ComposableBottomSheetComponent
import com.tangem.features.walletconnect.transaction.model.WcAddNetworkModel
import com.tangem.features.walletconnect.transaction.ui.chain.WcAddEthereumChainModalBottomSheetContent
@ -13,16 +12,23 @@ internal class WcAddNetworkComponent(
private val appComponentContext: AppComponentContext,
private val model: WcAddNetworkModel,
private val transactionInfoOnClick: () -> Unit,
) : AppComponentContext by appComponentContext, ComposableContentComponent {
private val onDismiss: () -> Unit,
) : AppComponentContext by appComponentContext, ComposableBottomSheetComponent {
override fun dismiss() {
onDismiss()
}
@Composable
override fun Content(modifier: Modifier) {
override fun BottomSheet() {
val content by model.uiState.collectAsStateWithLifecycle()
if (content != null) {
WcAddEthereumChainModalBottomSheetContent(
state = content!!.transaction,
onClickTransactionRequest = transactionInfoOnClick,
onBack = router::pop,
onDismiss = ::dismiss,
)
}
}

View file

@ -0,0 +1,87 @@
package com.tangem.features.walletconnect.transaction.components.chain
import androidx.activity.compose.BackHandler
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.subscribeAsState
import com.arkivanov.decompose.router.stack.StackNavigation
import com.arkivanov.decompose.router.stack.childStack
import com.arkivanov.decompose.router.stack.pop
import com.arkivanov.decompose.router.stack.pushNew
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.decompose.navigation.inner.InnerRouter
import com.tangem.core.ui.decompose.ComposableBottomSheetComponent
import com.tangem.core.ui.decompose.ComposableContentComponent
import com.tangem.domain.walletconnect.model.sdkcopy.WcSdkSessionRequest
import com.tangem.features.walletconnect.transaction.components.common.WcTransactionRequestInfoComponent
import com.tangem.features.walletconnect.transaction.model.WcAddNetworkModel
import com.tangem.features.walletconnect.transaction.routes.WcTransactionRoutes
internal class WcAddNetworkContainerComponent(
private val appComponentContext: AppComponentContext,
params: Params,
) : AppComponentContext by appComponentContext, ComposableContentComponent {
private val contentNavigation = StackNavigation<WcTransactionRoutes>()
private val innerRouter = InnerRouter<WcTransactionRoutes>(
stackNavigation = contentNavigation,
popCallback = { onChildBack() },
)
private val model: WcAddNetworkModel = getOrCreateModel(params = params, router = innerRouter)
private val contentStack = childStack(
key = "WcAddNetworkStack",
source = contentNavigation,
serializer = WcTransactionRoutes.serializer(),
initialConfiguration = WcTransactionRoutes.Transaction,
handleBackButton = true,
childFactory = ::screenChild,
)
@Composable
override fun Content(modifier: Modifier) {
val content by contentStack.subscribeAsState()
BackHandler(onBack = ::onChildBack)
content.active.instance.BottomSheet()
}
private fun dismiss() {
model.dismiss()
}
private fun onChildBack() {
when (contentStack.value.active.configuration) {
WcTransactionRoutes.Transaction -> contentNavigation.pop()
WcTransactionRoutes.TransactionRequestInfo -> contentNavigation.pushNew(WcTransactionRoutes.Transaction)
}
}
private fun toTransactionRequestInfo() {
contentNavigation.pushNew(WcTransactionRoutes.TransactionRequestInfo)
}
private fun screenChild(
config: WcTransactionRoutes,
componentContext: ComponentContext,
): ComposableBottomSheetComponent {
val appComponentContext = childByContext(componentContext = componentContext, router = innerRouter)
return when (config) {
is WcTransactionRoutes.Transaction -> WcAddNetworkComponent(
appComponentContext = childByContext(componentContext),
transactionInfoOnClick = ::toTransactionRequestInfo,
onDismiss = ::dismiss,
model = model,
)
is WcTransactionRoutes.TransactionRequestInfo -> WcTransactionRequestInfoComponent(
appComponentContext = appComponentContext,
onDismiss = ::dismiss,
model = model.uiState.value?.transactionRequestInfo,
)
}
}
data class Params(val rawRequest: WcSdkSessionRequest)
}

View file

@ -1,21 +1,25 @@
package com.tangem.features.walletconnect.transaction.components
package com.tangem.features.walletconnect.transaction.components.common
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import com.tangem.core.decompose.context.AppComponentContext
import com.tangem.core.ui.decompose.ComposableContentComponent
import com.tangem.core.ui.decompose.ComposableBottomSheetComponent
import com.tangem.features.walletconnect.transaction.entity.common.WcTransactionRequestInfoUM
import com.tangem.features.walletconnect.transaction.ui.common.TransactionRequestInfoContent
internal class WcTransactionRequestInfoComponent(
private val appComponentContext: AppComponentContext,
private val model: WcTransactionRequestInfoUM?,
) : AppComponentContext by appComponentContext, ComposableContentComponent {
private val onDismiss: () -> Unit,
) : AppComponentContext by appComponentContext, ComposableBottomSheetComponent {
override fun dismiss() {
onDismiss()
}
@Composable
override fun Content(modifier: Modifier) {
override fun BottomSheet() {
if (model != null) {
TransactionRequestInfoContent(model)
TransactionRequestInfoContent(model, onBack = router::pop, onDismiss = ::dismiss)
}
}
}

View file

@ -1,10 +1,10 @@
package com.tangem.features.walletconnect.transaction.components
package com.tangem.features.walletconnect.transaction.components.sign
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.runtime.getValue
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.tangem.core.decompose.context.AppComponentContext
import com.tangem.core.ui.decompose.ComposableContentComponent
import com.tangem.core.ui.decompose.ComposableBottomSheetComponent
import com.tangem.features.walletconnect.transaction.model.WcSignTransactionModel
import com.tangem.features.walletconnect.transaction.ui.sign.WcSignTransactionModalBottomSheetContent
@ -12,16 +12,23 @@ internal class WcSignTransactionComponent(
private val appComponentContext: AppComponentContext,
private val model: WcSignTransactionModel,
private val transactionInfoOnClick: () -> Unit,
) : AppComponentContext by appComponentContext, ComposableContentComponent {
private val onDismiss: () -> Unit,
) : AppComponentContext by appComponentContext, ComposableBottomSheetComponent {
override fun dismiss() {
onDismiss()
}
@Composable
override fun Content(modifier: Modifier) {
val content = model.uiState.collectAsStateWithLifecycle().value
override fun BottomSheet() {
val content by model.uiState.collectAsStateWithLifecycle()
if (content != null) {
WcSignTransactionModalBottomSheetContent(
state = content.transaction,
state = content!!.transaction,
onClickTransactionRequest = transactionInfoOnClick,
onBack = router::pop,
onDismiss = ::dismiss,
)
}
}

View file

@ -0,0 +1,77 @@
package com.tangem.features.walletconnect.transaction.components.sign
import androidx.activity.compose.BackHandler
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.subscribeAsState
import com.arkivanov.decompose.router.stack.*
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.decompose.navigation.inner.InnerRouter
import com.tangem.core.ui.decompose.ComposableBottomSheetComponent
import com.tangem.core.ui.decompose.ComposableContentComponent
import com.tangem.domain.walletconnect.model.sdkcopy.WcSdkSessionRequest
import com.tangem.features.walletconnect.transaction.components.common.WcTransactionRequestInfoComponent
import com.tangem.features.walletconnect.transaction.model.WcSignTransactionModel
import com.tangem.features.walletconnect.transaction.routes.WcTransactionRoutes
internal class WcSignTransactionContainerComponent(
private val appComponentContext: AppComponentContext,
params: Params,
) : AppComponentContext by appComponentContext, ComposableContentComponent {
private val contentNavigation = StackNavigation<WcTransactionRoutes>()
private val innerRouter = InnerRouter<WcTransactionRoutes>(
stackNavigation = contentNavigation,
popCallback = { onChildBack() },
)
private val model: WcSignTransactionModel = getOrCreateModel(params = params, router = innerRouter)
private val contentStack = childStack(
key = "WcSignTransactionStack",
source = contentNavigation,
serializer = WcTransactionRoutes.serializer(),
initialConfiguration = WcTransactionRoutes.Transaction,
handleBackButton = true,
childFactory = ::screenChild,
)
@Composable
override fun Content(modifier: Modifier) {
val content by contentStack.subscribeAsState()
BackHandler(onBack = ::onChildBack)
content.active.instance.BottomSheet()
}
private fun onChildBack() {
when (contentStack.value.active.configuration) {
WcTransactionRoutes.Transaction,
WcTransactionRoutes.TransactionRequestInfo,
-> contentNavigation.pop()
}
}
private fun screenChild(
config: WcTransactionRoutes,
componentContext: ComponentContext,
): ComposableBottomSheetComponent {
val appComponentContext = childByContext(componentContext = componentContext, router = innerRouter)
return when (config) {
is WcTransactionRoutes.Transaction -> WcSignTransactionComponent(
appComponentContext = appComponentContext,
onDismiss = model::dismiss,
model = model,
transactionInfoOnClick = { contentNavigation.pushNew(WcTransactionRoutes.TransactionRequestInfo) },
)
is WcTransactionRoutes.TransactionRequestInfo -> WcTransactionRequestInfoComponent(
appComponentContext = appComponentContext,
onDismiss = model::dismiss,
model = model.uiState.value?.transactionRequestInfo,
)
}
}
data class Params(val rawRequest: WcSdkSessionRequest)
}

View file

@ -9,7 +9,7 @@ import com.tangem.core.ui.clipboard.ClipboardManager
import com.tangem.domain.walletconnect.WcRequestUseCaseFactory
import com.tangem.domain.walletconnect.usecase.method.WcAddNetworkUseCase
import com.tangem.domain.walletconnect.usecase.method.WcMethodUseCase
import com.tangem.features.walletconnect.transaction.components.WcSignTransactionContainerComponent
import com.tangem.features.walletconnect.transaction.components.sign.WcSignTransactionContainerComponent
import com.tangem.features.walletconnect.transaction.entity.chain.WcAddEthereumChainUM
import com.tangem.features.walletconnect.transaction.entity.common.WcTransactionActionsUM
import com.tangem.features.walletconnect.transaction.utils.toUM

View file

@ -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.WcSignTransactionContainerComponent
import com.tangem.features.walletconnect.transaction.components.sign.WcSignTransactionContainerComponent
import com.tangem.features.walletconnect.transaction.entity.common.WcTransactionActionsUM
import com.tangem.features.walletconnect.transaction.entity.sign.WcSignTransactionUM
import com.tangem.features.walletconnect.transaction.utils.toUM

View file

@ -1,12 +1,13 @@
package com.tangem.features.walletconnect.transaction.routes
import androidx.compose.runtime.Immutable
import com.tangem.core.decompose.navigation.Route
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfigContent
import kotlinx.serialization.Serializable
@Serializable
@Immutable
internal sealed class WcTransactionRoutes : TangemBottomSheetConfigContent {
internal sealed class WcTransactionRoutes : TangemBottomSheetConfigContent, Route {
@Serializable
data object Transaction : WcTransactionRoutes()

View file

@ -17,8 +17,10 @@ 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.bottomsheets.TangemBottomSheetConfig
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfigContent
import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheet
import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheetTitle
import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheetWithFooter
import com.tangem.core.ui.components.divider.DividerWithPadding
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.res.TangemTheme
@ -37,52 +39,74 @@ import com.tangem.features.walletconnect.transaction.ui.common.WcWalletItem
internal fun WcAddEthereumChainModalBottomSheetContent(
state: WcAddEthereumChainItemUM,
onClickTransactionRequest: () -> Unit,
onBack: () -> Unit,
onDismiss: () -> Unit,
) {
Column(
modifier = Modifier
.padding(horizontal = TangemTheme.dimens.spacing16),
) {
Column(
modifier = Modifier
.clip(RoundedCornerShape(TangemTheme.dimens.radius14))
.background(color = TangemTheme.colors.background.action)
.fillMaxWidth()
.animateContentSize(),
) {
WcSmallTitleItem(R.string.wc_request_from)
WcAppInfoItem(
iconUrl = state.appInfo.appIcon,
title = state.appInfo.appName,
subtitle = state.appInfo.appSubtitle,
verifiedDAppState = state.appInfo.verifiedState,
TangemModalBottomSheetWithFooter<TangemBottomSheetConfigContent.Empty>(
config = TangemBottomSheetConfig(
isShown = true,
onDismissRequest = onDismiss,
content = TangemBottomSheetConfigContent.Empty,
),
containerColor = TangemTheme.colors.background.tertiary,
onBack = onBack,
title = {
TangemModalBottomSheetTitle(
title = resourceReference(R.string.wc_wallet_connect),
endIconRes = R.drawable.ic_close_24,
onEndClick = onDismiss,
)
DividerWithPadding(start = 0.dp, end = 0.dp)
WcTransactionRequestItem(
iconRes = R.drawable.ic_doc_new_24,
},
content = {
Column(
modifier = Modifier
.fillMaxWidth()
.clickable { onClickTransactionRequest() }
.padding(TangemTheme.dimens.spacing12),
)
}
Column(modifier = Modifier.padding(top = TangemTheme.dimens.spacing16)) {
WcAddEthereumChainItems(state)
.padding(horizontal = 16.dp),
) {
Column(
modifier = Modifier
.clip(RoundedCornerShape(14.dp))
.background(color = TangemTheme.colors.background.action)
.fillMaxWidth()
.animateContentSize(),
) {
WcSmallTitleItem(R.string.wc_request_from)
WcAppInfoItem(
iconUrl = state.appInfo.appIcon,
title = state.appInfo.appName,
subtitle = state.appInfo.appSubtitle,
verifiedDAppState = state.appInfo.verifiedState,
)
DividerWithPadding(start = 0.dp, end = 0.dp)
WcTransactionRequestItem(
iconRes = R.drawable.ic_doc_new_24,
modifier = Modifier
.fillMaxWidth()
.clickable { onClickTransactionRequest() }
.padding(12.dp),
)
}
Column(modifier = Modifier.padding(top = 16.dp)) {
WcAddEthereumChainItems(state)
}
}
},
footer = {
WcTransactionRequestButtons(
modifier = Modifier.padding(vertical = TangemTheme.dimens.spacing16),
modifier = Modifier.padding(16.dp),
onDismiss = state.onDismiss,
onClickActiveButton = state.onSign,
activeButtonText = resourceReference(R.string.common_sign),
isLoading = state.isLoading,
)
}
}
},
)
}
@Composable
private fun WcAddEthereumChainItems(state: WcAddEthereumChainItemUM) {
Column(
modifier = Modifier
.clip(RoundedCornerShape(TangemTheme.dimens.radius14))
.clip(RoundedCornerShape(14.dp))
.background(color = TangemTheme.colors.background.action)
.fillMaxWidth()
.animateContentSize(),
@ -91,10 +115,10 @@ private fun WcAddEthereumChainItems(state: WcAddEthereumChainItemUM) {
WcWalletItem(
modifier = Modifier
.fillMaxWidth()
.padding(TangemTheme.dimens.spacing12),
.padding(12.dp),
walletName = state.walletName,
)
DividerWithPadding(start = TangemTheme.dimens.spacing40, end = TangemTheme.dimens.spacing12)
DividerWithPadding(start = 40.dp, end = 12.dp)
}
}
@ -122,7 +146,7 @@ private fun WcAddEthereumChainBottomSheetPreview(
)
},
content = {
WcAddEthereumChainModalBottomSheetContent(state = state, onClickTransactionRequest = {})
WcAddEthereumChainModalBottomSheetContent(state, {}, {}, {})
},
)
}

View file

@ -8,7 +8,6 @@ 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
@ -16,11 +15,14 @@ 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.SecondaryButtonIconEnd
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfigContent
import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheet
import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheetTitle
import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheetWithFooter
import com.tangem.core.ui.extensions.resolveReference
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.extensions.stringResourceSafe
@ -36,33 +38,66 @@ private const val MIN_HEIGHT_SCREEN_PERCENT = 0.35f
private const val MAX_HEIGHT_SCREEN_PERCENT = 0.75f
@Composable
internal fun TransactionRequestInfoContent(state: WcTransactionRequestInfoUM) {
internal fun TransactionRequestInfoContent(
state: WcTransactionRequestInfoUM,
onBack: () -> Unit,
onDismiss: () -> Unit,
) {
val screenHeight = LocalConfiguration.current.screenHeightDp
val minHeight = (screenHeight * MIN_HEIGHT_SCREEN_PERCENT).dp
val maxHeight = (screenHeight * MAX_HEIGHT_SCREEN_PERCENT).dp
TangemModalBottomSheetWithFooter<TangemBottomSheetConfigContent.Empty>(
config = TangemBottomSheetConfig(
isShown = true,
onDismissRequest = onDismiss,
content = TangemBottomSheetConfigContent.Empty,
),
containerColor = TangemTheme.colors.background.tertiary,
onBack = onBack,
title = {
TangemModalBottomSheetTitle(
title = resourceReference(R.string.wc_transaction_request_title),
startIconRes = R.drawable.ic_back_24,
onStartClick = onDismiss,
)
},
content = {
TransactionRequestContent(state = state, minHeight = minHeight, maxHeight = maxHeight)
},
footer = {
SecondaryButtonIconEnd(
modifier = Modifier
.padding(bottom = 20.dp, start = 16.dp, end = 16.dp)
.fillMaxWidth(),
text = stringResourceSafe(R.string.wc_copy_data_button_text),
onClick = state.onCopy,
iconResId = R.drawable.ic_copy_24,
)
},
)
}
@Composable
private fun TransactionRequestContent(state: WcTransactionRequestInfoUM, minHeight: Dp, maxHeight: Dp) {
Box(
modifier = Modifier
.fillMaxWidth()
.heightIn(min = minHeight, max = maxHeight)
.padding(horizontal = TangemTheme.dimens.spacing16),
.padding(horizontal = 16.dp),
) {
LazyColumn(
modifier = Modifier
.fillMaxWidth(),
contentPadding = PaddingValues(top = TangemTheme.dimens.spacing8, bottom = TangemTheme.dimens.spacing70),
contentPadding = PaddingValues(top = 8.dp, bottom = 70.dp),
) {
items(state.blocks) { block ->
Column(
modifier = Modifier
.fillMaxWidth()
.clip(RoundedCornerShape(TangemTheme.dimens.radius16))
.clip(RoundedCornerShape(16.dp))
.background(TangemTheme.colors.background.action)
.padding(
start = TangemTheme.dimens.spacing16,
end = TangemTheme.dimens.spacing16,
top = TangemTheme.dimens.spacing20,
),
.padding(start = 16.dp, end = 16.dp, top = 20.dp),
) {
block.info.forEach { item ->
Text(
@ -73,31 +108,18 @@ internal fun TransactionRequestInfoContent(state: WcTransactionRequestInfoUM) {
if (item.description.isNotEmpty()) {
Text(
text = item.description,
modifier = Modifier.padding(
top = TangemTheme.dimens.spacing4,
bottom = TangemTheme.dimens.spacing20,
),
modifier = Modifier.padding(top = 4.dp, bottom = 20.dp),
style = TangemTheme.typography.body2,
color = TangemTheme.colors.text.primary1,
)
} else {
Spacer(modifier = Modifier.size(TangemTheme.dimens.size12))
Spacer(modifier = Modifier.size(12.dp))
}
}
}
Spacer(modifier = Modifier.size(TangemTheme.dimens.size20))
Spacer(modifier = Modifier.size(20.dp))
}
}
SecondaryButtonIconEnd(
modifier = Modifier
.align(Alignment.BottomCenter)
.padding(bottom = TangemTheme.dimens.spacing20)
.fillMaxWidth(),
text = stringResourceSafe(R.string.wc_copy_data_button_text),
onClick = state.onCopy,
iconResId = R.drawable.ic_copy_24,
)
}
}
@ -125,7 +147,7 @@ private fun WcSignTransactionRequestInfoBottomSheetPreview(
)
},
content = {
TransactionRequestInfoContent(state = state)
TransactionRequestInfoContent(state, {}, {})
},
)
}

View file

@ -1,34 +0,0 @@
package com.tangem.features.walletconnect.transaction.ui.common
import androidx.compose.runtime.Composable
import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheetTitle
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.features.walletconnect.impl.R
import com.tangem.features.walletconnect.transaction.routes.WcTransactionRoutes
@Composable
internal fun WcTransactionCommonBottomSheetTitle(
route: WcTransactionRoutes,
onStartClick: () -> Unit,
onEndClick: () -> Unit,
) {
TangemModalBottomSheetTitle(
title = resourceReference(R.string.wc_wallet_connect),
startIconRes = when (route) {
is WcTransactionRoutes.Transaction -> null
else -> R.drawable.ic_back_24
},
onStartClick = when (route) {
is WcTransactionRoutes.Transaction -> null
else -> onStartClick
},
endIconRes = when (route) {
is WcTransactionRoutes.Transaction -> R.drawable.ic_close_24
else -> null
},
onEndClick = when (route) {
is WcTransactionRoutes.Transaction -> onEndClick
else -> null
},
)
}

View file

@ -17,8 +17,10 @@ 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.bottomsheets.TangemBottomSheetConfig
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfigContent
import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheet
import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheetTitle
import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheetWithFooter
import com.tangem.core.ui.components.divider.DividerWithPadding
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.res.TangemTheme
@ -35,45 +37,67 @@ import com.tangem.features.walletconnect.transaction.ui.common.*
internal fun WcSignTransactionModalBottomSheetContent(
state: WcSignTransactionItemUM,
onClickTransactionRequest: () -> Unit,
onBack: () -> Unit,
onDismiss: () -> Unit,
) {
Column(
modifier = Modifier
.padding(horizontal = 16.dp),
) {
Column(
modifier = Modifier
.clip(RoundedCornerShape(14.dp))
.background(color = TangemTheme.colors.background.action)
.fillMaxWidth()
.animateContentSize(),
) {
WcSmallTitleItem(R.string.wc_request_from)
WcAppInfoItem(
iconUrl = state.appInfo.appIcon,
title = state.appInfo.appName,
subtitle = state.appInfo.appSubtitle,
verifiedDAppState = state.appInfo.verifiedState,
TangemModalBottomSheetWithFooter<TangemBottomSheetConfigContent.Empty>(
config = TangemBottomSheetConfig(
isShown = true,
onDismissRequest = onDismiss,
content = TangemBottomSheetConfigContent.Empty,
),
containerColor = TangemTheme.colors.background.tertiary,
onBack = onBack,
title = {
TangemModalBottomSheetTitle(
title = resourceReference(R.string.wc_wallet_connect),
endIconRes = R.drawable.ic_close_24,
onEndClick = onDismiss,
)
DividerWithPadding(start = 0.dp, end = 0.dp)
WcTransactionRequestItem(
iconRes = R.drawable.ic_doc_new_24,
},
content = {
Column(
modifier = Modifier
.fillMaxWidth()
.clickable { onClickTransactionRequest() }
.padding(12.dp),
)
}
Column(modifier = Modifier.padding(top = 16.dp)) {
WcSignTransactionItems(state)
.padding(horizontal = 16.dp),
) {
Column(
modifier = Modifier
.clip(RoundedCornerShape(14.dp))
.background(color = TangemTheme.colors.background.action)
.fillMaxWidth()
.animateContentSize(),
) {
WcSmallTitleItem(R.string.wc_request_from)
WcAppInfoItem(
iconUrl = state.appInfo.appIcon,
title = state.appInfo.appName,
subtitle = state.appInfo.appSubtitle,
verifiedDAppState = state.appInfo.verifiedState,
)
DividerWithPadding(start = 0.dp, end = 0.dp)
WcTransactionRequestItem(
iconRes = R.drawable.ic_doc_new_24,
modifier = Modifier
.fillMaxWidth()
.clickable { onClickTransactionRequest() }
.padding(12.dp),
)
}
Column(modifier = Modifier.padding(top = 16.dp)) {
WcSignTransactionItems(state)
}
}
},
footer = {
WcTransactionRequestButtons(
modifier = Modifier.padding(vertical = 16.dp),
modifier = Modifier.padding(16.dp),
onDismiss = state.onDismiss,
onClickActiveButton = state.onSign,
activeButtonText = resourceReference(R.string.common_sign),
isLoading = state.isLoading,
)
}
}
},
)
}
@Composable
@ -133,7 +157,7 @@ private fun WcSignTransactionBottomSheetPreview(
)
},
content = {
WcSignTransactionModalBottomSheetContent(state = state, onClickTransactionRequest = {})
WcSignTransactionModalBottomSheetContent(state, {}, {}, {})
},
)
}