Updated on 2026-08-14
This commit is contained in:
parent
418fbf710d
commit
8c47e9483c
20 changed files with 53 additions and 36 deletions
|
|
@ -593,7 +593,7 @@ internal class ChildFactory @Inject constructor(
|
|||
is AppRoute.TangemPayDetails -> {
|
||||
createComponentChild(
|
||||
context = context,
|
||||
params = TangemPayDetailsComponent.Params(userWalletId = route.userWalletId),
|
||||
params = TangemPayDetailsComponent.Params(customerWalletAddress = route.customerWalletAddress),
|
||||
componentFactory = tangemPayDetailsComponentFactory,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -439,7 +439,7 @@ sealed class AppRoute(val path: String) : Route {
|
|||
) : AppRoute(path = "/archived_account/${userWalletId.stringValue}")
|
||||
|
||||
@Serializable
|
||||
data class TangemPayDetails(val userWalletId: UserWalletId) : AppRoute(path = "/tangem_pay_details")
|
||||
data class TangemPayDetails(val customerWalletAddress: String) : AppRoute(path = "/tangem_pay_details")
|
||||
|
||||
@Serializable
|
||||
data class TangemPayOnboarding(
|
||||
|
|
|
|||
|
|
@ -2,21 +2,20 @@ package com.tangem.datasource.local.visa
|
|||
|
||||
import com.tangem.datasource.local.datastore.core.StringKeyDataStore
|
||||
import com.tangem.datasource.local.datastore.core.StringKeyDataStoreDecorator
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.visa.model.TangemPayTxHistoryItem
|
||||
|
||||
internal class DefaultTangemPayTxHistoryItemsStore(
|
||||
dataStore: StringKeyDataStore<Map<String, List<TangemPayTxHistoryItem>>>,
|
||||
) : TangemPayTxHistoryItemsStore,
|
||||
StringKeyDataStoreDecorator<UserWalletId, Map<String, List<TangemPayTxHistoryItem>>>(dataStore) {
|
||||
override fun provideStringKey(key: UserWalletId): String = key.stringValue
|
||||
StringKeyDataStoreDecorator<String, Map<String, List<TangemPayTxHistoryItem>>>(dataStore) {
|
||||
override fun provideStringKey(key: String): String = key
|
||||
|
||||
override suspend fun getSyncOrNull(key: UserWalletId, cursor: String): List<TangemPayTxHistoryItem>? {
|
||||
override suspend fun getSyncOrNull(key: String, cursor: String): List<TangemPayTxHistoryItem>? {
|
||||
val storedValue = getSyncOrNull(key)
|
||||
return storedValue?.get(cursor)
|
||||
}
|
||||
|
||||
override suspend fun store(key: UserWalletId, cursor: String, value: List<TangemPayTxHistoryItem>) {
|
||||
override suspend fun store(key: String, cursor: String, value: List<TangemPayTxHistoryItem>) {
|
||||
val oldValue = getSyncOrNull(key).orEmpty()
|
||||
val newValue = oldValue.toMutableMap().apply { put(cursor, value) }
|
||||
store(key, newValue)
|
||||
|
|
|
|||
|
|
@ -1,13 +1,12 @@
|
|||
package com.tangem.datasource.local.visa
|
||||
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.visa.model.TangemPayTxHistoryItem
|
||||
|
||||
interface TangemPayTxHistoryItemsStore {
|
||||
|
||||
suspend fun getSyncOrNull(key: UserWalletId, cursor: String): List<TangemPayTxHistoryItem>?
|
||||
suspend fun getSyncOrNull(key: String, cursor: String): List<TangemPayTxHistoryItem>?
|
||||
|
||||
suspend fun remove(key: UserWalletId)
|
||||
suspend fun remove(key: String)
|
||||
|
||||
suspend fun store(key: UserWalletId, cursor: String, value: List<TangemPayTxHistoryItem>)
|
||||
suspend fun store(key: String, cursor: String, value: List<TangemPayTxHistoryItem>)
|
||||
}
|
||||
|
|
@ -68,11 +68,14 @@ internal class DefaultOnboardingRepository @Inject constructor(
|
|||
private fun getCustomerInfo(response: CustomerMeResponse.Result?): CustomerInfo {
|
||||
val card = response?.card
|
||||
val balance = response?.balance
|
||||
val cardInfo = if (card != null && balance != null) {
|
||||
val productInstance = response?.productInstance
|
||||
val cardInfo = if (productInstance != null && card != null && balance != null) {
|
||||
CardInfo(
|
||||
lastFourDigits = card.cardNumberEnd,
|
||||
balance = balance.availableBalance,
|
||||
currencyCode = balance.currency,
|
||||
customerWalletAddress = productInstance.cardWalletAddress,
|
||||
|
||||
)
|
||||
} else {
|
||||
null
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ import com.tangem.data.common.cache.CacheRegistry
|
|||
import com.tangem.data.visa.utils.TangemPayTxHistoryItemConverter
|
||||
import com.tangem.datasource.api.pay.TangemPayApi
|
||||
import com.tangem.datasource.local.visa.TangemPayTxHistoryItemsStore
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.tangempay.model.TangemPayTxHistoryListBatchFlow
|
||||
import com.tangem.domain.tangempay.model.TangemPayTxHistoryListBatchingContext
|
||||
import com.tangem.domain.tangempay.model.TangemPayTxHistoryListConfig
|
||||
|
|
@ -65,28 +64,28 @@ internal class DefaultTangemPayTxHistoryRepository @Inject constructor(
|
|||
limit: Int,
|
||||
): List<TangemPayTxHistoryItem> {
|
||||
cacheRegistry.invokeOnExpire(
|
||||
key = getCacheKey(userWalletId = config.userWalletId, cursor = cursor),
|
||||
key = getCacheKey(customerWalletAddress = config.customerWalletAddress, cursor = cursor),
|
||||
skipCache = config.refresh,
|
||||
block = { fetch(userWalletId = config.userWalletId, cursor = cursor, pageSize = limit) },
|
||||
block = { fetch(customerWalletAddress = config.customerWalletAddress, cursor = cursor, pageSize = limit) },
|
||||
)
|
||||
|
||||
return txHistoryItemsStore.getSyncOrNull(
|
||||
key = config.userWalletId,
|
||||
key = config.customerWalletAddress,
|
||||
cursor = cursor ?: INITIAL_CURSOR,
|
||||
).orEmpty()
|
||||
}
|
||||
|
||||
private fun getCacheKey(userWalletId: UserWalletId, cursor: String?): String {
|
||||
return "tangem_pay_tx_history_${userWalletId}_${cursor ?: INITIAL_CURSOR}"
|
||||
private fun getCacheKey(customerWalletAddress: String, cursor: String?): String {
|
||||
return "tangem_pay_tx_history_${customerWalletAddress}_${cursor ?: INITIAL_CURSOR}"
|
||||
}
|
||||
|
||||
private suspend fun fetch(userWalletId: UserWalletId, cursor: String?, pageSize: Int) {
|
||||
private suspend fun fetch(customerWalletAddress: String, cursor: String?, pageSize: Int) {
|
||||
requestPerformer.runWithErrorLogs(TAG) {
|
||||
val result = requestPerformer.request { authHeader ->
|
||||
visaApi.getTangemPayTxHistory(authHeader = authHeader, limit = pageSize, cursor = cursor)
|
||||
}.result
|
||||
val items = TangemPayTxHistoryItemConverter.convertList(result.transactions)
|
||||
txHistoryItemsStore.store(key = userWalletId, cursor = cursor ?: INITIAL_CURSOR, value = items)
|
||||
txHistoryItemsStore.store(key = customerWalletAddress, cursor = cursor ?: INITIAL_CURSOR, value = items)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -24,6 +24,7 @@ data class CustomerInfo(
|
|||
val lastFourDigits: String,
|
||||
val balance: BigDecimal,
|
||||
val currencyCode: String,
|
||||
val customerWalletAddress: String,
|
||||
)
|
||||
|
||||
fun isKycApproved() = kycStatus == APPROVED_KYC_STATUS
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
package com.tangem.domain.tangempay.model
|
||||
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
|
||||
data class TangemPayTxHistoryListConfig(val userWalletId: UserWalletId, val refresh: Boolean)
|
||||
data class TangemPayTxHistoryListConfig(val customerWalletAddress: String, val refresh: Boolean)
|
||||
|
|
@ -2,9 +2,8 @@ package com.tangem.features.tangempay.components
|
|||
|
||||
import com.tangem.core.decompose.factory.ComponentFactory
|
||||
import com.tangem.core.ui.decompose.ComposableContentComponent
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
|
||||
interface TangemPayDetailsComponent : ComposableContentComponent {
|
||||
data class Params(val userWalletId: UserWalletId)
|
||||
data class Params(val customerWalletAddress: String)
|
||||
interface Factory : ComponentFactory<Params, TangemPayDetailsComponent>
|
||||
}
|
||||
|
|
@ -23,7 +23,7 @@ internal class DefaultTangemPayDetailsComponent @AssistedInject constructor(
|
|||
private val model: TangemPayDetailsModel = getOrCreateModel(params = params)
|
||||
private val txHistoryComponent = DefaultTangemPayTxHistoryComponent(
|
||||
appComponentContext = child("txHistoryComponent"),
|
||||
params = DefaultTangemPayTxHistoryComponent.Params(userWalletId = params.userWalletId),
|
||||
params = DefaultTangemPayTxHistoryComponent.Params(customerWalletAddress = params.customerWalletAddress),
|
||||
)
|
||||
|
||||
@Composable
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ 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
|
||||
|
|
@ -22,5 +21,5 @@ internal class DefaultTangemPayTxHistoryComponent(
|
|||
txHistoryItems(listState, state)
|
||||
}
|
||||
|
||||
data class Params(val userWalletId: UserWalletId)
|
||||
data class Params(val customerWalletAddress: String)
|
||||
}
|
||||
|
|
@ -31,7 +31,7 @@ internal class TangemPayTxHistoryModel @Inject constructor(
|
|||
private val listManager = TangemPayTxHistoryListManager(
|
||||
repository = tangemPayTxHistoryRepository,
|
||||
dispatchers = dispatchers,
|
||||
userWalletId = params.userWalletId,
|
||||
customerWalletAddress = params.customerWalletAddress,
|
||||
txHistoryUiActions = this,
|
||||
)
|
||||
|
||||
|
|
@ -86,7 +86,7 @@ internal class TangemPayTxHistoryModel @Inject constructor(
|
|||
}
|
||||
|
||||
private fun loadMoreItems(): Boolean {
|
||||
modelScope.launch { listManager.loadMore(params.userWalletId) }
|
||||
modelScope.launch { listManager.loadMore(params.customerWalletAddress) }
|
||||
return true
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
package com.tangem.features.tangempay.utils
|
||||
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.domain.tangempay.model.TangemPayTxHistoryListBatchingContext
|
||||
import com.tangem.domain.tangempay.model.TangemPayTxHistoryListConfig
|
||||
import com.tangem.domain.tangempay.repository.TangemPayTxHistoryRepository
|
||||
|
|
@ -23,7 +22,7 @@ private typealias TangemPayTxHistoryBatchAction = BatchAction<Int, TangemPayTxHi
|
|||
internal class TangemPayTxHistoryListManager(
|
||||
private val repository: TangemPayTxHistoryRepository,
|
||||
private val dispatchers: CoroutineDispatcherProvider,
|
||||
private val userWalletId: UserWalletId,
|
||||
private val customerWalletAddress: String,
|
||||
private val txHistoryUiActions: TxHistoryUiActions,
|
||||
) {
|
||||
private val jobHolder = JobHolder()
|
||||
|
|
@ -56,15 +55,18 @@ internal class TangemPayTxHistoryListManager(
|
|||
suspend fun reload() {
|
||||
actionsFlow.emit(
|
||||
BatchAction.Reload(
|
||||
requestParams = TangemPayTxHistoryListConfig(userWalletId = userWalletId, refresh = true),
|
||||
requestParams = TangemPayTxHistoryListConfig(
|
||||
customerWalletAddress = customerWalletAddress,
|
||||
refresh = true,
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
suspend fun loadMore(userWalletId: UserWalletId) {
|
||||
suspend fun loadMore(customerWalletAddress: String) {
|
||||
actionsFlow.emit(
|
||||
BatchAction.LoadMore(
|
||||
requestParams = TangemPayTxHistoryListConfig(userWalletId, refresh = false),
|
||||
requestParams = TangemPayTxHistoryListConfig(customerWalletAddress, refresh = false),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -349,6 +349,7 @@ internal class WalletModel @Inject constructor(
|
|||
value = info,
|
||||
onIssueOrderClick = ::issueOrder,
|
||||
onContinueKycClick = innerWalletRouter::openTangemPayOnboarding,
|
||||
cardOnClick = ::tangemPayCardOnClick,
|
||||
).transform(stateHolder.uiState.value.tangemPayState)
|
||||
}
|
||||
} ?: return
|
||||
|
|
@ -374,6 +375,10 @@ internal class WalletModel @Inject constructor(
|
|||
}
|
||||
}
|
||||
|
||||
private fun tangemPayCardOnClick(customerWalletAddress: String) {
|
||||
innerWalletRouter.openTangemPayDetails(customerWalletAddress)
|
||||
}
|
||||
|
||||
private fun needToRefreshTimer() {
|
||||
modelScope.launch {
|
||||
delay(REFRESH_WALLET_BACKGROUND_TIMER_MILLIS)
|
||||
|
|
|
|||
|
|
@ -111,4 +111,8 @@ internal class DefaultWalletRouter @Inject constructor(
|
|||
override fun openTangemPayOnboarding() {
|
||||
router.push(AppRoute.TangemPayOnboarding(AppRoute.TangemPayOnboarding.Mode.ContinueOnboarding))
|
||||
}
|
||||
|
||||
override fun openTangemPayDetails(custoemrWalletAddress: String) {
|
||||
router.push(AppRoute.TangemPayDetails(custoemrWalletAddress))
|
||||
}
|
||||
}
|
||||
|
|
@ -60,4 +60,6 @@ internal interface InnerWalletRouter {
|
|||
fun openTokenReceiveBottomSheet(tokenReceiveConfig: TokenReceiveConfig)
|
||||
|
||||
fun openTangemPayOnboarding()
|
||||
|
||||
fun openTangemPayDetails(custoemrWalletAddress: String)
|
||||
}
|
||||
|
|
@ -20,5 +20,6 @@ internal sealed class TangemPayState {
|
|||
data class Card(
|
||||
val lastFourDigits: TextReference,
|
||||
val balanceText: TextReference,
|
||||
val onClick: () -> Unit,
|
||||
) : TangemPayState()
|
||||
}
|
||||
|
|
@ -17,6 +17,7 @@ internal class TangemPayStateTransformer(
|
|||
private val value: MainScreenCustomerInfo? = null,
|
||||
private val onIssueOrderClick: () -> Unit = {},
|
||||
private val onContinueKycClick: () -> Unit = {},
|
||||
private val cardOnClick: (String) -> Unit = {},
|
||||
private val issueProgressState: Boolean = false,
|
||||
private val issueState: Boolean = false,
|
||||
) : Transformer<TangemPayState> {
|
||||
|
|
@ -63,6 +64,7 @@ internal class TangemPayStateTransformer(
|
|||
private fun getCardInfoState(cardInfo: CardInfo): TangemPayState = TangemPayState.Card(
|
||||
lastFourDigits = TextReference.Str("*${cardInfo.lastFourDigits}"),
|
||||
balanceText = TextReference.Str(getBalanceText(cardInfo)),
|
||||
onClick = { cardOnClick(cardInfo.customerWalletAddress) },
|
||||
)
|
||||
|
||||
private fun getBalanceText(cardInfo: CardInfo): String {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package com.tangem.feature.wallet.presentation.wallet.ui.components.singlecurrency
|
||||
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.material3.Surface
|
||||
|
|
@ -21,7 +22,9 @@ import com.tangem.feature.wallet.presentation.wallet.state.model.TangemPayState
|
|||
@Composable
|
||||
internal fun TangemPayCardMainBlock(state: TangemPayState.Card, modifier: Modifier = Modifier) {
|
||||
Surface(
|
||||
modifier = modifier.fillMaxWidth(),
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
.clickable { state.onClick() },
|
||||
shape = TangemTheme.shapes.roundedCornersXMedium,
|
||||
color = TangemTheme.colors.background.primary,
|
||||
) {
|
||||
|
|
|
|||
|
|
@ -81,6 +81,7 @@ private fun ResetCardScreenPreview() {
|
|||
TangemPayState.Card(
|
||||
lastFourDigits = TextReference.Str("*1234"),
|
||||
balanceText = TextReference.Str("$ 0.00"),
|
||||
onClick = {},
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue