diff --git a/core/res/src/main/res/values-ja/strings.xml b/core/res/src/main/res/values-ja/strings.xml
index aeed4388a0..15e20368f1 100644
--- a/core/res/src/main/res/values-ja/strings.xml
+++ b/core/res/src/main/res/values-ja/strings.xml
@@ -374,6 +374,9 @@
下落率上位
トレンド
%sについて
+
+ - %1$s取引所
+
- %d のレーティングに基づいて
@@ -384,6 +387,7 @@
循環供給量
取引可能で市場に流通しているコインの総数
循環供給量
+ 取引所が見つかりません
経験豊富な買い手
少なくとも100の発信取引を持つネット・バイヤー
経験豊富な買い手
diff --git a/core/res/src/main/res/values-ru/strings.xml b/core/res/src/main/res/values-ru/strings.xml
index c7e2221f9d..040fca1460 100644
--- a/core/res/src/main/res/values-ru/strings.xml
+++ b/core/res/src/main/res/values-ru/strings.xml
@@ -382,6 +382,12 @@
Лидеры падения
В тренде
О %s
+
+ - %1$s биржа
+ - %1$s биржи
+ - %1$s бирж
+ - %1$s бирж
+
- На основе %d оценки
- На основе %d оценок
@@ -395,6 +401,7 @@
Циркулир. предл.
Общее количество монет, доступных для торговли и находящихся в обращении на рынке
Циркулирующее предложение
+ Биржи не найдены
Опытные трейдеры
Покупатели, у которых было как минимум 100 исходящих транзакций.
Опытные трейдеры
@@ -412,6 +419,7 @@
Изменение объема ликвидности, доступной для токена в течение указанного периода времени.
Ликвидность
Индекс ликвидности
+ Листинг на
Низкий
Рын. кап.
Общая рыночная стоимость криптовалюты, рассчитываемая путем умножения текущей цены монеты на общее количество монет в обращении.
diff --git a/core/res/src/main/res/values/strings.xml b/core/res/src/main/res/values/strings.xml
index a75c4fce68..7e90b04d5e 100644
--- a/core/res/src/main/res/values/strings.xml
+++ b/core/res/src/main/res/values/strings.xml
@@ -378,6 +378,10 @@
Top Losers
Trending
About %s
+
+ - %1$s exchange
+ - %1$s exchanges
+
- Based on %d rating
- Based on %d ratings
@@ -389,6 +393,7 @@
Circulating supply
The total number of coins that are available for trading and are circulating in the market
Circulating supply
+ No exchanges found
Experienced buyers
Net buyers with the additional requirement of having at least 100 outgoing transactions
Experienced buyers
@@ -406,6 +411,7 @@
The change in how much liquidity is available for the token during the specified timeframe
Liquidity
Liquidity index
+ Listed on
Low
Market cap
The total market value of a cryptocurrency, calculated by multiplying the current price of the coin by the total number of coins in circulation
diff --git a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/details/impl/ui/components/ListedOnBlock.kt b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/details/impl/ui/components/ListedOnBlock.kt
new file mode 100644
index 0000000000..29550713b7
--- /dev/null
+++ b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/details/impl/ui/components/ListedOnBlock.kt
@@ -0,0 +1,135 @@
+package com.tangem.features.markets.details.impl.ui.components
+
+import android.content.res.Configuration
+import androidx.compose.foundation.clickable
+import androidx.compose.foundation.layout.Box
+import androidx.compose.foundation.layout.fillMaxWidth
+import androidx.compose.foundation.layout.padding
+import androidx.compose.material3.Icon
+import androidx.compose.material3.Text
+import androidx.compose.runtime.*
+import androidx.compose.ui.Alignment
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.res.painterResource
+import androidx.compose.ui.text.style.TextOverflow
+import androidx.compose.ui.tooling.preview.Preview
+import androidx.compose.ui.tooling.preview.PreviewParameter
+import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider
+import com.tangem.common.ui.R
+import com.tangem.core.ui.components.TextShimmer
+import com.tangem.core.ui.components.block.information.InformationBlock
+import com.tangem.core.ui.extensions.resolveReference
+import com.tangem.core.ui.res.TangemTheme
+import com.tangem.core.ui.res.TangemThemePreview
+import com.tangem.features.markets.details.impl.ui.state.ListedOnUM
+import kotlinx.coroutines.delay
+
+/**
+ * "Listed on" block
+ *
+ * @param state block state
+ *
+[REDACTED_AUTHOR]
+ */
+@Composable
+internal fun ListedOnBlock(state: ListedOnUM) {
+ Box {
+ InformationBlock(
+ title = {
+ Text(
+ text = state.title.resolveReference(),
+ style = TangemTheme.typography.subtitle2,
+ color = TangemTheme.colors.text.tertiary,
+ maxLines = 1,
+ overflow = TextOverflow.Ellipsis,
+ )
+ },
+ modifier = Modifier.clickable(enabled = state is ListedOnUM.Content) {
+ (state as? ListedOnUM.Content)?.onClick?.invoke()
+ },
+ ) {
+ Description(
+ state = state,
+ modifier = Modifier.padding(bottom = TangemTheme.dimens.spacing12),
+ )
+ }
+
+ if (state is ListedOnUM.Content) {
+ Icon(
+ painter = painterResource(id = R.drawable.ic_chevron_right_24),
+ contentDescription = null,
+ tint = TangemTheme.colors.icon.informative,
+ modifier = Modifier
+ .align(Alignment.CenterEnd)
+ .padding(end = TangemTheme.dimens.spacing12),
+ )
+ }
+ }
+}
+
+@Composable
+internal fun ListedOnBlockPlaceholder(modifier: Modifier = Modifier) {
+ InformationBlock(
+ title = {
+ TextShimmer(
+ style = TangemTheme.typography.subtitle2,
+ modifier = Modifier.fillMaxWidth(fraction = 0.5f),
+ )
+ },
+ modifier = modifier,
+ ) {
+ TextShimmer(
+ style = TangemTheme.typography.body2,
+ modifier = Modifier
+ .fillMaxWidth(fraction = 0.3f)
+ .padding(bottom = TangemTheme.dimens.spacing12),
+ )
+ }
+}
+
+@Composable
+private fun Description(state: ListedOnUM, modifier: Modifier = Modifier) {
+ Text(
+ text = state.description.resolveReference(),
+ modifier = modifier,
+ color = TangemTheme.colors.text.tertiary,
+ overflow = TextOverflow.Ellipsis,
+ maxLines = 1,
+ style = TangemTheme.typography.body2,
+ )
+}
+
+@Preview(widthDp = 328, heightDp = 68)
+@Preview(name = "Dark Theme", widthDp = 328, heightDp = 68, uiMode = Configuration.UI_MODE_NIGHT_YES)
+@Composable
+private fun Preview_ListedOnBlock(@PreviewParameter(ListenOnUMProvider::class) state: ListedOnUM?) {
+ TangemThemePreview {
+ if (state == null) {
+ ListedOnBlockPlaceholder()
+ } else {
+ ListedOnBlock(state = state)
+ }
+ }
+}
+
+@Preview
+@Composable
+private fun Preview_ListedOnBlock_StateChanging() {
+ var state by remember { mutableStateOf(value = null) }
+
+ Preview_ListedOnBlock(state = state)
+
+ LaunchedEffect(key1 = null) {
+ delay(timeMillis = 3000)
+
+ state = ListedOnUM.Empty
+ }
+}
+
+private class ListenOnUMProvider : CollectionPreviewParameterProvider(
+ collection = listOf(
+ ListedOnUM.Empty,
+ ListedOnUM.Content(onClick = {}, amount = 5),
+ null,
+ ),
+)
\ No newline at end of file
diff --git a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/details/impl/ui/components/TokenMarketDetailsBody.kt b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/details/impl/ui/components/TokenMarketDetailsBody.kt
index d7ae7737c6..df869b4c73 100644
--- a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/details/impl/ui/components/TokenMarketDetailsBody.kt
+++ b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/details/impl/ui/components/TokenMarketDetailsBody.kt
@@ -115,6 +115,10 @@ internal fun LazyListScope.infoBlocksList(state: MarketsTokenDetailsUM.Informati
}
}
+ item(key = "listedOn") {
+ ListedOnBlock(state = state.listedOn)
+ }
+
if (state.links != null) {
item("links") {
LinksBlock(
@@ -143,6 +147,10 @@ private fun LazyListScope.loadingInfoBlocks() {
PricePerformanceBlockPlaceholder(modifier = Modifier.blockPaddings())
}
+ item(key = "listedOn-loading") {
+ ListedOnBlockPlaceholder(modifier = Modifier.blockPaddings())
+ }
+
item("links-loading") {
LinksBlockPlaceholder(modifier = Modifier.blockPaddings())
}
diff --git a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/details/impl/ui/state/ListedOnUM.kt b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/details/impl/ui/state/ListedOnUM.kt
index 753c6ca7c1..a853675b10 100644
--- a/features/markets/impl/src/main/kotlin/com/tangem/features/markets/details/impl/ui/state/ListedOnUM.kt
+++ b/features/markets/impl/src/main/kotlin/com/tangem/features/markets/details/impl/ui/state/ListedOnUM.kt
@@ -1,7 +1,10 @@
package com.tangem.features.markets.details.impl.ui.state
import com.tangem.core.ui.extensions.TextReference
-import com.tangem.core.ui.extensions.stringReference
+import com.tangem.core.ui.extensions.pluralReference
+import com.tangem.core.ui.extensions.resourceReference
+import com.tangem.core.ui.extensions.wrappedList
+import com.tangem.features.markets.impl.R
/**
* "Listed on" block UI model
@@ -10,13 +13,16 @@ import com.tangem.core.ui.extensions.stringReference
*/
internal sealed interface ListedOnUM {
+ /** Title */
+ val title: TextReference
+ get() = resourceReference(id = R.string.markets_token_details_listed_on)
+
/** Description */
val description: TextReference
/** Empty state. No exchanges found */
data object Empty : ListedOnUM {
- // TODO [REDACTED_JIRA]
- override val description: TextReference = stringReference(value = "No exchanges found")
+ override val description = resourceReference(id = R.string.markets_token_details_empty_exchanges)
}
/**
@@ -29,7 +35,10 @@ internal sealed interface ListedOnUM {
val onClick: () -> Unit,
private val amount: Int,
) : ListedOnUM {
- // TODO [REDACTED_JIRA]
- override val description: TextReference = stringReference(value = "$amount exchanges")
+ override val description: TextReference = pluralReference(
+ id = R.plurals.markets_token_details_amount_exchanges,
+ count = amount,
+ formatArgs = wrappedList(amount),
+ )
}
}
\ No newline at end of file