diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/details/DetailsScreenState.kt b/app/src/main/java/com/tangem/tap/features/details/ui/details/DetailsScreenState.kt
index 63bab8fcdb..b8d8025916 100644
--- a/app/src/main/java/com/tangem/tap/features/details/ui/details/DetailsScreenState.kt
+++ b/app/src/main/java/com/tangem/tap/features/details/ui/details/DetailsScreenState.kt
@@ -35,7 +35,7 @@ internal sealed class SettingsItem(
data class WalletConnect(
override val onClick: () -> Unit,
) : SettingsItem(
- iconResId = R.drawable.ic_walletconnect,
+ iconResId = R.drawable.ic_wallet_connect_24,
title = resourceReference(R.string.wallet_connect_title),
subtitle = resourceReference(R.string.wallet_connect_subtitle),
isLarge = true,
@@ -81,14 +81,14 @@ internal sealed class SettingsItem(
data class Chat(
override val onClick: () -> Unit,
) : SettingsItem(
- iconResId = R.drawable.ic_chat,
+ iconResId = R.drawable.ic_chat_24,
title = resourceReference(R.string.details_chat),
)
data class SendFeedback(
override val onClick: () -> Unit,
) : SettingsItem(
- iconResId = R.drawable.ic_comment,
+ iconResId = R.drawable.ic_comment_24,
title = resourceReference(R.string.details_row_title_contact_to_support),
)
@@ -102,7 +102,7 @@ internal sealed class SettingsItem(
data class TermsOfService(
override val onClick: () -> Unit,
) : SettingsItem(
- iconResId = R.drawable.ic_text,
+ iconResId = R.drawable.ic_text_24,
title = resourceReference(R.string.disclaimer_title),
)
@@ -125,15 +125,15 @@ internal sealed class EventError {
}
sealed class SocialNetwork(val id: String, val iconRes: Int) {
- object Twitter : SocialNetwork("Twitter", R.drawable.ic_twitter)
- object Telegram : SocialNetwork("Telegram", R.drawable.ic_telegram)
- object Discord : SocialNetwork("Discord", R.drawable.ic_discord)
- object Reddit : SocialNetwork("Reddit", R.drawable.ic_reddit)
- object Instagram : SocialNetwork("Instagram", R.drawable.ic_instagram)
- object GitHub : SocialNetwork("GitHub", R.drawable.ic_github)
- object Facebook : SocialNetwork("Facebook", R.drawable.ic_facebook)
- object LinkedIn : SocialNetwork("LinkedIn", R.drawable.ic_linkedin)
- object YouTube : SocialNetwork("YouTube", R.drawable.ic_youtube)
+ object Twitter : SocialNetwork("Twitter", R.drawable.ic_twitter_24)
+ object Telegram : SocialNetwork("Telegram", R.drawable.ic_telegram_24)
+ object Discord : SocialNetwork("Discord", R.drawable.ic_discord_24)
+ object Reddit : SocialNetwork("Reddit", R.drawable.ic_reddit_24)
+ object Instagram : SocialNetwork("Instagram", R.drawable.ic_instagram_24)
+ object GitHub : SocialNetwork("GitHub", R.drawable.ic_github_24)
+ object Facebook : SocialNetwork("Facebook", R.drawable.ic_facebook_24)
+ object LinkedIn : SocialNetwork("LinkedIn", R.drawable.ic_linkedin_24)
+ object YouTube : SocialNetwork("YouTube", R.drawable.ic_youtube_24)
}
internal object TangemSocialAccounts {
diff --git a/app/src/main/java/com/tangem/tap/features/details/ui/walletconnect/WalletConnectScreen.kt b/app/src/main/java/com/tangem/tap/features/details/ui/walletconnect/WalletConnectScreen.kt
index 79e8b38b23..7e5b3542cd 100644
--- a/app/src/main/java/com/tangem/tap/features/details/ui/walletconnect/WalletConnectScreen.kt
+++ b/app/src/main/java/com/tangem/tap/features/details/ui/walletconnect/WalletConnectScreen.kt
@@ -88,7 +88,7 @@ private fun EmptyScreen(state: WalletConnectScreenState) {
horizontalAlignment = Alignment.CenterHorizontally,
) {
Image(
- painter = painterResource(id = R.drawable.ic_walletconnect),
+ painter = painterResource(id = R.drawable.ic_wallet_connect_24),
contentDescription = "",
colorFilter = ColorFilter.tint(TangemTheme.colors.icon.inactive),
contentScale = ContentScale.FillWidth,
diff --git a/app/src/main/res/drawable/ic_chat.xml b/core/ui/src/main/res/drawable/ic_chat_24.xml
similarity index 100%
rename from app/src/main/res/drawable/ic_chat.xml
rename to core/ui/src/main/res/drawable/ic_chat_24.xml
diff --git a/app/src/main/res/drawable/ic_comment.xml b/core/ui/src/main/res/drawable/ic_comment_24.xml
similarity index 100%
rename from app/src/main/res/drawable/ic_comment.xml
rename to core/ui/src/main/res/drawable/ic_comment_24.xml
diff --git a/app/src/main/res/drawable/ic_discord.xml b/core/ui/src/main/res/drawable/ic_discord_24.xml
similarity index 97%
rename from app/src/main/res/drawable/ic_discord.xml
rename to core/ui/src/main/res/drawable/ic_discord_24.xml
index 6502165e77..b1f5039116 100644
--- a/app/src/main/res/drawable/ic_discord.xml
+++ b/core/ui/src/main/res/drawable/ic_discord_24.xml
@@ -5,5 +5,5 @@
android:viewportHeight="24">
+ android:fillColor="#000" />
diff --git a/app/src/main/res/drawable/ic_facebook.xml b/core/ui/src/main/res/drawable/ic_facebook_24.xml
similarity index 94%
rename from app/src/main/res/drawable/ic_facebook.xml
rename to core/ui/src/main/res/drawable/ic_facebook_24.xml
index 1db025e42c..eeb0ea2747 100644
--- a/app/src/main/res/drawable/ic_facebook.xml
+++ b/core/ui/src/main/res/drawable/ic_facebook_24.xml
@@ -5,5 +5,5 @@
android:viewportHeight="24">
+ android:fillColor="#000" />
diff --git a/app/src/main/res/drawable/ic_github.xml b/core/ui/src/main/res/drawable/ic_github_24.xml
similarity index 97%
rename from app/src/main/res/drawable/ic_github.xml
rename to core/ui/src/main/res/drawable/ic_github_24.xml
index daa1de7021..8e105d74a6 100644
--- a/app/src/main/res/drawable/ic_github.xml
+++ b/core/ui/src/main/res/drawable/ic_github_24.xml
@@ -5,5 +5,5 @@
android:viewportHeight="24">
+ android:fillColor="#000" />
diff --git a/app/src/main/res/drawable/ic_instagram.xml b/core/ui/src/main/res/drawable/ic_instagram_24.xml
similarity index 95%
rename from app/src/main/res/drawable/ic_instagram.xml
rename to core/ui/src/main/res/drawable/ic_instagram_24.xml
index 76744cf7f5..a1b00c2ca5 100644
--- a/app/src/main/res/drawable/ic_instagram.xml
+++ b/core/ui/src/main/res/drawable/ic_instagram_24.xml
@@ -8,12 +8,12 @@
android:pathData="M2.4,2.4h19.2v19.2h-19.2z"/>
+ android:fillColor="#000" />
+ android:fillColor="#000" />
+ android:fillColor="#000" />
diff --git a/app/src/main/res/drawable/ic_linkedin.xml b/core/ui/src/main/res/drawable/ic_linkedin_24.xml
similarity index 95%
rename from app/src/main/res/drawable/ic_linkedin.xml
rename to core/ui/src/main/res/drawable/ic_linkedin_24.xml
index 2df3cb834a..5f82e64300 100644
--- a/app/src/main/res/drawable/ic_linkedin.xml
+++ b/core/ui/src/main/res/drawable/ic_linkedin_24.xml
@@ -5,5 +5,5 @@
android:viewportHeight="24">
+ android:fillColor="#000" />
diff --git a/app/src/main/res/drawable/ic_reddit.xml b/core/ui/src/main/res/drawable/ic_reddit_24.xml
similarity index 98%
rename from app/src/main/res/drawable/ic_reddit.xml
rename to core/ui/src/main/res/drawable/ic_reddit_24.xml
index 2a1e04a004..61919b1686 100644
--- a/app/src/main/res/drawable/ic_reddit.xml
+++ b/core/ui/src/main/res/drawable/ic_reddit_24.xml
@@ -5,6 +5,6 @@
android:viewportHeight="24">
diff --git a/app/src/main/res/drawable/ic_telegram.xml b/core/ui/src/main/res/drawable/ic_telegram_24.xml
similarity index 95%
rename from app/src/main/res/drawable/ic_telegram.xml
rename to core/ui/src/main/res/drawable/ic_telegram_24.xml
index 020ee3bc71..d2d923c5a3 100644
--- a/app/src/main/res/drawable/ic_telegram.xml
+++ b/core/ui/src/main/res/drawable/ic_telegram_24.xml
@@ -5,5 +5,5 @@
android:viewportHeight="24">
+ android:fillColor="#000" />
diff --git a/app/src/main/res/drawable/ic_text.xml b/core/ui/src/main/res/drawable/ic_text_24.xml
similarity index 100%
rename from app/src/main/res/drawable/ic_text.xml
rename to core/ui/src/main/res/drawable/ic_text_24.xml
diff --git a/app/src/main/res/drawable/ic_twitter.xml b/core/ui/src/main/res/drawable/ic_twitter_24.xml
similarity index 92%
rename from app/src/main/res/drawable/ic_twitter.xml
rename to core/ui/src/main/res/drawable/ic_twitter_24.xml
index 1c3cb6cfef..cd94ecb5b6 100644
--- a/app/src/main/res/drawable/ic_twitter.xml
+++ b/core/ui/src/main/res/drawable/ic_twitter_24.xml
@@ -5,5 +5,5 @@
android:viewportHeight="24">
+ android:fillColor="#000" />
diff --git a/app/src/main/res/drawable/ic_walletconnect.xml b/core/ui/src/main/res/drawable/ic_wallet_connect_24.xml
similarity index 96%
rename from app/src/main/res/drawable/ic_walletconnect.xml
rename to core/ui/src/main/res/drawable/ic_wallet_connect_24.xml
index d4b4c99942..a4378111f1 100644
--- a/app/src/main/res/drawable/ic_walletconnect.xml
+++ b/core/ui/src/main/res/drawable/ic_wallet_connect_24.xml
@@ -2,6 +2,6 @@
android:viewportHeight="24" android:viewportWidth="24"
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
diff --git a/app/src/main/res/drawable/ic_youtube.xml b/core/ui/src/main/res/drawable/ic_youtube_24.xml
similarity index 95%
rename from app/src/main/res/drawable/ic_youtube.xml
rename to core/ui/src/main/res/drawable/ic_youtube_24.xml
index 6d5ade9d08..7eb2833038 100644
--- a/app/src/main/res/drawable/ic_youtube.xml
+++ b/core/ui/src/main/res/drawable/ic_youtube_24.xml
@@ -5,5 +5,5 @@
android:viewportHeight="24">
+ android:fillColor="#000" />
diff --git a/features/details/impl/build.gradle.kts b/features/details/impl/build.gradle.kts
index 76cfca8bdc..4f9498a097 100644
--- a/features/details/impl/build.gradle.kts
+++ b/features/details/impl/build.gradle.kts
@@ -26,6 +26,7 @@ dependencies {
/* AndroidX */
implementation(deps.androidx.fragment.ktx)
+ implementation(deps.androidx.activity.compose)
implementation(deps.lifecycle.compose)
/* Compose */
diff --git a/features/details/impl/src/main/kotlin/com/tangem/features/details/component/preview/PreviewDetailsComponent.kt b/features/details/impl/src/main/kotlin/com/tangem/features/details/component/preview/PreviewDetailsComponent.kt
index c0c9d5492c..59a69914fd 100644
--- a/features/details/impl/src/main/kotlin/com/tangem/features/details/component/preview/PreviewDetailsComponent.kt
+++ b/features/details/impl/src/main/kotlin/com/tangem/features/details/component/preview/PreviewDetailsComponent.kt
@@ -3,12 +3,36 @@ package com.tangem.features.details.component.preview
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import com.tangem.features.details.component.DetailsComponent
+import com.tangem.features.details.entity.DetailsFooterUM
+import com.tangem.features.details.entity.DetailsUM
+import com.tangem.features.details.ui.DetailsScreen
+import com.tangem.features.details.utils.ItemsBuilder
+import com.tangem.features.details.utils.SocialsBuilder
+import kotlinx.coroutines.runBlocking
internal class PreviewDetailsComponent : DetailsComponent {
+ private val previewBlocks = runBlocking {
+ ItemsBuilder(
+ walletConnectComponent = PreviewWalletConnectComponent(),
+ userWalletListComponent = PreviewUserWalletListComponent(),
+ ).buldAll()
+ }
+
+ private val previewFooter = DetailsFooterUM(
+ socials = SocialsBuilder(urlOpener = { /* no-op */ }).buildAll(),
+ appVersion = "1.0.0-preview",
+ )
+
+ val previewState = DetailsUM(
+ items = previewBlocks,
+ footer = previewFooter,
+ popBack = { /* no-op */ },
+ )
+
@Composable
@Suppress("TopLevelComposableFunctions") // TODO: Remove this check
override fun View(modifier: Modifier) {
- TODO("Will be implemented in [REDACTED_TASK_KEY]")
+ DetailsScreen(state = previewState, modifier = modifier)
}
}
\ No newline at end of file
diff --git a/features/details/impl/src/main/kotlin/com/tangem/features/details/component/preview/PreviewUserWalletListComponent.kt b/features/details/impl/src/main/kotlin/com/tangem/features/details/component/preview/PreviewUserWalletListComponent.kt
index 8341d24070..c7628c2619 100644
--- a/features/details/impl/src/main/kotlin/com/tangem/features/details/component/preview/PreviewUserWalletListComponent.kt
+++ b/features/details/impl/src/main/kotlin/com/tangem/features/details/component/preview/PreviewUserWalletListComponent.kt
@@ -2,13 +2,63 @@ package com.tangem.features.details.component.preview
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
+import com.tangem.core.ui.extensions.TextReference
+import com.tangem.core.ui.extensions.resourceReference
+import com.tangem.core.ui.extensions.stringReference
+import com.tangem.core.ui.extensions.wrappedList
+import com.tangem.domain.wallets.models.UserWalletId
import com.tangem.features.details.component.UserWalletListComponent
+import com.tangem.features.details.entity.UserWalletListUM
+import com.tangem.features.details.impl.R
+import com.tangem.features.details.ui.UserWalletListBlock
+import kotlinx.collections.immutable.persistentListOf
internal class PreviewUserWalletListComponent : UserWalletListComponent {
+ private val previewState = UserWalletListUM(
+ userWallets = persistentListOf(
+ UserWalletListUM.UserWalletUM(
+ id = UserWalletId("user_wallet_1".encodeToByteArray()),
+ name = "My Wallet",
+ information = getInformation(3, "4 496,75 $"),
+ imageResId = R.drawable.ill_card_wallet_2_211_343,
+ onClick = {},
+ ),
+ UserWalletListUM.UserWalletUM(
+ id = UserWalletId("user_wallet_2".encodeToByteArray()),
+ name = "Old wallet",
+ information = getInformation(3, "4 496,75 $"),
+ imageResId = R.drawable.ill_card_note_eth_211_343,
+ onClick = {},
+ ),
+ UserWalletListUM.UserWalletUM(
+ id = UserWalletId("user_wallet_3".encodeToByteArray()),
+ name = "Multi Card",
+ information = getInformation(3, "4 496,75 $"),
+ imageResId = R.drawable.ill_card_note_bnb_211_343,
+ onClick = {},
+ ),
+ ),
+ addNewWalletText = resourceReference(R.string.user_wallet_list_add_button),
+ isWalletSavingInProgress = false,
+ onAddNewWalletClick = {},
+ )
+
@Composable
@Suppress("TopLevelComposableFunctions") // TODO: Remove this check
override fun View(modifier: Modifier) {
- TODO("Will be implemented in [REDACTED_TASK_KEY]")
+ UserWalletListBlock(state = previewState, modifier = modifier)
+ }
+
+ private fun getInformation(cardCount: Int, totalBalance: String): TextReference {
+ val t1 = TextReference.PluralRes(
+ id = R.plurals.card_label_card_count,
+ count = cardCount,
+ formatArgs = wrappedList(cardCount),
+ )
+ val divider = stringReference(value = " • ")
+ val t2 = stringReference(totalBalance)
+
+ return TextReference.Combined(wrappedList(t1, divider, t2))
}
}
\ No newline at end of file
diff --git a/features/details/impl/src/main/kotlin/com/tangem/features/details/component/preview/PreviewWalletConnectComponent.kt b/features/details/impl/src/main/kotlin/com/tangem/features/details/component/preview/PreviewWalletConnectComponent.kt
index 6a4aa2df28..4f94585d78 100644
--- a/features/details/impl/src/main/kotlin/com/tangem/features/details/component/preview/PreviewWalletConnectComponent.kt
+++ b/features/details/impl/src/main/kotlin/com/tangem/features/details/component/preview/PreviewWalletConnectComponent.kt
@@ -3,6 +3,7 @@ package com.tangem.features.details.component.preview
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import com.tangem.features.details.component.WalletConnectComponent
+import com.tangem.features.details.ui.WalletConnectBlock
internal class PreviewWalletConnectComponent : WalletConnectComponent {
@@ -11,6 +12,6 @@ internal class PreviewWalletConnectComponent : WalletConnectComponent {
@Composable
@Suppress("TopLevelComposableFunctions") // TODO: Remove this check
override fun View(modifier: Modifier) {
- TODO("Will be implemented in [REDACTED_TASK_KEY]")
+ WalletConnectBlock(onClick = { /* no-op */ }, modifier = modifier)
}
}
\ No newline at end of file
diff --git a/features/details/impl/src/main/kotlin/com/tangem/features/details/entity/DetailsItemUM.kt b/features/details/impl/src/main/kotlin/com/tangem/features/details/entity/DetailsItemUM.kt
index 0dabab81bd..1aa5a52ab5 100644
--- a/features/details/impl/src/main/kotlin/com/tangem/features/details/entity/DetailsItemUM.kt
+++ b/features/details/impl/src/main/kotlin/com/tangem/features/details/entity/DetailsItemUM.kt
@@ -18,6 +18,7 @@ internal sealed class DetailsItemUM {
) : DetailsItemUM() {
data class Item(
+ val id: String,
val title: TextReference,
@DrawableRes
val iconRes: Int,
diff --git a/features/details/impl/src/main/kotlin/com/tangem/features/details/entity/UserWalletListUM.kt b/features/details/impl/src/main/kotlin/com/tangem/features/details/entity/UserWalletListUM.kt
index 6848e0e77b..d6f947b063 100644
--- a/features/details/impl/src/main/kotlin/com/tangem/features/details/entity/UserWalletListUM.kt
+++ b/features/details/impl/src/main/kotlin/com/tangem/features/details/entity/UserWalletListUM.kt
@@ -7,6 +7,7 @@ import kotlinx.collections.immutable.ImmutableList
internal data class UserWalletListUM(
val userWallets: ImmutableList,
+ val isWalletSavingInProgress: Boolean,
val addNewWalletText: TextReference,
val onAddNewWalletClick: () -> Unit,
) {
diff --git a/features/details/impl/src/main/kotlin/com/tangem/features/details/ui/BlockCard.kt b/features/details/impl/src/main/kotlin/com/tangem/features/details/ui/BlockCard.kt
new file mode 100644
index 0000000000..e11a41c41e
--- /dev/null
+++ b/features/details/impl/src/main/kotlin/com/tangem/features/details/ui/BlockCard.kt
@@ -0,0 +1,36 @@
+package com.tangem.features.details.ui
+
+import androidx.compose.foundation.layout.ColumnScope
+import androidx.compose.material3.Card
+import androidx.compose.material3.CardColors
+import androidx.compose.runtime.Composable
+import androidx.compose.runtime.ReadOnlyComposable
+import androidx.compose.ui.Modifier
+import com.tangem.core.ui.res.TangemTheme
+
+@Composable
+internal fun BlockCard(
+ modifier: Modifier = Modifier,
+ enabled: Boolean = true,
+ onClick: () -> Unit = {},
+ content: @Composable ColumnScope.() -> Unit = {},
+) {
+ Card(
+ modifier = modifier,
+ onClick = onClick,
+ shape = TangemTheme.shapes.roundedCornersXMedium,
+ colors = BlockColors,
+ enabled = enabled,
+ content = content,
+ )
+}
+
+private val BlockColors: CardColors
+ @Composable
+ @ReadOnlyComposable
+ get() = CardColors(
+ containerColor = TangemTheme.colors.background.primary,
+ contentColor = TangemTheme.colors.text.primary1,
+ disabledContainerColor = TangemTheme.colors.button.disabled,
+ disabledContentColor = TangemTheme.colors.text.disabled,
+ )
\ No newline at end of file
diff --git a/features/details/impl/src/main/kotlin/com/tangem/features/details/ui/BlockItem.kt b/features/details/impl/src/main/kotlin/com/tangem/features/details/ui/BlockItem.kt
new file mode 100644
index 0000000000..80d99b3b20
--- /dev/null
+++ b/features/details/impl/src/main/kotlin/com/tangem/features/details/ui/BlockItem.kt
@@ -0,0 +1,45 @@
+package com.tangem.features.details.ui
+
+import androidx.compose.foundation.layout.Arrangement
+import androidx.compose.foundation.layout.Row
+import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
+import androidx.compose.material3.Icon
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.text.style.TextOverflow
+import com.tangem.core.ui.extensions.resolveReference
+import com.tangem.core.ui.res.TangemTheme
+import com.tangem.features.details.entity.DetailsItemUM
+
+@Composable
+internal fun BlockItem(model: DetailsItemUM.Basic.Item, modifier: Modifier = Modifier) {
+ BlockCard(
+ modifier = modifier,
+ onClick = model.onClick,
+ ) {
+ Row(
+ modifier = Modifier.padding(all = TangemTheme.dimens.spacing12),
+ verticalAlignment = Alignment.CenterVertically,
+ horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing12, Alignment.Start),
+ ) {
+ Icon(
+ modifier = Modifier.size(TangemTheme.dimens.size24),
+ painter = painterResource(id = model.iconRes),
+ tint = TangemTheme.colors.icon.secondary,
+ contentDescription = null,
+ )
+
+ Text(
+ text = model.title.resolveReference(),
+ style = TangemTheme.typography.subtitle1,
+ color = TangemTheme.colors.text.primary1,
+ maxLines = 1,
+ overflow = TextOverflow.Ellipsis,
+ )
+ }
+ }
+}
\ No newline at end of file
diff --git a/features/details/impl/src/main/kotlin/com/tangem/features/details/ui/DetailsScreen.kt b/features/details/impl/src/main/kotlin/com/tangem/features/details/ui/DetailsScreen.kt
new file mode 100644
index 0000000000..ff67ebbd9e
--- /dev/null
+++ b/features/details/impl/src/main/kotlin/com/tangem/features/details/ui/DetailsScreen.kt
@@ -0,0 +1,221 @@
+package com.tangem.features.details.ui
+
+import android.content.res.Configuration
+import androidx.activity.compose.BackHandler
+import androidx.compose.foundation.background
+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.material3.*
+import androidx.compose.runtime.*
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.input.nestedscroll.nestedScroll
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.res.stringResource
+import androidx.compose.ui.text.style.TextOverflow
+import androidx.compose.ui.tooling.preview.Preview
+import com.tangem.core.ui.components.SystemBarsEffect
+import com.tangem.core.ui.res.TangemTheme
+import com.tangem.core.ui.res.TangemThemePreview
+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
+
+private const val COLLAPSED_APP_BAR_THRESHOLD = 0.4f
+
+@OptIn(ExperimentalMaterial3Api::class)
+@Composable
+internal fun DetailsScreen(state: DetailsUM, modifier: Modifier = Modifier) {
+ val backgroundColor = TangemTheme.colors.background.secondary
+ val scrollBehavior = TopAppBarDefaults.exitUntilCollapsedScrollBehavior()
+
+ SystemBarsEffect {
+ setSystemBarsColor(backgroundColor)
+ }
+
+ BackHandler(onBack = state.popBack)
+
+ Scaffold(
+ modifier = modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
+ containerColor = backgroundColor,
+ topBar = { TopBar(state, scrollBehavior) },
+ ) { paddingValues ->
+ Content(
+ modifier = Modifier.padding(paddingValues),
+ state = state,
+ )
+ }
+}
+
+@OptIn(ExperimentalMaterial3Api::class)
+@Composable
+private fun TopBar(state: DetailsUM, scrollBehavior: TopAppBarScrollBehavior, modifier: Modifier = Modifier) {
+ MediumTopAppBar(
+ modifier = modifier,
+ scrollBehavior = scrollBehavior,
+ colors = TopAppBarColors(
+ containerColor = TangemTheme.colors.background.secondary,
+ scrolledContainerColor = TangemTheme.colors.background.secondary,
+ navigationIconContentColor = TangemTheme.colors.icon.primary1,
+ titleContentColor = TangemTheme.colors.text.primary1,
+ actionIconContentColor = TangemTheme.colors.icon.primary1,
+ ),
+ title = {
+ val collapsedStyle = TangemTheme.typography.subtitle1
+ val expandedStyle = TangemTheme.typography.h1
+ val style by remember(scrollBehavior.state.collapsedFraction) {
+ derivedStateOf {
+ if (scrollBehavior.state.collapsedFraction >= COLLAPSED_APP_BAR_THRESHOLD) {
+ collapsedStyle
+ } else {
+ expandedStyle
+ }
+ }
+ }
+
+ Text(
+ text = stringResource(id = R.string.details_title),
+ style = style,
+ maxLines = 1,
+ overflow = TextOverflow.Ellipsis,
+ )
+ },
+ navigationIcon = {
+ IconButton(
+ modifier = Modifier.size(TangemTheme.dimens.size32),
+ onClick = state.popBack,
+ ) {
+ Icon(
+ modifier = Modifier.size(TangemTheme.dimens.size24),
+ painter = painterResource(id = R.drawable.ic_back_24),
+ contentDescription = null,
+ )
+ }
+ },
+ )
+}
+
+@Composable
+private fun Content(state: DetailsUM, modifier: Modifier = Modifier) {
+ LazyColumn(
+ modifier = modifier,
+ verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing16),
+ contentPadding = PaddingValues(
+ top = TangemTheme.dimens.spacing16,
+ bottom = TangemTheme.dimens.spacing16,
+ ),
+ ) {
+ items(
+ items = state.items,
+ key = DetailsItemUM::id,
+ ) { block ->
+ Block(
+ modifier = Modifier.padding(horizontal = TangemTheme.dimens.spacing16),
+ model = block,
+ )
+ }
+
+ item(key = "footer") {
+ Footer(
+ modifier = Modifier.padding(horizontal = TangemTheme.dimens.spacing12),
+ model = state.footer,
+ )
+ }
+ }
+}
+
+@Composable
+private fun Block(model: DetailsItemUM, modifier: Modifier = Modifier) {
+ Column(
+ modifier = modifier
+ .fillMaxWidth()
+ .background(
+ shape = TangemTheme.shapes.roundedCornersXMedium,
+ color = TangemTheme.colors.background.primary,
+ ),
+ horizontalAlignment = Alignment.Start,
+ verticalArrangement = Arrangement.Top,
+ ) {
+ when (model) {
+ is DetailsItemUM.Basic -> {
+ model.items.forEach { item ->
+ key(item.id) {
+ BlockItem(
+ modifier = Modifier.fillMaxWidth(),
+ model = item,
+ )
+ }
+ }
+ }
+ is DetailsItemUM.Component -> {
+ model.content(
+ modifier = Modifier.fillMaxWidth(),
+ )
+ }
+ }
+ }
+}
+
+@Composable
+private fun Footer(model: DetailsFooterUM, modifier: Modifier = Modifier) {
+ Column(
+ modifier = modifier
+ .padding(
+ top = TangemTheme.dimens.spacing12,
+ bottom = TangemTheme.dimens.spacing16,
+ )
+ .fillMaxWidth(),
+ horizontalAlignment = Alignment.Start,
+ verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing16),
+ ) {
+ val socialsScrollState = rememberScrollState()
+
+ Row(
+ modifier = Modifier
+ .fillMaxWidth()
+ .scrollable(socialsScrollState, orientation = Orientation.Horizontal),
+ verticalAlignment = Alignment.CenterVertically,
+ horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing8),
+ ) {
+ model.socials.forEach { social ->
+ key(social.id) {
+ IconButton(
+ modifier = Modifier.size(TangemTheme.dimens.size32),
+ onClick = social.onClick,
+ ) {
+ Icon(
+ modifier = Modifier.size(TangemTheme.dimens.size24),
+ painter = painterResource(id = social.iconResId),
+ tint = TangemTheme.colors.icon.informative,
+ contentDescription = null,
+ )
+ }
+ }
+ }
+ }
+
+ Text(
+ modifier = Modifier.padding(horizontal = TangemTheme.dimens.spacing6),
+ text = model.appVersion,
+ style = TangemTheme.typography.caption2,
+ color = TangemTheme.colors.text.tertiary,
+ )
+ }
+}
+
+// region Preview
+@Composable
+@Preview(showBackground = true, widthDp = 360)
+@Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES)
+private fun Preview_DetailsScreen() {
+ TangemThemePreview {
+ PreviewDetailsComponent().View(modifier = Modifier.fillMaxSize())
+ }
+}
+// endregion Preview
\ No newline at end of file
diff --git a/features/details/impl/src/main/kotlin/com/tangem/features/details/ui/UserWalletListBlock.kt b/features/details/impl/src/main/kotlin/com/tangem/features/details/ui/UserWalletListBlock.kt
new file mode 100644
index 0000000000..254c434047
--- /dev/null
+++ b/features/details/impl/src/main/kotlin/com/tangem/features/details/ui/UserWalletListBlock.kt
@@ -0,0 +1,121 @@
+package com.tangem.features.details.ui
+
+import androidx.compose.foundation.Image
+import androidx.compose.foundation.layout.*
+import androidx.compose.material3.Icon
+import androidx.compose.material3.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.layout.ContentScale
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.text.style.TextOverflow
+import com.tangem.core.ui.extensions.TextReference
+import com.tangem.core.ui.extensions.resolveReference
+import com.tangem.core.ui.res.TangemTheme
+import com.tangem.features.details.entity.UserWalletListUM
+import com.tangem.features.details.impl.R
+
+@Composable
+internal fun UserWalletListBlock(state: UserWalletListUM, modifier: Modifier = Modifier) {
+ BlockCard(
+ modifier = modifier,
+ ) {
+ state.userWallets.forEach { model ->
+ key(model.id) {
+ UserWalletItem(
+ modifier = Modifier.fillMaxWidth(),
+ model = model,
+ )
+ }
+ }
+ AddWalletButton(
+ text = state.addNewWalletText,
+ isInProgress = state.isWalletSavingInProgress,
+ onClick = state.onAddNewWalletClick,
+ )
+ }
+}
+
+@Composable
+private fun UserWalletItem(model: UserWalletListUM.UserWalletUM, modifier: Modifier = Modifier) {
+ BlockCard(
+ modifier = modifier,
+ onClick = model.onClick,
+ ) {
+ Row(
+ modifier = Modifier
+ .fillMaxWidth()
+ .heightIn(min = TangemTheme.dimens.size68)
+ .padding(all = TangemTheme.dimens.spacing12),
+ verticalAlignment = Alignment.CenterVertically,
+ horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing12),
+ ) {
+ Image(
+ modifier = Modifier
+ .width(TangemTheme.dimens.size24)
+ .height(TangemTheme.dimens.size36),
+ painter = painterResource(id = model.imageResId),
+ contentScale = ContentScale.FillBounds,
+ contentDescription = null,
+ )
+
+ Column(
+ modifier = Modifier.heightIn(min = TangemTheme.dimens.size40),
+ horizontalAlignment = Alignment.Start,
+ verticalArrangement = Arrangement.SpaceEvenly,
+ ) {
+ Text(
+ text = model.name,
+ style = TangemTheme.typography.subtitle1,
+ color = TangemTheme.colors.text.primary1,
+ maxLines = 1,
+ overflow = TextOverflow.Ellipsis,
+ )
+ Text(
+ text = model.information.resolveReference(),
+ style = TangemTheme.typography.caption2,
+ color = TangemTheme.colors.text.tertiary,
+ maxLines = 1,
+ overflow = TextOverflow.Ellipsis,
+ )
+ }
+ }
+ }
+}
+
+@Composable
+private fun AddWalletButton(
+ text: TextReference,
+ isInProgress: Boolean,
+ onClick: () -> Unit,
+ modifier: Modifier = Modifier,
+) {
+ BlockCard(
+ modifier = modifier,
+ onClick = onClick,
+ enabled = !isInProgress,
+ ) {
+ Row(
+ modifier = Modifier
+ .fillMaxWidth()
+ .padding(all = TangemTheme.dimens.spacing12),
+ verticalAlignment = Alignment.CenterVertically,
+ horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing12),
+ ) {
+ Icon(
+ modifier = Modifier.size(TangemTheme.dimens.size24),
+ painter = painterResource(id = R.drawable.ic_plus_24),
+ tint = TangemTheme.colors.icon.accent,
+ contentDescription = null,
+ )
+
+ Text(
+ text = text.resolveReference(),
+ style = TangemTheme.typography.subtitle1,
+ color = TangemTheme.colors.text.accent,
+ )
+ }
+ }
+}
\ No newline at end of file
diff --git a/features/details/impl/src/main/kotlin/com/tangem/features/details/ui/WalletConnectBlock.kt b/features/details/impl/src/main/kotlin/com/tangem/features/details/ui/WalletConnectBlock.kt
new file mode 100644
index 0000000000..11a28b3a75
--- /dev/null
+++ b/features/details/impl/src/main/kotlin/com/tangem/features/details/ui/WalletConnectBlock.kt
@@ -0,0 +1,51 @@
+package com.tangem.features.details.ui
+
+import androidx.compose.foundation.layout.*
+import androidx.compose.material3.Icon
+import androidx.compose.material3.Text
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.res.stringResource
+import com.tangem.core.ui.res.TangemColorPalette
+import com.tangem.core.ui.res.TangemTheme
+import com.tangem.features.details.impl.R
+
+@Composable
+internal fun WalletConnectBlock(onClick: () -> Unit, modifier: Modifier = Modifier) {
+ BlockCard(
+ modifier = modifier,
+ onClick = onClick,
+ ) {
+ Row(
+ modifier = Modifier.padding(all = TangemTheme.dimens.spacing12),
+ verticalAlignment = Alignment.Top,
+ horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing12),
+ ) {
+ Icon(
+ modifier = Modifier.size(TangemTheme.dimens.size24),
+ painter = painterResource(id = R.drawable.ic_wallet_connect_24),
+ tint = TangemColorPalette.Azure,
+ contentDescription = null,
+ )
+
+ Column(
+ modifier = Modifier.heightIn(min = TangemTheme.dimens.size48),
+ horizontalAlignment = Alignment.Start,
+ verticalArrangement = Arrangement.SpaceAround,
+ ) {
+ Text(
+ text = stringResource(id = R.string.wallet_connect_title),
+ style = TangemTheme.typography.subtitle1,
+ color = TangemTheme.colors.text.primary1,
+ )
+ Text(
+ text = stringResource(id = R.string.wallet_connect_subtitle),
+ style = TangemTheme.typography.body2,
+ color = TangemTheme.colors.text.secondary,
+ )
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/features/details/impl/src/main/kotlin/com/tangem/features/details/utils/ItemsBuilder.kt b/features/details/impl/src/main/kotlin/com/tangem/features/details/utils/ItemsBuilder.kt
new file mode 100644
index 0000000000..9ef2760ab6
--- /dev/null
+++ b/features/details/impl/src/main/kotlin/com/tangem/features/details/utils/ItemsBuilder.kt
@@ -0,0 +1,97 @@
+package com.tangem.features.details.utils
+
+import com.tangem.core.ui.extensions.resourceReference
+import com.tangem.core.ui.extensions.stringReference
+import com.tangem.features.details.component.UserWalletListComponent
+import com.tangem.features.details.component.WalletConnectComponent
+import com.tangem.features.details.entity.DetailsItemUM
+import com.tangem.features.details.impl.BuildConfig
+import com.tangem.features.details.impl.R
+import kotlinx.collections.immutable.ImmutableList
+import kotlinx.collections.immutable.persistentListOf
+import kotlinx.collections.immutable.toImmutableList
+
+internal class ItemsBuilder(
+ private val walletConnectComponent: WalletConnectComponent,
+ private val userWalletListComponent: UserWalletListComponent,
+) {
+
+ suspend fun buldAll(): ImmutableList = buildList {
+ buildWalletConnectBlock()?.let(::add)
+ buildUserWalletListBlock().let(::add)
+ buildShopBlock().let(::add)
+ buildSettingsBlock().let(::add)
+ buildSupportBlock().let(::add)
+ }.toImmutableList()
+
+ private suspend fun buildWalletConnectBlock(): DetailsItemUM? {
+ return if (walletConnectComponent.checkIsAvailable()) {
+ DetailsItemUM.Component(
+ id = "wallet_connect",
+ content = {
+ walletConnectComponent.View(modifier = it)
+ },
+ )
+ } else {
+ null
+ }
+ }
+
+ fun buildUserWalletListBlock(): DetailsItemUM = DetailsItemUM.Component(
+ id = "user_wallet_list",
+ content = {
+ userWalletListComponent.View(modifier = it)
+ },
+ )
+
+ private fun buildShopBlock(): DetailsItemUM = DetailsItemUM.Basic(
+ id = "shop",
+ items = persistentListOf(
+ DetailsItemUM.Basic.Item(
+ id = "buy_tangem_wallet",
+ title = stringReference("Buy Tangem Wallet"), // TODO: Move to resources in [REDACTED_TASK_KEY]
+ iconRes = R.drawable.ic_tangem_24,
+ onClick = { /* [REDACTED_TODO_COMMENT] */ },
+ ),
+ ),
+ )
+
+ private fun buildSettingsBlock(): DetailsItemUM = DetailsItemUM.Basic(
+ id = "settings",
+ items = buildList {
+ DetailsItemUM.Basic.Item(
+ id = "app_settings",
+ title = resourceReference(R.string.app_settings_title),
+ iconRes = R.drawable.ic_settings_24,
+ onClick = { /* [REDACTED_TODO_COMMENT] */ },
+ ).let(::add)
+
+ if (BuildConfig.TESTER_MENU_ENABLED) {
+ DetailsItemUM.Basic.Item(
+ id = "tester_menu",
+ title = stringReference(value = "Tester menu"),
+ iconRes = R.drawable.ic_alert_24,
+ onClick = { /* [REDACTED_TODO_COMMENT] */ },
+ ).let(::add)
+ }
+ }.toImmutableList(),
+ )
+
+ private fun buildSupportBlock(): DetailsItemUM = DetailsItemUM.Basic(
+ id = "support",
+ items = persistentListOf(
+ DetailsItemUM.Basic.Item(
+ id = "send_feedback",
+ title = stringReference("Send feedback"), // TODO: Move to resources in [REDACTED_TASK_KEY]
+ iconRes = R.drawable.ic_comment_24,
+ onClick = { /* [REDACTED_TODO_COMMENT] */ },
+ ),
+ DetailsItemUM.Basic.Item(
+ id = "disclaimer",
+ title = resourceReference(R.string.disclaimer_title),
+ iconRes = R.drawable.ic_text_24,
+ onClick = { /* [REDACTED_TODO_COMMENT] */ },
+ ),
+ ),
+ )
+}
\ No newline at end of file
diff --git a/features/details/impl/src/main/kotlin/com/tangem/features/details/utils/SocialsBuilder.kt b/features/details/impl/src/main/kotlin/com/tangem/features/details/utils/SocialsBuilder.kt
new file mode 100644
index 0000000000..d2666a03e7
--- /dev/null
+++ b/features/details/impl/src/main/kotlin/com/tangem/features/details/utils/SocialsBuilder.kt
@@ -0,0 +1,84 @@
+package com.tangem.features.details.utils
+
+import androidx.compose.ui.text.intl.Locale
+import com.tangem.features.details.entity.DetailsFooterUM
+import com.tangem.features.details.impl.R
+import kotlinx.collections.immutable.ImmutableList
+import kotlinx.collections.immutable.toImmutableList
+
+internal class SocialsBuilder(
+ private val urlOpener: (url: String) -> Unit,
+) {
+
+ fun buildAll(): ImmutableList = Social.all.map { social ->
+ DetailsFooterUM.Social(
+ id = social.name,
+ iconResId = social.iconResId,
+ onClick = { openUrl(social) },
+ )
+ }.toImmutableList()
+
+ private fun openUrl(social: Social) {
+ val locale = Locale.current.region
+
+ if (locale == RUSSIA_LOCALE && social.urlRu != null) {
+ urlOpener(social.urlRu)
+ } else {
+ urlOpener(social.url)
+ }
+ }
+
+ private enum class Social(
+ val iconResId: Int,
+ val url: String,
+ val urlRu: String? = null,
+ ) {
+ X(
+ iconResId = R.drawable.ic_twitter_24,
+ url = "https://x.com/tangem",
+ ),
+ TELEGRAM(
+ iconResId = R.drawable.ic_telegram_24,
+ url = "https://t.me/tangem_chat",
+ urlRu = "https://t.me/tangem_chat_ru",
+ ),
+ DISCORD(
+ iconResId = R.drawable.ic_discord_24,
+ url = "https://discord.gg/tangem",
+ ),
+ REDDIT(
+ iconResId = R.drawable.ic_reddit_24,
+ url = "https://www.reddit.com/r/Tangem/",
+ ),
+ INSTAGRAM(
+ iconResId = R.drawable.ic_instagram_24,
+ url = "https://www.instagram.com/tangemwallet",
+ ),
+ GIT_HUB(
+ iconResId = R.drawable.ic_github_24,
+ url = "https://github.com/tangem",
+ ),
+ FACEBOOK(
+ iconResId = R.drawable.ic_facebook_24,
+ url = "https://www.facebook.com/tangemwallet",
+ ),
+ LINKEDIN(
+ iconResId = R.drawable.ic_linkedin_24,
+ url = "https://www.linkedin.com/company/tangem",
+ ),
+ YOUTUBE(
+ iconResId = R.drawable.ic_youtube_24,
+ url = "https://youtube.com/@tangem_official",
+ ),
+ ;
+
+ companion object {
+
+ val all = values()
+ }
+ }
+
+ private companion object {
+ const val RUSSIA_LOCALE = "ru"
+ }
+}
\ No newline at end of file
diff --git a/features/details/impl/src/main/res/drawable/ill_card_note_bnb_211_343.png b/features/details/impl/src/main/res/drawable/ill_card_note_bnb_211_343.png
new file mode 100644
index 0000000000..033efd2699
Binary files /dev/null and b/features/details/impl/src/main/res/drawable/ill_card_note_bnb_211_343.png differ
diff --git a/features/details/impl/src/main/res/drawable/ill_card_note_eth_211_343.png b/features/details/impl/src/main/res/drawable/ill_card_note_eth_211_343.png
new file mode 100644
index 0000000000..b338ee1eb5
Binary files /dev/null and b/features/details/impl/src/main/res/drawable/ill_card_note_eth_211_343.png differ
diff --git a/features/details/impl/src/main/res/drawable/ill_card_wallet_2_211_343.png b/features/details/impl/src/main/res/drawable/ill_card_wallet_2_211_343.png
new file mode 100644
index 0000000000..9625b941a1
Binary files /dev/null and b/features/details/impl/src/main/res/drawable/ill_card_wallet_2_211_343.png differ