Updated on 2026-08-14
This commit is contained in:
parent
99b517455a
commit
09db4a7d03
58 changed files with 1353 additions and 826 deletions
|
|
@ -25,10 +25,11 @@ internal sealed class DetailsItemUM {
|
|||
override val id: String = "wallet_connect"
|
||||
}
|
||||
|
||||
data class WalletConnectAddressBookBlock(val items: List<Item>) : DetailsItemUM() {
|
||||
data class WalletActionBlock(val items: ImmutableList<Item>) : DetailsItemUM() {
|
||||
override val id: String = "wallet_connect_address_book"
|
||||
|
||||
sealed class Item(open val onClick: () -> Unit) {
|
||||
|
||||
data class WalletConnect(override val onClick: () -> Unit) : Item(onClick)
|
||||
data class AddressBook(override val onClick: () -> Unit) : Item(onClick)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,13 +2,13 @@ package com.tangem.features.details.ui
|
|||
|
||||
import android.content.res.Configuration
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.gestures.Orientation
|
||||
import androidx.compose.foundation.gestures.scrollable
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.Scaffold
|
||||
|
|
@ -17,6 +17,7 @@ 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.platform.testTag
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
|
|
@ -27,19 +28,27 @@ import com.tangem.core.ui.components.appbar.TangemTopAppBar
|
|||
import com.tangem.core.ui.components.appbar.models.TopAppBarButtonUM
|
||||
import com.tangem.core.ui.components.block.BlockCard
|
||||
import com.tangem.core.ui.components.block.BlockItem
|
||||
import com.tangem.core.ui.components.inputrow.InputRowImageBase
|
||||
import com.tangem.core.ui.decompose.ComposableContentComponent
|
||||
import com.tangem.core.ui.ds.image.TangemIcon
|
||||
import com.tangem.core.ui.ds.image.TangemIconUM
|
||||
import com.tangem.core.ui.ds2.row.TangemRow
|
||||
import com.tangem.core.ui.ds2.row.TangemRowText
|
||||
import com.tangem.core.ui.ds2.row.TangemRowTextRole
|
||||
import com.tangem.core.ui.ds2.row.TangemRowVerticalAlignment
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import com.tangem.core.ui.extensions.resolveReference
|
||||
import com.tangem.core.ui.extensions.stringResourceSafe
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.core.ui.res.generated.icons.Icons
|
||||
import com.tangem.core.ui.res.generated.icons.ic_chevron_right_20
|
||||
import com.tangem.core.ui.test.DetailsScreenTestTags
|
||||
import com.tangem.features.details.component.preview.PreviewDetailsComponent
|
||||
import com.tangem.features.details.entity.DetailsFooterUM
|
||||
import com.tangem.features.details.entity.DetailsItemUM
|
||||
import com.tangem.features.details.entity.DetailsUM
|
||||
import com.tangem.features.details.impl.R
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
|
||||
@Composable
|
||||
internal fun DetailsScreen(
|
||||
|
|
@ -159,9 +168,9 @@ private fun Block(
|
|||
onClick = model.onClick,
|
||||
)
|
||||
}
|
||||
is DetailsItemUM.WalletConnectAddressBookBlock -> {
|
||||
is DetailsItemUM.WalletActionBlock -> {
|
||||
BlockCard {
|
||||
WalletConnectAddressBookBlockItems(
|
||||
WalletActionsBlock(
|
||||
items = model.items,
|
||||
modifier = itemModifier,
|
||||
)
|
||||
|
|
@ -170,37 +179,106 @@ private fun Block(
|
|||
is DetailsItemUM.UserWalletList -> {
|
||||
userWalletListBlockContent.Content(modifier = itemModifier)
|
||||
}
|
||||
is DetailsItemUM.UnderSectionText -> { /* Handled above */
|
||||
}
|
||||
is DetailsItemUM.UnderSectionText -> Unit
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun WalletConnectAddressBookBlockItems(
|
||||
items: List<DetailsItemUM.WalletConnectAddressBookBlock.Item>,
|
||||
private fun WalletActionsBlock(
|
||||
items: ImmutableList<DetailsItemUM.WalletActionBlock.Item>,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
items.fastForEach { item ->
|
||||
when (item) {
|
||||
is DetailsItemUM.WalletConnectAddressBookBlock.Item.WalletConnect -> InputRowImageBase(
|
||||
modifier = modifier.clickable(onClick = item.onClick).padding(12.dp),
|
||||
iconResVector = R.drawable.ic_wallet_connect_24,
|
||||
iconTint = TangemTheme.colors.icon.primary1,
|
||||
subtitle = TextReference.Res(R.string.wallet_connect_title),
|
||||
caption = TextReference.Res(R.string.wallet_connect_subtitle),
|
||||
is DetailsItemUM.WalletActionBlock.Item.WalletConnect -> WalletConnectActionRow(
|
||||
onClick = item.onClick,
|
||||
modifier = modifier,
|
||||
)
|
||||
is DetailsItemUM.WalletConnectAddressBookBlock.Item.AddressBook -> InputRowImageBase(
|
||||
modifier = modifier.clickable(onClick = item.onClick).padding(12.dp),
|
||||
iconResVector = R.drawable.ic_contact_20,
|
||||
iconTint = TangemTheme.colors.icon.accent,
|
||||
subtitle = TextReference.Res(R.string.address_book_title),
|
||||
caption = TextReference.Res(R.string.address_book_description),
|
||||
is DetailsItemUM.WalletActionBlock.Item.AddressBook -> AddressBookActionRow(
|
||||
onClick = item.onClick,
|
||||
modifier = modifier,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun WalletConnectActionRow(onClick: () -> Unit, modifier: Modifier = Modifier) {
|
||||
TangemRow(
|
||||
verticalAlignment = TangemRowVerticalAlignment.Center,
|
||||
modifier = modifier,
|
||||
onClick = onClick,
|
||||
startSlot = {
|
||||
TangemIcon(
|
||||
tangemIconUM = TangemIconUM.Image(R.drawable.img_wallet_connect_76),
|
||||
modifier = Modifier
|
||||
.size(40.dp)
|
||||
.clip(RoundedCornerShape(12.dp)),
|
||||
)
|
||||
},
|
||||
titleSlot = {
|
||||
TangemRowText(
|
||||
text = TextReference.Res(R.string.wallet_connect_title),
|
||||
role = TangemRowTextRole.Title,
|
||||
)
|
||||
},
|
||||
subtitleSlot = {
|
||||
TangemRowText(
|
||||
text = TextReference.Res(R.string.wallet_connect_subtitle),
|
||||
role = TangemRowTextRole.Subtitle,
|
||||
)
|
||||
},
|
||||
endSlot = { ActionRowChevron() },
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun AddressBookActionRow(onClick: () -> Unit, modifier: Modifier = Modifier) {
|
||||
TangemRow(
|
||||
verticalAlignment = TangemRowVerticalAlignment.Center,
|
||||
modifier = modifier,
|
||||
onClick = onClick,
|
||||
startSlot = {
|
||||
TangemIcon(
|
||||
tangemIconUM = TangemIconUM.Icon(
|
||||
iconRes = R.drawable.ic_address_book_24,
|
||||
tintReference = { TangemTheme.colors3.icon.brand },
|
||||
),
|
||||
modifier = Modifier
|
||||
.size(40.dp)
|
||||
.background(
|
||||
color = TangemTheme.colors3.bg.status.infoSubtle,
|
||||
shape = RoundedCornerShape(12.dp),
|
||||
)
|
||||
.padding(8.dp),
|
||||
)
|
||||
},
|
||||
titleSlot = {
|
||||
TangemRowText(
|
||||
text = TextReference.Res(R.string.address_book_title),
|
||||
role = TangemRowTextRole.Title,
|
||||
)
|
||||
},
|
||||
subtitleSlot = {
|
||||
TangemRowText(
|
||||
text = TextReference.Res(R.string.address_book_description),
|
||||
role = TangemRowTextRole.Subtitle,
|
||||
)
|
||||
},
|
||||
endSlot = { ActionRowChevron() },
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ActionRowChevron() {
|
||||
Icon(
|
||||
imageVector = Icons.ic_chevron_right_20,
|
||||
contentDescription = null,
|
||||
tint = TangemTheme.colors3.icon.secondary,
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun UnderSectionTextBlock(text: TextReference, modifier: Modifier = Modifier) {
|
||||
Text(
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ internal class ItemsBuilder @Inject constructor(
|
|||
onBuyClick: () -> Unit,
|
||||
): ImmutableList<DetailsItemUM> = buildList {
|
||||
if (isAddressBookAvailable) {
|
||||
buildWalletConnectAddressBookBlock(isWalletConnectAvailable, userWalletId)
|
||||
buildWalletActionBlock(isWalletConnectAvailable, userWalletId)
|
||||
} else {
|
||||
buildWalletConnectBlock(isWalletConnectAvailable, userWalletId)?.let(::add)
|
||||
}
|
||||
|
|
@ -91,29 +91,29 @@ internal class ItemsBuilder @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private fun MutableList<DetailsItemUM>.buildWalletConnectAddressBookBlock(
|
||||
private fun MutableList<DetailsItemUM>.buildWalletActionBlock(
|
||||
isWalletConnectAvailable: Boolean,
|
||||
userWalletId: UserWalletId,
|
||||
) {
|
||||
val walletConnectAddressBookItems = buildList {
|
||||
val walletActionItems = buildList {
|
||||
if (isWalletConnectAvailable) add(buildWalletConnectButton(userWalletId))
|
||||
add(buildAddressBookButton())
|
||||
}
|
||||
if (walletConnectAddressBookItems.isNotEmpty()) {
|
||||
add(DetailsItemUM.WalletConnectAddressBookBlock(walletConnectAddressBookItems))
|
||||
}.toImmutableList()
|
||||
if (walletActionItems.isNotEmpty()) {
|
||||
add(DetailsItemUM.WalletActionBlock(walletActionItems))
|
||||
}
|
||||
}
|
||||
|
||||
private fun buildWalletConnectButton(
|
||||
userWalletId: UserWalletId,
|
||||
): DetailsItemUM.WalletConnectAddressBookBlock.Item.WalletConnect {
|
||||
return DetailsItemUM.WalletConnectAddressBookBlock.Item.WalletConnect(
|
||||
): DetailsItemUM.WalletActionBlock.Item.WalletConnect {
|
||||
return DetailsItemUM.WalletActionBlock.Item.WalletConnect(
|
||||
onClick = { router.push(AppRoute.WalletConnectSessions(userWalletId)) },
|
||||
)
|
||||
}
|
||||
|
||||
private fun buildAddressBookButton(): DetailsItemUM.WalletConnectAddressBookBlock.Item.AddressBook {
|
||||
return DetailsItemUM.WalletConnectAddressBookBlock.Item.AddressBook(
|
||||
private fun buildAddressBookButton(): DetailsItemUM.WalletActionBlock.Item.AddressBook {
|
||||
return DetailsItemUM.WalletActionBlock.Item.AddressBook(
|
||||
onClick = { router.push(AppRoute.AddressBook()) },
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -65,10 +65,10 @@ internal class ItemsBuilderTest {
|
|||
"support",
|
||||
).inOrder()
|
||||
|
||||
val block = result.first() as DetailsItemUM.WalletConnectAddressBookBlock
|
||||
val block = result.first() as DetailsItemUM.WalletActionBlock
|
||||
assertThat(block.items.map { it::class.java }).containsExactly(
|
||||
DetailsItemUM.WalletConnectAddressBookBlock.Item.WalletConnect::class.java,
|
||||
DetailsItemUM.WalletConnectAddressBookBlock.Item.AddressBook::class.java,
|
||||
DetailsItemUM.WalletActionBlock.Item.WalletConnect::class.java,
|
||||
DetailsItemUM.WalletActionBlock.Item.AddressBook::class.java,
|
||||
).inOrder()
|
||||
}
|
||||
|
||||
|
|
@ -86,9 +86,9 @@ internal class ItemsBuilderTest {
|
|||
"support",
|
||||
).inOrder()
|
||||
|
||||
val block = result.first() as DetailsItemUM.WalletConnectAddressBookBlock
|
||||
val block = result.first() as DetailsItemUM.WalletActionBlock
|
||||
assertThat(block.items.map { it::class.java }).containsExactly(
|
||||
DetailsItemUM.WalletConnectAddressBookBlock.Item.AddressBook::class.java,
|
||||
DetailsItemUM.WalletActionBlock.Item.AddressBook::class.java,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
@ -109,9 +109,9 @@ internal class ItemsBuilderTest {
|
|||
fun `GIVEN combined block walletConnect item WHEN clicked THEN router pushes WalletConnectSessions`() {
|
||||
// Arrange
|
||||
val result = buildAll(isWalletConnectAvailable = true, isAddressBookAvailable = true)
|
||||
val block = result.first() as DetailsItemUM.WalletConnectAddressBookBlock
|
||||
val block = result.first() as DetailsItemUM.WalletActionBlock
|
||||
val walletConnect = block.items
|
||||
.filterIsInstance<DetailsItemUM.WalletConnectAddressBookBlock.Item.WalletConnect>()
|
||||
.filterIsInstance<DetailsItemUM.WalletActionBlock.Item.WalletConnect>()
|
||||
.single()
|
||||
|
||||
// Act
|
||||
|
|
@ -125,9 +125,9 @@ internal class ItemsBuilderTest {
|
|||
fun `GIVEN combined block addressBook item WHEN clicked THEN router pushes AddressBook`() {
|
||||
// Arrange
|
||||
val result = buildAll(isWalletConnectAvailable = true, isAddressBookAvailable = true)
|
||||
val block = result.first() as DetailsItemUM.WalletConnectAddressBookBlock
|
||||
val block = result.first() as DetailsItemUM.WalletActionBlock
|
||||
val addressBook = block.items
|
||||
.filterIsInstance<DetailsItemUM.WalletConnectAddressBookBlock.Item.AddressBook>()
|
||||
.filterIsInstance<DetailsItemUM.WalletActionBlock.Item.AddressBook>()
|
||||
.single()
|
||||
|
||||
// Act
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue