Updated on 2026-08-14

This commit is contained in:
Tangem 2025-09-04 17:10:01 +05:00
parent 2471b9c1a8
commit 941863f79b
18 changed files with 334 additions and 43 deletions

View file

@ -525,8 +525,11 @@ class MainActivity : AppCompatActivity(), ActivityResultCallbackHolder {
// Workaround to navigate to TangemPayDetails screen. Will be deleted in next PRs // Workaround to navigate to TangemPayDetails screen. Will be deleted in next PRs
if (tangemPayFeatureToggles.isTangemPayEnabled) { if (tangemPayFeatureToggles.isTangemPayEnabled) {
lifecycleScope.launch {
val selectedUserWalledId = userWalletsListRepository.selectedUserWalletSync()?.walletId
store.dispatchNavigationAction { store.dispatchNavigationAction {
replaceAll(AppRoute.TangemPayDetails) replaceAll(AppRoute.TangemPayDetails(requireNotNull(selectedUserWalledId)))
}
} }
} else if (userWalletsListManager.isLockable && userWalletsListManager.hasUserWallets) { } else if (userWalletsListManager.isLockable && userWalletsListManager.hasUserWallets) {
store.dispatchNavigationAction { store.dispatchNavigationAction {

View file

@ -591,7 +591,7 @@ internal class ChildFactory @Inject constructor(
is AppRoute.TangemPayDetails -> { is AppRoute.TangemPayDetails -> {
createComponentChild( createComponentChild(
context = context, context = context,
params = TangemPayDetailsComponent.Params(), params = TangemPayDetailsComponent.Params(userWalletId = route.userWalletId),
componentFactory = tangemPayDetailsComponentFactory, componentFactory = tangemPayDetailsComponentFactory,
) )
} }

View file

@ -369,5 +369,5 @@ sealed class AppRoute(val path: String) : Route {
) : AppRoute(path = "/archived_account/${userWalletId.stringValue}") ) : AppRoute(path = "/archived_account/${userWalletId.stringValue}")
@Serializable @Serializable
data object TangemPayDetails : AppRoute(path = "/tangem_pay_details") data class TangemPayDetails(val userWalletId: UserWalletId) : AppRoute(path = "/tangem_pay_details")
} }

View file

@ -23,7 +23,7 @@ import java.util.UUID
* @param modifier modifier * @param modifier modifier
*/ */
@Composable @Composable
internal fun TxHistoryGroupTitle(config: TxHistoryItemState.GroupTitle, modifier: Modifier = Modifier) { fun TxHistoryGroupTitle(config: TxHistoryItemState.GroupTitle, modifier: Modifier = Modifier) {
Box( Box(
modifier = modifier modifier = modifier
.background(TangemTheme.colors.background.primary) .background(TangemTheme.colors.background.primary)

View file

@ -13,6 +13,9 @@ dependencies {
implementation(projects.core.decompose) implementation(projects.core.decompose)
implementation(projects.core.ui) implementation(projects.core.ui)
/** Domain */
implementation(projects.domain.models)
/** Compose */ /** Compose */
implementation(deps.compose.runtime) implementation(deps.compose.runtime)
} }

View file

@ -2,9 +2,9 @@ package com.tangem.features.tangempay.components
import com.tangem.core.decompose.factory.ComponentFactory import com.tangem.core.decompose.factory.ComponentFactory
import com.tangem.core.ui.decompose.ComposableContentComponent import com.tangem.core.ui.decompose.ComposableContentComponent
import com.tangem.domain.models.wallet.UserWalletId
interface TangemPayDetailsComponent : ComposableContentComponent { interface TangemPayDetailsComponent : ComposableContentComponent {
@Suppress("EmptyDefaultConstructor") // Will add params in Next PRs data class Params(val userWalletId: UserWalletId)
class Params()
interface Factory : ComponentFactory<Params, TangemPayDetailsComponent> interface Factory : ComponentFactory<Params, TangemPayDetailsComponent>
} }

View file

@ -19,6 +19,12 @@ dependencies {
/** Features api */ /** Features api */
implementation(projects.features.tangempay.details.api) implementation(projects.features.tangempay.details.api)
implementation(projects.features.txhistory.api)
/** Domain */
implementation(projects.domain.balanceHiding)
implementation(projects.domain.balanceHiding.models)
implementation(projects.domain.models)
/** Compose */ /** Compose */
implementation(deps.compose.foundation) implementation(deps.compose.foundation)

View file

@ -5,8 +5,10 @@ import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.lifecycle.compose.collectAsStateWithLifecycle import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.tangem.core.decompose.context.AppComponentContext import com.tangem.core.decompose.context.AppComponentContext
import com.tangem.core.decompose.context.child
import com.tangem.core.decompose.model.getOrCreateModel import com.tangem.core.decompose.model.getOrCreateModel
import com.tangem.core.ui.components.NavigationBar3ButtonsScrim import com.tangem.core.ui.components.NavigationBar3ButtonsScrim
import com.tangem.features.tangempay.components.txHistory.DefaultTangemPayTxHistoryComponent
import com.tangem.features.tangempay.model.TangemPayDetailsModel import com.tangem.features.tangempay.model.TangemPayDetailsModel
import com.tangem.features.tangempay.ui.TangemPayDetailsScreen import com.tangem.features.tangempay.ui.TangemPayDetailsScreen
import dagger.assisted.Assisted import dagger.assisted.Assisted
@ -19,12 +21,16 @@ internal class DefaultTangemPayDetailsComponent @AssistedInject constructor(
) : AppComponentContext by appComponentContext, TangemPayDetailsComponent { ) : AppComponentContext by appComponentContext, TangemPayDetailsComponent {
private val model: TangemPayDetailsModel = getOrCreateModel(params = params) private val model: TangemPayDetailsModel = getOrCreateModel(params = params)
private val txHistoryComponent = DefaultTangemPayTxHistoryComponent(
appComponentContext = child("txHistoryComponent"),
params = DefaultTangemPayTxHistoryComponent.Params(userWalletId = params.userWalletId),
)
@Composable @Composable
override fun Content(modifier: Modifier) { override fun Content(modifier: Modifier) {
val state by model.uiState.collectAsStateWithLifecycle() val state by model.uiState.collectAsStateWithLifecycle()
NavigationBar3ButtonsScrim() NavigationBar3ButtonsScrim()
TangemPayDetailsScreen(state = state, modifier = modifier) TangemPayDetailsScreen(state = state, txHistoryComponent = txHistoryComponent, modifier = modifier)
} }
@AssistedFactory @AssistedFactory

View file

@ -0,0 +1,26 @@
package com.tangem.features.tangempay.components.txHistory
import androidx.compose.foundation.lazy.LazyListScope
import androidx.compose.foundation.lazy.LazyListState
import com.tangem.core.decompose.context.AppComponentContext
import com.tangem.core.decompose.model.getOrCreateModel
import com.tangem.domain.models.wallet.UserWalletId
import com.tangem.features.tangempay.model.TangemPayTxHistoryModel
import com.tangem.features.txhistory.entity.TxHistoryUM
import com.tangem.features.txhistory.ui.txHistoryItems
import kotlinx.coroutines.flow.StateFlow
internal class DefaultTangemPayTxHistoryComponent(
appComponentContext: AppComponentContext,
params: Params,
) : AppComponentContext by appComponentContext, TangemPayTxHistoryComponent {
private val model: TangemPayTxHistoryModel = getOrCreateModel(params = params)
override val state: StateFlow<TxHistoryUM> = model.uiState
override fun LazyListScope.txHistoryContent(listState: LazyListState, state: TxHistoryUM) {
txHistoryItems(listState, state)
}
data class Params(val userWalletId: UserWalletId)
}

View file

@ -0,0 +1,174 @@
package com.tangem.features.tangempay.components.txHistory
import androidx.compose.foundation.lazy.LazyListScope
import androidx.compose.foundation.lazy.LazyListState
import com.tangem.core.ui.components.transactions.state.TransactionState
import com.tangem.core.ui.extensions.stringReference
import com.tangem.features.tangempay.details.impl.R
import com.tangem.features.txhistory.entity.TxHistoryUM
import com.tangem.features.txhistory.ui.txHistoryItems
import kotlinx.collections.immutable.persistentListOf
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
internal class PreviewTangemPayTxHistoryComponent(txHistoryUM: TxHistoryUM) : TangemPayTxHistoryComponent {
override val state: StateFlow<TxHistoryUM> = MutableStateFlow(txHistoryUM)
override fun LazyListScope.txHistoryContent(listState: LazyListState, state: TxHistoryUM) {
txHistoryItems(listState, state)
}
companion object {
val loadingUM = TxHistoryUM.Loading(isBalanceHidden = true, onExploreClick = {})
val emptyUM = TxHistoryUM.Empty(isBalanceHidden = true, onExploreClick = {})
val contentUM = TxHistoryUM.Content(
isBalanceHidden = false,
loadMore = { false },
items = persistentListOf(
TxHistoryUM.TxHistoryItemUM.Title(onExploreClick = {}),
TxHistoryUM.TxHistoryItemUM.GroupTitle(title = "Today", itemKey = "Today"),
TxHistoryUM.TxHistoryItemUM.Transaction(
state = TransactionState.Content(
txHash = "signiferumque",
amount = "-4.99 USD",
time = "16:41",
status = TransactionState.Content.Status.Confirmed,
direction = TransactionState.Content.Direction.OUTGOING,
onClick = {},
iconRes = R.drawable.ic_arrow_up_24,
title = stringReference("Starbucks"),
subtitle = stringReference("Food&Drinks"),
timestamp = 3464,
),
),
TxHistoryUM.TxHistoryItemUM.Transaction(
state = TransactionState.Content(
txHash = "signiferumque",
amount = "-126.20 USD",
time = "12:04",
status = TransactionState.Content.Status.Confirmed,
direction = TransactionState.Content.Direction.OUTGOING,
onClick = {},
iconRes = R.drawable.ic_arrow_up_24,
title = stringReference("Wallmart"),
subtitle = stringReference("Supermarket"),
timestamp = 3465,
),
),
TxHistoryUM.TxHistoryItemUM.GroupTitle(title = "Yesterday", itemKey = "Yesterday"),
TxHistoryUM.TxHistoryItemUM.Transaction(
state = TransactionState.Content(
txHash = "signiferumque",
amount = "-4.99 USD",
time = "21:41",
status = TransactionState.Content.Status.Confirmed,
direction = TransactionState.Content.Direction.OUTGOING,
onClick = {},
iconRes = R.drawable.ic_arrow_up_24,
title = stringReference("Starbucks"),
subtitle = stringReference("Food&Drinks"),
timestamp = 3464,
),
),
TxHistoryUM.TxHistoryItemUM.Transaction(
state = TransactionState.Content(
txHash = "signiferumque",
amount = "-126.20 USD",
time = "10:04",
status = TransactionState.Content.Status.Confirmed,
direction = TransactionState.Content.Direction.OUTGOING,
onClick = {},
iconRes = R.drawable.ic_arrow_up_24,
title = stringReference("Wallmart"),
subtitle = stringReference("Supermarket"),
timestamp = 3465,
),
),
TxHistoryUM.TxHistoryItemUM.Transaction(
state = TransactionState.Content(
txHash = "signiferumque",
amount = "-4.99 USD",
time = "19:41",
status = TransactionState.Content.Status.Confirmed,
direction = TransactionState.Content.Direction.OUTGOING,
onClick = {},
iconRes = R.drawable.ic_arrow_up_24,
title = stringReference("Starbucks"),
subtitle = stringReference("Food&Drinks"),
timestamp = 3464,
),
),
TxHistoryUM.TxHistoryItemUM.Transaction(
state = TransactionState.Content(
txHash = "signiferumque",
amount = "-126.20 USD",
time = "18:04",
status = TransactionState.Content.Status.Confirmed,
direction = TransactionState.Content.Direction.OUTGOING,
onClick = {},
iconRes = R.drawable.ic_arrow_up_24,
title = stringReference("Wallmart"),
subtitle = stringReference("Supermarket"),
timestamp = 3465,
),
),
TxHistoryUM.TxHistoryItemUM.Transaction(
state = TransactionState.Content(
txHash = "signiferumque",
amount = "-4.99 USD",
time = "17:41",
status = TransactionState.Content.Status.Confirmed,
direction = TransactionState.Content.Direction.OUTGOING,
onClick = {},
iconRes = R.drawable.ic_arrow_up_24,
title = stringReference("Starbucks"),
subtitle = stringReference("Food&Drinks"),
timestamp = 3464,
),
),
TxHistoryUM.TxHistoryItemUM.Transaction(
state = TransactionState.Content(
txHash = "signiferumque",
amount = "-126.20 USD",
time = "16:04",
status = TransactionState.Content.Status.Confirmed,
direction = TransactionState.Content.Direction.OUTGOING,
onClick = {},
iconRes = R.drawable.ic_arrow_up_24,
title = stringReference("Wallmart"),
subtitle = stringReference("Supermarket"),
timestamp = 3465,
),
),
TxHistoryUM.TxHistoryItemUM.Transaction(
state = TransactionState.Content(
txHash = "signiferumque",
amount = "-4.99 USD",
time = "15:41",
status = TransactionState.Content.Status.Confirmed,
direction = TransactionState.Content.Direction.OUTGOING,
onClick = {},
iconRes = R.drawable.ic_arrow_up_24,
title = stringReference("Starbucks"),
subtitle = stringReference("Food&Drinks"),
timestamp = 3464,
),
),
TxHistoryUM.TxHistoryItemUM.Transaction(
state = TransactionState.Content(
txHash = "signiferumque",
amount = "-126.20 USD",
time = "14:04",
status = TransactionState.Content.Status.Confirmed,
direction = TransactionState.Content.Direction.OUTGOING,
onClick = {},
iconRes = R.drawable.ic_arrow_up_24,
title = stringReference("Wallmart"),
subtitle = stringReference("Supermarket"),
timestamp = 3465,
),
),
),
)
}
}

View file

@ -0,0 +1,11 @@
package com.tangem.features.tangempay.components.txHistory
import androidx.compose.foundation.lazy.LazyListScope
import androidx.compose.foundation.lazy.LazyListState
import com.tangem.features.txhistory.entity.TxHistoryUM
import kotlinx.coroutines.flow.StateFlow
internal interface TangemPayTxHistoryComponent {
val state: StateFlow<TxHistoryUM>
fun LazyListScope.txHistoryContent(listState: LazyListState, state: TxHistoryUM)
}

View file

@ -3,6 +3,7 @@ package com.tangem.features.tangempay.di
import com.tangem.core.decompose.di.ModelComponent import com.tangem.core.decompose.di.ModelComponent
import com.tangem.core.decompose.model.Model import com.tangem.core.decompose.model.Model
import com.tangem.features.tangempay.model.TangemPayDetailsModel import com.tangem.features.tangempay.model.TangemPayDetailsModel
import com.tangem.features.tangempay.model.TangemPayTxHistoryModel
import dagger.Binds import dagger.Binds
import dagger.Module import dagger.Module
import dagger.hilt.InstallIn import dagger.hilt.InstallIn
@ -16,5 +17,10 @@ internal interface TangemPayModelModule {
@Binds @Binds
@IntoMap @IntoMap
@ClassKey(TangemPayDetailsModel::class) @ClassKey(TangemPayDetailsModel::class)
fun bindWcConnectionsModel(model: TangemPayDetailsModel): Model fun bindTangemPayDetailsModel(model: TangemPayDetailsModel): Model
@Binds
@IntoMap
@ClassKey(TangemPayTxHistoryModel::class)
fun bindTangemPayTxHistoryModel(model: TangemPayTxHistoryModel): Model
} }

View file

@ -0,0 +1,62 @@
package com.tangem.features.tangempay.model
import androidx.compose.runtime.Stable
import com.tangem.core.decompose.di.ModelScoped
import com.tangem.core.decompose.model.Model
import com.tangem.core.decompose.model.ParamsContainer
import com.tangem.domain.balancehiding.GetBalanceHidingSettingsUseCase
import com.tangem.features.tangempay.components.txHistory.DefaultTangemPayTxHistoryComponent
import com.tangem.features.tangempay.components.txHistory.PreviewTangemPayTxHistoryComponent
import com.tangem.features.txhistory.entity.TxHistoryUM
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import timber.log.Timber
import javax.inject.Inject
@Stable
@ModelScoped
internal class TangemPayTxHistoryModel @Inject constructor(
private val getBalanceHidingSettingsUseCase: GetBalanceHidingSettingsUseCase,
override val dispatchers: CoroutineDispatcherProvider,
paramsContainer: ParamsContainer,
) : Model() {
private val params: DefaultTangemPayTxHistoryComponent.Params = paramsContainer.require()
val uiState: StateFlow<TxHistoryUM>
field = MutableStateFlow(getInitialState())
init {
handleBalanceHiding()
subscribeToUiItemChanges()
}
@Suppress("MagicNumber")
private fun subscribeToUiItemChanges() {
modelScope.launch {
Timber.d("subscribeToUiItemChanges: ${params.userWalletId}")
delay(2000)
uiState.update { PreviewTangemPayTxHistoryComponent.contentUM }
}
}
private fun handleBalanceHiding() {
getBalanceHidingSettingsUseCase()
.onEach { uiState.update { state -> state.copySealed(isBalanceHidden = it.isBalanceHidden) } }
.launchIn(modelScope)
}
private fun onExploreClick() {
Timber.d("onExploreClick: open explorer")
}
private fun getInitialState(): TxHistoryUM {
return TxHistoryUM.Loading(isBalanceHidden = true, onExploreClick = ::onExploreClick)
}
}

View file

@ -19,11 +19,13 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.testTag import androidx.compose.ui.platform.testTag
import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.painterResource
import androidx.compose.ui.tooling.preview.Devices
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.util.fastForEach import androidx.compose.ui.util.fastForEach
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.tangem.core.ui.components.RectangleShimmer import com.tangem.core.ui.components.RectangleShimmer
import com.tangem.core.ui.components.buttons.HorizontalActionChips import com.tangem.core.ui.components.buttons.HorizontalActionChips
import com.tangem.core.ui.components.buttons.actions.ActionButtonConfig import com.tangem.core.ui.components.buttons.actions.ActionButtonConfig
@ -37,6 +39,8 @@ import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.res.TangemTheme import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview import com.tangem.core.ui.res.TangemThemePreview
import com.tangem.core.ui.test.TokenDetailsTopBarTestTags import com.tangem.core.ui.test.TokenDetailsTopBarTestTags
import com.tangem.features.tangempay.components.txHistory.PreviewTangemPayTxHistoryComponent
import com.tangem.features.tangempay.components.txHistory.TangemPayTxHistoryComponent
import com.tangem.features.tangempay.details.impl.R import com.tangem.features.tangempay.details.impl.R
import com.tangem.features.tangempay.entity.TangemPayCardDetailsUM import com.tangem.features.tangempay.entity.TangemPayCardDetailsUM
import com.tangem.features.tangempay.entity.TangemPayDetailsBalanceBlockState import com.tangem.features.tangempay.entity.TangemPayDetailsBalanceBlockState
@ -46,7 +50,11 @@ import com.tangem.utils.StringsSigns.DASH_SIGN
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
@Composable @Composable
internal fun TangemPayDetailsScreen(state: TangemPayDetailsUM, modifier: Modifier = Modifier) { internal fun TangemPayDetailsScreen(
state: TangemPayDetailsUM,
txHistoryComponent: TangemPayTxHistoryComponent,
modifier: Modifier = Modifier,
) {
Scaffold( Scaffold(
modifier = modifier, modifier = modifier,
topBar = { TangemPayDetailsTopAppBar(config = state.topBarConfig) }, topBar = { TangemPayDetailsTopAppBar(config = state.topBarConfig) },
@ -55,6 +63,7 @@ internal fun TangemPayDetailsScreen(state: TangemPayDetailsUM, modifier: Modifie
) { scaffoldPaddings -> ) { scaffoldPaddings ->
val listState = rememberLazyListState() val listState = rememberLazyListState()
val bottomBarHeight = with(LocalDensity.current) { WindowInsets.systemBars.getBottom(this).toDp() } val bottomBarHeight = with(LocalDensity.current) { WindowInsets.systemBars.getBottom(this).toDp() }
val txHistoryState by txHistoryComponent.state.collectAsStateWithLifecycle()
TangemPullToRefreshContainer( TangemPullToRefreshContainer(
config = state.pullToRefreshConfig, config = state.pullToRefreshConfig,
@ -91,6 +100,8 @@ internal fun TangemPayDetailsScreen(state: TangemPayDetailsUM, modifier: Modifie
) )
}, },
) )
with(txHistoryComponent) { txHistoryContent(listState = listState, state = txHistoryState) }
} }
} }
} }
@ -317,14 +328,19 @@ private fun TangemPayDetailsTopAppBar(config: TangemPayDetailsTopBarConfig, modi
) )
} }
@Preview(showBackground = true, widthDp = 360) @Preview(device = Devices.PIXEL_7_PRO, group = "day")
@Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES) @Preview(uiMode = Configuration.UI_MODE_NIGHT_YES, device = Devices.PIXEL_7_PRO, group = "night")
@Composable @Composable
private fun TangemPayDetailsScreenPreview( private fun TangemPayDetailsScreenPreview(
@PreviewParameter(TangemPayDetailsUMProvider::class) state: TangemPayDetailsUM, @PreviewParameter(TangemPayDetailsUMProvider::class) state: TangemPayDetailsUM,
) { ) {
TangemThemePreview { TangemThemePreview {
TangemPayDetailsScreen(state = state) TangemPayDetailsScreen(
state = state,
txHistoryComponent = PreviewTangemPayTxHistoryComponent(
txHistoryUM = PreviewTangemPayTxHistoryComponent.contentUM,
),
)
} }
} }

View file

@ -1,6 +1,7 @@
package com.tangem.features.txhistory.entity package com.tangem.features.txhistory.entity
import com.tangem.core.ui.components.transactions.state.TransactionState import com.tangem.core.ui.components.transactions.state.TransactionState
import com.tangem.core.ui.components.transactions.state.TxHistoryState
import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
@ -81,7 +82,9 @@ sealed interface TxHistoryUM {
data class GroupTitle( data class GroupTitle(
val title: String, val title: String,
val itemKey: String, val itemKey: String,
) : TxHistoryItemUM ) : TxHistoryItemUM {
val legacyGroupTitle = TxHistoryState.TxHistoryItemState.GroupTitle(title = title, itemKey = itemKey)
}
/** /**
* Transaction item * Transaction item

View file

@ -1,20 +1,16 @@
package com.tangem.features.txhistory.ui package com.tangem.features.txhistory.ui
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.heightIn
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyListScope import androidx.compose.foundation.lazy.LazyListScope
import androidx.compose.foundation.lazy.LazyListState import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import com.tangem.core.ui.components.list.InfiniteListHandler import com.tangem.core.ui.components.list.InfiniteListHandler
import com.tangem.core.ui.components.transactions.PendingTxsBlock import com.tangem.core.ui.components.transactions.PendingTxsBlock
import com.tangem.core.ui.components.transactions.Transaction import com.tangem.core.ui.components.transactions.Transaction
import com.tangem.core.ui.components.transactions.TxHistoryGroupTitle
import com.tangem.core.ui.components.transactions.TxHistoryTitle import com.tangem.core.ui.components.transactions.TxHistoryTitle
import com.tangem.core.ui.components.transactions.empty.EmptyTransactionBlock import com.tangem.core.ui.components.transactions.empty.EmptyTransactionBlock
import com.tangem.core.ui.components.transactions.empty.EmptyTransactionsBlockState import com.tangem.core.ui.components.transactions.empty.EmptyTransactionsBlockState
@ -25,7 +21,7 @@ import com.tangem.features.txhistory.entity.TxHistoryUM
private const val LOAD_ITEMS_BUFFER = 20 private const val LOAD_ITEMS_BUFFER = 20
internal fun LazyListScope.txHistoryItems(listState: LazyListState, state: TxHistoryUM) { fun LazyListScope.txHistoryItems(listState: LazyListState, state: TxHistoryUM) {
when (state) { when (state) {
is TxHistoryUM.Content -> contentItems(listState, state) is TxHistoryUM.Content -> contentItems(listState, state)
is TxHistoryUM.Empty -> nonContentItem(state = EmptyTransactionsBlockState.Empty(state.onExploreClick)) is TxHistoryUM.Empty -> nonContentItem(state = EmptyTransactionsBlockState.Empty(state.onExploreClick))
@ -127,7 +123,7 @@ internal fun TxHistoryListItem(
) { ) {
when (state) { when (state) {
is TxHistoryUM.TxHistoryItemUM.GroupTitle -> { is TxHistoryUM.TxHistoryItemUM.GroupTitle -> {
TxHistoryGroupTitle(config = state, modifier = modifier) TxHistoryGroupTitle(config = state.legacyGroupTitle, modifier = modifier)
} }
is TxHistoryUM.TxHistoryItemUM.Title -> { is TxHistoryUM.TxHistoryItemUM.Title -> {
TxHistoryTitle(onExploreClick = state.onExploreClick, modifier = modifier) TxHistoryTitle(onExploreClick = state.onExploreClick, modifier = modifier)
@ -141,24 +137,3 @@ internal fun TxHistoryListItem(
} }
} }
} }
@Composable
private fun TxHistoryGroupTitle(config: TxHistoryUM.TxHistoryItemUM.GroupTitle, modifier: Modifier = Modifier) {
Box(
modifier = modifier
.background(TangemTheme.colors.background.primary)
.padding(
vertical = TangemTheme.dimens.spacing8,
horizontal = TangemTheme.dimens.spacing12,
)
.fillMaxWidth()
.heightIn(min = TangemTheme.dimens.size24),
contentAlignment = Alignment.CenterStart,
) {
Text(
text = config.title,
color = TangemTheme.colors.text.tertiary,
style = TangemTheme.typography.body2,
)
}
}

View file

@ -2,7 +2,6 @@ package com.tangem.features.txhistory.component
import androidx.compose.foundation.lazy.LazyListScope import androidx.compose.foundation.lazy.LazyListScope
import androidx.compose.foundation.lazy.LazyListState import androidx.compose.foundation.lazy.LazyListState
import androidx.compose.runtime.*
import com.tangem.core.decompose.context.AppComponentContext import com.tangem.core.decompose.context.AppComponentContext
import com.tangem.core.decompose.model.getOrCreateModel import com.tangem.core.decompose.model.getOrCreateModel
import com.tangem.features.txhistory.entity.TxHistoryUM import com.tangem.features.txhistory.entity.TxHistoryUM

View file

@ -29,6 +29,7 @@ internal fun BaseExtension.configureCompose(project: Project) {
contains(Regex(pattern = ":app\$")) || // TODO: [REDACTED_JIRA] contains(Regex(pattern = ":app\$")) || // TODO: [REDACTED_JIRA]
contains(Regex(pattern = ":features:markets:api\$")) || // provides Composable function contains(Regex(pattern = ":features:markets:api\$")) || // provides Composable function
contains(Regex(pattern = ":features:manage-tokens:api\$")) || // provides Composable function contains(Regex(pattern = ":features:manage-tokens:api\$")) || // provides Composable function
contains(Regex(pattern = ":features:txhistory:api\$")) || // provides Composable function
contains(Regex(pattern = ":impl\$")) contains(Regex(pattern = ":impl\$"))
} }