Updated on 2026-08-14
This commit is contained in:
parent
70e40cb2a7
commit
bbb9280413
8 changed files with 294 additions and 49 deletions
|
|
@ -37,7 +37,7 @@ internal class MainViewModel @Inject constructor(
|
||||||
private val listenToFlipsUseCase: ListenToFlipsUseCase,
|
private val listenToFlipsUseCase: ListenToFlipsUseCase,
|
||||||
private val router: AppRouter,
|
private val router: AppRouter,
|
||||||
private val fetchAppCurrenciesUseCase: FetchAppCurrenciesUseCase,
|
private val fetchAppCurrenciesUseCase: FetchAppCurrenciesUseCase,
|
||||||
private val deleteDeprecatedLogsUseCase: DeleteDeprecatedLogsUseCase,
|
deleteDeprecatedLogsUseCase: DeleteDeprecatedLogsUseCase,
|
||||||
private val incrementAppLaunchCounterUseCase: IncrementAppLaunchCounterUseCase,
|
private val incrementAppLaunchCounterUseCase: IncrementAppLaunchCounterUseCase,
|
||||||
private val blockchainSDKFactory: BlockchainSDKFactory,
|
private val blockchainSDKFactory: BlockchainSDKFactory,
|
||||||
private val userWalletsListManager: UserWalletsListManager,
|
private val userWalletsListManager: UserWalletsListManager,
|
||||||
|
|
@ -76,10 +76,8 @@ internal class MainViewModel @Inject constructor(
|
||||||
fetchStakingTokens()
|
fetchStakingTokens()
|
||||||
}
|
}
|
||||||
|
|
||||||
viewModelScope.launch(dispatchers.main) {
|
|
||||||
deleteDeprecatedLogsUseCase()
|
deleteDeprecatedLogsUseCase()
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/** Loading the resources needed to run the application */
|
/** Loading the resources needed to run the application */
|
||||||
private fun loadApplicationResources() {
|
private fun loadApplicationResources() {
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ import com.tangem.datasource.api.markets.TangemTechMarketsApi
|
||||||
import com.tangem.datasource.api.stakekit.StakeKitApi
|
import com.tangem.datasource.api.stakekit.StakeKitApi
|
||||||
import com.tangem.datasource.api.tangemTech.TangemTechApi
|
import com.tangem.datasource.api.tangemTech.TangemTechApi
|
||||||
import com.tangem.datasource.api.tangemTech.TangemTechApiV2
|
import com.tangem.datasource.api.tangemTech.TangemTechApiV2
|
||||||
|
import com.tangem.datasource.local.logs.AppLogsStore
|
||||||
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
||||||
import com.tangem.datasource.utils.*
|
import com.tangem.datasource.utils.*
|
||||||
import com.tangem.datasource.utils.RequestHeader.AppVersionPlatformHeaders
|
import com.tangem.datasource.utils.RequestHeader.AppVersionPlatformHeaders
|
||||||
|
|
@ -58,12 +59,18 @@ internal object NetworkModule {
|
||||||
@NetworkMoshi moshi: Moshi,
|
@NetworkMoshi moshi: Moshi,
|
||||||
@ApplicationContext context: Context,
|
@ApplicationContext context: Context,
|
||||||
apiConfigsManager: ApiConfigsManager,
|
apiConfigsManager: ApiConfigsManager,
|
||||||
|
appLogsStore: AppLogsStore,
|
||||||
): TangemExpressApi {
|
): TangemExpressApi {
|
||||||
return createApi(
|
return createApi(
|
||||||
id = ApiConfig.ID.Express,
|
id = ApiConfig.ID.Express,
|
||||||
moshi = moshi,
|
moshi = moshi,
|
||||||
context = context,
|
context = context,
|
||||||
apiConfigsManager = apiConfigsManager,
|
apiConfigsManager = apiConfigsManager,
|
||||||
|
clientBuilder = {
|
||||||
|
addInterceptor(
|
||||||
|
NetworkLogsSaveInterceptor(appLogsStore),
|
||||||
|
)
|
||||||
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -73,12 +80,18 @@ internal object NetworkModule {
|
||||||
@NetworkMoshi moshi: Moshi,
|
@NetworkMoshi moshi: Moshi,
|
||||||
@ApplicationContext context: Context,
|
@ApplicationContext context: Context,
|
||||||
apiConfigsManager: ApiConfigsManager,
|
apiConfigsManager: ApiConfigsManager,
|
||||||
|
appLogsStore: AppLogsStore,
|
||||||
): StakeKitApi {
|
): StakeKitApi {
|
||||||
return createApi(
|
return createApi(
|
||||||
id = ApiConfig.ID.StakeKit,
|
id = ApiConfig.ID.StakeKit,
|
||||||
moshi = moshi,
|
moshi = moshi,
|
||||||
context = context,
|
context = context,
|
||||||
apiConfigsManager = apiConfigsManager,
|
apiConfigsManager = apiConfigsManager,
|
||||||
|
clientBuilder = {
|
||||||
|
addInterceptor(
|
||||||
|
NetworkLogsSaveInterceptor(appLogsStore),
|
||||||
|
)
|
||||||
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -94,6 +107,7 @@ internal object NetworkModule {
|
||||||
moshi = moshi,
|
moshi = moshi,
|
||||||
context = context,
|
context = context,
|
||||||
apiConfigsManager = apiConfigsManager,
|
apiConfigsManager = apiConfigsManager,
|
||||||
|
clientBuilder = { applyTimeoutAnnotations() },
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -200,6 +214,7 @@ internal object NetworkModule {
|
||||||
moshi: Moshi,
|
moshi: Moshi,
|
||||||
context: Context,
|
context: Context,
|
||||||
apiConfigsManager: ApiConfigsManager,
|
apiConfigsManager: ApiConfigsManager,
|
||||||
|
clientBuilder: OkHttpClient.Builder.() -> OkHttpClient.Builder = { this },
|
||||||
): T {
|
): T {
|
||||||
val environmentConfig = apiConfigsManager.getEnvironmentConfig(id)
|
val environmentConfig = apiConfigsManager.getEnvironmentConfig(id)
|
||||||
|
|
||||||
|
|
@ -210,8 +225,8 @@ internal object NetworkModule {
|
||||||
.client(
|
.client(
|
||||||
OkHttpClient.Builder()
|
OkHttpClient.Builder()
|
||||||
.applyApiConfig(id, apiConfigsManager)
|
.applyApiConfig(id, apiConfigsManager)
|
||||||
.applyTimeoutAnnotations()
|
|
||||||
.addLoggers(context)
|
.addLoggers(context)
|
||||||
|
.clientBuilder()
|
||||||
.build(),
|
.build(),
|
||||||
)
|
)
|
||||||
.build()
|
.build()
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,69 @@
|
||||||
|
package com.tangem.datasource.local.logs
|
||||||
|
|
||||||
|
import androidx.datastore.preferences.core.MutablePreferences
|
||||||
|
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
||||||
|
import com.tangem.datasource.local.preferences.PreferencesKeys
|
||||||
|
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.sync.Mutex
|
||||||
|
import kotlinx.coroutines.sync.withLock
|
||||||
|
import org.joda.time.DateTime
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Store for saving app logs
|
||||||
|
*
|
||||||
|
* @property appPreferencesStore app preferences store
|
||||||
|
* @param dispatchers coroutine dispatcher provider
|
||||||
|
*
|
||||||
|
[REDACTED_AUTHOR]
|
||||||
|
*/
|
||||||
|
class AppLogsStore @Inject constructor(
|
||||||
|
private val appPreferencesStore: AppPreferencesStore,
|
||||||
|
dispatchers: CoroutineDispatcherProvider,
|
||||||
|
) {
|
||||||
|
|
||||||
|
private val scope = CoroutineScope(dispatchers.io)
|
||||||
|
private val mutex = Mutex()
|
||||||
|
|
||||||
|
/** Save log [message] */
|
||||||
|
fun saveLogMessage(message: String) {
|
||||||
|
val newLogs = DateTime.now().millis.toString() to message
|
||||||
|
|
||||||
|
appPreferencesStore.editDataWithLock { preferences ->
|
||||||
|
val savedLogs = preferences.getObjectMap<String>(PreferencesKeys.APP_LOGS_KEY)
|
||||||
|
|
||||||
|
preferences.setObjectMap(key = PreferencesKeys.APP_LOGS_KEY, value = savedLogs + newLogs)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Delete deprecated logs if file size exceeds [maxSize] */
|
||||||
|
fun deleteDeprecatedLogs(maxSize: Int) {
|
||||||
|
appPreferencesStore.editDataWithLock { preferences ->
|
||||||
|
val savedLogs = preferences.getObjectMap<String>(PreferencesKeys.APP_LOGS_KEY)
|
||||||
|
|
||||||
|
var sum = 0
|
||||||
|
preferences.setObjectMap(
|
||||||
|
key = PreferencesKeys.APP_LOGS_KEY,
|
||||||
|
value = savedLogs.entries
|
||||||
|
.sortedBy(Map.Entry<String, String>::key)
|
||||||
|
.takeLastWhile {
|
||||||
|
sum += it.value.length
|
||||||
|
sum < maxSize
|
||||||
|
}
|
||||||
|
.associate { it.key to it.value },
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun AppPreferencesStore.editDataWithLock(
|
||||||
|
transform: suspend AppPreferencesStore.(MutablePreferences) -> Unit,
|
||||||
|
) {
|
||||||
|
scope.launch {
|
||||||
|
mutex.withLock {
|
||||||
|
editData(transform)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,197 @@
|
||||||
|
package com.tangem.datasource.utils
|
||||||
|
|
||||||
|
import com.tangem.datasource.local.logs.AppLogsStore
|
||||||
|
import okhttp3.Headers
|
||||||
|
import okhttp3.Interceptor
|
||||||
|
import okhttp3.Request
|
||||||
|
import okhttp3.Response
|
||||||
|
import okhttp3.internal.http.promisesBody
|
||||||
|
import okio.Buffer
|
||||||
|
import okio.EOFException
|
||||||
|
import okio.GzipSource
|
||||||
|
import okio.IOException
|
||||||
|
import org.json.JSONArray
|
||||||
|
import org.json.JSONObject
|
||||||
|
import java.nio.charset.Charset
|
||||||
|
import java.nio.charset.StandardCharsets
|
||||||
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
|
private const val JSON_INDENT_SPACES = 4
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interceptor for save network requests and responses logs
|
||||||
|
*
|
||||||
|
* @property appLogsStore app logs store
|
||||||
|
*
|
||||||
|
[REDACTED_AUTHOR]
|
||||||
|
*/
|
||||||
|
internal class NetworkLogsSaveInterceptor(
|
||||||
|
private val appLogsStore: AppLogsStore,
|
||||||
|
) : Interceptor {
|
||||||
|
|
||||||
|
@Throws(IOException::class)
|
||||||
|
override fun intercept(chain: Interceptor.Chain): Response {
|
||||||
|
val request = chain.request()
|
||||||
|
|
||||||
|
logRequestMessage(chain, request)
|
||||||
|
|
||||||
|
val startNs = System.nanoTime()
|
||||||
|
val response: Response
|
||||||
|
try {
|
||||||
|
response = chain.proceed(request)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
appLogsStore.saveLogMessage("<-- HTTP FAILED: $e")
|
||||||
|
throw e
|
||||||
|
}
|
||||||
|
|
||||||
|
logResponseMessage(response, startNs)
|
||||||
|
|
||||||
|
return response
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun logRequestMessage(chain: Interceptor.Chain, request: Request) {
|
||||||
|
val connection = chain.connection()
|
||||||
|
val connectionProtocol = if (connection != null) " ${connection.protocol()}" else ""
|
||||||
|
|
||||||
|
appLogsStore.saveLogMessage(
|
||||||
|
"--> ${request.method} ${request.url}$connectionProtocol\n" +
|
||||||
|
createRequestEndMessage(request),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createRequestEndMessage(request: Request): String {
|
||||||
|
val requestBody = request.body
|
||||||
|
val method = request.method
|
||||||
|
|
||||||
|
return if (requestBody == null) {
|
||||||
|
"--> END $method"
|
||||||
|
} else if (bodyHasUnknownEncoding(request.headers)) {
|
||||||
|
"--> END $method (encoded body omitted)"
|
||||||
|
} else if (requestBody.isDuplex()) {
|
||||||
|
"--> END $method (duplex request body omitted)"
|
||||||
|
} else if (requestBody.isOneShot()) {
|
||||||
|
"--> END $method (one-shot body omitted)"
|
||||||
|
} else {
|
||||||
|
val buffer = Buffer()
|
||||||
|
requestBody.writeTo(buffer)
|
||||||
|
|
||||||
|
val contentType = requestBody.contentType()
|
||||||
|
val charset: Charset = contentType?.charset(StandardCharsets.UTF_8) ?: StandardCharsets.UTF_8
|
||||||
|
|
||||||
|
if (buffer.isProbablyUtf8()) {
|
||||||
|
val json = buffer.readString(charset).beautifyJson()
|
||||||
|
"$json\n--> END $method (${requestBody.contentLength()}-byte body)"
|
||||||
|
} else {
|
||||||
|
"--> END $method (binary ${requestBody.contentLength()}-byte body omitted)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun logResponseMessage(response: Response, startNs: Long) {
|
||||||
|
val tookMs = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startNs)
|
||||||
|
|
||||||
|
val responseMessage = if (response.message.isEmpty()) "" else ' ' + response.message
|
||||||
|
val startMessage = "<-- ${response.code}$responseMessage ${response.request.url} " +
|
||||||
|
"(${tookMs}ms)"
|
||||||
|
|
||||||
|
val responseHeaders = response.headers
|
||||||
|
val responseBody = response.body!!
|
||||||
|
val contentLength = responseBody.contentLength()
|
||||||
|
|
||||||
|
val message = if (!response.promisesBody()) {
|
||||||
|
"<-- END HTTP"
|
||||||
|
} else if (bodyHasUnknownEncoding(response.headers)) {
|
||||||
|
"<-- END HTTP (encoded body omitted)"
|
||||||
|
} else {
|
||||||
|
val source = responseBody.source()
|
||||||
|
source.request(Long.MAX_VALUE)
|
||||||
|
var buffer = source.buffer
|
||||||
|
|
||||||
|
var gzippedLength: Long? = null
|
||||||
|
if ("gzip".equals(responseHeaders["Content-Encoding"], ignoreCase = true)) {
|
||||||
|
gzippedLength = buffer.size
|
||||||
|
GzipSource(buffer.clone()).use { gzippedResponseBody ->
|
||||||
|
buffer = Buffer()
|
||||||
|
buffer.writeAll(gzippedResponseBody)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val contentType = responseBody.contentType()
|
||||||
|
val charset: Charset = contentType?.charset(StandardCharsets.UTF_8) ?: StandardCharsets.UTF_8
|
||||||
|
|
||||||
|
if (!buffer.isProbablyUtf8()) {
|
||||||
|
"<-- END HTTP (binary ${buffer.size}-byte body omitted)"
|
||||||
|
} else {
|
||||||
|
val json = if (contentLength != 0L) {
|
||||||
|
buffer.clone().readString(charset).beautifyJson()
|
||||||
|
} else {
|
||||||
|
""
|
||||||
|
}
|
||||||
|
|
||||||
|
val end = if (gzippedLength != null) {
|
||||||
|
"<-- END HTTP (${buffer.size}-byte, $gzippedLength-gzipped-byte body)"
|
||||||
|
} else {
|
||||||
|
"<-- END HTTP (${buffer.size}-byte body)"
|
||||||
|
}
|
||||||
|
|
||||||
|
"$json\n$end"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
appLogsStore.saveLogMessage(startMessage + "\n" + message)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun bodyHasUnknownEncoding(headers: Headers): Boolean {
|
||||||
|
val contentEncoding = headers["Content-Encoding"] ?: return false
|
||||||
|
return !contentEncoding.equals("identity", ignoreCase = true) &&
|
||||||
|
!contentEncoding.equals("gzip", ignoreCase = true)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun Buffer.isProbablyUtf8(): Boolean {
|
||||||
|
try {
|
||||||
|
val prefix = Buffer()
|
||||||
|
val byteCount = size.coerceAtMost(maximumValue = 64)
|
||||||
|
copyTo(out = prefix, offset = 0, byteCount = byteCount)
|
||||||
|
|
||||||
|
@Suppress("MagicNumber", "UnusedPrivateMember")
|
||||||
|
for (i in 0 until 16) {
|
||||||
|
if (prefix.exhausted()) break
|
||||||
|
|
||||||
|
val codePoint = prefix.readUtf8CodePoint()
|
||||||
|
if (Character.isISOControl(codePoint) && !Character.isWhitespace(codePoint)) return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
} catch (_: EOFException) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun String.beautifyJson(): String {
|
||||||
|
beautifyIfObject(json = this)?.let {
|
||||||
|
return it
|
||||||
|
}
|
||||||
|
|
||||||
|
beautifyIfArray(json = this)?.let {
|
||||||
|
return it
|
||||||
|
}
|
||||||
|
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun beautifyIfObject(json: String): String? {
|
||||||
|
return try {
|
||||||
|
JSONObject(json).toString(JSON_INDENT_SPACES)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun beautifyIfArray(json: String): String? {
|
||||||
|
return try {
|
||||||
|
JSONArray(json).toString(JSON_INDENT_SPACES)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,25 +1,17 @@
|
||||||
package com.tangem.data.settings
|
package com.tangem.data.settings
|
||||||
|
|
||||||
|
import com.tangem.datasource.local.logs.AppLogsStore
|
||||||
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
||||||
import com.tangem.datasource.local.preferences.PreferencesKeys
|
import com.tangem.datasource.local.preferences.PreferencesKeys
|
||||||
import com.tangem.datasource.local.preferences.utils.getSyncOrDefault
|
import com.tangem.datasource.local.preferences.utils.getSyncOrDefault
|
||||||
import com.tangem.datasource.local.preferences.utils.store
|
import com.tangem.datasource.local.preferences.utils.store
|
||||||
import com.tangem.domain.settings.repositories.SettingsRepository
|
import com.tangem.domain.settings.repositories.SettingsRepository
|
||||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
|
||||||
import kotlinx.coroutines.CoroutineScope
|
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import kotlinx.coroutines.sync.Mutex
|
|
||||||
import kotlinx.coroutines.sync.withLock
|
|
||||||
import org.joda.time.DateTime
|
|
||||||
|
|
||||||
internal class DefaultSettingsRepository(
|
internal class DefaultSettingsRepository(
|
||||||
private val appPreferencesStore: AppPreferencesStore,
|
private val appPreferencesStore: AppPreferencesStore,
|
||||||
dispatchers: CoroutineDispatcherProvider,
|
private val appLogsStore: AppLogsStore,
|
||||||
) : SettingsRepository {
|
) : SettingsRepository {
|
||||||
|
|
||||||
private val scope = CoroutineScope(dispatchers.io)
|
|
||||||
private val mutex = Mutex()
|
|
||||||
|
|
||||||
override suspend fun shouldShowSaveUserWalletScreen(): Boolean {
|
override suspend fun shouldShowSaveUserWalletScreen(): Boolean {
|
||||||
return appPreferencesStore.getSyncOrDefault(
|
return appPreferencesStore.getSyncOrDefault(
|
||||||
key = PreferencesKeys.SHOULD_SHOW_SAVE_USER_WALLET_SCREEN_KEY,
|
key = PreferencesKeys.SHOULD_SHOW_SAVE_USER_WALLET_SCREEN_KEY,
|
||||||
|
|
@ -46,35 +38,11 @@ internal class DefaultSettingsRepository(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun saveLogMessage(message: String) {
|
override fun saveLogMessage(message: String) {
|
||||||
val newLogs = DateTime.now().millis.toString() to message
|
appLogsStore.saveLogMessage(message)
|
||||||
|
|
||||||
scope.launch {
|
|
||||||
mutex.withLock {
|
|
||||||
appPreferencesStore.editData { preferences ->
|
|
||||||
val savedLogs = preferences.getObjectMap<String>(PreferencesKeys.APP_LOGS_KEY)
|
|
||||||
|
|
||||||
preferences.setObjectMap(key = PreferencesKeys.APP_LOGS_KEY, value = savedLogs + newLogs)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun deleteDeprecatedLogs(maxSize: Int) {
|
override fun deleteDeprecatedLogs(maxSize: Int) {
|
||||||
appPreferencesStore.editData { preferences ->
|
appLogsStore.deleteDeprecatedLogs(maxSize)
|
||||||
val savedLogs = preferences.getObjectMap<String>(PreferencesKeys.APP_LOGS_KEY)
|
|
||||||
|
|
||||||
var sum = 0
|
|
||||||
preferences.setObjectMap(
|
|
||||||
key = PreferencesKeys.APP_LOGS_KEY,
|
|
||||||
value = savedLogs.entries
|
|
||||||
.sortedBy(Map.Entry<String, String>::key)
|
|
||||||
.takeLastWhile {
|
|
||||||
sum += it.value.length
|
|
||||||
sum < maxSize
|
|
||||||
}
|
|
||||||
.associate { it.key to it.value },
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun isSendTapHelpPreviewEnabled(): Boolean {
|
override suspend fun isSendTapHelpPreviewEnabled(): Boolean {
|
||||||
|
|
|
||||||
|
|
@ -4,12 +4,12 @@ import com.tangem.data.settings.DefaultAppRatingRepository
|
||||||
import com.tangem.data.settings.DefaultPermissionRepository
|
import com.tangem.data.settings.DefaultPermissionRepository
|
||||||
import com.tangem.data.settings.DefaultPromoSettingsRepository
|
import com.tangem.data.settings.DefaultPromoSettingsRepository
|
||||||
import com.tangem.data.settings.DefaultSettingsRepository
|
import com.tangem.data.settings.DefaultSettingsRepository
|
||||||
|
import com.tangem.datasource.local.logs.AppLogsStore
|
||||||
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
||||||
import com.tangem.domain.settings.repositories.AppRatingRepository
|
import com.tangem.domain.settings.repositories.AppRatingRepository
|
||||||
import com.tangem.domain.settings.repositories.PermissionRepository
|
import com.tangem.domain.settings.repositories.PermissionRepository
|
||||||
import com.tangem.domain.settings.repositories.PromoSettingsRepository
|
import com.tangem.domain.settings.repositories.PromoSettingsRepository
|
||||||
import com.tangem.domain.settings.repositories.SettingsRepository
|
import com.tangem.domain.settings.repositories.SettingsRepository
|
||||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
|
||||||
import dagger.Module
|
import dagger.Module
|
||||||
import dagger.Provides
|
import dagger.Provides
|
||||||
import dagger.hilt.InstallIn
|
import dagger.hilt.InstallIn
|
||||||
|
|
@ -24,9 +24,9 @@ internal object SettingsDataModule {
|
||||||
@Singleton
|
@Singleton
|
||||||
fun provideSettingsRepository(
|
fun provideSettingsRepository(
|
||||||
appPreferencesStore: AppPreferencesStore,
|
appPreferencesStore: AppPreferencesStore,
|
||||||
dispatchers: CoroutineDispatcherProvider,
|
appLogsStore: AppLogsStore,
|
||||||
): SettingsRepository {
|
): SettingsRepository {
|
||||||
return DefaultSettingsRepository(appPreferencesStore = appPreferencesStore, dispatchers = dispatchers)
|
return DefaultSettingsRepository(appPreferencesStore = appPreferencesStore, appLogsStore = appLogsStore)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ class DeleteDeprecatedLogsUseCase(
|
||||||
private val settingsRepository: SettingsRepository,
|
private val settingsRepository: SettingsRepository,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
suspend operator fun invoke() {
|
operator fun invoke() {
|
||||||
settingsRepository.deleteDeprecatedLogs(maxSize = MAX_LOGS_SIZE)
|
settingsRepository.deleteDeprecatedLogs(maxSize = MAX_LOGS_SIZE)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,11 +10,9 @@ interface SettingsRepository {
|
||||||
|
|
||||||
suspend fun setWalletScrollPreviewAvailability(isEnabled: Boolean)
|
suspend fun setWalletScrollPreviewAvailability(isEnabled: Boolean)
|
||||||
|
|
||||||
@Throws
|
|
||||||
fun saveLogMessage(message: String)
|
fun saveLogMessage(message: String)
|
||||||
|
|
||||||
@Throws
|
fun deleteDeprecatedLogs(maxSize: Int)
|
||||||
suspend fun deleteDeprecatedLogs(maxSize: Int)
|
|
||||||
|
|
||||||
suspend fun isSendTapHelpPreviewEnabled(): Boolean
|
suspend fun isSendTapHelpPreviewEnabled(): Boolean
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue