From fd93510a748b290655d4f73e7e7b11311bbdcfa6 Mon Sep 17 00:00:00 2001 From: Tangem Date: Mon, 1 Aug 2022 01:11:18 +0300 Subject: [PATCH] Updated on 2026-08-14 --- .../ui/compose/CollapsedCurrencyItem.kt | 155 ------------- .../tokens/ui/compose/ExpandedCurrencyItem.kt | 152 ------------- .../tokens/ui/compose/ListOfCurrencies.kt | 12 +- .../currencyItem/CurrencyExpandedContent.kt | 62 ++++++ .../{ => currencyItem}/CurrencyItem.kt | 28 ++- .../compose/currencyItem/CurrencyItemArrow.kt | 91 ++++++++ .../currencyItem/CurrencyItemHeader.kt | 208 ++++++++++++++++++ .../compose/{ => currencyItem}/NetworkItem.kt | 89 +++++--- 8 files changed, 438 insertions(+), 359 deletions(-) delete mode 100644 app/src/main/java/com/tangem/tap/features/tokens/ui/compose/CollapsedCurrencyItem.kt delete mode 100644 app/src/main/java/com/tangem/tap/features/tokens/ui/compose/ExpandedCurrencyItem.kt create mode 100644 app/src/main/java/com/tangem/tap/features/tokens/ui/compose/currencyItem/CurrencyExpandedContent.kt rename app/src/main/java/com/tangem/tap/features/tokens/ui/compose/{ => currencyItem}/CurrencyItem.kt (53%) create mode 100644 app/src/main/java/com/tangem/tap/features/tokens/ui/compose/currencyItem/CurrencyItemArrow.kt create mode 100644 app/src/main/java/com/tangem/tap/features/tokens/ui/compose/currencyItem/CurrencyItemHeader.kt rename app/src/main/java/com/tangem/tap/features/tokens/ui/compose/{ => currencyItem}/NetworkItem.kt (70%) diff --git a/app/src/main/java/com/tangem/tap/features/tokens/ui/compose/CollapsedCurrencyItem.kt b/app/src/main/java/com/tangem/tap/features/tokens/ui/compose/CollapsedCurrencyItem.kt deleted file mode 100644 index 5ac13c1815..0000000000 --- a/app/src/main/java/com/tangem/tap/features/tokens/ui/compose/CollapsedCurrencyItem.kt +++ /dev/null @@ -1,155 +0,0 @@ -package com.tangem.tap.features.tokens.ui.compose - -import androidx.compose.foundation.Image -import androidx.compose.foundation.background -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.material.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.graphics.Color -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.res.painterResource -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import coil.compose.SubcomposeAsyncImage -import coil.request.ImageRequest -import com.tangem.blockchain.common.Blockchain -import com.tangem.domain.common.extensions.fromNetworkId -import com.tangem.tap.common.extensions.getGreyedOutIconRes -import com.tangem.tap.common.extensions.getRoundIconRes -import com.tangem.tap.domain.tokens.Currency -import com.tangem.tap.features.tokens.redux.TokenWithBlockchain -import com.tangem.wallet.R - -@Composable -fun CollapsedCurrencyItem( - currency: Currency, - addedTokens: List, - addedBlockchains: List, - onCurrencyClick: (String) -> Unit -) { - Row( - modifier = Modifier - .fillMaxWidth() - .clickable(onClick = { onCurrencyClick(currency.id) }) - ) { - val blockchain = Blockchain.fromNetworkId(currency.id) - - SubcomposeAsyncImage( - model = ImageRequest.Builder(LocalContext.current) - .data(currency.iconUrl) - .crossfade(true) - .build(), - contentDescription = currency.id, - loading = { CurrencyPlaceholderIcon(currency.id) }, - error = { CurrencyPlaceholderIcon(currency.id) }, - modifier = Modifier - .clip(CircleShape) - .padding(16.dp) - .size(46.dp), - ) - Column( - modifier = Modifier - .fillMaxHeight() - .weight(1f) - .align(Alignment.CenterVertically) - ) { - Text( - text = currency.fullName, - fontSize = 17.sp, - fontWeight = FontWeight.Normal, - color = Color(0xFF1C1C1E), - ) - Spacer(modifier = Modifier.size(6.dp)) - Row { - if (!currency.contracts.isNullOrEmpty()) { - currency.contracts.map { contract -> - if (contract.address == null) { - BlockchainNetworkItem( - blockchain = contract.blockchain, - isMainNetwork = true, - addedBlockchains = addedBlockchains - ) - } else { - val added = - addedTokens.map { it.token.contractAddress } - .contains(contract.address) - val icon = if (added) { - contract.blockchain.getRoundIconRes() - } else { - contract.blockchain.getGreyedOutIconRes() - } - Image( - painter = painterResource(id = icon), - contentDescription = null, - Modifier - .size(20.dp) - ) - Spacer(modifier = Modifier.size(5.dp)) - } - - } - } else { - BlockchainNetworkItem( - blockchain = blockchain, - isMainNetwork = false, - addedBlockchains = addedBlockchains - ) - } - } - } - Image( - painter = painterResource(id = R.drawable.ic_arrow_collapsed), - contentDescription = null, - Modifier - .padding(20.dp) - .align(Alignment.CenterVertically) - - ) - } -} - -@Composable -fun BlockchainNetworkItem( - blockchain: Blockchain?, - isMainNetwork: Boolean, - addedBlockchains: List -) { - val added = addedBlockchains.contains(blockchain) - val icon = - if (added) blockchain?.getRoundIconRes() else blockchain?.getGreyedOutIconRes() - if (icon != null) { - Box(Modifier - .size(20.dp)) { - Image( - painter = painterResource(id = icon), - contentDescription = null, - Modifier - .size(20.dp) - ) - if (isMainNetwork) { - Box( - modifier = Modifier - .align(Alignment.TopEnd) - .size(7.dp) - .clip(CircleShape) - .background(Color.White) - ) { - Box( - modifier = Modifier - .align(Alignment.Center) - .size(5.dp) - .clip(CircleShape) - .background(Color(0xFF1ACE80)) - ) - } - } - } - Spacer(modifier = Modifier.size(5.dp)) - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/tokens/ui/compose/ExpandedCurrencyItem.kt b/app/src/main/java/com/tangem/tap/features/tokens/ui/compose/ExpandedCurrencyItem.kt deleted file mode 100644 index cecf873bf9..0000000000 --- a/app/src/main/java/com/tangem/tap/features/tokens/ui/compose/ExpandedCurrencyItem.kt +++ /dev/null @@ -1,152 +0,0 @@ -package com.tangem.tap.features.tokens.ui.compose - -import androidx.compose.foundation.Image -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.material.Divider -import androidx.compose.material.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.graphics.Color -import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.res.painterResource -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import coil.compose.SubcomposeAsyncImage -import coil.request.ImageRequest -import com.tangem.blockchain.common.Blockchain -import com.tangem.tap.domain.tokens.Currency -import com.tangem.tap.features.tokens.redux.ContractAddress -import com.tangem.tap.features.tokens.redux.TokenWithBlockchain -import com.tangem.wallet.R - -@Composable -fun ExpandedCurrencyItem( - currency: Currency, - addedTokens: List, - addedBlockchains: List, - allowToAdd: Boolean, - onCurrencyClick: (String) -> Unit, - onAddCurrencyToggled: (Currency, TokenWithBlockchain?) -> Unit, - onNetworkItemClicked: (ContractAddress) -> Unit -) { - Column { - Row( - modifier = Modifier - .fillMaxWidth() - .clickable(onClick = { onCurrencyClick(currency.id) }) - ) { - SubcomposeAsyncImage( - model = ImageRequest.Builder(LocalContext.current) - .data(currency.iconUrl) - .crossfade(true) - .build(), - contentDescription = currency.id, - loading = { CurrencyPlaceholderIcon(currency.id) }, - error = { CurrencyPlaceholderIcon(currency.id) }, - modifier = Modifier - .clip(CircleShape) - .padding(start = 16.dp, top = 16.dp, end = 16.dp) - .size(46.dp), - ) - Column( - modifier = Modifier - .fillMaxHeight() - .weight(1f) - .padding(top = 14.dp) - .align(Alignment.CenterVertically) - ) { - Text( - text = currency.fullName, - fontSize = 17.sp, - fontWeight = FontWeight.Normal, - color = Color(0xFF1C1C1E), - ) - Spacer(modifier = Modifier.size(6.dp)) - Text( - text = stringResource(id = R.string.currency_subtitle_expanded), - fontSize = 13.sp, - fontWeight = FontWeight.Normal, - color = Color(0xFF8E8E93), - ) - } - Image( - painter = painterResource(id = R.drawable.ic_arrow_extended), - contentDescription = null, - Modifier - .padding(20.dp) - .align(Alignment.CenterVertically) - ) - } - - val blockchains = currency.contracts.map { it.blockchain } - - Row { - Box( - modifier = Modifier - .fillMaxHeight() - ) { - if (blockchains.size > 1) { - val dividerHeight = if (blockchains.size == 2) { - 60 - } else if (blockchains.size == 3) { - 110 - } else { - 43 * blockchains.size - } - Divider( - color = Color(0xFFDEDEDE), - modifier = Modifier - .height(dividerHeight.dp) - .padding(start = 37.5.dp) - .width(1.dp) - ) - } - - Column { - blockchains.map { - Image( - painter = painterResource(id = R.drawable.ic_link), - contentDescription = null, - Modifier - .padding( - start = 37.dp, - ) - ) - Spacer(modifier = Modifier.size(13.5.dp)) - } - } - } - - Column( - modifier = Modifier - .fillMaxWidth() - .padding(top = 6.dp), - ) { - blockchains.map { blockchain -> - val contract = currency.contracts.firstOrNull { it.blockchain == blockchain } - ?: return@map - val added = if (contract.address != null) { - addedTokens.map { it.token.contractAddress }.contains(contract.address) - } else { - addedBlockchains.contains(blockchain) - } - NetworkItem( - currency = currency, - contract = contract, - blockchain = blockchain, - allowToAdd = allowToAdd, - added = added, - onAddCurrencyToggled = onAddCurrencyToggled, - onNetworkItemClicked = onNetworkItemClicked, - ) - } - } - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/tokens/ui/compose/ListOfCurrencies.kt b/app/src/main/java/com/tangem/tap/features/tokens/ui/compose/ListOfCurrencies.kt index 14f36c1dd4..613f741c55 100644 --- a/app/src/main/java/com/tangem/tap/features/tokens/ui/compose/ListOfCurrencies.kt +++ b/app/src/main/java/com/tangem/tap/features/tokens/ui/compose/ListOfCurrencies.kt @@ -1,5 +1,6 @@ package com.tangem.tap.features.tokens.ui.compose +import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.lazy.LazyColumn @@ -16,7 +17,7 @@ import com.tangem.tap.common.compose.extensions.OnBottomReached import com.tangem.tap.domain.tokens.Currency import com.tangem.tap.features.tokens.redux.ContractAddress import com.tangem.tap.features.tokens.redux.TokenWithBlockchain - +import com.tangem.tap.features.tokens.ui.compose.currencyItem.CurrencyItem @Composable fun ListOfCurrencies( @@ -27,7 +28,7 @@ fun ListOfCurrencies( allowToAdd: Boolean, onAddCurrencyToggled: (Currency, TokenWithBlockchain?) -> Unit, onNetworkItemClicked: (ContractAddress) -> Unit, - onLoadMore: () -> Unit + onLoadMore: () -> Unit, ) { val expandedCurrencies = remember { mutableStateOf(listOf("")) } @@ -50,7 +51,8 @@ fun ListOfCurrencies( state = listState, modifier = Modifier .fillMaxSize(), - contentPadding = PaddingValues(bottom = 90.dp) + contentPadding = PaddingValues(bottom = 90.dp), + verticalArrangement = Arrangement.spacedBy(12.dp), ) { item { header() } itemsIndexed(currencies) { index, currency -> @@ -59,10 +61,10 @@ fun ListOfCurrencies( addedTokens = addedTokens, addedBlockchains = addedBlockchains, allowToAdd = allowToAdd, - expanded = expandedCurrencies.value.contains(currency.id), + isExpanded = expandedCurrencies.value.contains(currency.id), onCurrencyClick = onCurrencyClick, onAddCurrencyToggled = onAddCurrencyToggled, - onNetworkItemClicked = onNetworkItemClicked + onNetworkItemClicked = onNetworkItemClicked, ) } } diff --git a/app/src/main/java/com/tangem/tap/features/tokens/ui/compose/currencyItem/CurrencyExpandedContent.kt b/app/src/main/java/com/tangem/tap/features/tokens/ui/compose/currencyItem/CurrencyExpandedContent.kt new file mode 100644 index 0000000000..b6d2fb3070 --- /dev/null +++ b/app/src/main/java/com/tangem/tap/features/tokens/ui/compose/currencyItem/CurrencyExpandedContent.kt @@ -0,0 +1,62 @@ +package com.tangem.tap.features.tokens.ui.compose.currencyItem + +import androidx.compose.animation.AnimatedVisibility +import androidx.compose.animation.expandVertically +import androidx.compose.animation.fadeIn +import androidx.compose.animation.fadeOut +import androidx.compose.animation.shrinkVertically +import androidx.compose.foundation.layout.Column +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.blockchain.common.Blockchain +import com.tangem.tap.domain.tokens.Currency +import com.tangem.tap.features.tokens.redux.ContractAddress +import com.tangem.tap.features.tokens.redux.TokenWithBlockchain + +@Composable +fun CurrencyExpandedContent( + currency: Currency, + addedTokens: List, + addedBlockchains: List, + allowToAdd: Boolean, + isExpanded: Boolean, + onAddCurrencyToggled: (Currency, TokenWithBlockchain?) -> Unit, + onNetworkItemClicked: (ContractAddress) -> Unit, +) { + AnimatedVisibility( + visible = isExpanded, + enter = fadeIn() + expandVertically(), + exit = fadeOut() + shrinkVertically(), + ) { + val blockchains = currency.contracts.map { it.blockchain } + Row { + Column( + modifier = Modifier + .fillMaxWidth(), + ) { + blockchains.mapIndexed { index, blockchain -> + val contract = currency.contracts.firstOrNull { it.blockchain == blockchain } + ?: return@mapIndexed + val added = if (contract.address != null) { + addedTokens.map { it.token.contractAddress }.contains(contract.address) + } else { + addedBlockchains.contains(blockchain) + } + NetworkItem( + currency = currency, + contract = contract, + blockchain = blockchain, + allowToAdd = allowToAdd, + added = added, + index = index, + size = blockchains.size, + onAddCurrencyToggled = onAddCurrencyToggled, + onNetworkItemClicked = onNetworkItemClicked, + ) + } + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/tokens/ui/compose/CurrencyItem.kt b/app/src/main/java/com/tangem/tap/features/tokens/ui/compose/currencyItem/CurrencyItem.kt similarity index 53% rename from app/src/main/java/com/tangem/tap/features/tokens/ui/compose/CurrencyItem.kt rename to app/src/main/java/com/tangem/tap/features/tokens/ui/compose/currencyItem/CurrencyItem.kt index 5ba1f8b683..6758c71e82 100644 --- a/app/src/main/java/com/tangem/tap/features/tokens/ui/compose/CurrencyItem.kt +++ b/app/src/main/java/com/tangem/tap/features/tokens/ui/compose/currencyItem/CurrencyItem.kt @@ -1,5 +1,6 @@ -package com.tangem.tap.features.tokens.ui.compose +package com.tangem.tap.features.tokens.ui.compose.currencyItem +import androidx.compose.foundation.layout.Column import androidx.compose.runtime.Composable import com.tangem.blockchain.common.Blockchain import com.tangem.tap.domain.tokens.Currency @@ -12,24 +13,27 @@ fun CurrencyItem( addedTokens: List, addedBlockchains: List, allowToAdd: Boolean, - expanded: Boolean, + isExpanded: Boolean, onCurrencyClick: (String) -> Unit, onAddCurrencyToggled: (Currency, TokenWithBlockchain?) -> Unit, - onNetworkItemClicked: (ContractAddress) -> Unit + onNetworkItemClicked: (ContractAddress) -> Unit, ) { - if (expanded) { - ExpandedCurrencyItem( + Column { + CurrencyItemHeader( + currency = currency, + addedTokens = addedTokens, + addedBlockchains = addedBlockchains, + isExpanded = isExpanded, + onCurrencyClick = onCurrencyClick, + ) + CurrencyExpandedContent( currency = currency, addedTokens = addedTokens, addedBlockchains = addedBlockchains, allowToAdd = allowToAdd, - onCurrencyClick = onCurrencyClick, onAddCurrencyToggled = onAddCurrencyToggled, - onNetworkItemClicked = onNetworkItemClicked - ) - } else { - CollapsedCurrencyItem( - currency = currency, addedTokens = addedTokens, - addedBlockchains = addedBlockchains, onCurrencyClick + isExpanded = isExpanded, + onAddCurrencyToggled = onAddCurrencyToggled, + onNetworkItemClicked = onNetworkItemClicked, ) } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/tokens/ui/compose/currencyItem/CurrencyItemArrow.kt b/app/src/main/java/com/tangem/tap/features/tokens/ui/compose/currencyItem/CurrencyItemArrow.kt new file mode 100644 index 0000000000..4be02043d5 --- /dev/null +++ b/app/src/main/java/com/tangem/tap/features/tokens/ui/compose/currencyItem/CurrencyItemArrow.kt @@ -0,0 +1,91 @@ +package com.tangem.tap.features.tokens.ui.compose.currencyItem + +import androidx.compose.foundation.Image +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.layout.wrapContentHeight +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp +import com.tangem.wallet.R + +/** +[REDACTED_AUTHOR] + */ +@Composable +fun CurrencyItemArrow( + rowHeight: Dp, + isLastArrow: Boolean, +) { + Box(Modifier.height(rowHeight)) { + if (!isLastArrow) { + MiddleArrowView(rowHeight) + } else { + LastArrowView(rowHeight) + } + } +} + +@Composable +private fun MiddleArrowView(rowHeight: Dp) { + Box { + Box( + modifier = Modifier + .padding(start = 0.5.dp), + ) { + Box( + modifier = Modifier + .background(color = Color(0xFFDEDEDE)) + .width(0.8.dp) + .fillMaxHeight(), + ) + } + + LastArrowView(rowHeight) + } +} + +@Composable +private fun LastArrowView(rowHeight: Dp) { + Image( + modifier = Modifier + .height(rowHeight / 2 + 3.5.dp), + painter = painterResource(id = R.drawable.ic_link), + contentDescription = null, + ) +} + +@Preview +@Composable +fun ArrowViewPreview() { + Box( + Modifier + .background(color = Color.White), + ) { + Column( + modifier = Modifier + .fillMaxWidth() + .wrapContentHeight() + .padding(start = 37.dp), + ) { + CurrencyItemArrow( + rowHeight = 62.dp, + isLastArrow = false, + ) + CurrencyItemArrow( + rowHeight = 62.dp, + isLastArrow = true, + ) + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/tokens/ui/compose/currencyItem/CurrencyItemHeader.kt b/app/src/main/java/com/tangem/tap/features/tokens/ui/compose/currencyItem/CurrencyItemHeader.kt new file mode 100644 index 0000000000..f3d40a401b --- /dev/null +++ b/app/src/main/java/com/tangem/tap/features/tokens/ui/compose/currencyItem/CurrencyItemHeader.kt @@ -0,0 +1,208 @@ +package com.tangem.tap.features.tokens.ui.compose.currencyItem + +import androidx.compose.foundation.Image +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import coil.compose.SubcomposeAsyncImage +import coil.request.ImageRequest +import com.tangem.blockchain.common.Blockchain +import com.tangem.domain.common.extensions.fromNetworkId +import com.tangem.tap.common.extensions.getGreyedOutIconRes +import com.tangem.tap.common.extensions.getRoundIconRes +import com.tangem.tap.domain.tokens.Currency +import com.tangem.tap.features.tokens.redux.TokenWithBlockchain +import com.tangem.tap.features.tokens.ui.compose.CurrencyPlaceholderIcon +import com.tangem.tap.features.tokens.ui.compose.fullName +import com.tangem.wallet.R + +@Composable +fun CurrencyItemHeader( + currency: Currency, + addedTokens: List, + addedBlockchains: List, + isExpanded: Boolean, + onCurrencyClick: (String) -> Unit, +) { + Row( + modifier = Modifier + .fillMaxWidth() + .height(62.dp) + .clickable( + interactionSource = remember { MutableInteractionSource() }, + indication = null, + onClick = { onCurrencyClick(currency.id) }, + ), + ) { + Box( + modifier = Modifier + .padding(horizontal = 16.dp) + .align(Alignment.CenterVertically) + .clip(RoundedCornerShape(6.dp)), + ) { + SubcomposeAsyncImage( + modifier = Modifier + .size(46.dp), + model = ImageRequest.Builder(LocalContext.current) + .data(currency.iconUrl) + .crossfade(true) + .build(), + contentDescription = currency.id, + loading = { CurrencyPlaceholderIcon(currency.id) }, + error = { CurrencyPlaceholderIcon(currency.id) }, + ) + } + + Column( + modifier = Modifier + .weight(1f) + .align(Alignment.CenterVertically), + ) { + Text( + text = currency.fullName, + fontSize = 17.sp, + fontWeight = FontWeight.Normal, + color = Color(0xFF1C1C1E), + ) + Spacer(modifier = Modifier.size(6.dp)) + + Box( + modifier = Modifier + .fillMaxWidth() + .height(20.dp), + ) { + if (isExpanded) { + Text( + modifier = Modifier.align(Alignment.TopStart), + text = stringResource(id = R.string.currency_subtitle_expanded), + fontSize = 13.sp, + fontWeight = FontWeight.Normal, + color = Color(0xFF8E8E93), + ) + } else { + NetworksRow( + currency = currency, + addedTokens = addedTokens, + addedBlockchains = addedBlockchains, + ) + } + } + } + + val expandCollapseArrow = if (isExpanded) R.drawable.ic_arrow_extended else R.drawable.ic_arrow_collapsed + Image( + painter = painterResource(id = expandCollapseArrow), + contentDescription = null, + Modifier + .padding(20.dp) + .align(Alignment.CenterVertically), + ) + } +} + +@Composable +private fun NetworksRow( + currency: Currency, + addedTokens: List, + addedBlockchains: List, +) { + Row { + if (currency.contracts.isNotEmpty()) { + currency.contracts.map { contract -> + if (contract.address == null) { + BlockchainNetworkItem( + blockchain = contract.blockchain, + isMainNetwork = true, + addedBlockchains = addedBlockchains, + ) + } else { + val isAdded = addedTokens.map { it.token.contractAddress }.contains(contract.address) + val iconResId = if (isAdded) { + contract.blockchain.getRoundIconRes() + } else { + contract.blockchain.getGreyedOutIconRes() + } + Image( + modifier = Modifier + .size(20.dp), + painter = painterResource(id = iconResId), + contentDescription = null, + ) + Spacer(Modifier.size(5.dp)) + } + + } + } else { + BlockchainNetworkItem( + blockchain = Blockchain.fromNetworkId(currency.id), + isMainNetwork = false, + addedBlockchains = addedBlockchains, + ) + } + } +} + +@Composable +private fun BlockchainNetworkItem( + blockchain: Blockchain?, + isMainNetwork: Boolean, + addedBlockchains: List, +) { + val added = addedBlockchains.contains(blockchain) + val icon = + if (added) blockchain?.getRoundIconRes() else blockchain?.getGreyedOutIconRes() + if (icon != null) { + Box( + Modifier + .size(20.dp), + ) { + Image( + painter = painterResource(id = icon), + contentDescription = null, + Modifier + .size(20.dp), + ) + if (isMainNetwork) { + Box( + modifier = Modifier + .align(Alignment.TopEnd) + .size(7.dp) + .clip(CircleShape) + .background(Color.White), + ) { + Box( + modifier = Modifier + .align(Alignment.Center) + .size(5.dp) + .clip(CircleShape) + .background(Color(0xFF1ACE80)), + ) + } + } + } + Spacer(modifier = Modifier.size(5.dp)) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/tokens/ui/compose/NetworkItem.kt b/app/src/main/java/com/tangem/tap/features/tokens/ui/compose/currencyItem/NetworkItem.kt similarity index 70% rename from app/src/main/java/com/tangem/tap/features/tokens/ui/compose/NetworkItem.kt rename to app/src/main/java/com/tangem/tap/features/tokens/ui/compose/currencyItem/NetworkItem.kt index 0f45d867bf..2928ace0d8 100644 --- a/app/src/main/java/com/tangem/tap/features/tokens/ui/compose/NetworkItem.kt +++ b/app/src/main/java/com/tangem/tap/features/tokens/ui/compose/currencyItem/NetworkItem.kt @@ -1,10 +1,18 @@ -package com.tangem.tap.features.tokens.ui.compose +package com.tangem.tap.features.tokens.ui.compose.currencyItem import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.background import androidx.compose.foundation.combinedClickable import androidx.compose.foundation.interaction.MutableInteractionSource -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width import androidx.compose.foundation.shape.CircleShape import androidx.compose.material.Switch import androidx.compose.material.SwitchDefaults @@ -31,6 +39,7 @@ import com.tangem.tap.domain.tokens.Contract import com.tangem.tap.domain.tokens.Currency import com.tangem.tap.features.tokens.redux.ContractAddress import com.tangem.tap.features.tokens.redux.TokenWithBlockchain +import com.tangem.tap.features.tokens.ui.compose.CurrencyPlaceholderIcon @OptIn(ExperimentalFoundationApi::class) @Composable @@ -40,13 +49,17 @@ fun NetworkItem( blockchain: Blockchain, allowToAdd: Boolean, added: Boolean, + index: Int, + size: Int, onAddCurrencyToggled: (Currency, TokenWithBlockchain?) -> Unit, - onNetworkItemClicked: (ContractAddress) -> Unit + onNetworkItemClicked: (ContractAddress) -> Unit, ) { + val rowHeight = 53.dp Row( modifier = Modifier .fillMaxWidth() + .height(rowHeight) .combinedClickable( enabled = allowToAdd, onLongClick = { @@ -54,13 +67,22 @@ fun NetworkItem( }, onClick = {}, indication = null, - interactionSource = remember { MutableInteractionSource() } - ) + interactionSource = remember { MutableInteractionSource() }, + ), ) { + Box( + Modifier + .width(78.dp) + .padding(start = 38.dp), + ) { + CurrencyItemArrow( + rowHeight = rowHeight, + isLastArrow = index == size - 1, + ) + } Box( modifier = Modifier - .align(Alignment.CenterVertically) - .padding(start = 8.dp, top = 16.dp, bottom = 16.dp, end = 6.dp) + .align(Alignment.CenterVertically), ) { SubcomposeAsyncImage( model = if (added) blockchain.getRoundIconRes() else blockchain.getGreyedOutIconRes(), @@ -68,7 +90,7 @@ fun NetworkItem( loading = { CurrencyPlaceholderIcon(blockchain.id) }, error = { CurrencyPlaceholderIcon(blockchain.id) }, modifier = Modifier - .size(20.dp) + .size(20.dp), ) if (contract.address == null) { Box( @@ -76,34 +98,31 @@ fun NetworkItem( .align(Alignment.TopEnd) .size(7.dp) .clip(CircleShape) - .background(Color.White) + .background(Color.White), ) { Box( modifier = Modifier .align(Alignment.Center) .size(5.dp) .clip(CircleShape) - .background(Color(0xFF1ACE80)) + .background(Color(0xFF1ACE80)), ) } } } - Row( + Spacer(Modifier.width(6.dp)) + Text( modifier = Modifier - .fillMaxHeight() .weight(1f) - .align(Alignment.CenterVertically) - ) { - Text( - text = prepareNetworkNameSpannableText( - blockchain = blockchain, - contractAddress = contract.address - ), - fontWeight = FontWeight.SemiBold, - fontSize = 13.sp, - color = if (added) Color.Black else Color(0xFF848488), - ) - } + .align(Alignment.CenterVertically), + text = prepareNetworkNameSpannableText( + blockchain = blockchain, + contractAddress = contract.address, + ), + fontWeight = FontWeight.SemiBold, + fontSize = 13.sp, + color = if (added) Color.Black else Color(0xFF848488), + ) if (allowToAdd) { val token = if (contract.address != null) { @@ -117,8 +136,7 @@ fun NetworkItem( } else { null } - val tokenWithBlockchain = - token?.let { TokenWithBlockchain(token, contract.blockchain) } + val tokenWithBlockchain = token?.let { TokenWithBlockchain(it, contract.blockchain) } val currencyToSave = if (contract.address == null) { currency.copy(id = contract.networkId) @@ -127,22 +145,23 @@ fun NetworkItem( } Switch( + modifier = Modifier + .fillMaxHeight() + .padding(start = 16.dp, end = 16.dp), checked = added, onCheckedChange = { onAddCurrencyToggled(currencyToSave, tokenWithBlockchain) }, - modifier = Modifier.padding(start = 16.dp, end = 16.dp), colors = SwitchDefaults.colors( - checkedThumbColor = Color(0xFF1ACE80) - ) + checkedThumbColor = Color(0xFF1ACE80), + ), ) } } } - @Composable -fun prepareNetworkNameSpannableText( +private fun prepareNetworkNameSpannableText( blockchain: Blockchain, - contractAddress: String? + contractAddress: String?, ): AnnotatedString { val blockchainName = blockchain.fullNameWithoutTestnet.uppercase() @@ -158,11 +177,11 @@ fun prepareNetworkNameSpannableText( AnnotatedString.Range( SpanStyle( fontWeight = FontWeight.Normal, - color = if (contractAddress != null) Color(0xFF8E8E93) else Color(0xFF1ACE80) + color = if (contractAddress != null) Color(0xFF8E8E93) else Color(0xFF1ACE80), ), start = startOfAdditionalText, - end = text.length - ) + end = text.length, + ), ) return AnnotatedString(text = text, spanStyles = spanStyles) } \ No newline at end of file