Updated on 2026-08-14

This commit is contained in:
Tangem 2023-09-26 12:23:07 +03:00
parent 223a558f90
commit 0bbb95db97
10 changed files with 144 additions and 8 deletions

View file

@ -584,4 +584,5 @@
<string name="welcome_unlock_card">Сканировать карту</string>
<string name="welcome_unlock_description">Используйте %s или отсканируйте карту для входа в приложение</string>
<string name="welcome_unlock_title">C возвращением!</string>
<string name="token_details_choose_address">Выберите адрес</string>
</resources>

View file

@ -609,4 +609,5 @@
<string name="welcome_unlock_card">Scan card</string>
<string name="welcome_unlock_description">Use %s or scan a card to access the app</string>
<string name="welcome_unlock_title">Welcome back!</string>
<string name="token_details_choose_address">Choose address</string>
</resources>

View file

@ -0,0 +1,57 @@
package com.tangem.core.ui.components.bottomsheets.chooseaddress
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import com.tangem.core.ui.R
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import com.tangem.core.ui.components.SecondaryButton
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheet
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
import com.tangem.core.ui.res.TangemTheme
@Composable
fun ChooseAddressBottomSheet(config: TangemBottomSheetConfig) {
if (config.content is ChooseAddressBottomSheetConfig && config.isShow) {
TangemBottomSheet(config) { content ->
ChooseAddressBottomSheetContent(
content = content as ChooseAddressBottomSheetConfig,
)
}
}
}
@Composable
private fun ChooseAddressBottomSheetContent(content: ChooseAddressBottomSheetConfig) {
Column(
modifier = Modifier
.fillMaxWidth()
.padding(
start = TangemTheme.dimens.spacing24,
top = TangemTheme.dimens.spacing24,
end = TangemTheme.dimens.spacing24,
bottom = TangemTheme.dimens.spacing16,
),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(space = TangemTheme.dimens.spacing24),
) {
Text(
text = stringResource(id = R.string.token_details_choose_address),
color = TangemTheme.colors.text.secondary,
textAlign = TextAlign.Center,
style = TangemTheme.typography.body2,
)
content.addressModels.forEach { addressModel ->
SecondaryButton(
text = addressModel.type.name,
onClick = { content.onClick(addressModel) },
)
}
}
}

View file

@ -0,0 +1,9 @@
package com.tangem.core.ui.components.bottomsheets.chooseaddress
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfigContent
import com.tangem.core.ui.components.bottomsheets.tokenreceive.AddressModel
class ChooseAddressBottomSheetConfig(
val addressModels: List<AddressModel>,
val onClick: (AddressModel) -> Unit,
) : TangemBottomSheetConfigContent

View file

