Updated on 2026-08-14
This commit is contained in:
parent
fcdfe622f9
commit
effaf2d680
12 changed files with 157 additions and 13 deletions
|
|
@ -4,8 +4,8 @@ import com.squareup.moshi.Json
|
|||
|
||||
data class UserTokensResponse(
|
||||
@Json(name = "version") val version: Int = 0,
|
||||
@Json(name = "group") val group: String? = null,
|
||||
@Json(name = "sort") val sort: String? = null,
|
||||
@Json(name = "group") val group: GroupType,
|
||||
@Json(name = "sort") val sort: SortType,
|
||||
@Json(name = "tokens") val tokens: List<Token> = emptyList(),
|
||||
) {
|
||||
|
||||
|
|
@ -18,4 +18,26 @@ data class UserTokensResponse(
|
|||
@Json(name = "decimals") val decimals: Int,
|
||||
@Json(name = "contractAddress") val contractAddress: String?,
|
||||
)
|
||||
|
||||
enum class GroupType {
|
||||
@Json(name = "none")
|
||||
NONE,
|
||||
|
||||
@Json(name = "token")
|
||||
TOKEN,
|
||||
|
||||
@Json(name = "network")
|
||||
NETWORK,
|
||||
}
|
||||
|
||||
enum class SortType {
|
||||
@Json(name = "balance")
|
||||
BALANCE,
|
||||
|
||||
@Json(name = "manual")
|
||||
MANUAL,
|
||||
|
||||
@Json(name = "marketcap")
|
||||
MARKETCAP,
|
||||
}
|
||||
}
|
||||
|
|
@ -19,8 +19,8 @@ class MoshiModule {
|
|||
@NetworkMoshi
|
||||
fun provideNetworkMoshi(): Moshi {
|
||||
return Moshi.Builder()
|
||||
.add(KotlinJsonAdapterFactory())
|
||||
.add(BigDecimalAdapter())
|
||||
.add(KotlinJsonAdapterFactory())
|
||||
.build()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,22 @@
|
|||
package com.tangem.datasource.di
|
||||
|
||||
import com.squareup.moshi.Moshi
|
||||
import com.tangem.datasource.files.FileReader
|
||||
import com.tangem.datasource.local.token.FileUserTokensStore
|
||||
import com.tangem.datasource.local.token.UserTokensStore
|
||||
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 UserTokensStoreModule {
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideUserTokensStore(fileReader: FileReader, @NetworkMoshi moshi: Moshi): UserTokensStore {
|
||||
return FileUserTokensStore(fileReader, moshi)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,11 +1,11 @@
|
|||
package com.tangem.datasource.local.cache
|
||||
|
||||
import com.tangem.datasource.local.cache.model.CacheKey
|
||||
import com.tangem.datasource.local.store.RuntimeStore
|
||||
import com.tangem.datasource.local.datastore.RuntimeDataStore
|
||||
|
||||
internal class RuntimeCacheKeysStore : CacheKeysStore {
|
||||
|
||||
private val store = RuntimeStore(keyProvider = CacheKey::id)
|
||||
private val store = RuntimeDataStore(keyProvider = CacheKey::id)
|
||||
|
||||
override fun get(id: String): CacheKey? {
|
||||
return store.getSync { it.id == id }.firstOrNull()
|
||||
|
|
|
|||
|
|
@ -0,0 +1,52 @@
|
|||
package com.tangem.datasource.local.datastore
|
||||
|
||||
import com.squareup.moshi.JsonAdapter
|
||||
import com.tangem.datasource.files.FileReader
|
||||
import com.tangem.domain.core.error.DataError
|
||||
import kotlinx.coroutines.channels.BufferOverflow
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import kotlinx.coroutines.flow.filterNotNull
|
||||
import kotlinx.coroutines.flow.map
|
||||
|
||||
internal class FileDataStore<Data>(
|
||||
private val fileNameProvider: (key: String) -> String,
|
||||
private val fileReader: FileReader,
|
||||
private val adapter: JsonAdapter<Data>,
|
||||
) {
|
||||
|
||||
private val writeTrigger = MutableSharedFlow<Unit>(
|
||||
onBufferOverflow = BufferOverflow.DROP_OLDEST,
|
||||
)
|
||||
|
||||
fun get(key: String): Flow<Data> {
|
||||
return writeTrigger
|
||||
.map { getInternal(fileNameProvider(key)) }
|
||||
.filterNotNull()
|
||||
}
|
||||
|
||||
fun getSync(key: String): Data? {
|
||||
return getInternal(fileNameProvider(key))
|
||||
}
|
||||
|
||||
fun store(key: String, content: Data) {
|
||||
try {
|
||||
val json = adapter.toJson(content)
|
||||
|
||||
fileReader.rewriteFile(json, fileNameProvider(key))
|
||||
writeTrigger.tryEmit(Unit)
|
||||
} catch (e: Throwable) {
|
||||
throw DataError.PersistenceError.UnableToWriteFile(e)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getInternal(fileName: String): Data? {
|
||||
return try {
|
||||
val json = fileReader.readFile(fileName)
|
||||
|
||||
adapter.fromJson(json)
|
||||
} catch (e: Throwable) {
|
||||
throw DataError.PersistenceError.UnableToReadFile(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,11 +1,11 @@
|
|||
package com.tangem.datasource.local.store
|
||||
package com.tangem.datasource.local.datastore
|
||||
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.update
|
||||
|
||||
internal class RuntimeStore<Key, Data>(private val keyProvider: (Data) -> Key) {
|
||||
internal class RuntimeDataStore<Key, Data>(private val keyProvider: (Data) -> Key) {
|
||||
|
||||
private val store = MutableStateFlow<HashMap<Key, Data>>(hashMapOf())
|
||||
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
package com.tangem.datasource.local.token
|
||||
|
||||
import com.squareup.moshi.Moshi
|
||||
import com.tangem.datasource.api.tangemTech.models.UserTokensResponse
|
||||
import com.tangem.datasource.files.FileReader
|
||||
import com.tangem.datasource.local.datastore.FileDataStore
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
internal class FileUserTokensStore(fileReader: FileReader, moshi: Moshi) : UserTokensStore {
|
||||
|
||||
private val store = FileDataStore<UserTokensResponse>(
|
||||
fileNameProvider = { key -> "user_tokens_$key" },
|
||||
fileReader = fileReader,
|
||||
adapter = moshi.adapter(UserTokensResponse::class.java),
|
||||
)
|
||||
|
||||
override fun get(userWalletId: String): Flow<UserTokensResponse> {
|
||||
return store.get(userWalletId)
|
||||
}
|
||||
|
||||
override suspend fun getSync(userWalletId: String): UserTokensResponse? {
|
||||
return store.getSync(userWalletId)
|
||||
}
|
||||
|
||||
override suspend fun store(userWalletId: String, tokens: UserTokensResponse) {
|
||||
store.store(userWalletId, tokens)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
package com.tangem.datasource.local.token
|
||||
|
||||
import com.tangem.datasource.api.tangemTech.models.UserTokensResponse
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
interface UserTokensStore {
|
||||
|
||||
fun get(userWalletId: String): Flow<UserTokensResponse>
|
||||
|
||||
suspend fun getSync(userWalletId: String): UserTokensResponse?
|
||||
|
||||
suspend fun store(userWalletId: String, tokens: UserTokensResponse)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue