Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ton connect tx confirm refactor #7816

Merged
merged 20 commits into from
Dec 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package io.horizontalsystems.bankwallet.modules.tonconnect

import androidx.activity.ComponentActivity
import androidx.compose.animation.Crossfade
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
Expand All @@ -18,22 +20,36 @@ import androidx.navigation.NavController
import io.horizontalsystems.bankwallet.R
import io.horizontalsystems.bankwallet.core.App
import io.horizontalsystems.bankwallet.core.AppLogger
import io.horizontalsystems.bankwallet.core.adapters.TonTransactionRecord
import io.horizontalsystems.bankwallet.core.stats.StatPage
import io.horizontalsystems.bankwallet.modules.confirm.ConfirmTransactionScreen
import io.horizontalsystems.bankwallet.modules.main.MainActivityViewModel
import io.horizontalsystems.bankwallet.modules.transactionInfo.TransactionInfoSection
import io.horizontalsystems.bankwallet.modules.xtransaction.cells.HeaderCell
import io.horizontalsystems.bankwallet.modules.xtransaction.helpers.TransactionInfoHelper
import io.horizontalsystems.bankwallet.modules.xtransaction.sections.BurnSection
import io.horizontalsystems.bankwallet.modules.xtransaction.sections.FeeSection
import io.horizontalsystems.bankwallet.modules.xtransaction.sections.MintSection
import io.horizontalsystems.bankwallet.modules.xtransaction.sections.ReceiveCoinSection
import io.horizontalsystems.bankwallet.modules.xtransaction.sections.SendCoinSection
import io.horizontalsystems.bankwallet.modules.xtransaction.sections.SwapSection
import io.horizontalsystems.bankwallet.modules.xtransaction.sections.ton.ContractCallSection
import io.horizontalsystems.bankwallet.modules.xtransaction.sections.ton.ContractDeploySection
import io.horizontalsystems.bankwallet.ui.compose.components.ButtonPrimaryDefault
import io.horizontalsystems.bankwallet.ui.compose.components.ButtonPrimaryYellow
import io.horizontalsystems.bankwallet.ui.compose.components.TextImportantError
import io.horizontalsystems.bankwallet.ui.compose.components.VSpacer
import io.horizontalsystems.bankwallet.ui.compose.components.cell.SectionUniversalLawrence
import io.horizontalsystems.core.SnackbarDuration
import io.horizontalsystems.core.helpers.HudHelper
import io.horizontalsystems.marketkit.models.BlockchainType
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch

