Updated on 2026-08-14

This commit is contained in:
Tangem 2024-07-18 20:52:46 +05:00
parent 7af70694ca
commit b0d9d81348
11 changed files with 93 additions and 20 deletions

View file

@ -43,6 +43,7 @@ import com.tangem.domain.apptheme.model.AppThemeMode
import com.tangem.domain.card.ScanCardUseCase
import com.tangem.domain.card.repository.CardRepository
import com.tangem.domain.card.repository.CardSdkConfigRepository
import com.tangem.domain.settings.ShouldInitiallyAskPermissionUseCase
import com.tangem.domain.settings.repositories.SettingsRepository
import com.tangem.domain.staking.SendUnsubmittedHashesUseCase
import com.tangem.domain.tokens.GetPolkadotCheckHasImmortalUseCase
@ -51,6 +52,7 @@ import com.tangem.domain.wallets.legacy.UserWalletsListManager
import com.tangem.feature.qrscanning.QrScanningRouter
import com.tangem.feature.wallet.presentation.wallet.analytics.WalletScreenAnalyticsEvent
import com.tangem.features.pushnotifications.api.navigation.PushNotificationsRouter
import com.tangem.features.pushnotifications.api.utils.PUSH_PERMISSION
import com.tangem.features.send.api.navigation.SendRouter
import com.tangem.features.staking.api.navigation.StakingRouter
import com.tangem.features.tester.api.TesterRouter
@ -188,6 +190,9 @@ class MainActivity : AppCompatActivity(), SnackbarHandler, ActivityResultCallbac
@Inject
lateinit var cardRepository: CardRepository
@Inject
lateinit var shouldInitiallyAskPermissionUseCase: ShouldInitiallyAskPermissionUseCase
internal val viewModel: MainViewModel by viewModels()
private lateinit var appThemeModeFlow: SharedFlow<AppThemeMode>
@ -531,8 +536,16 @@ class MainActivity : AppCompatActivity(), SnackbarHandler, ActivityResultCallbac
} else {
lifecycleScope.launch {
val toggles = store.inject(getDependency = DaggerGraphState::pushNotificationsFeatureToggles)
val isEnabled = toggles.isPushNotificationsEnabled && !cardRepository.isTangemTOSAccepted()
val route = if (isEnabled) AppRoute.Disclaimer(isTosAccepted = false) else AppRoute.Home
val isPushPermissionEnabled = toggles.isPushNotificationsEnabled
val shouldShowTos = !cardRepository.isTangemTOSAccepted() && isPushPermissionEnabled
val wasPushInitiallyAsked = shouldInitiallyAskPermissionUseCase(PUSH_PERMISSION).getOrElse { false }
val shouldShowInitialPush = wasPushInitiallyAsked && isPushPermissionEnabled
val route = when {
shouldShowTos -> AppRoute.Disclaimer(isTosAccepted = false)
shouldShowInitialPush -> AppRoute.PushNotification
else -> AppRoute.Home
}
store.dispatchNavigationAction { replaceAll(route) }
intentProcessor.handleIntent(intentWhichStartedActivity, false)

View file

@ -176,6 +176,14 @@ internal object SettingsDomainModule {
return ShouldInitiallyAskPermissionUseCase(repository = permissionRepository)
}
@Provides
@Singleton
fun provideNeverToInitiallyAskPermissionUseCase(
permissionRepository: PermissionRepository,
): NeverToInitiallyAskPermissionUseCase {
return NeverToInitiallyAskPermissionUseCase(repository = permissionRepository)
}
@Provides
@Singleton
fun provideIsFirstTimeAskingPermissionUseCase(

View file

@ -17,10 +17,17 @@ internal class DefaultPermissionRepository(
) : PermissionRepository {
override suspend fun shouldInitiallyShowPermissionScreen(permission: String): Boolean {
val key = getShouldShowInitialPermissionScreen(permission)
val initialPermissionScreen = appPreferencesStore.getSyncOrDefault(key = key, default = true)
if (initialPermissionScreen) appPreferencesStore.store(key = key, value = false)
return initialPermissionScreen
return appPreferencesStore.getSyncOrDefault(
key = getShouldShowInitialPermissionScreen(permission),
default = true,
)
}
override suspend fun neverInitiallyShowPermissionScreen(permission: String) {
appPreferencesStore.store(
key = getShouldShowInitialPermissionScreen(permission),
value = false,
)
}
override suspend fun isFirstTimeAskingPermission(permission: String): Boolean =

View file

@ -0,0 +1,12 @@
package com.tangem.domain.settings
import com.tangem.domain.settings.repositories.PermissionRepository
class NeverToInitiallyAskPermissionUseCase(
private val repository: PermissionRepository,
) {
suspend operator fun invoke(permission: String) {
repository.neverInitiallyShowPermissionScreen(permission)
}
}

View file

@ -8,6 +8,11 @@ interface PermissionRepository {
*/
suspend fun shouldInitiallyShowPermissionScreen(permission: String): Boolean
/**
* Sets value indicating that screen for [permission] was shown in initial app launch
*/
suspend fun neverInitiallyShowPermissionScreen(permission: String)
/**
* Indicates which time [permission] was asked via platform dialog.
* NOTE: Use this method to indicate either reroute to settings or display platform dialog.

View file

@ -5,6 +5,7 @@ import androidx.lifecycle.viewModelScope
import com.tangem.core.navigation.settings.SettingsManager
import com.tangem.domain.settings.DelayPermissionRequestUseCase
import com.tangem.domain.settings.NeverRequestPermissionUseCase
import com.tangem.domain.settings.NeverToInitiallyAskPermissionUseCase
import com.tangem.domain.settings.SetFirstTimeAskingPermissionUseCase
import com.tangem.features.pushnotifications.api.utils.PUSH_PERMISSION
import com.tangem.features.pushnotifications.impl.navigation.DefaultPushNotificationsRouter
@ -12,11 +13,13 @@ import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.launch
import javax.inject.Inject
@Suppress("LongParameterList")
@HiltViewModel
internal class PushNotificationViewModel @Inject constructor(
private val setFirstTimeAskingPermissionUseCase: SetFirstTimeAskingPermissionUseCase,
private val delayPermissionRequestUseCase: DelayPermissionRequestUseCase,
private val neverRequestPermissionUseCase: NeverRequestPermissionUseCase,
private val neverToInitiallyAskPermissionUseCase: NeverToInitiallyAskPermissionUseCase,
private val router: DefaultPushNotificationsRouter,
private val settingsManager: SettingsManager,
) : ViewModel(), PushNotificationsClickIntents {
@ -25,6 +28,7 @@ internal class PushNotificationViewModel @Inject constructor(
viewModelScope.launch {
delayPermissionRequestUseCase(PUSH_PERMISSION)
setFirstTimeAskingPermissionUseCase(PUSH_PERMISSION)
neverToInitiallyAskPermissionUseCase(PUSH_PERMISSION)
}
router.openHome()
}
@ -38,6 +42,7 @@ internal class PushNotificationViewModel @Inject constructor(
override fun onAllowedPermission() {
viewModelScope.launch {
neverRequestPermissionUseCase(PUSH_PERMISSION)
neverToInitiallyAskPermissionUseCase(PUSH_PERMISSION)
}
router.openHome()
}

View file

@ -65,12 +65,19 @@ internal class WalletStateController @Inject constructor() {
return with(value) { wallets[selectedWalletIndex].walletCardState.id }
}
fun showBottomSheet(content: TangemBottomSheetConfigContent, userWalletId: UserWalletId = getSelectedWalletId()) {
fun showBottomSheet(
content: TangemBottomSheetConfigContent,
userWalletId: UserWalletId = getSelectedWalletId(),
onDismiss: (() -> Unit)? = null,
) {
update(
OpenBottomSheetTransformer(
userWalletId = userWalletId,
content = content,
onDismissBottomSheet = { update(CloseBottomSheetTransformer(userWalletId)) },
onDismissBottomSheet = {
onDismiss?.invoke()
update(CloseBottomSheetTransformer(userWalletId))
},
),
)
}

View file

@ -3,7 +3,8 @@ package com.tangem.feature.wallet.presentation.wallet.state.model
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfigContent
data class PushNotificationsBottomSheetConfig(
val isFirstTimeAsking: Boolean,
val isFirstTimeRequested: Boolean,
val wasInitiallyAsk: Boolean,
val onRequest: () -> Unit,
val onAllow: () -> Unit,
val onDeny: () -> Unit,

View file

@ -39,7 +39,7 @@ private fun PushNotificationsSheetContent(content: PushNotificationsBottomSheetC
val isClicked = remember { mutableStateOf(false) }
val requestPushPermission = requestPushPermission(
pushPermission = getPushPermissionOrNull(),
isFirstTimeAsking = content.isFirstTimeAsking,
isFirstTimeAsking = content.isFirstTimeRequested,
isClicked = isClicked,
onAllow = {
content.onAllow()
@ -78,7 +78,11 @@ private fun PushNotificationsSheetContent(content: PushNotificationsBottomSheetC
),
) {
SecondaryButton(
text = stringResource(R.string.common_later),
text = if (content.wasInitiallyAsk) {
stringResource(R.string.common_later)
} else {
stringResource(R.string.common_cancel)
},
onClick = {
content.onDeny()
onDismiss()
@ -106,7 +110,8 @@ private fun PushNotificationsSheetContent_Preview() {
TangemThemePreview {
PushNotificationsSheetContent(
PushNotificationsBottomSheetConfig(
isFirstTimeAsking = false,
isFirstTimeRequested = false,
wasInitiallyAsk = false,
onRequest = {},
onAllow = {},
onDeny = {},

View file

@ -43,7 +43,7 @@ import kotlinx.coroutines.withContext
import timber.log.Timber
import javax.inject.Inject
@Suppress("LongParameterList")
@Suppress("LongParameterList", "LargeClass")
@HiltViewModel
internal class WalletViewModel @Inject constructor(
private val stateHolder: WalletStateController,
@ -157,21 +157,23 @@ internal class WalletViewModel @Inject constructor(
delay(timeMillis = 1_800)
val isFirstTimeAsking = isFirstTimeAskingPermissionUseCase(PUSH_PERMISSION).getOrElse { true }
val isFirstTimeRequested = isFirstTimeAskingPermissionUseCase(PUSH_PERMISSION).getOrElse { true }
val wasInitiallyAsk = shouldInitiallyAskPermissionUseCase(PUSH_PERMISSION).getOrElse { true }
val onDenyClick: () -> Unit = if (wasInitiallyAsk) {
clickIntents::onDelayAskPushPermission
} else {
clickIntents::onNeverAskPushPermission
clickIntents::onDenyPushPermission
}
stateHolder.showBottomSheet(
PushNotificationsBottomSheetConfig(
isFirstTimeAsking = isFirstTimeAsking,
content = PushNotificationsBottomSheetConfig(
isFirstTimeRequested = isFirstTimeRequested,
wasInitiallyAsk = wasInitiallyAsk,
onRequest = clickIntents::onRequestPushPermission,
onAllow = clickIntents::onNeverAskPushPermission,
onAllow = clickIntents::onAllowPushPermission,
onDeny = onDenyClick,
openSettings = settingsManager::openSettings,
),
onDismiss = onDenyClick,
)
}
}

View file

@ -14,7 +14,9 @@ internal interface WalletPushPermissionClickIntents {
fun onDelayAskPushPermission()
fun onNeverAskPushPermission()
fun onDenyPushPermission()
fun onAllowPushPermission()
}
@ViewModelScoped
@ -36,7 +38,13 @@ internal class WalletPushPermissionClickIntentsImplementor @Inject constructor(
}
}
override fun onNeverAskPushPermission() {
override fun onDenyPushPermission() {
viewModelScope.launch {
neverRequestPermissionUseCase(PUSH_PERMISSION)
}
}
override fun onAllowPushPermission() {
viewModelScope.launch {
neverRequestPermissionUseCase(PUSH_PERMISSION)
}