Updated on 2026-08-14

This commit is contained in:
Tangem 2025-10-16 11:20:32 +04:00
parent d66d86dd82
commit c562c3fbba
6 changed files with 130 additions and 0 deletions

View file

@ -0,0 +1,18 @@
package com.tangem.data.account.di
import com.tangem.data.account.producer.DefaultSingleAccountProducer
import com.tangem.domain.account.producer.SingleAccountProducer
import dagger.Binds
import dagger.Module
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import javax.inject.Singleton
@Module
@InstallIn(SingletonComponent::class)
internal interface SingleAccountProducerFactoryModule {
@Binds
@Singleton
fun bindSingleAccountProducerFactory(impl: DefaultSingleAccountProducer.Factory): SingleAccountProducer.Factory
}

View file

@ -0,0 +1,23 @@
package com.tangem.data.account.di
import com.tangem.domain.account.producer.SingleAccountProducer
import com.tangem.domain.account.supplier.SingleAccountSupplier
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import javax.inject.Singleton
@Module
@InstallIn(SingletonComponent::class)
internal object SingleAccountSupplierModule {
@Provides
@Singleton
fun provideSingleAccountSupplier(factory: SingleAccountProducer.Factory): SingleAccountSupplier {
return object : SingleAccountSupplier(
factory = factory,
keyCreator = { "single_account_${it.accountId.value}" },
) {}
}
}

View file

@ -54,6 +54,7 @@ internal class AccountListCryptoCurrenciesProducer @AssistedInject constructor(
).toSet()
}
.onEmpty { emit(emptySet()) }
.distinctUntilChanged()
.flowOn(dispatchers.default)
}

View file

@ -0,0 +1,55 @@
package com.tangem.data.account.producer
import arrow.core.Option
import arrow.core.none
import com.tangem.domain.account.producer.SingleAccountListProducer
import com.tangem.domain.account.producer.SingleAccountProducer
import com.tangem.domain.account.supplier.SingleAccountListSupplier
import com.tangem.domain.models.account.Account
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.mapNotNull
/**
* Default implementation of [SingleAccountProducer] that produces a flow of [Account.CryptoPortfolio]
* for a single account identified by [SingleAccountProducer.Params.accountId].
*
* It uses [SingleAccountListSupplier] to get the list of accounts and filters it to find the
* specific account.
*
* @property params Parameters containing the account ID for which the portfolio is produced.
* @property singleAccountListSupplier Supplier to get the list of accounts.
* @property dispatchers Coroutine dispatcher provider for managing threading.
*/
internal class DefaultSingleAccountProducer @AssistedInject constructor(
@Assisted val params: SingleAccountProducer.Params,
private val singleAccountListSupplier: SingleAccountListSupplier,
private val dispatchers: CoroutineDispatcherProvider,
) : SingleAccountProducer {
override val fallback: Option<Account.CryptoPortfolio>
get() = none()
override fun produce(): Flow<Account.CryptoPortfolio> {
return singleAccountListSupplier(
params = SingleAccountListProducer.Params(userWalletId = params.accountId.userWalletId),
)
.mapNotNull { accountList ->
accountList.accounts.firstOrNull {
it is Account.CryptoPortfolio && params.accountId == it.accountId
} as? Account.CryptoPortfolio
}
.distinctUntilChanged()
.flowOn(dispatchers.default)
}
@AssistedFactory
interface Factory : SingleAccountProducer.Factory {
override fun create(params: SingleAccountProducer.Params): DefaultSingleAccountProducer
}
}

View file

@ -0,0 +1,16 @@
package com.tangem.domain.account.producer
import com.tangem.domain.core.flow.FlowProducer
import com.tangem.domain.models.account.Account
import com.tangem.domain.models.account.AccountId
/**
* Produces a flow of [Account.CryptoPortfolio] for a single account identified by [Params.accountId].
* The flow emits updates whenever the account's portfolio changes.
*/
interface SingleAccountProducer : FlowProducer<Account.CryptoPortfolio> {
data class Params(val accountId: AccountId)
interface Factory : FlowProducer.Factory<Params, SingleAccountProducer>
}

View file

@ -0,0 +1,17 @@
package com.tangem.domain.account.supplier
import com.tangem.domain.account.producer.SingleAccountProducer
import com.tangem.domain.core.flow.FlowCachingSupplier
import com.tangem.domain.models.account.Account
/**
* Supplies instances of [SingleAccountProducer] that produce flows of [Account.CryptoPortfolio]
* for individual accounts. Each producer is uniquely identified by its [SingleAccountProducer.Params].
*
* @property factory A factory to create instances of [SingleAccountProducer].
* @property keyCreator A function that generates a unique key for caching based on [SingleAccountProducer.Params].
*/
abstract class SingleAccountSupplier(
override val factory: SingleAccountProducer.Factory,
override val keyCreator: (SingleAccountProducer.Params) -> String,
) : FlowCachingSupplier<SingleAccountProducer, SingleAccountProducer.Params, Account.CryptoPortfolio>()