Updated on 2026-08-14
This commit is contained in:
parent
e9512b1afe
commit
ecd02950fb
15 changed files with 796 additions and 0 deletions
|
|
@ -5,6 +5,7 @@ import com.tangem.core.decompose.model.Model
|
|||
import com.tangem.features.walletconnect.connections.model.WcAppInfoModel
|
||||
import com.tangem.features.walletconnect.connections.model.WcConnectedAppInfoModel
|
||||
import com.tangem.features.walletconnect.connections.model.WcConnectionsModel
|
||||
import com.tangem.features.walletconnect.transaction.model.WcSignTransactionModel
|
||||
import dagger.Binds
|
||||
import dagger.Module
|
||||
import dagger.hilt.InstallIn
|
||||
|
|
@ -29,4 +30,9 @@ internal interface WalletConnectModelModule {
|
|||
@IntoMap
|
||||
@ClassKey(WcConnectedAppInfoModel::class)
|
||||
fun bindWcConnectedAppInfoModel(model: WcConnectedAppInfoModel): Model
|
||||
|
||||
@Binds
|
||||
@IntoMap
|
||||
@ClassKey(WcSignTransactionModel::class)
|
||||
fun bindWcSignTransactionModel(model: WcSignTransactionModel): Model
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
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
|
||||
|
||||
internal class WcSignTransactionComponent(
|
||||
appComponentContext: AppComponentContext,
|
||||
params: Params,
|
||||
) : 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,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
data class Params(val rawRequest: WcSdkSessionRequest)
|
||||
}
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
package com.tangem.features.walletconnect.transaction.entity
|
||||
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.compose.runtime.Immutable
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfigContent
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
@Immutable
|
||||
internal data class WcTransactionUM(
|
||||
val appName: String,
|
||||
val appIcon: String,
|
||||
val isVerified: Boolean,
|
||||
val appSubtitle: String,
|
||||
val walletName: String,
|
||||
val networkInfo: WcNetworkInfoUM,
|
||||
val isLoading: Boolean = false,
|
||||
)
|
||||
|
||||
@Immutable
|
||||
internal data class WcTransactionRequestInfoUM(
|
||||
val info: ImmutableList<WcTransactionRequestInfoItemUM>,
|
||||
)
|
||||
|
||||
@Immutable
|
||||
internal data class WcTransactionRequestInfoItemUM(
|
||||
val title: TextReference,
|
||||
val description: String,
|
||||
)
|
||||
|
||||
@Immutable
|
||||
internal data class WcTransactionActionsUM(
|
||||
val transactionRequestOnClick: () -> Unit,
|
||||
val onDismiss: () -> Unit,
|
||||
val onSign: () -> Unit,
|
||||
val onBack: () -> Unit,
|
||||
val onCopy: () -> Unit,
|
||||
)
|
||||
|
||||
@Immutable
|
||||
internal data class WcNetworkInfoUM(
|
||||
val name: String,
|
||||
@DrawableRes val iconRes: Int,
|
||||
)
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
package com.tangem.features.walletconnect.transaction.model
|
||||
|
||||
import androidx.compose.runtime.Stable
|
||||
import com.tangem.core.decompose.di.ModelScoped
|
||||
import com.tangem.core.decompose.model.Model
|
||||
import com.tangem.core.decompose.model.ParamsContainer
|
||||
import com.tangem.core.decompose.navigation.Router
|
||||
import com.tangem.core.ui.clipboard.ClipboardManager
|
||||
import com.tangem.domain.walletconnect.WcRequestUseCaseFactory
|
||||
import com.tangem.domain.walletconnect.usecase.sign.WcSignState
|
||||
import com.tangem.domain.walletconnect.usecase.sign.WcSignStep
|
||||
import com.tangem.domain.walletconnect.usecase.sign.WcSignUseCase
|
||||
import com.tangem.features.walletconnect.transaction.components.WcSignTransactionComponent
|
||||
import com.tangem.features.walletconnect.transaction.entity.WcSignTransactionUM
|
||||
import com.tangem.features.walletconnect.transaction.entity.WcTransactionActionsUM
|
||||
import com.tangem.features.walletconnect.transaction.utils.toUM
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
@Stable
|
||||
@ModelScoped
|
||||
internal class WcSignTransactionModel @Inject constructor(
|
||||
paramsContainer: ParamsContainer,
|
||||
override val dispatchers: CoroutineDispatcherProvider,
|
||||
private val router: Router,
|
||||
private val clipboardManager: ClipboardManager,
|
||||
private val useCaseFactory: WcRequestUseCaseFactory,
|
||||
) : Model() {
|
||||
|
||||
private val _uiState = MutableStateFlow<WcSignTransactionUM?>(null)
|
||||
val uiState: StateFlow<WcSignTransactionUM?> = _uiState
|
||||
|
||||
private val params = paramsContainer.require<WcSignTransactionComponent.Params>()
|
||||
|
||||
init {
|
||||
modelScope.launch {
|
||||
val useCase: WcSignUseCase.SimpleRun<*> = useCaseFactory.createUseCase(params.rawRequest)
|
||||
useCase.invoke()
|
||||
.onEach { signState ->
|
||||
if (signingIsDone(signState)) return@onEach
|
||||
val signTransactionUM = (useCase as? WcSignUseCase)?.toUM(
|
||||
signState = signState,
|
||||
actions = WcTransactionActionsUM(
|
||||
onDismiss = { cancel(useCase) },
|
||||
onBack = ::showTransactionState,
|
||||
onSign = useCase::sign,
|
||||
onCopy = { copyData(useCase.rawSdkRequest.request.params) },
|
||||
transactionRequestOnClick = ::showTransactionRequestState,
|
||||
),
|
||||
)
|
||||
_uiState.emit(signTransactionUM)
|
||||
}
|
||||
.launchIn(this)
|
||||
}
|
||||
}
|
||||
|
||||
private fun signingIsDone(signState: WcSignState<*>): Boolean {
|
||||
(signState.domainStep as? WcSignStep.Result)?.result?.let {
|
||||
router.pop()
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
private fun cancel(useCase: WcSignUseCase) {
|
||||
useCase.cancel()
|
||||
router.pop()
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
package com.tangem.features.walletconnect.transaction.ui.common
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.*
|
||||
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.unit.dp
|
||||
import com.tangem.core.ui.components.SecondaryButtonIconEnd
|
||||
import com.tangem.core.ui.extensions.resolveReference
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.features.walletconnect.impl.R
|
||||
import com.tangem.features.walletconnect.transaction.entity.WcSignTransactionUM
|
||||
|
||||
@Composable
|
||||
internal fun TransactionRequestInfoContent(state: WcSignTransactionUM) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.heightIn(min = 310.dp)
|
||||
.padding(horizontal = TangemTheme.dimens.spacing16),
|
||||
) {
|
||||
Column(
|
||||
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,
|
||||
),
|
||||
) {
|
||||
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,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
SecondaryButtonIconEnd(
|
||||
modifier = Modifier
|
||||
.align(Alignment.BottomCenter)
|
||||
.padding(bottom = TangemTheme.dimens.spacing20)
|
||||
.fillMaxWidth(),
|
||||
text = stringResourceSafe(R.string.wc_copy_data_button_text),
|
||||
onClick = state.actions.onCopy,
|
||||
iconResId = R.drawable.ic_copy_24,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
package com.tangem.features.walletconnect.transaction.ui.common
|
||||
|
||||
import androidx.compose.foundation.Image
|
||||
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.layout.ContentScale
|
||||
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
|
||||
import com.tangem.features.walletconnect.transaction.entity.WcNetworkInfoUM
|
||||
|
||||
@Composable
|
||||
internal fun WcNetworkItem(networkInfo: WcNetworkInfoUM, modifier: Modifier = Modifier) {
|
||||
Row(
|
||||
modifier = modifier,
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Icon(
|
||||
modifier = Modifier.size(TangemTheme.dimens.size24),
|
||||
painter = painterResource(R.drawable.ic_network_new_24),
|
||||
contentDescription = null,
|
||||
tint = TangemTheme.colors.icon.accent,
|
||||
)
|
||||
Text(
|
||||
modifier = Modifier
|
||||
.padding(start = TangemTheme.dimens.spacing4)
|
||||
.weight(1f),
|
||||
text = stringResourceSafe(R.string.wc_common_network),
|
||||
style = TangemTheme.typography.body1,
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
)
|
||||
Row(
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
horizontalArrangement = Arrangement.End,
|
||||
modifier = Modifier.weight(1f),
|
||||
) {
|
||||
Text(
|
||||
text = networkInfo.name,
|
||||
style = TangemTheme.typography.body1,
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
)
|
||||
Spacer(modifier = Modifier.width(TangemTheme.dimens.spacing6))
|
||||
Image(
|
||||
painter = painterResource(id = networkInfo.iconRes),
|
||||
contentDescription = null,
|
||||
contentScale = ContentScale.Crop,
|
||||
modifier = Modifier
|
||||
.clip(CircleShape)
|
||||
.size(TangemTheme.dimens.size20),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
package com.tangem.features.walletconnect.transaction.ui.common
|
||||
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.features.walletconnect.impl.R
|
||||
|
||||
@Composable
|
||||
fun RequestFromItem(modifier: Modifier = Modifier) {
|
||||
Text(
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
.padding(top = TangemTheme.dimens.spacing12, start = TangemTheme.dimens.spacing12),
|
||||
text = stringResourceSafe(R.string.wc_request_from),
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
style = TangemTheme.typography.subtitle2,
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
package com.tangem.features.walletconnect.transaction.ui.common
|
||||
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import com.tangem.core.ui.components.PrimaryButtonIconEnd
|
||||
import com.tangem.core.ui.components.SecondaryButton
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.features.walletconnect.impl.R
|
||||
|
||||
@Composable
|
||||
internal fun WcTransactionRequestButtons(
|
||||
isLoading: Boolean,
|
||||
onDismiss: () -> Unit,
|
||||
onSign: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
Row(modifier = modifier, horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing8)) {
|
||||
SecondaryButton(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.weight(1f),
|
||||
text = stringResourceSafe(R.string.common_cancel),
|
||||
onClick = onDismiss,
|
||||
)
|
||||
PrimaryButtonIconEnd(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.weight(1f),
|
||||
text = stringResourceSafe(R.string.wc_sign_message_button_text),
|
||||
onClick = onSign,
|
||||
iconResId = R.drawable.ic_tangem_24,
|
||||
showProgress = isLoading,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
package com.tangem.features.walletconnect.transaction.ui.common
|
||||
|
||||
import androidx.annotation.DrawableRes
|
||||
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 com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.features.walletconnect.impl.R
|
||||
|
||||
@Composable
|
||||
internal fun WcTransactionRequestItem(@DrawableRes iconRes: Int, modifier: Modifier = Modifier) {
|
||||
Row(modifier = modifier, verticalAlignment = Alignment.CenterVertically) {
|
||||
Icon(
|
||||
modifier = Modifier.size(TangemTheme.dimens.size24),
|
||||
painter = painterResource(iconRes),
|
||||
contentDescription = null,
|
||||
tint = TangemTheme.colors.icon.accent,
|
||||
)
|
||||
Text(
|
||||
modifier = Modifier
|
||||
.padding(start = TangemTheme.dimens.spacing4)
|
||||
.weight(1f),
|
||||
text = stringResourceSafe(R.string.wc_transaction_request),
|
||||
style = TangemTheme.typography.body1,
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
)
|
||||
Icon(
|
||||
modifier = Modifier
|
||||
.padding(start = TangemTheme.dimens.spacing12)
|
||||
.size(width = TangemTheme.dimens.size18, height = TangemTheme.dimens.size24),
|
||||
painter = painterResource(R.drawable.ic_chevron_right_24),
|
||||
contentDescription = null,
|
||||
tint = TangemTheme.colors.icon.informative,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -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 WcWalletItem(walletName: String, modifier: Modifier = Modifier) {
|
||||
Row(modifier = modifier, verticalAlignment = Alignment.CenterVertically) {
|
||||
Icon(
|
||||
modifier = Modifier.size(TangemTheme.dimens.size24),
|
||||
painter = painterResource(R.drawable.ic_wallet_new_24),
|
||||
contentDescription = null,
|
||||
tint = TangemTheme.colors.icon.accent,
|
||||
)
|
||||
Text(
|
||||
modifier = Modifier
|
||||
.padding(start = TangemTheme.dimens.spacing4)
|
||||
.weight(1f),
|
||||
text = stringResourceSafe(R.string.manage_tokens_network_selector_wallet),
|
||||
style = TangemTheme.typography.body1,
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
)
|
||||
Text(
|
||||
modifier = Modifier
|
||||
.padding(start = TangemTheme.dimens.spacing16)
|
||||
.weight(1f),
|
||||
text = walletName,
|
||||
textAlign = TextAlign.End,
|
||||
style = TangemTheme.typography.body1,
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,154 @@
|
|||
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<WcSignTransactionUM>(
|
||||
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<WcSignTransactionUM>(
|
||||
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 = {},
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
package com.tangem.features.walletconnect.transaction.ui.sign
|
||||
|
||||
import androidx.compose.animation.animateContentSize
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.HorizontalDivider
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.features.walletconnect.connections.ui.WcAppInfoItem
|
||||
import com.tangem.features.walletconnect.transaction.entity.WcSignTransactionUM
|
||||
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
|
||||
|
||||
@Composable
|
||||
internal fun WcSignTransactionModalBottomSheetContent(state: WcSignTransactionUM) {
|
||||
Column(modifier = Modifier.padding(horizontal = TangemTheme.dimens.spacing16)) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.clip(RoundedCornerShape(TangemTheme.dimens.radius14))
|
||||
.background(color = TangemTheme.colors.background.action)
|
||||
.fillMaxWidth()
|
||||
.animateContentSize(),
|
||||
) {
|
||||
RequestFromItem()
|
||||
WcAppInfoItem(
|
||||
iconUrl = state.transaction.appIcon,
|
||||
title = state.transaction.appName,
|
||||
subtitle = state.transaction.appSubtitle,
|
||||
isVerified = state.transaction.isVerified,
|
||||
)
|
||||
HorizontalDivider(
|
||||
thickness = TangemTheme.dimens.size1,
|
||||
color = TangemTheme.colors.stroke.primary,
|
||||
)
|
||||
WcTransactionRequestItem(
|
||||
iconRes = state.transactionIconRes,
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.clickable { state.actions.transactionRequestOnClick() }
|
||||
.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,
|
||||
)
|
||||
}
|
||||
WcTransactionRequestButtons(
|
||||
modifier = Modifier.padding(vertical = TangemTheme.dimens.spacing16),
|
||||
onDismiss = state.actions.onDismiss,
|
||||
onSign = state.actions.onSign,
|
||||
isLoading = state.transaction.isLoading,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
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.usecase.ethereum.WcEthMessageSignUseCase
|
||||
import com.tangem.domain.walletconnect.usecase.sign.WcSignState
|
||||
import com.tangem.domain.walletconnect.usecase.sign.WcSignStep
|
||||
import com.tangem.domain.walletconnect.usecase.sign.WcSignUseCase
|
||||
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.WcTransactionRequestInfoItemUM
|
||||
import com.tangem.features.walletconnect.transaction.entity.WcTransactionRequestInfoUM
|
||||
import com.tangem.features.walletconnect.transaction.entity.WcTransactionUM
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
|
||||
internal fun WcSignUseCase.toUM(signState: WcSignState<*>, actions: WcTransactionActionsUM): WcSignTransactionUM? {
|
||||
return when (this) {
|
||||
is WcEthMessageSignUseCase -> {
|
||||
ethMessageSignToUM(
|
||||
signState = signState,
|
||||
signModel = signState.signModel as WcEthMessageSignUseCase.SignModel,
|
||||
actions = actions,
|
||||
)
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
private fun WcEthMessageSignUseCase.ethMessageSignToUM(
|
||||
signState: WcSignState<*>,
|
||||
signModel: WcEthMessageSignUseCase.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,
|
||||
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),
|
||||
),
|
||||
isLoading = signState.domainStep == WcSignStep.Signing,
|
||||
),
|
||||
transactionRequestInfo = WcTransactionRequestInfoUM(
|
||||
persistentListOf(
|
||||
WcTransactionRequestInfoItemUM(
|
||||
title = resourceReference(R.string.wc_signature_type),
|
||||
description = rawSdkRequest.request.method,
|
||||
),
|
||||
WcTransactionRequestInfoItemUM(
|
||||
title = resourceReference(R.string.wc_contents),
|
||||
description = signModel.humanMsg,
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
Loading…
Add table
Add a link
Reference in a new issue