Updated on 2026-08-14
This commit is contained in:
parent
6446a08369
commit
e67a77e973
11 changed files with 250 additions and 2 deletions
|
|
@ -7,6 +7,7 @@ import com.tangem.domain.balancehiding.UpdateBalanceHidingSettingsUseCase
|
|||
import com.tangem.domain.balancehiding.repositories.BalanceHidingRepository
|
||||
import com.tangem.domain.settings.*
|
||||
import com.tangem.domain.settings.repositories.AppRatingRepository
|
||||
import com.tangem.domain.settings.repositories.PermissionRepository
|
||||
import com.tangem.domain.settings.repositories.PromoSettingsRepository
|
||||
import com.tangem.domain.settings.repositories.SettingsRepository
|
||||
import com.tangem.tap.domain.sdk.TangemSdkManager
|
||||
|
|
@ -17,6 +18,7 @@ import dagger.hilt.InstallIn
|
|||
import dagger.hilt.components.SingletonComponent
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Suppress("TooManyFunctions")
|
||||
@Module
|
||||
@InstallIn(SingletonComponent::class)
|
||||
internal object SettingsDomainModule {
|
||||
|
|
@ -164,4 +166,52 @@ internal object SettingsDomainModule {
|
|||
): IncrementAppLaunchCounterUseCase {
|
||||
return IncrementAppLaunchCounterUseCase(settingsRepository = settingsRepository)
|
||||
}
|
||||
|
||||
// region PushPermissionRepository
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideShouldInitiallyAskPermissionUseCase(
|
||||
permissionRepository: PermissionRepository,
|
||||
): ShouldInitiallyAskPermissionUseCase {
|
||||
return ShouldInitiallyAskPermissionUseCase(repository = permissionRepository)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideIsFirstTimeAskingPermissionUseCase(
|
||||
permissionRepository: PermissionRepository,
|
||||
): IsFirstTimeAskingPermissionUseCase {
|
||||
return IsFirstTimeAskingPermissionUseCase(repository = permissionRepository)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideSetFirstTimeAskingPushPermissionUseCase(
|
||||
permissionRepository: PermissionRepository,
|
||||
): SetFirstTimeAskingPermissionUseCase {
|
||||
return SetFirstTimeAskingPermissionUseCase(repository = permissionRepository)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideDelayPermissionRequestUseCase(
|
||||
permissionRepository: PermissionRepository,
|
||||
): DelayPermissionRequestUseCase {
|
||||
return DelayPermissionRequestUseCase(repository = permissionRepository)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideShouldAskPermissionUseCase(permissionRepository: PermissionRepository): ShouldAskPermissionUseCase {
|
||||
return ShouldAskPermissionUseCase(repository = permissionRepository)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideNeverRequestPermissionUseCase(
|
||||
permissionRepository: PermissionRepository,
|
||||
): NeverRequestPermissionUseCase {
|
||||
return NeverRequestPermissionUseCase(repository = permissionRepository)
|
||||
}
|
||||
// endregion
|
||||
}
|
||||
|
|
@ -94,6 +94,20 @@ object PreferencesKeys {
|
|||
val IS_WALLET_NAMES_MIGRATION_DONE_KEY by lazy { booleanPreferencesKey(name = "isWalletNamesMigrationDone") }
|
||||
|
||||
fun getStart2CoinTOSAcceptedKey(region: String?) = booleanPreferencesKey(name = "start2Coin_tos_accepted_$region")
|
||||
|
||||
// region Permission
|
||||
fun getShouldShowPermission(permission: Int) = booleanPreferencesKey("shouldShowPushPermission_$permission")
|
||||
|
||||
fun getShouldShowInitialPermissionScreen(permission: Int) =
|
||||
booleanPreferencesKey("shouldShowInitialPushPermissionScreen_$permission")
|
||||
|
||||
fun getIsFirstTimeAskingPermission(permission: Int) =
|
||||
booleanPreferencesKey("shouldAskInitialPushPermission_$permission")
|
||||
|
||||
fun getPermissionLaunchCount(permission: Int) = intPreferencesKey("pushPermissionLaunchCount_$permission")
|
||||
|
||||
fun getPermissionDaysCount(permission: Int) = longPreferencesKey("pushPermissionDaysCount_$permission")
|
||||
// endregion
|
||||
}
|
||||
|
||||
/** Preferences keys set that should be migrated from "PreferencesDataSource" to a new DataStore<Preferences> */
|
||||
|
|
|
|||
|
|
@ -0,0 +1,68 @@
|
|||
package com.tangem.data.settings
|
||||
|
||||
import android.os.SystemClock
|
||||
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
||||
import com.tangem.datasource.local.preferences.PreferencesKeys
|
||||
import com.tangem.datasource.local.preferences.PreferencesKeys.getIsFirstTimeAskingPermission
|
||||
import com.tangem.datasource.local.preferences.PreferencesKeys.getPermissionDaysCount
|
||||
import com.tangem.datasource.local.preferences.PreferencesKeys.getPermissionLaunchCount
|
||||
import com.tangem.datasource.local.preferences.PreferencesKeys.getShouldShowInitialPermissionScreen
|
||||
import com.tangem.datasource.local.preferences.PreferencesKeys.getShouldShowPermission
|
||||
import com.tangem.datasource.local.preferences.utils.getSyncOrDefault
|
||||
import com.tangem.datasource.local.preferences.utils.store
|
||||
import com.tangem.domain.settings.repositories.PermissionRepository
|
||||
|
||||
internal class DefaultPermissionRepository(
|
||||
private val appPreferencesStore: AppPreferencesStore,
|
||||
) : PermissionRepository {
|
||||
|
||||
override suspend fun shouldInitiallyShowPermissionScreen(permission: Int): Boolean {
|
||||
val key = getShouldShowInitialPermissionScreen(permission)
|
||||
val initialPermissionScreen = appPreferencesStore.getSyncOrDefault(key = key, default = true)
|
||||
if (initialPermissionScreen) appPreferencesStore.store(key = key, value = false)
|
||||
return initialPermissionScreen
|
||||
}
|
||||
|
||||
override suspend fun isFirstTimeAskingPermission(permission: Int): Boolean = appPreferencesStore.getSyncOrDefault(
|
||||
key = getIsFirstTimeAskingPermission(permission),
|
||||
default = true,
|
||||
)
|
||||
|
||||
override suspend fun setFirstTimeAskingPermission(permission: Int, value: Boolean) {
|
||||
appPreferencesStore.store(
|
||||
key = getIsFirstTimeAskingPermission(permission),
|
||||
value = value,
|
||||
)
|
||||
}
|
||||
|
||||
override suspend fun shouldAskPermission(permission: Int): Boolean {
|
||||
val shouldAskPermission = appPreferencesStore.getSyncOrDefault(getShouldShowPermission(permission), true)
|
||||
val delayedLaunches = appPreferencesStore.getSyncOrDefault(getPermissionLaunchCount(permission), 0)
|
||||
val delayedDays = appPreferencesStore.getSyncOrDefault(getPermissionDaysCount(permission), 0)
|
||||
val currentLaunchCounter = appPreferencesStore.getSyncOrDefault(PreferencesKeys.APP_LAUNCH_COUNT_KEY, 0)
|
||||
|
||||
val nowMillis = SystemClock.elapsedRealtime()
|
||||
val isDaysDelayed = delayedDays < nowMillis
|
||||
val isLaunchesDelayed = delayedLaunches < currentLaunchCounter
|
||||
return shouldAskPermission && isDaysDelayed && isLaunchesDelayed
|
||||
}
|
||||
|
||||
override suspend fun neverAskPermission(permission: Int) {
|
||||
appPreferencesStore.store(key = getShouldShowPermission(permission), value = false)
|
||||
}
|
||||
|
||||
override suspend fun delayPermissionAsking(permission: Int) {
|
||||
appPreferencesStore.editData {
|
||||
val appLaunchCounter = it.getOrDefault(PreferencesKeys.APP_LAUNCH_COUNT_KEY, 0)
|
||||
val nowMillis = SystemClock.elapsedRealtime()
|
||||
|
||||
it[getPermissionLaunchCount(permission)] = appLaunchCounter + DELAY_LAUNCH_COUNT
|
||||
it[getPermissionDaysCount(permission)] = nowMillis + DELAY_DAYS_COUNT
|
||||
}
|
||||
}
|
||||
|
||||
private companion object {
|
||||
const val DELAY_LAUNCH_COUNT = 5
|
||||
const val DELAY_DAYS_COUNT = 3L * 24 * 3600 * 1000 // 3 days in millis
|
||||
}
|
||||
}
|
||||
|
|
@ -1,12 +1,14 @@
|
|||
package com.tangem.data.settings.di
|
||||
|
||||
import com.tangem.data.settings.DefaultAppRatingRepository
|
||||
import com.tangem.data.settings.DefaultSettingsRepository
|
||||
import com.tangem.data.settings.DefaultPromoSettingsRepository
|
||||
import com.tangem.data.settings.DefaultPermissionRepository
|
||||
import com.tangem.data.settings.DefaultSettingsRepository
|
||||
import com.tangem.datasource.local.preferences.AppPreferencesStore
|
||||
import com.tangem.domain.settings.repositories.AppRatingRepository
|
||||
import com.tangem.domain.settings.repositories.SettingsRepository
|
||||
import com.tangem.domain.settings.repositories.PromoSettingsRepository
|
||||
import com.tangem.domain.settings.repositories.PermissionRepository
|
||||
import com.tangem.domain.settings.repositories.SettingsRepository
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
|
|
@ -34,4 +36,10 @@ internal object SettingsDataModule {
|
|||
fun providePromoSettingsSettingsRepository(appPreferencesStore: AppPreferencesStore): PromoSettingsRepository {
|
||||
return DefaultPromoSettingsRepository(appPreferencesStore = appPreferencesStore)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun providePushPermissionRepository(appPreferencesStore: AppPreferencesStore): PermissionRepository {
|
||||
return DefaultPermissionRepository(appPreferencesStore = appPreferencesStore)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
package com.tangem.domain.settings
|
||||
|
||||
import arrow.core.Either
|
||||
import com.tangem.domain.settings.repositories.PermissionRepository
|
||||
|
||||
class DelayPermissionRequestUseCase(
|
||||
private val repository: PermissionRepository,
|
||||
) {
|
||||
|
||||
suspend operator fun invoke(permission: Int): Either<Throwable, Unit> = Either.catch {
|
||||
repository.delayPermissionAsking(permission)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
package com.tangem.domain.settings
|
||||
|
||||
import arrow.core.Either
|
||||
import com.tangem.domain.settings.repositories.PermissionRepository
|
||||
|
||||
class IsFirstTimeAskingPermissionUseCase(private val repository: PermissionRepository) {
|
||||
|
||||
suspend operator fun invoke(permission: Int): Either<Throwable, Boolean> = Either.catch {
|
||||
repository.isFirstTimeAskingPermission(permission)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
package com.tangem.domain.settings
|
||||
|
||||
import arrow.core.Either
|
||||
import com.tangem.domain.settings.repositories.PermissionRepository
|
||||
|
||||
class NeverRequestPermissionUseCase(
|
||||
private val repository: PermissionRepository,
|
||||
) {
|
||||
|
||||
suspend operator fun invoke(permission: Int): Either<Throwable, Unit> = Either.catch {
|
||||
repository.neverAskPermission(permission)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
package com.tangem.domain.settings
|
||||
|
||||
import arrow.core.Either
|
||||
import com.tangem.domain.settings.repositories.PermissionRepository
|
||||
|
||||
class SetFirstTimeAskingPermissionUseCase(private val repository: PermissionRepository) {
|
||||
|
||||
suspend operator fun invoke(permission: Int): Either<Throwable, Unit> = Either.catch {
|
||||
repository.setFirstTimeAskingPermission(permission, false)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
package com.tangem.domain.settings
|
||||
|
||||
import com.tangem.domain.settings.repositories.PermissionRepository
|
||||
|
||||
class ShouldAskPermissionUseCase(
|
||||
private val repository: PermissionRepository,
|
||||
) {
|
||||
|
||||
suspend operator fun invoke(permission: Int): Boolean = repository.shouldAskPermission(permission)
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
package com.tangem.domain.settings
|
||||
|
||||
import arrow.core.Either
|
||||
import com.tangem.domain.settings.repositories.PermissionRepository
|
||||
|
||||
class ShouldInitiallyAskPermissionUseCase(private val repository: PermissionRepository) {
|
||||
|
||||
suspend operator fun invoke(permission: Int): Either<Throwable, Boolean> = Either.catch {
|
||||
repository.shouldInitiallyShowPermissionScreen(permission)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
package com.tangem.domain.settings.repositories
|
||||
|
||||
interface PermissionRepository {
|
||||
|
||||
/**
|
||||
* Return true if should display screen ONCE asking to allow [permission].
|
||||
* False otherwise or screen already was displayed
|
||||
*/
|
||||
suspend fun shouldInitiallyShowPermissionScreen(permission: Int): Boolean
|
||||
|
||||
/**
|
||||
* Indicates which time [permission] was asked via platform dialog.
|
||||
* NOTE: Use this method to indicate either reroute to settings or display platform dialog.
|
||||
*/
|
||||
suspend fun isFirstTimeAskingPermission(permission: Int): Boolean
|
||||
|
||||
/**
|
||||
* Sets value indicating that [permission] was asked via platform dialog.
|
||||
* NOTE: Use this method to indicate either reroute to settings or display platform dialog.
|
||||
*/
|
||||
suspend fun setFirstTimeAskingPermission(permission: Int, value: Boolean)
|
||||
|
||||
/**
|
||||
* Is clear to ask [permission].
|
||||
* User could already granted or permanently denied permission
|
||||
* Or there is an active delay before next request
|
||||
*/
|
||||
suspend fun shouldAskPermission(permission: Int): Boolean
|
||||
|
||||
/**
|
||||
* Permanently deny [permission] and never request again
|
||||
*/
|
||||
suspend fun neverAskPermission(permission: Int)
|
||||
|
||||
/**
|
||||
* Delay next [permission] request for some time or active sessions
|
||||
*/
|
||||
suspend fun delayPermissionAsking(permission: Int)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue