Updated on 2026-08-14
This commit is contained in:
parent
2ca7759e7e
commit
552e8cc752
12 changed files with 1051 additions and 93 deletions
|
|
@ -45,6 +45,7 @@ dependencies {
|
|||
implementation(deps.lifecycle.viewModel.ktx)
|
||||
|
||||
/** Compose libraries */
|
||||
implementation(deps.compose.constraintLayout)
|
||||
implementation(deps.compose.material)
|
||||
implementation(deps.compose.animation)
|
||||
implementation(deps.compose.foundation)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,223 @@
|
|||
package com.tangem.tap.features.tokens.presentation.ui
|
||||
|
||||
import androidx.activity.compose.BackHandler
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.imePadding
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||
import androidx.compose.material.CircularProgressIndicator
|
||||
import androidx.compose.material.Scaffold
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import com.tangem.core.ui.components.PrimaryButton
|
||||
import com.tangem.core.ui.res.TangemColorPalette
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.tap.common.compose.extensions.OnBottomReached
|
||||
import com.tangem.tap.features.tokens.presentation.states.AddTokensNetworkItemState
|
||||
import com.tangem.tap.features.tokens.presentation.states.AddTokensStateHolder
|
||||
import com.tangem.tap.features.tokens.presentation.states.AddTokensToolbarState
|
||||
import com.tangem.tap.features.tokens.presentation.states.TokenItemModel
|
||||
import com.tangem.tap.features.tokens.presentation.states.TokensListVisibility
|
||||
import com.tangem.tap.features.tokens.redux.TokensAction
|
||||
import com.tangem.tap.store
|
||||
import com.tangem.wallet.R
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
@Composable
|
||||
internal fun AddTokensScreen(stateHolder: AddTokensStateHolder) {
|
||||
BackHandler(onBack = stateHolder.toolbarState.onBackButtonClick)
|
||||
|
||||
Scaffold(
|
||||
topBar = { AddTokensToolbar(state = stateHolder.toolbarState) },
|
||||
floatingActionButton = {
|
||||
if (stateHolder is AddTokensStateHolder.ManageAccess) {
|
||||
SaveChangesButton(onClick = stateHolder.onSaveButtonClick)
|
||||
}
|
||||
},
|
||||
) {
|
||||
when (stateHolder) {
|
||||
is AddTokensStateHolder.Loading -> LoadingContent()
|
||||
is TokensListVisibility -> TokensListContent(stateHolder = stateHolder, scaffoldPadding = it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun LoadingContent() {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.background(color = TangemColorPalette.White),
|
||||
contentAlignment = Alignment.Center,
|
||||
) {
|
||||
CircularProgressIndicator(color = TangemColorPalette.Meadow)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun TokensListContent(stateHolder: TokensListVisibility, scaffoldPadding: PaddingValues) {
|
||||
val state = rememberLazyListState()
|
||||
state.OnBottomReached(loadMoreThreshold = 40) {
|
||||
store.dispatch(TokensAction.LoadMore(scanResponse = store.state.globalState.scanResponse))
|
||||
}
|
||||
LazyColumn(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.padding(scaffoldPadding),
|
||||
state,
|
||||
) {
|
||||
items(
|
||||
items = stateHolder.tokens,
|
||||
key = TokenItemModel::name,
|
||||
itemContent = { TokenItem(model = it) },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun SaveChangesButton(onClick: () -> Unit) {
|
||||
PrimaryButton(
|
||||
modifier = Modifier
|
||||
.imePadding()
|
||||
.padding(horizontal = TangemTheme.dimens.spacing16)
|
||||
.fillMaxWidth(),
|
||||
text = stringResource(id = R.string.common_save_changes),
|
||||
onClick = onClick,
|
||||
)
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
private fun Preview_AddTokensScreen_Loading() {
|
||||
TangemTheme {
|
||||
AddTokensScreen(
|
||||
stateHolder = AddTokensStateHolder.Loading(
|
||||
toolbarState = AddTokensToolbarState.Title.EditAccess(
|
||||
titleResId = R.string.main_manage_tokens,
|
||||
onBackButtonClick = {},
|
||||
onSearchButtonClick = {},
|
||||
onAddCustomTokenClick = {},
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
private fun Preview_AddTokensScreen_ManageAccess() {
|
||||
TangemTheme {
|
||||
AddTokensScreen(
|
||||
stateHolder = AddTokensStateHolder.ManageAccess(
|
||||
toolbarState = AddTokensToolbarState.Title.EditAccess(
|
||||
titleResId = R.string.main_manage_tokens,
|
||||
onBackButtonClick = {},
|
||||
onSearchButtonClick = {},
|
||||
onAddCustomTokenClick = {},
|
||||
),
|
||||
tokens = listOf(
|
||||
TokenItemModel(
|
||||
name = "ETHEREUM (ETH)",
|
||||
iconUrl = "",
|
||||
networks = listOf(
|
||||
AddTokensNetworkItemState.EditAccess(
|
||||
name = "ETHEREUM",
|
||||
protocolName = "MAIN",
|
||||
iconResId = R.drawable.img_btc_22,
|
||||
isMainNetwork = true,
|
||||
isAdded = true,
|
||||
networkId = "",
|
||||
onToggleClick = {},
|
||||
),
|
||||
),
|
||||
),
|
||||
TokenItemModel(
|
||||
name = "Tether (USDT)",
|
||||
iconUrl = "https://s3.eu-central-1.amazonaws.com/tangem.api/coins/large/tether.png",
|
||||
networks = listOf(
|
||||
AddTokensNetworkItemState.EditAccess(
|
||||
name = "ETHEREUM",
|
||||
protocolName = "MAIN",
|
||||
iconResId = R.drawable.img_eth_22,
|
||||
isMainNetwork = false,
|
||||
isAdded = true,
|
||||
networkId = "",
|
||||
onToggleClick = {},
|
||||
),
|
||||
AddTokensNetworkItemState.EditAccess(
|
||||
name = "BNB SMART CHAIN",
|
||||
protocolName = "BEP20",
|
||||
iconResId = R.drawable.ic_bsc_no_color,
|
||||
isMainNetwork = false,
|
||||
isAdded = false,
|
||||
networkId = "",
|
||||
onToggleClick = {},
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
onSaveButtonClick = {},
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
private fun Preview_AddTokensScreen_ReadAccess() {
|
||||
TangemTheme {
|
||||
AddTokensScreen(
|
||||
stateHolder = AddTokensStateHolder.ReadAccess(
|
||||
toolbarState = AddTokensToolbarState.Title.EditAccess(
|
||||
titleResId = R.string.search_tokens_title,
|
||||
onBackButtonClick = {},
|
||||
onSearchButtonClick = {},
|
||||
onAddCustomTokenClick = {},
|
||||
),
|
||||
tokens = listOf(
|
||||
TokenItemModel(
|
||||
name = "ETHEREUM (ETH)",
|
||||
iconUrl = "",
|
||||
networks = listOf(
|
||||
AddTokensNetworkItemState.ReadAccess(
|
||||
name = "ETHEREUM",
|
||||
protocolName = "MAIN",
|
||||
iconResId = R.drawable.img_btc_22,
|
||||
isMainNetwork = true,
|
||||
),
|
||||
),
|
||||
),
|
||||
TokenItemModel(
|
||||
name = "Tether (USDT)",
|
||||
iconUrl = "https://s3.eu-central-1.amazonaws.com/tangem.api/coins/large/tether.png",
|
||||
networks = listOf(
|
||||
AddTokensNetworkItemState.ReadAccess(
|
||||
name = "ETHEREUM",
|
||||
protocolName = "MAIN",
|
||||
iconResId = R.drawable.img_eth_22,
|
||||
isMainNetwork = false,
|
||||
),
|
||||
AddTokensNetworkItemState.ReadAccess(
|
||||
name = "BNB SMART CHAIN",
|
||||
protocolName = "BEP20",
|
||||
iconResId = R.drawable.ic_bsc_no_color,
|
||||
isMainNetwork = false,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,207 @@
|
|||
package com.tangem.tap.features.tokens.presentation.ui
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.text.BasicTextField
|
||||
import androidx.compose.foundation.text.KeyboardActions
|
||||
import androidx.compose.foundation.text.KeyboardOptions
|
||||
import androidx.compose.material.Icon
|
||||
import androidx.compose.material.IconButton
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.material.TopAppBar
|
||||
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.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.SolidColor
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.input.ImeAction
|
||||
import androidx.compose.ui.text.input.KeyboardType
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.sp
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.tap.features.tokens.presentation.states.AddTokensToolbarState
|
||||
import com.tangem.tap.features.tokens.presentation.states.AddTokensToolbarState.SearchInputField
|
||||
import com.tangem.tap.features.tokens.presentation.states.AddTokensToolbarState.Title
|
||||
import com.tangem.wallet.R
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
@Composable
|
||||
internal fun AddTokensToolbar(state: AddTokensToolbarState) {
|
||||
TopAppBar(backgroundColor = TangemTheme.colors.background.secondary) {
|
||||
IconButton(onClick = state.onBackButtonClick) {
|
||||
Icon(
|
||||
painter = painterResource(id = R.drawable.ic_back_24),
|
||||
contentDescription = "Go back",
|
||||
tint = TangemTheme.colors.icon.secondary,
|
||||
)
|
||||
}
|
||||
|
||||
val contentModifier = Modifier
|
||||
.weight(1f)
|
||||
.padding(horizontal = TangemTheme.dimens.spacing16)
|
||||
.padding(bottom = TangemTheme.dimens.spacing4)
|
||||
|
||||
when (state) {
|
||||
is Title -> TitleContent(state = state, modifier = contentModifier)
|
||||
is SearchInputField -> InputContent(state = state, modifier = contentModifier)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun TitleContent(state: Title, modifier: Modifier = Modifier) {
|
||||
Text(
|
||||
text = stringResource(id = state.titleResId),
|
||||
modifier = modifier,
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
maxLines = 1,
|
||||
style = TangemTheme.typography.h3,
|
||||
)
|
||||
|
||||
IconButton(onClick = state.onSearchButtonClick) {
|
||||
Icon(
|
||||
painter = painterResource(id = R.drawable.ic_search_24),
|
||||
contentDescription = "Search",
|
||||
tint = TangemTheme.colors.icon.secondary,
|
||||
)
|
||||
}
|
||||
|
||||
if (state is Title.EditAccess) {
|
||||
IconButton(onClick = state.onAddCustomTokenClick) {
|
||||
Icon(
|
||||
painter = painterResource(id = R.drawable.ic_plus_24),
|
||||
contentDescription = "Add custom token",
|
||||
tint = TangemTheme.colors.icon.secondary,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun InputContent(state: SearchInputField, modifier: Modifier = Modifier) {
|
||||
BasicTextField(
|
||||
value = state.value,
|
||||
onValueChange = state.onValueChange,
|
||||
modifier = modifier,
|
||||
textStyle = TangemTheme.typography.subtitle1.copy(fontWeight = FontWeight.Normal),
|
||||
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text, imeAction = ImeAction.Search),
|
||||
keyboardActions = KeyboardActions(onSearch = { state.onSearchButtonClick() }),
|
||||
singleLine = true,
|
||||
maxLines = 1,
|
||||
cursorBrush = SolidColor(value = TangemTheme.colors.stroke.secondary),
|
||||
) { innerTextField ->
|
||||
Column(modifier = Modifier.padding(top = TangemTheme.dimens.spacing6)) {
|
||||
Row(verticalAlignment = Alignment.CenterVertically) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.padding(start = TangemTheme.dimens.spacing6),
|
||||
) {
|
||||
Hint(value = state.value)
|
||||
innerTextField()
|
||||
}
|
||||
|
||||
IconButton(onClick = state.onCleanButtonClick) {
|
||||
Icon(
|
||||
painter = painterResource(id = R.drawable.ic_cross_rounded_24),
|
||||
contentDescription = "Clean entered value",
|
||||
tint = TangemTheme.colors.icon.secondary,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.height(height = TangemTheme.dimens.size1)
|
||||
.background(color = TangemTheme.colors.stroke.primary),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun Hint(value: String) {
|
||||
if (value.isBlank()) {
|
||||
Row(
|
||||
modifier = Modifier.padding(horizontal = TangemTheme.dimens.spacing4),
|
||||
horizontalArrangement = Arrangement.spacedBy(space = TangemTheme.dimens.spacing4),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Icon(
|
||||
painter = painterResource(id = R.drawable.ic_search_24),
|
||||
contentDescription = null,
|
||||
tint = TangemTheme.colors.icon.secondary,
|
||||
)
|
||||
Text(
|
||||
text = stringResource(id = R.string.common_search),
|
||||
modifier = Modifier.padding(bottom = TangemTheme.dimens.spacing2),
|
||||
color = TangemTheme.colors.text.tertiary,
|
||||
maxLines = 1,
|
||||
// FIXME("Incorrect typography. Replace with typography from design system")
|
||||
style = TangemTheme.typography.subtitle1.copy(fontSize = 18.sp, fontWeight = FontWeight.Normal),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
private fun Preview_AddTokensToolbar_EditAccess() {
|
||||
TangemTheme {
|
||||
AddTokensToolbar(
|
||||
state = Title.EditAccess(
|
||||
titleResId = R.string.main_manage_tokens,
|
||||
onBackButtonClick = {},
|
||||
onSearchButtonClick = {},
|
||||
onAddCustomTokenClick = {},
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
private fun Preview_AddTokensToolbar_ReadAccess() {
|
||||
TangemTheme {
|
||||
AddTokensToolbar(
|
||||
state = Title.ReadAccess(
|
||||
titleResId = R.string.search_tokens_title,
|
||||
onBackButtonClick = {},
|
||||
onSearchButtonClick = {},
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
private fun Preview_AddTokensToolbar_SearchInputField() {
|
||||
var value by remember { mutableStateOf("") }
|
||||
|
||||
TangemTheme {
|
||||
AddTokensToolbar(
|
||||
state = SearchInputField(
|
||||
onBackButtonClick = {},
|
||||
onSearchButtonClick = {},
|
||||
value = value,
|
||||
onValueChange = { value = it },
|
||||
onCleanButtonClick = { value = "" },
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
package com.tangem.tap.features.tokens.presentation.ui
|
||||
|
||||
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.Image
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.key
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import com.tangem.core.ui.res.TangemColorPalette
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.tap.features.tokens.presentation.states.AddTokensNetworkItemState
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
@Composable
|
||||
internal fun BriefNetworksList(
|
||||
isCollapsed: Boolean,
|
||||
networks: List<AddTokensNetworkItemState>,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
AnimatedVisibility(
|
||||
visible = isCollapsed,
|
||||
modifier = modifier,
|
||||
enter = fadeIn() + expandVertically(),
|
||||
exit = shrinkVertically() + fadeOut(),
|
||||
) {
|
||||
if (isCollapsed) {
|
||||
Row(horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing4)) {
|
||||
networks.forEach {
|
||||
key(it.name) {
|
||||
BriefNetworkItem(model = it)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
@Composable
|
||||
internal fun BriefNetworkItem(model: AddTokensNetworkItemState) {
|
||||
Box(modifier = Modifier.size(size = TangemTheme.dimens.size20)) {
|
||||
Image(
|
||||
painter = painterResource(id = model.iconResId),
|
||||
contentDescription = null,
|
||||
modifier = Modifier.size(size = TangemTheme.dimens.size20),
|
||||
)
|
||||
|
||||
if (model.isMainNetwork) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.align(Alignment.TopEnd)
|
||||
.size(TangemTheme.dimens.size7)
|
||||
.clip(CircleShape)
|
||||
.background(TangemColorPalette.White),
|
||||
contentAlignment = Alignment.Center,
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.size(TangemTheme.dimens.size5)
|
||||
.clip(CircleShape)
|
||||
.background(TangemColorPalette.Meadow),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,168 @@
|
|||
package com.tangem.tap.features.tokens.presentation.ui
|
||||
|
||||
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.RowScope
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.heightIn
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.material.Switch
|
||||
import androidx.compose.material.SwitchDefaults
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.key
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.text.SpanStyle
|
||||
import androidx.compose.ui.text.buildAnnotatedString
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.withStyle
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.sp
|
||||
import com.tangem.core.ui.res.TangemColorPalette
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.tap.features.tokens.presentation.states.AddTokensNetworkItemState
|
||||
import com.tangem.wallet.R
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
@Composable
|
||||
internal fun DetailedNetworksList(
|
||||
isExpanded: Boolean,
|
||||
networks: List<AddTokensNetworkItemState>,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
AnimatedVisibility(
|
||||
visible = isExpanded,
|
||||
modifier = modifier,
|
||||
enter = fadeIn() + expandVertically(),
|
||||
exit = shrinkVertically() + fadeOut(),
|
||||
) {
|
||||
if (isExpanded) {
|
||||
Column {
|
||||
networks.forEachIndexed { index, network ->
|
||||
key(network.name) {
|
||||
DetailedNetworkItem(model = network, isLastItem = networks.lastIndex == index)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun DetailedNetworkItem(model: AddTokensNetworkItemState, isLastItem: Boolean) {
|
||||
val itemHeight = TangemTheme.dimens.size50
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.heightIn(min = itemHeight)
|
||||
.padding(start = TangemTheme.dimens.spacing38),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
NetworkItemArrow(itemHeight = itemHeight, isLastItem = isLastItem)
|
||||
Spacer(modifier = Modifier.width(TangemTheme.dimens.spacing14))
|
||||
BriefNetworkItem(model = model)
|
||||
Spacer(modifier = Modifier.width(TangemTheme.dimens.spacing6))
|
||||
NetworkTitle(model = model)
|
||||
|
||||
if (model is AddTokensNetworkItemState.EditAccess) {
|
||||
Switch(
|
||||
checked = model.isAdded,
|
||||
onCheckedChange = { model.onToggleClick(model.networkId) },
|
||||
modifier = Modifier.padding(start = TangemTheme.dimens.spacing16, end = TangemTheme.dimens.spacing8),
|
||||
colors = SwitchDefaults.colors(
|
||||
checkedThumbColor = TangemColorPalette.Meadow,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun RowScope.NetworkTitle(model: AddTokensNetworkItemState) {
|
||||
Text(
|
||||
modifier = Modifier.weight(1f),
|
||||
text = buildAnnotatedString {
|
||||
append(text = model.name)
|
||||
append(text = " ")
|
||||
withStyle(
|
||||
style = SpanStyle(
|
||||
fontWeight = FontWeight.Normal,
|
||||
color = if (model.isMainNetwork) TangemColorPalette.Meadow else TangemColorPalette.Dark2,
|
||||
),
|
||||
) {
|
||||
append(text = model.protocolName)
|
||||
}
|
||||
},
|
||||
fontWeight = FontWeight.SemiBold,
|
||||
fontSize = 13.sp,
|
||||
color = if (model is AddTokensNetworkItemState.EditAccess && model.isAdded) {
|
||||
TangemColorPalette.Black
|
||||
} else {
|
||||
TangemColorPalette.Dark2
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
private fun Preview_DetailedNetworksList_EditAccess() {
|
||||
TangemTheme {
|
||||
DetailedNetworksList(
|
||||
networks = listOf(
|
||||
AddTokensNetworkItemState.EditAccess(
|
||||
name = "ETHEREUM",
|
||||
protocolName = "MAIN",
|
||||
iconResId = R.drawable.ic_eth_no_color,
|
||||
isMainNetwork = true,
|
||||
isAdded = true,
|
||||
networkId = "",
|
||||
onToggleClick = {},
|
||||
),
|
||||
AddTokensNetworkItemState.EditAccess(
|
||||
name = "BNB SMART CHAIN",
|
||||
protocolName = "BEP20",
|
||||
iconResId = R.drawable.ic_bsc_no_color,
|
||||
isMainNetwork = false,
|
||||
isAdded = false,
|
||||
networkId = "",
|
||||
onToggleClick = {},
|
||||
),
|
||||
),
|
||||
isExpanded = false,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
private fun Preview_DetailedNetworksList_ReadAccess() {
|
||||
TangemTheme {
|
||||
DetailedNetworksList(
|
||||
networks = listOf(
|
||||
AddTokensNetworkItemState.ReadAccess(
|
||||
name = "ETHEREUM",
|
||||
protocolName = "MAIN",
|
||||
iconResId = R.drawable.ic_eth_no_color,
|
||||
isMainNetwork = true,
|
||||
),
|
||||
AddTokensNetworkItemState.ReadAccess(
|
||||
name = "BNB SMART CHAIN",
|
||||
protocolName = "BEP20",
|
||||
iconResId = R.drawable.ic_bsc_no_color,
|
||||
isMainNetwork = false,
|
||||
),
|
||||
),
|
||||
isExpanded = false,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
package com.tangem.tap.features.tokens.presentation.ui
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
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.material.Icon
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
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.core.ui.res.TangemTheme
|
||||
import com.tangem.wallet.R
|
||||
|
||||
private const val SPECIAL_HEIGHT_3_5 = 3.5
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
@Composable
|
||||
internal fun NetworkItemArrow(itemHeight: Dp, isLastItem: Boolean) {
|
||||
Box(modifier = Modifier.height(height = itemHeight)) {
|
||||
if (!isLastItem) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.padding(start = TangemTheme.dimens.spacing0_5)
|
||||
.background(color = TangemTheme.colors.stroke.primary)
|
||||
.size(width = TangemTheme.dimens.size1, height = itemHeight),
|
||||
)
|
||||
}
|
||||
|
||||
Icon(
|
||||
painter = painterResource(id = R.drawable.ic_link),
|
||||
contentDescription = null,
|
||||
modifier = Modifier.height(height = itemHeight / 2 + SPECIAL_HEIGHT_3_5.dp),
|
||||
tint = TangemTheme.colors.stroke.primary,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
private fun Preview_NetworkItemArrow_Column() {
|
||||
TangemTheme {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.background(color = TangemTheme.colors.background.primary)
|
||||
.padding(start = TangemTheme.dimens.size36),
|
||||
) {
|
||||
NetworkItemArrow(itemHeight = TangemTheme.dimens.size62, isLastItem = false)
|
||||
NetworkItemArrow(itemHeight = TangemTheme.dimens.size62, isLastItem = true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,292 @@
|
|||
package com.tangem.tap.features.tokens.presentation.ui
|
||||
|
||||
import androidx.compose.animation.AnimatedContent
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.animation.ExperimentalAnimationApi
|
||||
import androidx.compose.animation.expandVertically
|
||||
import androidx.compose.animation.fadeIn
|
||||
import androidx.compose.animation.fadeOut
|
||||
import androidx.compose.animation.scaleIn
|
||||
import androidx.compose.animation.scaleOut
|
||||
import androidx.compose.animation.shrinkVertically
|
||||
import androidx.compose.animation.with
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.material.Icon
|
||||
import androidx.compose.material.IconButton
|
||||
import androidx.compose.material.Text
|
||||
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.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
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.text.style.TextAlign
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.constraintlayout.compose.ConstraintLayout
|
||||
import androidx.constraintlayout.compose.Dimension
|
||||
import coil.compose.SubcomposeAsyncImage
|
||||
import coil.request.ImageRequest
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.tap.common.compose.extensions.toPx
|
||||
import com.tangem.tap.features.tokens.presentation.states.AddTokensNetworkItemState
|
||||
import com.tangem.tap.features.tokens.presentation.states.TokenItemModel
|
||||
import com.tangem.wallet.R
|
||||
|
||||
/**
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
@Composable
|
||||
internal fun TokenItem(model: TokenItemModel) {
|
||||
var isExpanded by remember { mutableStateOf(false) }
|
||||
|
||||
ConstraintLayout(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(top = TangemTheme.dimens.spacing16),
|
||||
) {
|
||||
val (icon, title, availableNetworksText) = createRefs()
|
||||
val (briefNetworksList, detailedNetworksList, changeNetworksViewButton) = createRefs()
|
||||
|
||||
val spacing16 = TangemTheme.dimens.spacing16
|
||||
val spacing6 = TangemTheme.dimens.spacing6
|
||||
|
||||
Icon(
|
||||
name = model.name,
|
||||
iconUrl = model.iconUrl,
|
||||
modifier = Modifier.constrainAs(icon) {
|
||||
top.linkTo(parent.top)
|
||||
start.linkTo(anchor = parent.start, margin = spacing16)
|
||||
},
|
||||
)
|
||||
|
||||
Title(
|
||||
title = model.name,
|
||||
modifier = Modifier.constrainAs(title) {
|
||||
top.linkTo(parent.top)
|
||||
start.linkTo(icon.end, margin = spacing16)
|
||||
end.linkTo(anchor = changeNetworksViewButton.start, margin = spacing16)
|
||||
width = Dimension.fillToConstraints
|
||||
},
|
||||
)
|
||||
|
||||
Subtitle(
|
||||
isExpanded = isExpanded,
|
||||
modifier = Modifier.constrainAs(availableNetworksText) {
|
||||
top.linkTo(title.bottom, margin = spacing6)
|
||||
start.linkTo(icon.end, margin = spacing16)
|
||||
end.linkTo(anchor = changeNetworksViewButton.start, margin = spacing16)
|
||||
width = Dimension.fillToConstraints
|
||||
},
|
||||
)
|
||||
|
||||
BriefNetworksList(
|
||||
isCollapsed = !isExpanded,
|
||||
networks = model.networks,
|
||||
modifier = Modifier.constrainAs(briefNetworksList) {
|
||||
top.linkTo(title.bottom, margin = spacing6)
|
||||
start.linkTo(icon.end, margin = spacing16)
|
||||
end.linkTo(anchor = changeNetworksViewButton.start, margin = spacing16)
|
||||
width = Dimension.fillToConstraints
|
||||
},
|
||||
)
|
||||
|
||||
DetailedNetworksList(
|
||||
isExpanded = isExpanded,
|
||||
networks = model.networks,
|
||||
modifier = Modifier.constrainAs(detailedNetworksList) {
|
||||
top.linkTo(anchor = availableNetworksText.bottom, margin = spacing16)
|
||||
centerHorizontallyTo(parent)
|
||||
width = Dimension.fillToConstraints
|
||||
},
|
||||
)
|
||||
|
||||
ChangeNetworksViewButton(
|
||||
isExpanded = isExpanded,
|
||||
onClick = { isExpanded = !isExpanded },
|
||||
modifier = Modifier.constrainAs(changeNetworksViewButton) {
|
||||
top.linkTo(parent.top)
|
||||
end.linkTo(anchor = parent.end, margin = spacing16)
|
||||
if (!isExpanded) bottom.linkTo(parent.bottom)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun Icon(name: String, iconUrl: String, modifier: Modifier = Modifier) {
|
||||
val iconModifier = modifier.size(size = TangemTheme.dimens.size46)
|
||||
|
||||
SubcomposeAsyncImage(
|
||||
modifier = iconModifier,
|
||||
model = ImageRequest.Builder(context = LocalContext.current)
|
||||
.size(size = TangemTheme.dimens.size46.toPx().toInt())
|
||||
.data(data = iconUrl)
|
||||
.crossfade(enable = true)
|
||||
.build(),
|
||||
contentDescription = null,
|
||||
loading = { PlaceholderIcon(name = name, modifier = iconModifier) },
|
||||
error = { PlaceholderIcon(name = name, modifier = iconModifier) },
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun PlaceholderIcon(name: String, modifier: Modifier = Modifier) {
|
||||
Box(
|
||||
contentAlignment = Alignment.Center,
|
||||
modifier = modifier.background(TangemTheme.colors.icon.primary1, shape = CircleShape),
|
||||
) {
|
||||
Text(
|
||||
text = name.firstOrNull()?.titlecase() ?: "",
|
||||
color = TangemTheme.colors.icon.primary2,
|
||||
maxLines = 1,
|
||||
// FIXME("Incorrect typography. Replace with typography from design system")
|
||||
style = TangemTheme.typography.h3.copy(fontWeight = FontWeight.Bold),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun Title(title: String, modifier: Modifier = Modifier) {
|
||||
Text(
|
||||
text = title,
|
||||
modifier = modifier,
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
textAlign = TextAlign.Start,
|
||||
maxLines = 1,
|
||||
style = TangemTheme.typography.body1,
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun Subtitle(isExpanded: Boolean, modifier: Modifier = Modifier) {
|
||||
AnimatedVisibility(
|
||||
visible = isExpanded,
|
||||
modifier = modifier,
|
||||
enter = fadeIn() + expandVertically(),
|
||||
exit = shrinkVertically() + fadeOut(),
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(id = R.string.currency_subtitle_expanded),
|
||||
color = TangemTheme.colors.text.secondary,
|
||||
maxLines = 1,
|
||||
style = TangemTheme.typography.body2,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalAnimationApi::class)
|
||||
@Composable
|
||||
private fun ChangeNetworksViewButton(
|
||||
isExpanded: Boolean,
|
||||
onClick: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
IconButton(onClick = onClick, modifier = modifier.size(size = TangemTheme.dimens.size46)) {
|
||||
AnimatedContent(
|
||||
targetState = isExpanded,
|
||||
transitionSpec = { fadeIn() + scaleIn() with scaleOut() + fadeOut() },
|
||||
) { isExpanded ->
|
||||
Icon(
|
||||
painter = painterResource(
|
||||
id = if (isExpanded) R.drawable.ic_arrow_extended else R.drawable.ic_arrow_collapsed,
|
||||
),
|
||||
contentDescription = null,
|
||||
tint = TangemTheme.colors.icon.secondary,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
private fun Preview_TokenItem_EditAccess() {
|
||||
TangemTheme {
|
||||
TokenItem(
|
||||
TokenItemModel(
|
||||
name = "Tether (USDT)",
|
||||
iconUrl = "https://s3.eu-central-1.amazonaws.com/tangem.api/coins/large/tether.png",
|
||||
networks = listOf(
|
||||
AddTokensNetworkItemState.EditAccess(
|
||||
name = "Ethereum",
|
||||
protocolName = "MAIN",
|
||||
iconResId = R.drawable.ic_eth_no_color,
|
||||
isMainNetwork = true,
|
||||
isAdded = true,
|
||||
networkId = "",
|
||||
onToggleClick = {},
|
||||
),
|
||||
AddTokensNetworkItemState.EditAccess(
|
||||
name = "BNB SMART CHAIN",
|
||||
protocolName = "BEP20",
|
||||
iconResId = R.drawable.ic_bsc_no_color,
|
||||
isMainNetwork = false,
|
||||
isAdded = false,
|
||||
networkId = "",
|
||||
onToggleClick = {},
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
private fun Preview_TokenItem_ReadAccess() {
|
||||
TangemTheme {
|
||||
TokenItem(
|
||||
TokenItemModel(
|
||||
name = "Tether (USDT)",
|
||||
iconUrl = "https://s3.eu-central-1.amazonaws.com/tangem.api/coins/large/tether.png",
|
||||
networks = listOf(
|
||||
AddTokensNetworkItemState.ReadAccess(
|
||||
name = "Ethereum",
|
||||
protocolName = "MAIN",
|
||||
iconResId = R.drawable.ic_eth_no_color,
|
||||
isMainNetwork = true,
|
||||
),
|
||||
AddTokensNetworkItemState.ReadAccess(
|
||||
name = "BNB SMART CHAIN",
|
||||
protocolName = "BEP20",
|
||||
iconResId = R.drawable.ic_bsc_no_color,
|
||||
isMainNetwork = false,
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
private fun Preview_TokenItem_EditAccess_LargeNetworkList() {
|
||||
TangemTheme {
|
||||
TokenItem(
|
||||
TokenItemModel(
|
||||
name = "Tether (USDT)",
|
||||
iconUrl = "https://s3.eu-central-1.amazonaws.com/tangem.api/coins/large/tether.png",
|
||||
networks = List(
|
||||
size = 15,
|
||||
init = {
|
||||
AddTokensNetworkItemState.ReadAccess(
|
||||
name = if (it % 2 != 0) "Ethereum" else "BNB SMART CHAIN",
|
||||
protocolName = if (it % 2 != 0) "MAIN" else "BEP20",
|
||||
iconResId = if (it % 2 != 0) R.drawable.ic_eth_no_color else R.drawable.ic_bsc_no_color,
|
||||
isMainNetwork = it % 2 != 0,
|
||||
)
|
||||
},
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,89 +0,0 @@
|
|||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("MagicNumber")
|
||||
@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
|
||||
private 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,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -37,6 +37,7 @@ import com.tangem.tap.common.extensions.getGreyedOutIconRes
|
|||
import com.tangem.tap.common.extensions.getNetworkName
|
||||
import com.tangem.tap.domain.tokens.Contract
|
||||
import com.tangem.tap.domain.tokens.Currency
|
||||
import com.tangem.tap.features.tokens.presentation.ui.NetworkItemArrow
|
||||
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
|
||||
|
|
@ -76,9 +77,9 @@ fun NetworkItem(
|
|||
.width(78.dp)
|
||||
.padding(start = 38.dp),
|
||||
) {
|
||||
CurrencyItemArrow(
|
||||
rowHeight = rowHeight,
|
||||
isLastArrow = index == size - 1,
|
||||
NetworkItemArrow(
|
||||
itemHeight = rowHeight,
|
||||
isLastItem = index == size - 1,
|
||||
)
|
||||
}
|
||||
Box(
|
||||
|
|
|
|||
9
app/src/main/res/drawable/ic_back_24.xml
Normal file
9
app/src/main/res/drawable/ic_back_24.xml
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="#000000"
|
||||
android:pathData="M20,11V13H8L13.5,18.5L12.08,19.92L4.16,12L12.08,4.08L13.5,5.5L8,11H20Z" />
|
||||
</vector>
|
||||
|
|
@ -32,8 +32,11 @@ data class TangemDimens internal constructor(
|
|||
// region Size
|
||||
val size0: Dp = 0.dp,
|
||||
val size0_5: Dp = 0.5.dp,
|
||||
val size1: Dp = 1.dp,
|
||||
val size2: Dp = 2.dp,
|
||||
val size4: Dp = 4.dp,
|
||||
val size5: Dp = 5.dp,
|
||||
val size7: Dp = 7.dp,
|
||||
val size8: Dp = 8.dp,
|
||||
val size11: Dp = 11.dp,
|
||||
val size12: Dp = 12.dp,
|
||||
|
|
@ -80,6 +83,7 @@ data class TangemDimens internal constructor(
|
|||
val spacing28: Dp = 28.dp,
|
||||
val spacing32: Dp = 32.dp,
|
||||
val spacing34: Dp = 34.dp,
|
||||
val spacing38: Dp = 38.dp,
|
||||
val spacing44: Dp = 44.dp,
|
||||
val spacing50: Dp = 50.dp,
|
||||
val spacing52: Dp = 52.dp,
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ complexity:
|
|||
threshold: 300
|
||||
LongMethod:
|
||||
active: true
|
||||
threshold: 60
|
||||
threshold: 70
|
||||
LongParameterList:
|
||||
active: true
|
||||
functionThreshold: 6
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue