Updated on 2026-08-14
This commit is contained in:
commit
ea661f55ab
250 changed files with 6169 additions and 949 deletions
|
|
@ -1,8 +1,10 @@
|
|||
package com.tangem.datasource.api.common
|
||||
|
||||
import android.util.Log
|
||||
import com.ihsanbal.logging.Level
|
||||
import com.ihsanbal.logging.LoggingInterceptor
|
||||
import okhttp3.Interceptor
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.logging.HttpLoggingInterceptor
|
||||
import retrofit2.Retrofit
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
|
|
@ -22,7 +24,7 @@ fun createRetrofitInstance(
|
|||
}
|
||||
interceptors.forEach { okHttpBuilder.addInterceptor(it) }
|
||||
|
||||
if (logEnabled) okHttpBuilder.addInterceptor(createHttpLoggingInterceptor())
|
||||
if (logEnabled) okHttpBuilder.addInterceptor(createNetworkLoggingInterceptor())
|
||||
|
||||
return Retrofit.Builder()
|
||||
.baseUrl(baseUrl)
|
||||
|
|
@ -31,6 +33,9 @@ fun createRetrofitInstance(
|
|||
.build()
|
||||
}
|
||||
|
||||
private fun createHttpLoggingInterceptor(): HttpLoggingInterceptor = HttpLoggingInterceptor().apply {
|
||||
level = HttpLoggingInterceptor.Level.BODY
|
||||
fun createNetworkLoggingInterceptor(): Interceptor {
|
||||
return LoggingInterceptor.Builder()
|
||||
.setLevel(Level.BODY)
|
||||
.log(Log.VERBOSE)
|
||||
.build()
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
package com.tangem.datasource.di
|
||||
|
||||
import com.tangem.datasource.local.cache.CacheKeysStore
|
||||
import com.tangem.datasource.local.cache.RuntimeCacheKeysStore
|
||||
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 CacheKeysStoreModule {
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideCacheKeysStore(): CacheKeysStore {
|
||||
return RuntimeCacheKeysStore()
|
||||
}
|
||||
}
|
||||
|
|
@ -63,9 +63,7 @@ class NetworkModule {
|
|||
@PromotionOneInch
|
||||
fun providePromotionOneInchApi(authProvider: AuthProvider, @NetworkMoshi moshi: Moshi): PromotionApi {
|
||||
val okClient = OkHttpClient.Builder()
|
||||
.addHeaders(
|
||||
AuthenticationHeader(authProvider),
|
||||
)
|
||||
.addHeaders(AuthenticationHeader(authProvider))
|
||||
.allowLogging()
|
||||
.callTimeout(API_ONE_INCH_TIMEOUT_MS, TimeUnit.MILLISECONDS)
|
||||
.connectTimeout(API_ONE_INCH_TIMEOUT_MS, TimeUnit.MILLISECONDS)
|
||||
|
|
|
|||
14
core/datasource/src/main/java/com/tangem/datasource/local/cache/CacheKeysStore.kt
vendored
Normal file
14
core/datasource/src/main/java/com/tangem/datasource/local/cache/CacheKeysStore.kt
vendored
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
package com.tangem.datasource.local.cache
|
||||
|
||||
import com.tangem.datasource.local.cache.model.CacheKey
|
||||
|
||||
interface CacheKeysStore {
|
||||
|
||||
fun get(id: String): CacheKey?
|
||||
|
||||
fun addOrReplace(key: CacheKey)
|
||||
|
||||
fun remove(id: String)
|
||||
|
||||
fun clear()
|
||||
}
|
||||
25
core/datasource/src/main/java/com/tangem/datasource/local/cache/RuntimeCacheKeysStore.kt
vendored
Normal file
25
core/datasource/src/main/java/com/tangem/datasource/local/cache/RuntimeCacheKeysStore.kt
vendored
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
package com.tangem.datasource.local.cache
|
||||
|
||||
import com.tangem.datasource.local.cache.model.CacheKey
|
||||
import com.tangem.datasource.local.store.RuntimeStore
|
||||
|
||||
internal class RuntimeCacheKeysStore : CacheKeysStore {
|
||||
|
||||
private val store = RuntimeStore(keyProvider = CacheKey::id)
|
||||
|
||||
override fun get(id: String): CacheKey? {
|
||||
return store.getSync { it.id == id }.firstOrNull()
|
||||
}
|
||||
|
||||
override fun addOrReplace(key: CacheKey) {
|
||||
store.addOrReplace(key)
|
||||
}
|
||||
|
||||
override fun remove(id: String) {
|
||||
store.remove { it.id == id }
|
||||
}
|
||||
|
||||
override fun clear() {
|
||||
store.clear()
|
||||
}
|
||||
}
|
||||
10
core/datasource/src/main/java/com/tangem/datasource/local/cache/model/CacheKey.kt
vendored
Normal file
10
core/datasource/src/main/java/com/tangem/datasource/local/cache/model/CacheKey.kt
vendored
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
package com.tangem.datasource.local.cache.model
|
||||
|
||||
import org.joda.time.Duration
|
||||
import org.joda.time.LocalDateTime
|
||||
|
||||
data class CacheKey(
|
||||
val id: String,
|
||||
val updatedAt: LocalDateTime,
|
||||
val expiresIn: Duration,
|
||||
)
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
package com.tangem.datasource.local.store
|
||||
|
||||
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) {
|
||||
|
||||
private val store = MutableStateFlow<HashMap<Key, Data>>(hashMapOf())
|
||||
|
||||
fun get(selector: (Data) -> Boolean = { true }): Flow<List<Data>> {
|
||||
return store.map { getInternal(it, selector) }
|
||||
}
|
||||
|
||||
fun getSync(selector: (Data) -> Boolean = { true }): List<Data> {
|
||||
return getInternal(store.value, selector)
|
||||
}
|
||||
|
||||
// TODO: Uncomment if needed
|
||||
// fun addOrReplace(items: Collection<Data>) {
|
||||
// if (items.isEmpty()) return
|
||||
//
|
||||
// val storeValue = store.value
|
||||
//
|
||||
// items.forEach { item ->
|
||||
// storeValue[keyProvider(item)] = item
|
||||
// }
|
||||
//
|
||||
// store.value = storeValue
|
||||
// }
|
||||
|
||||
fun addOrReplace(item: Data) {
|
||||
val storeValue = store.value
|
||||
storeValue[keyProvider(item)] = item
|
||||
|
||||
store.value = storeValue
|
||||
}
|
||||
|
||||
fun remove(selector: (Data) -> Boolean) {
|
||||
val storeValue = store.value
|
||||
|
||||
storeValue.forEach { (key, item) ->
|
||||
if (selector(item)) {
|
||||
storeValue.remove(key)
|
||||
}
|
||||
}
|
||||
|
||||
store.value = storeValue
|
||||
}
|
||||
|
||||
fun clear() {
|
||||
store.update { hashMapOf() }
|
||||
}
|
||||
|
||||
private fun getInternal(store: HashMap<Key, Data>, selector: (Data) -> Boolean): List<Data> {
|
||||
return store.values.filter { selector(it) }
|
||||
}
|
||||
}
|
||||
|
|
@ -1,10 +1,9 @@
|
|||
package com.tangem.datasource.utils
|
||||
|
||||
import com.tangem.datasource.BuildConfig
|
||||
import com.tangem.datasource.api.common.createNetworkLoggingInterceptor
|
||||
import okhttp3.Interceptor
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.logging.HttpLoggingInterceptor
|
||||
import okhttp3.logging.HttpLoggingInterceptor.Level
|
||||
|
||||
/** Extension for adding headers [requestHeaders] to every [OkHttpClient] request */
|
||||
internal fun OkHttpClient.Builder.addHeaders(vararg requestHeaders: RequestHeader): OkHttpClient.Builder {
|
||||
|
|
@ -26,5 +25,10 @@ internal fun OkHttpClient.Builder.addHeaders(vararg requestHeaders: RequestHeade
|
|||
*
|
||||
* @param level logging level. By default, only the request body.
|
||||
*/
|
||||
internal fun OkHttpClient.Builder.allowLogging(level: Level = Level.BODY): OkHttpClient.Builder =
|
||||
if (BuildConfig.DEBUG) addInterceptor(interceptor = HttpLoggingInterceptor().setLevel(level)) else this
|
||||
internal fun OkHttpClient.Builder.allowLogging(): OkHttpClient.Builder {
|
||||
return if (BuildConfig.DEBUG) {
|
||||
addInterceptor(interceptor = createNetworkLoggingInterceptor())
|
||||
} else {
|
||||
this
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue