Updated on 2026-08-14
This commit is contained in:
parent
b6a8a4937b
commit
22cbd1b422
10 changed files with 64 additions and 69 deletions
|
|
@ -7,7 +7,10 @@ import com.squareup.moshi.Moshi
|
|||
import com.tangem.datasource.local.datastore.RuntimeDataStore
|
||||
import com.tangem.datasource.local.network.DefaultNetworksStatusesStore
|
||||
import com.tangem.datasource.local.network.NetworksStatusesStore
|
||||
import com.tangem.datasource.local.network.utils.NetworkStatusesSerializer
|
||||
import com.tangem.datasource.local.network.entity.NetworkStatusDM
|
||||
import com.tangem.datasource.utils.MoshiDataStoreSerializer
|
||||
import com.tangem.datasource.utils.mapWithStringKeyTypes
|
||||
import com.tangem.datasource.utils.setTypes
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
|
|
@ -30,7 +33,11 @@ internal object NetworksStatusesStoreModule {
|
|||
return DefaultNetworksStatusesStore(
|
||||
runtimeDataStore = RuntimeDataStore(),
|
||||
persistenceDataStore = DataStoreFactory.create(
|
||||
serializer = NetworkStatusesSerializer(moshi),
|
||||
serializer = MoshiDataStoreSerializer(
|
||||
moshi = moshi,
|
||||
types = mapWithStringKeyTypes(valueTypes = setTypes<NetworkStatusDM>()),
|
||||
defaultValue = emptyMap(),
|
||||
),
|
||||
produceFile = { context.dataStoreFile(fileName = "networks_statuses") },
|
||||
scope = CoroutineScope(context = dispatchers.io + SupervisorJob()),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ package com.tangem.datasource.local.network
|
|||
|
||||
import androidx.datastore.core.DataStore
|
||||
import com.tangem.datasource.local.datastore.RuntimeDataStore
|
||||
import com.tangem.datasource.local.network.entity.NetworkStatusesDM
|
||||
import com.tangem.datasource.local.network.entity.NetworkStatusesByWalletId
|
||||
import com.tangem.datasource.local.network.utils.toDataModel
|
||||
import com.tangem.datasource.local.network.utils.toDomainModel
|
||||
import com.tangem.domain.tokens.model.Network
|
||||
|
|
@ -16,7 +16,7 @@ import kotlinx.coroutines.sync.withLock
|
|||
|
||||
internal class DefaultNetworksStatusesStore(
|
||||
private val runtimeDataStore: RuntimeDataStore<Set<NetworkStatus>>,
|
||||
private val persistenceDataStore: DataStore<NetworkStatusesDM>,
|
||||
private val persistenceDataStore: DataStore<NetworkStatusesByWalletId>,
|
||||
) : NetworksStatusesStore {
|
||||
|
||||
private val mutex = Mutex()
|
||||
|
|
@ -33,7 +33,7 @@ internal class DefaultNetworksStatusesStore(
|
|||
.firstOrNull { it.id == status.networkId }
|
||||
?: return@mapNotNullTo null
|
||||
|
||||
status.toDomainModel(network)
|
||||
status.toDomainModel(network = network, isCached = true)
|
||||
}
|
||||
.orEmpty()
|
||||
|
||||
|
|
@ -110,7 +110,7 @@ internal class DefaultNetworksStatusesStore(
|
|||
|
||||
persistenceDataStore.updateData { storedStatuses ->
|
||||
val userWalletStatuses = storedStatuses[userWalletId.stringValue] ?: emptySet()
|
||||
val updatedStatuses = userWalletStatuses.addOrReplace(status.toDataModel(network)) {
|
||||
val updatedStatuses = userWalletStatuses.addOrReplace(item = status.toDataModel(network)) {
|
||||
it.networkId == network.id
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,27 +1,34 @@
|
|||
package com.tangem.datasource.local.network.entity
|
||||
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
import com.tangem.domain.tokens.model.Network
|
||||
import java.math.BigDecimal
|
||||
|
||||
internal typealias NetworkStatusesDM = Map<String, Set<NetworkStatusDM>>
|
||||
internal typealias NetworkStatusesByWalletId = Map<String, Set<NetworkStatusDM>>
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
internal data class NetworkStatusDM(
|
||||
val networkId: Network.ID,
|
||||
val selectedAddress: String,
|
||||
val availableAddresses: Set<Address>,
|
||||
val amounts: Map<String, BigDecimal>,
|
||||
@Json(name = "network_id") val networkId: Network.ID,
|
||||
@Json(name = "selected_address") val selectedAddress: String,
|
||||
@Json(name = "available_addresses") val availableAddresses: Set<Address>,
|
||||
@Json(name = "amounts") val amounts: Map<String, BigDecimal>,
|
||||
) {
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class Address(
|
||||
val value: String,
|
||||
val type: Type,
|
||||
@Json(name = "value") val value: String,
|
||||
@Json(name = "type") val type: Type,
|
||||
) {
|
||||
|
||||
@JsonClass(generateAdapter = false)
|
||||
enum class Type {
|
||||
Primary, Secondary,
|
||||
|
||||
@Json(name = "primary")
|
||||
Primary,
|
||||
|
||||
@Json(name = "secondary")
|
||||
Secondary,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -32,7 +32,7 @@ internal fun NetworkStatus.Verified.toDataModel(network: Network): NetworkStatus
|
|||
)
|
||||
}
|
||||
|
||||
internal fun NetworkStatusDM.toDomainModel(network: Network): NetworkStatus {
|
||||
internal fun NetworkStatusDM.toDomainModel(network: Network, isCached: Boolean): NetworkStatus {
|
||||
return NetworkStatus(
|
||||
network = network,
|
||||
value = NetworkStatus.Verified(
|
||||
|
|
@ -40,6 +40,7 @@ internal fun NetworkStatusDM.toDomainModel(network: Network): NetworkStatus {
|
|||
amounts = mapToDomainAmounts(amounts),
|
||||
pendingTransactions = mapOf(),
|
||||
),
|
||||
isCached = isCached,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,36 +0,0 @@
|
|||
package com.tangem.datasource.local.network.utils
|
||||
|
||||
import androidx.datastore.core.Serializer
|
||||
import com.squareup.moshi.Moshi
|
||||
import com.squareup.moshi.Types
|
||||
import com.tangem.datasource.local.network.entity.NetworkStatusDM
|
||||
import com.tangem.datasource.local.network.entity.NetworkStatusesDM
|
||||
import java.io.InputStream
|
||||
import java.io.OutputStream
|
||||
|
||||
internal class NetworkStatusesSerializer(moshi: Moshi) : Serializer<NetworkStatusesDM> {
|
||||
|
||||
private val adapter by lazy {
|
||||
val type = Types.newParameterizedType(
|
||||
Map::class.java,
|
||||
String::class.java,
|
||||
Types.newParameterizedType(Set::class.java, NetworkStatusDM::class.java),
|
||||
)
|
||||
|
||||
moshi.adapter<NetworkStatusesDM>(type)
|
||||
}
|
||||
|
||||
override val defaultValue: NetworkStatusesDM = emptyMap()
|
||||
|
||||
override suspend fun readFrom(input: InputStream): NetworkStatusesDM {
|
||||
return input.bufferedReader().use { reader ->
|
||||
adapter.fromJson(reader.readText()) ?: defaultValue
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun writeTo(t: NetworkStatusesDM, output: OutputStream) {
|
||||
output.bufferedWriter().use { writer ->
|
||||
writer.write(adapter.toJson(t))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3,6 +3,10 @@ package com.tangem.datasource.utils
|
|||
import com.squareup.moshi.Types
|
||||
import java.lang.reflect.ParameterizedType
|
||||
|
||||
fun mapWithStringKeyTypes(valueTypes: ParameterizedType): ParameterizedType {
|
||||
return Types.newParameterizedType(Map::class.java, String::class.java, valueTypes)
|
||||
}
|
||||
|
||||
inline fun <reified T> mapWithStringKeyTypes(): ParameterizedType {
|
||||
return Types.newParameterizedType(Map::class.java, String::class.java, T::class.java)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -120,8 +120,17 @@ internal class DefaultNetworksRepository(
|
|||
refresh: Boolean,
|
||||
) = coroutineScope {
|
||||
if (refresh) {
|
||||
val statusesToRefresh = networks.map { NetworkStatus(it, NetworkStatus.Refreshing) }
|
||||
networksStatusesStore.storeAll(userWalletId, statusesToRefresh)
|
||||
val statusesToRefresh = networksStatusesStore.getSyncOrNull(userWalletId)?.mapNotNull {
|
||||
if (it.network in networks) {
|
||||
it.copy(value = NetworkStatus.Refreshing)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
if (statusesToRefresh != null) {
|
||||
networksStatusesStore.storeAll(key = userWalletId, values = statusesToRefresh)
|
||||
}
|
||||
}
|
||||
|
||||
val currencies = getCurrencies(userWalletId, networks)
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ internal class NetworkStatusFactory {
|
|||
),
|
||||
)
|
||||
},
|
||||
isCached = false,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,10 +8,12 @@ import java.math.BigDecimal
|
|||
*
|
||||
* @property network The network for which the status is provided.
|
||||
* @property value The specific status value, represented as a sealed class to encapsulate the various possible states of the network.
|
||||
* @property isCached flag that determines whether the status is a cache
|
||||
*/
|
||||
data class NetworkStatus(
|
||||
val network: Network,
|
||||
val value: Value,
|
||||
val isCached: Boolean,
|
||||
) {
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ import com.tangem.domain.tokens.model.NetworkAddress
|
|||
import com.tangem.domain.tokens.model.NetworkStatus
|
||||
import java.math.BigDecimal
|
||||
|
||||
@Suppress("MemberVisibilityCanBePrivate")
|
||||
internal object MockNetworks {
|
||||
|
||||
val amountToCreateAccount: BigDecimal = BigDecimal.TEN
|
||||
|
|
@ -52,17 +51,26 @@ internal object MockNetworks {
|
|||
transactionExtrasType = Network.TransactionExtrasType.NONE,
|
||||
)
|
||||
|
||||
val networkStatus1 = NetworkStatus(
|
||||
val verifiedNetworksStatuses: NonEmptySet<NetworkStatus>
|
||||
get() = nonEmptySetOf(
|
||||
verifiedNetworkStatus1,
|
||||
verifiedNetworkStatus2,
|
||||
verifiedNetworkStatus3,
|
||||
)
|
||||
|
||||
private val networkStatus1 = NetworkStatus(
|
||||
network = network1,
|
||||
value = NetworkStatus.Unreachable(address = null),
|
||||
isCached = false,
|
||||
)
|
||||
|
||||
val networkStatus2 = NetworkStatus(
|
||||
private val networkStatus2 = NetworkStatus(
|
||||
network = network2,
|
||||
value = NetworkStatus.MissedDerivation,
|
||||
isCached = false,
|
||||
)
|
||||
|
||||
val networkStatus3 = NetworkStatus(
|
||||
private val networkStatus3 = NetworkStatus(
|
||||
network = network3,
|
||||
value = NetworkStatus.NoAccount(
|
||||
amountToCreateAccount = amountToCreateAccount,
|
||||
|
|
@ -71,11 +79,10 @@ internal object MockNetworks {
|
|||
),
|
||||
errorMessage = "",
|
||||
),
|
||||
isCached = false,
|
||||
)
|
||||
|
||||
val errorNetworksStatuses = nonEmptySetOf(networkStatus1, networkStatus2, networkStatus3)
|
||||
|
||||
val verifiedNetworkStatus1: NetworkStatus
|
||||
private val verifiedNetworkStatus1: NetworkStatus
|
||||
get() = networkStatus1.copy(
|
||||
value = NetworkStatus.Verified(
|
||||
amounts = mapOf(
|
||||
|
|
@ -90,7 +97,7 @@ internal object MockNetworks {
|
|||
),
|
||||
)
|
||||
|
||||
val verifiedNetworkStatus2: NetworkStatus
|
||||
private val verifiedNetworkStatus2: NetworkStatus
|
||||
get() = networkStatus2.copy(
|
||||
value = NetworkStatus.Verified(
|
||||
amounts = mapOf(
|
||||
|
|
@ -105,7 +112,7 @@ internal object MockNetworks {
|
|||
),
|
||||
)
|
||||
|
||||
val verifiedNetworkStatus3: NetworkStatus
|
||||
private val verifiedNetworkStatus3: NetworkStatus
|
||||
get() = networkStatus3.copy(
|
||||
value = NetworkStatus.Verified(
|
||||
amounts = mapOf(
|
||||
|
|
@ -120,11 +127,4 @@ internal object MockNetworks {
|
|||
),
|
||||
),
|
||||
)
|
||||
|
||||
val verifiedNetworksStatuses: NonEmptySet<NetworkStatus>
|
||||
get() = nonEmptySetOf(
|
||||
verifiedNetworkStatus1,
|
||||
verifiedNetworkStatus2,
|
||||
verifiedNetworkStatus3,
|
||||
)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue