Updated on 2026-08-14

This commit is contained in:
Tangem 2024-06-20 12:30:53 +05:00
parent 76c5fd4032
commit 9b665a76b3
9 changed files with 33 additions and 23 deletions

View file

@ -1,7 +1,5 @@
package com.tangem.core.ui.utils package com.tangem.core.ui.utils
import android.Manifest
import android.os.Build
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.MutableState import androidx.compose.runtime.MutableState
@ -14,17 +12,18 @@ import com.google.accompanist.permissions.shouldShowRationale
* Returns push permission requester. * Returns push permission requester.
* Handles granting permission from app settings. * Handles granting permission from app settings.
*/ */
@Suppress("LongParameterList")
@OptIn(ExperimentalPermissionsApi::class) @OptIn(ExperimentalPermissionsApi::class)
@Composable @Composable
fun requestPushPermission( fun requestPushPermission(
isFirstTimeAsking: Boolean, isFirstTimeAsking: Boolean,
pushPermission: String?,
isClicked: MutableState<Boolean>, isClicked: MutableState<Boolean>,
onAllow: () -> Unit, onAllow: () -> Unit,
onDeny: () -> Unit, onDeny: () -> Unit,
onOpenSettings: () -> Unit, onOpenSettings: () -> Unit,
): () -> Unit { ): () -> Unit {
val permissionState = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { val permissionState = pushPermission?.let { permission ->
val permission = Manifest.permission.POST_NOTIFICATIONS
val tempPermissionState = rememberPermissionState(permission = permission) val tempPermissionState = rememberPermissionState(permission = permission)
rememberPermissionState(permission = permission) { rememberPermissionState(permission = permission) {
when { when {
@ -33,8 +32,6 @@ fun requestPushPermission(
else -> onDeny() else -> onDeny()
} }
} }
} else {
null
} }
// Check if user granted permission and close bottom sheet // Check if user granted permission and close bottom sheet

View file

@ -40,6 +40,7 @@ dependencies {
/** Feature modules */ /** Feature modules */
implementation(projects.features.disclaimer.api) implementation(projects.features.disclaimer.api)
implementation(projects.features.pushNotifications.api)
/** DI */ /** DI */
implementation(deps.hilt.android) implementation(deps.hilt.android)

View file

@ -1,9 +1,7 @@
package com.tangem.features.disclaimer.impl.presentation.ui package com.tangem.features.disclaimer.impl.presentation.ui
import android.Manifest
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.content.res.Configuration import android.content.res.Configuration
import android.os.Build
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import android.webkit.WebView import android.webkit.WebView
@ -37,6 +35,7 @@ import com.tangem.core.ui.res.TangemThemePreview
import com.tangem.features.disclaimer.impl.R import com.tangem.features.disclaimer.impl.R
import com.tangem.features.disclaimer.impl.presentation.state.DisclaimerState import com.tangem.features.disclaimer.impl.presentation.state.DisclaimerState
import com.tangem.features.disclaimer.impl.presentation.state.DummyDisclaimer import com.tangem.features.disclaimer.impl.presentation.state.DummyDisclaimer
import com.tangem.features.pushnotifications.api.utils.getPushPermissionOrNull
@Composable @Composable
internal fun DisclaimerScreen(state: DisclaimerState, onBackClick: () -> Unit) { internal fun DisclaimerScreen(state: DisclaimerState, onBackClick: () -> Unit) {
@ -135,11 +134,9 @@ private fun DisclaimerContent(url: String, isTosAccepted: Boolean) {
@OptIn(ExperimentalPermissionsApi::class) @OptIn(ExperimentalPermissionsApi::class)
@Composable @Composable
private fun BoxScope.DisclaimerButton(onAccept: (Boolean) -> Unit) { private fun BoxScope.DisclaimerButton(onAccept: (Boolean) -> Unit) {
val shouldAskPushPermission = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { val shouldAskPushPermission = getPushPermissionOrNull()?.let { permission ->
rememberPermissionState(permission = Manifest.permission.POST_NOTIFICATIONS).status.isGranted rememberPermissionState(permission = permission).status.isGranted
} else { } ?: true
true
}
PrimaryButton( PrimaryButton(
text = stringResource(id = R.string.common_accept), text = stringResource(id = R.string.common_accept),
onClick = { onAccept(shouldAskPushPermission) }, onClick = { onAccept(shouldAskPushPermission) },

View file

@ -2,9 +2,19 @@ package com.tangem.features.pushnotifications.api.utils
import android.Manifest import android.Manifest
import android.os.Build import android.os.Build
import androidx.annotation.ChecksSdkIntAtLeast
val PUSH_PERMISSION = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { @ChecksSdkIntAtLeast(api = Build.VERSION_CODES.TIRAMISU)
private val isRequirePushPermission = Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU
val PUSH_PERMISSION = if (isRequirePushPermission) {
Manifest.permission.POST_NOTIFICATIONS Manifest.permission.POST_NOTIFICATIONS
} else { } else {
"android.permission.POST_NOTIFICATIONS" "android.permission.POST_NOTIFICATIONS"
}
fun getPushPermissionOrNull() = if (isRequirePushPermission) {
Manifest.permission.POST_NOTIFICATIONS
} else {
null
} }

View file

@ -11,6 +11,7 @@ import com.tangem.core.ui.components.showcase.model.ShowcaseItemModel
import com.tangem.core.ui.extensions.resourceReference import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.utils.requestPushPermission import com.tangem.core.ui.utils.requestPushPermission
import com.tangem.feature.pushnotifications.impl.R import com.tangem.feature.pushnotifications.impl.R
import com.tangem.features.pushnotifications.api.utils.getPushPermissionOrNull
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
@Composable @Composable
@ -27,6 +28,7 @@ internal fun PushNotificationsScreen(
onAllow = onAllow, onAllow = onAllow,
onDeny = onLater, onDeny = onLater,
onOpenSettings = onOpenSettings, onOpenSettings = onOpenSettings,
pushPermission = getPushPermissionOrNull(),
) )
Showcase( Showcase(

View file

@ -4,8 +4,8 @@ import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfigContent
data class PushNotificationsBottomSheetConfig( data class PushNotificationsBottomSheetConfig(
val isFirstTimeAsking: Boolean, val isFirstTimeAsking: Boolean,
val onRequest: () -> Unit,
val onAllow: () -> Unit, val onAllow: () -> Unit,
val onAllowed: () -> Unit,
val onDeny: () -> Unit, val onDeny: () -> Unit,
val openSettings: () -> Unit, val openSettings: () -> Unit,
) : TangemBottomSheetConfigContent ) : TangemBottomSheetConfigContent

View file

@ -24,6 +24,7 @@ import com.tangem.core.ui.res.TangemThemePreview
import com.tangem.core.ui.utils.requestPushPermission import com.tangem.core.ui.utils.requestPushPermission
import com.tangem.feature.wallet.impl.R import com.tangem.feature.wallet.impl.R
import com.tangem.feature.wallet.presentation.wallet.state.model.PushNotificationsBottomSheetConfig import com.tangem.feature.wallet.presentation.wallet.state.model.PushNotificationsBottomSheetConfig
import com.tangem.features.pushnotifications.api.utils.getPushPermissionOrNull
import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.persistentListOf
@Composable @Composable
@ -37,10 +38,11 @@ internal fun PushNotificationsBottomSheet(config: TangemBottomSheetConfig) {
private fun PushNotificationsSheetContent(content: PushNotificationsBottomSheetConfig, onDismiss: () -> Unit) { private fun PushNotificationsSheetContent(content: PushNotificationsBottomSheetConfig, onDismiss: () -> Unit) {
val isClicked = remember { mutableStateOf(false) } val isClicked = remember { mutableStateOf(false) }
val requestPushPermission = requestPushPermission( val requestPushPermission = requestPushPermission(
pushPermission = getPushPermissionOrNull(),
isFirstTimeAsking = content.isFirstTimeAsking, isFirstTimeAsking = content.isFirstTimeAsking,
isClicked = isClicked, isClicked = isClicked,
onAllow = { onAllow = {
content.onAllowed() content.onAllow()
onDismiss() onDismiss()
}, },
onDeny = { onDeny = {
@ -87,7 +89,7 @@ private fun PushNotificationsSheetContent(content: PushNotificationsBottomSheetC
text = stringResource(R.string.common_allow), text = stringResource(R.string.common_allow),
onClick = { onClick = {
isClicked.value = true isClicked.value = true
content.onAllow() content.onRequest()
requestPushPermission() requestPushPermission()
}, },
modifier = Modifier.weight(1f), modifier = Modifier.weight(1f),
@ -105,8 +107,8 @@ private fun PushNotificationsSheetContent_Preview() {
PushNotificationsSheetContent( PushNotificationsSheetContent(
PushNotificationsBottomSheetConfig( PushNotificationsBottomSheetConfig(
isFirstTimeAsking = false, isFirstTimeAsking = false,
onRequest = {},
onAllow = {}, onAllow = {},
onAllowed = {},
onDeny = {}, onDeny = {},
openSettings = {}, openSettings = {},
), ),

View file

@ -155,7 +155,8 @@ internal class WalletViewModel @Inject constructor(
private fun subscribeOnPushNotificationsPermission() { private fun subscribeOnPushNotificationsPermission() {
viewModelScope.launch { viewModelScope.launch {
if (!shouldAskPermissionUseCase(PUSH_PERMISSION)) return@launch if (!shouldAskPermissionUseCase(PUSH_PERMISSION)) return@launch
withContext(dispatchers.io) { delay(timeMillis = 1_800) }
delay(timeMillis = 1_800)
val isFirstTimeAsking = isFirstTimeAskingPermissionUseCase(PUSH_PERMISSION).getOrElse { true } val isFirstTimeAsking = isFirstTimeAskingPermissionUseCase(PUSH_PERMISSION).getOrElse { true }
val wasInitiallyAsk = shouldInitiallyAskPermissionUseCase(PUSH_PERMISSION).getOrElse { true } val wasInitiallyAsk = shouldInitiallyAskPermissionUseCase(PUSH_PERMISSION).getOrElse { true }
@ -167,8 +168,8 @@ internal class WalletViewModel @Inject constructor(
stateHolder.showBottomSheet( stateHolder.showBottomSheet(
PushNotificationsBottomSheetConfig( PushNotificationsBottomSheetConfig(
isFirstTimeAsking = isFirstTimeAsking, isFirstTimeAsking = isFirstTimeAsking,
onAllow = clickIntents::onAllowPushPermission, onRequest = clickIntents::onRequestPushPermission,
onAllowed = clickIntents::onNeverAskPushPermission, onAllow = clickIntents::onNeverAskPushPermission,
onDeny = onDenyClick, onDeny = onDenyClick,
openSettings = settingsManager::openSettings, openSettings = settingsManager::openSettings,
), ),

View file

@ -10,7 +10,7 @@ import javax.inject.Inject
internal interface WalletPushPermissionClickIntents { internal interface WalletPushPermissionClickIntents {
fun onAllowPushPermission() fun onRequestPushPermission()
fun onDelayAskPushPermission() fun onDelayAskPushPermission()
@ -24,7 +24,7 @@ internal class WalletPushPermissionClickIntentsImplementor @Inject constructor(
private val delayPermissionRequestUseCase: DelayPermissionRequestUseCase, private val delayPermissionRequestUseCase: DelayPermissionRequestUseCase,
) : BaseWalletClickIntents(), WalletPushPermissionClickIntents { ) : BaseWalletClickIntents(), WalletPushPermissionClickIntents {
override fun onAllowPushPermission() { override fun onRequestPushPermission() {
viewModelScope.launch { viewModelScope.launch {
setFirstTimeAskingPermissionUseCase(PUSH_PERMISSION) setFirstTimeAskingPermissionUseCase(PUSH_PERMISSION)
} }