@ -8,6 +8,7 @@ import com.tangem.blockchain.common.BlockchainSdkError
import com.tangem.blockchain.common.WalletManager
import com.tangem.blockchain.common.address.Address
import com.tangem.blockchain.common.txhistory.TransactionHistoryRequest
import com.tangem.blockchain.common.address.AddressType
import com.tangem.blockchain.extensions.Result
import com.tangem.crypto.hdWallet.DerivationPath
import com.tangem.datasource.config.ConfigManager
@ -55,7 +56,11 @@ class DefaultWalletManagersFacade(
return getAndUpdateWalletManager(userWallet, blockchain, derivationPath, extraTokens)
}
override suspend fun getExploreUrl(userWalletId: UserWalletId, network: Network): String {
override suspend fun getExploreUrl(
userWalletId: UserWalletId,
network: Network,
addressType: AddressType,
): String {
val userWallet = getUserWallet(userWalletId)
val blockchain = Blockchain.fromId(network.id.value)
@ -69,7 +74,8 @@ class DefaultWalletManagersFacade(
"Unable to get a wallet manager for blockchain: $blockchain"
}
return walletManager.wallet.getExploreUrl()
val address = walletManager.wallet.addresses.find { it.type == addressType }?.value
return walletManager.wallet.getExploreUrl(address)
}
override suspend fun getTxHistoryState(userWalletId: UserWalletId, network: Network): TxHistoryState {

View file

@ -7,6 +7,7 @@ import com.tangem.blockchain.common.address.Address
import com.tangem.domain.tokens.model.CryptoCurrency
import com.tangem.domain.tokens.model.Network
import com.tangem.domain.tokens.model.warnings.CryptoCurrencyWarning
import com.tangem.blockchain.common.address.AddressType
import com.tangem.domain.txhistory.models.PaginationWrapper
import com.tangem.domain.txhistory.models.TxHistoryItem
import com.tangem.domain.txhistory.models.TxHistoryState
@ -40,10 +41,11 @@ interface WalletManagersFacade {
*
* @param userWalletId The ID of the user's wallet.
* @param network The network.
* @param addressType Address type.
*
* @return The network explorer URL, maybe empty if the wallet manager was not found.
* */
suspend fun getExploreUrl(userWalletId: UserWalletId, network: Network): String
suspend fun getExploreUrl(userWalletId: UserWalletId, network: Network, addressType: AddressType): String
/**
* Returns transactions count

View file

@ -2,6 +2,7 @@ package com.tangem.domain.wallets.usecase
import arrow.core.raise.catch
import com.tangem.domain.tokens.model.Network
import com.tangem.blockchain.common.address.AddressType
import com.tangem.domain.walletmanager.WalletManagersFacade
import com.tangem.domain.wallets.models.UserWalletId
@ -9,8 +10,12 @@ import com.tangem.domain.wallets.models.UserWalletId
class GetExploreUrlUseCase(private val walletsManagersFacade: WalletManagersFacade) {
// FIXME: Handle error
suspend operator fun invoke(userWalletId: UserWalletId, network: Network): String {
return catch({ walletsManagersFacade.getExploreUrl(userWalletId, network) }) {
suspend operator fun invoke(
userWalletId: UserWalletId,
network: Network,
addressType: AddressType = AddressType.Default,
): String {
return catch({ walletsManagersFacade.getExploreUrl(userWalletId, network, addressType) }) {
""
}
}

View file

@ -5,6 +5,7 @@ import arrow.core.Either
import com.tangem.blockchain.common.address.Address
import com.tangem.common.Provider
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
import com.tangem.core.ui.components.bottomsheets.chooseaddress.ChooseAddressBottomSheetConfig
import com.tangem.core.ui.components.bottomsheets.tokenreceive.AddressModel
import com.tangem.core.ui.components.bottomsheets.tokenreceive.TokenReceiveBottomSheetConfig
import com.tangem.domain.appcurrency.model.AppCurrency
@ -164,6 +165,27 @@ internal class TokenDetailsStateFactory(
)
}
fun getStateWithChooseAddressBottomSheet(
addresses: List<Address>,
onAddressTypeClick: (AddressModel) -> Unit,
): TokenDetailsState {
return currentStateProvider().copy(
bottomSheetConfig = TangemBottomSheetConfig(
isShow = true,
onDismissRequest = clickIntents::onDismissBottomSheet,
content = ChooseAddressBottomSheetConfig(
addressModels = addresses.map {
AddressModel(
value = it.value,
type = AddressModel.Type.valueOf(it.type.name),
)
},
onClick = onAddressTypeClick,
),
),
)
}
fun getStateWithClosedBottomSheet(): TokenDetailsState {
val state = currentStateProvider()
return state.copy(

View file

@ -17,7 +17,10 @@ import androidx.compose.ui.draw.clip
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.util.fastForEach
import androidx.paging.compose.collectAsLazyPagingItems
import com.tangem.core.ui.components.bottomsheets.chooseaddress.ChooseAddressBottomSheet
import com.tangem.core.ui.components.bottomsheets.chooseaddress.ChooseAddressBottomSheetConfig
import com.tangem.core.ui.components.bottomsheets.tokenreceive.TokenReceiveBottomSheet
import com.tangem.core.ui.components.bottomsheets.tokenreceive.TokenReceiveBottomSheetConfig
import com.tangem.core.ui.components.marketprice.MarketPriceBlock
import com.tangem.core.ui.components.marketprice.MarketPriceBlockState
import com.tangem.core.ui.components.notifications.Notification
@ -109,9 +112,16 @@ internal fun TokenDetailsScreen(state: TokenDetailsState) {
TokenDetailsDialogs(state = state)
state.bottomSheetConfig?.let { config ->
TokenReceiveBottomSheet(
config = config,
)
if (config.isShow) {
when (config.content) {
is TokenReceiveBottomSheetConfig -> {
TokenReceiveBottomSheet(config = config)
}
is ChooseAddressBottomSheetConfig -> {
ChooseAddressBottomSheet(config = config)
}
}
}
}
}
}

View file

@ -6,6 +6,7 @@ import androidx.compose.runtime.setValue
import androidx.lifecycle.*
import androidx.paging.cachedIn
import arrow.core.getOrElse
import com.tangem.blockchain.common.address.AddressType
import com.tangem.common.Provider
import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
import com.tangem.domain.appcurrency.model.AppCurrency
@ -299,11 +300,33 @@ internal class TokenDetailsViewModel @Inject constructor(
}
override fun onExploreClick() {
viewModelScope.launch(dispatchers.io) {
val addresses = walletManagersFacade.getAddress(
userWalletId = wallet.walletId,
network = cryptoCurrency.network,
)
if (addresses.size == 1) {
openUrl(AddressType.Default)
} else {
uiState = stateFactory.getStateWithChooseAddressBottomSheet(
addresses = addresses,
onAddressTypeClick = {
openUrl(AddressType.valueOf(it.type.name))
uiState = stateFactory.getStateWithClosedBottomSheet()
},
)
}
}
}
private fun openUrl(addressType: AddressType) {
viewModelScope.launch {
router.openUrl(
url = getExploreUrlUseCase(
userWalletId = wallet.walletId,
network = cryptoCurrency.network,
addressType = addressType,
),
)
}