@Composable
fun TonConnectSendRequestScreen(navController: NavController) {
val logger = remember { AppLogger("ton-connect request") }
val mainActivityViewModel = viewModel<MainActivityViewModel>(viewModelStoreOwner = LocalContext.current as ComponentActivity)
val mainActivityViewModel =
viewModel<MainActivityViewModel>(viewModelStoreOwner = LocalContext.current as ComponentActivity)
val viewModel = viewModel<TonConnectSendRequestViewModel>(initializer = {
val sendRequestEntity = mainActivityViewModel.tcSendRequest.value
mainActivityViewModel.onTcSendRequestHandled()
Expand Down Expand Up @@ -64,7 +80,11 @@ fun TonConnectSendRequestScreen(navController: NavController) {
onClick = {
coroutineScope.launch {
buttonEnabled = false
HudHelper.showInProcessMessage(view, R.string.Send_Sending, SnackbarDuration.INDEFINITE)
HudHelper.showInProcessMessage(
view,
R.string.Send_Sending,
SnackbarDuration.INDEFINITE
)

try {
logger.info("click confirm button")
Expand Down Expand Up @@ -99,9 +119,118 @@ fun TonConnectSendRequestScreen(navController: NavController) {
TextImportantError(text = error.message ?: error.javaClass.simpleName)
}

uiState.itemSections.forEach { items ->
TransactionInfoSection(items, navController, { null })
VSpacer(12.dp)
Crossfade(uiState.tonTransactionRecord) { record ->
if (record != null) {
val transactionInfoHelper = remember {
TransactionInfoHelper()
}

Column {
record.actions.forEachIndexed { index, action ->
if (index != 0) {
VSpacer(12.dp)
}
TonConnectRequestActionSection(
action = action,
transactionInfoHelper = transactionInfoHelper,
navController = navController
)
}
VSpacer(12.dp)

FeeSection(
transactionInfoHelper = transactionInfoHelper,
fee = record.fee,
navController = navController
)
}
}
}
}
}

@Composable
fun TonConnectRequestActionSection(
action: TonTransactionRecord.Action,
transactionInfoHelper: TransactionInfoHelper,
navController: NavController,
) {
when (val actionType = action.type) {
is TonTransactionRecord.Action.Type.Burn -> {
BurnSection(
transactionValue = actionType.value,
transactionInfoHelper = transactionInfoHelper,
navController = navController
)
}

is TonTransactionRecord.Action.Type.ContractCall -> {
ContractCallSection(
navController = navController,
operation = actionType.operation,
address = actionType.address,
transactionValue = actionType.value,
transactionInfoHelper = transactionInfoHelper,
blockchainType = BlockchainType.Ton
)
}

is TonTransactionRecord.Action.Type.ContractDeploy -> {
ContractDeploySection(
interfaces = actionType.interfaces
)
}

is TonTransactionRecord.Action.Type.Mint -> {
MintSection(
transactionValue = actionType.value,
transactionInfoHelper = transactionInfoHelper,
navController = navController
)
}

is TonTransactionRecord.Action.Type.Receive -> {
ReceiveCoinSection(
transactionValue = actionType.value,
address = actionType.from,
comment = actionType.comment,
statPage = StatPage.TonConnect,
navController = navController,
transactionInfoHelper = transactionInfoHelper,
blockchainType = BlockchainType.Ton
)
}

is TonTransactionRecord.Action.Type.Send -> {
SendCoinSection(
transactionValue = actionType.value,
address = actionType.to,
comment = actionType.comment,
sentToSelf = actionType.sentToSelf,
statPage = StatPage.TonConnect,
navController = navController,
transactionInfoHelper = transactionInfoHelper,
blockchainType = BlockchainType.Ton
)
}

is TonTransactionRecord.Action.Type.Swap -> {
SwapSection(
transactionInfoHelper = transactionInfoHelper,
navController = navController,
transactionValueIn = actionType.valueIn,
transactionValueOut = actionType.valueOut
)
}

is TonTransactionRecord.Action.Type.Unsupported -> {
SectionUniversalLawrence {
HeaderCell(
title = stringResource(R.string.Send_Confirmation_Action),
value = actionType.type,
painter = null
)
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,9 @@ import io.horizontalsystems.bankwallet.core.IAccountManager
import io.horizontalsystems.bankwallet.core.ViewModelUiState
import io.horizontalsystems.bankwallet.core.adapters.TonTransactionRecord
import io.horizontalsystems.bankwallet.core.managers.TonConnectManager
import io.horizontalsystems.bankwallet.core.managers.TonHelper
import io.horizontalsystems.bankwallet.core.managers.TonKitWrapper
import io.horizontalsystems.bankwallet.core.managers.toTonWalletFullAccess
import io.horizontalsystems.bankwallet.core.meta
import io.horizontalsystems.bankwallet.entities.Currency
import io.horizontalsystems.bankwallet.modules.transactionInfo.TransactionInfoViewItem
import io.horizontalsystems.bankwallet.modules.transactions.TransactionSource
import io.horizontalsystems.marketkit.models.BlockchainType
import io.horizontalsystems.marketkit.models.TokenQuery
Expand All @@ -32,21 +29,16 @@ class TonConnectSendRequestViewModel(
private val transactionSigner = tonConnectManager.transactionSigner
private val tonConnectKit = App.tonConnectManager.kit
private var tonTransactionRecord: TonTransactionRecord? = null
private var itemSections: List<List<TransactionInfoViewItem>> = listOf()

private var currency = App.currencyManager.baseCurrency

private var tonWallet: TonWallet.FullAccess? = null
private var tonKitWrapper: TonKitWrapper? = null
private var tonEvent: Event? = null

override fun createState() = TonConnectSendRequestUiState(
tonTransactionRecord = tonTransactionRecord,
currency = currency,
error = error,
confirmEnabled = sendRequestEntity != null && tonWallet != null,
rejectEnabled = sendRequestEntity != null,
itemSections = itemSections
rejectEnabled = sendRequestEntity != null
)

init {
Expand Down Expand Up @@ -95,13 +87,6 @@ class TonConnectSendRequestViewModel(
)

tonTransactionRecord = tonTransactionConverter?.createTransactionRecord(tonEvent)

tonTransactionRecord?.let {
itemSections = it.actions.map { action ->
TonHelper.getViewItemsForAction(action, mapOf(), BlockchainType.Ton, false, showHistoricalRate = false)
}
}

}

fun confirm() {
Expand Down Expand Up @@ -133,9 +118,7 @@ sealed class TonConnectSendRequestError : Error() {

data class TonConnectSendRequestUiState(
val tonTransactionRecord: TonTransactionRecord?,
val currency: Currency,
val error: TonConnectSendRequestError?,
val confirmEnabled: Boolean,
val rejectEnabled: Boolean,
val itemSections: List<List<TransactionInfoViewItem>>,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
package io.horizontalsystems.bankwallet.modules.xtransaction.cells

import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalView
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.navigation.NavController
import io.horizontalsystems.bankwallet.R
import io.horizontalsystems.bankwallet.core.slideFromRight
import io.horizontalsystems.bankwallet.core.stats.StatEntity
import io.horizontalsystems.bankwallet.core.stats.StatEvent
import io.horizontalsystems.bankwallet.core.stats.StatPage
import io.horizontalsystems.bankwallet.core.stats.StatSection
import io.horizontalsystems.bankwallet.core.stats.stat
import io.horizontalsystems.bankwallet.modules.contacts.ContactsFragment
import io.horizontalsystems.bankwallet.modules.contacts.ContactsModule
import io.horizontalsystems.bankwallet.modules.contacts.Mode
import io.horizontalsystems.bankwallet.ui.compose.components.ButtonSecondaryCircle
import io.horizontalsystems.bankwallet.ui.compose.components.HSpacer
import io.horizontalsystems.bankwallet.ui.compose.components.SelectorDialogCompose
import io.horizontalsystems.bankwallet.ui.compose.components.SelectorItem
import io.horizontalsystems.bankwallet.ui.compose.components.cell.CellUniversal
import io.horizontalsystems.bankwallet.ui.compose.components.subhead1_leah
import io.horizontalsystems.bankwallet.ui.compose.components.subhead2_grey
import io.horizontalsystems.bankwallet.ui.helpers.TextHelper
import io.horizontalsystems.core.helpers.HudHelper
import io.horizontalsystems.marketkit.models.BlockchainType

@Composable
fun AddressCell(
title: String,
value: String,
showAddContactButton: Boolean,
blockchainType: BlockchainType?,
statPage: StatPage,
statSection: StatSection,
navController: NavController? = null,
borderTop: Boolean = true
) {
val view = LocalView.current
var showSaveAddressDialog by remember { mutableStateOf(false) }
CellUniversal(borderTop = borderTop) {
subhead2_grey(text = title)

HSpacer(16.dp)
subhead1_leah(
modifier = Modifier.weight(1f),
text = value,
textAlign = TextAlign.Right
)

if (showAddContactButton) {
HSpacer(16.dp)
ButtonSecondaryCircle(
icon = R.drawable.icon_20_user_plus,
onClick = { showSaveAddressDialog = true }
)
}

HSpacer(16.dp)
ButtonSecondaryCircle(
icon = R.drawable.ic_copy_20,
onClick = {
TextHelper.copyText(value)
HudHelper.showSuccessMessage(view, R.string.Hud_Text_Copied)

stat(
page = statPage,
section = statSection,
event = StatEvent.Copy(StatEntity.Address)
)
}
)
}

if (showSaveAddressDialog) {
SelectorDialogCompose(
title = stringResource(R.string.Contacts_AddAddress),
items = ContactsModule.AddAddressAction.entries.map {
SelectorItem(stringResource(it.title), false, it)
},
onDismissRequest = {
showSaveAddressDialog = false
},
onSelectItem = { action ->
blockchainType?.let {
val args = when (action) {
ContactsModule.AddAddressAction.AddToNewContact -> {
stat(
page = statPage,
section = statSection,
event = StatEvent.Open(StatPage.ContactNew)
)
ContactsFragment.Input(
Mode.AddAddressToNewContact(
blockchainType,
value
)
)
}

ContactsModule.AddAddressAction.AddToExistingContact -> {
stat(
page = statPage,
section = statSection,
event = StatEvent.Open(StatPage.ContactAddToExisting)
)
ContactsFragment.Input(
Mode.AddAddressToExistingContact(
blockchainType,
value
)
)
}
}
navController?.slideFromRight(R.id.contactsFragment, args)
}
})
}
}
Loading
Loading