Updated on 2026-08-14

This commit is contained in:
Tangem 2025-04-02 11:04:24 +03:00
commit d314c8733a
21 changed files with 57 additions and 40 deletions

View file

@ -108,11 +108,11 @@ internal var lockUserWalletsTimer: LockUserWalletsTimer? = null
var notificationsHandler: NotificationsHandler? = null var notificationsHandler: NotificationsHandler? = null
private val coroutineContext: CoroutineContext private val coroutineContext: CoroutineContext
get() = Job() + Dispatchers.IO + FeatureCoroutineExceptionHandler.create("scope") get() = SupervisorJob() + Dispatchers.IO + FeatureCoroutineExceptionHandler.create("scope")
val scope = CoroutineScope(coroutineContext) val scope = CoroutineScope(coroutineContext)
private val mainCoroutineContext: CoroutineContext private val mainCoroutineContext: CoroutineContext
get() = Job() + Dispatchers.Main + FeatureCoroutineExceptionHandler.create("mainScope") get() = SupervisorJob() + Dispatchers.Main + FeatureCoroutineExceptionHandler.create("mainScope")
val mainScope = CoroutineScope(mainCoroutineContext) val mainScope = CoroutineScope(mainCoroutineContext)
@Suppress("LargeClass") @Suppress("LargeClass")

View file

@ -623,7 +623,12 @@ private fun handleBackupAction(appState: () -> AppState?, action: BackupAction)
if (action.unfinishedBackupScanResponse != null) { if (action.unfinishedBackupScanResponse != null) {
// onboarding V2 // onboarding V2
store.dispatchNavigationAction { store.dispatchNavigationAction {
push(AppRoute.Onboarding(scanResponse = action.unfinishedBackupScanResponse)) push(
AppRoute.Onboarding(
scanResponse = action.unfinishedBackupScanResponse,
mode = AppRoute.Onboarding.Mode.ContinueFinalize,
),
)
} }
} else { } else {
store.dispatch( store.dispatch(

View file

@ -16,7 +16,7 @@ import com.tangem.wallet.databinding.LayoutBackupAccessCodeBinding
class AccessCodeDialog(context: Context) : BottomSheetDialog(context) { class AccessCodeDialog(context: Context) : BottomSheetDialog(context) {
var binding: LayoutBackupAccessCodeBinding? = null private var binding: LayoutBackupAccessCodeBinding? = null
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
@ -33,7 +33,7 @@ class AccessCodeDialog(context: Context) : BottomSheetDialog(context) {
} }
} }
fun showInfoScreen() = with(binding!!) { fun showInfoScreen() = binding?.run {
behavior.state = BottomSheetBehavior.STATE_EXPANDED behavior.state = BottomSheetBehavior.STATE_EXPANDED
accessCodeTitle.text = context.getText(R.string.onboarding_access_code_intro_title) accessCodeTitle.text = context.getText(R.string.onboarding_access_code_intro_title)
layoutBackupAccessCodeInfo.root.show() layoutBackupAccessCodeInfo.root.show()
@ -43,7 +43,7 @@ class AccessCodeDialog(context: Context) : BottomSheetDialog(context) {
} }
} }
fun showEnterAccessCode() = with(binding!!) { fun showEnterAccessCode() = binding?.run {
layoutBackupAccessCodeInfo.root.hide() layoutBackupAccessCodeInfo.root.hide()
layoutBackupAccessCodeSubmit.root.show() layoutBackupAccessCodeSubmit.root.show()
accessCodeTitle.text = context.getText(R.string.onboarding_access_code_intro_title) accessCodeTitle.text = context.getText(R.string.onboarding_access_code_intro_title)
@ -56,7 +56,7 @@ class AccessCodeDialog(context: Context) : BottomSheetDialog(context) {
} }
} }
fun showReenterAccessCode() = with(binding!!) { fun showReenterAccessCode() = binding?.run {
layoutBackupAccessCodeInfo.root.hide() layoutBackupAccessCodeInfo.root.hide()
layoutBackupAccessCodeSubmit.root.show() layoutBackupAccessCodeSubmit.root.show()
accessCodeTitle.text = context.getText(R.string.onboarding_access_code_repeat_code_title) accessCodeTitle.text = context.getText(R.string.onboarding_access_code_repeat_code_title)
@ -69,7 +69,7 @@ class AccessCodeDialog(context: Context) : BottomSheetDialog(context) {
} }
} }
fun showError(error: AccessCodeError?) = with(binding!!.layoutBackupAccessCodeSubmit) { fun showError(error: AccessCodeError?) = binding?.layoutBackupAccessCodeSubmit?.run {
when (error) { when (error) {
AccessCodeError.CodeTooShort -> AccessCodeError.CodeTooShort ->
tilAccessCode.error = context.getString(R.string.onboarding_access_code_too_short) tilAccessCode.error = context.getString(R.string.onboarding_access_code_too_short)

View file

@ -2,6 +2,7 @@ package com.tangem.tap.features.welcome.model
import com.tangem.common.core.TangemError import com.tangem.common.core.TangemError
import com.tangem.core.analytics.Analytics import com.tangem.core.analytics.Analytics
import com.tangem.core.decompose.di.ModelScoped
import com.tangem.core.decompose.model.Model import com.tangem.core.decompose.model.Model
import com.tangem.core.decompose.model.ParamsContainer import com.tangem.core.decompose.model.ParamsContainer
import com.tangem.core.navigation.finisher.AppFinisher import com.tangem.core.navigation.finisher.AppFinisher
@ -14,7 +15,6 @@ import com.tangem.tap.features.welcome.redux.WelcomeAction
import com.tangem.tap.features.welcome.redux.WelcomeState import com.tangem.tap.features.welcome.redux.WelcomeState
import com.tangem.tap.features.welcome.ui.WelcomeScreenState import com.tangem.tap.features.welcome.ui.WelcomeScreenState
import com.tangem.tap.features.welcome.ui.model.WarningModel import com.tangem.tap.features.welcome.ui.model.WarningModel
import com.tangem.tap.mainScope
import com.tangem.tap.store import com.tangem.tap.store
import com.tangem.utils.coroutines.CoroutineDispatcherProvider import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
@ -23,6 +23,7 @@ import org.rekotlin.StoreSubscriber
import javax.inject.Inject import javax.inject.Inject
// FIXME: Remove redux: [REDACTED_JIRA] // FIXME: Remove redux: [REDACTED_JIRA]
@ModelScoped
internal class WelcomeModel @Inject constructor( internal class WelcomeModel @Inject constructor(
override val dispatchers: CoroutineDispatcherProvider, override val dispatchers: CoroutineDispatcherProvider,
private val appFinisher: AppFinisher, private val appFinisher: AppFinisher,
@ -40,8 +41,6 @@ internal class WelcomeModel @Inject constructor(
val state: MutableStateFlow<WelcomeScreenState> = MutableStateFlow(initialState) val state: MutableStateFlow<WelcomeScreenState> = MutableStateFlow(initialState)
init { init {
store.dispatch(WelcomeAction.SetCoroutineScope(mainScope))
subscribeToStoreChanges() subscribeToStoreChanges()
initGlobalState() initGlobalState()
@ -87,7 +86,6 @@ internal class WelcomeModel @Inject constructor(
} }
override fun onDestroy() { override fun onDestroy() {
store.dispatch(WelcomeAction.ClearCoroutineScope)
store.unsubscribe(subscriber = this) store.unsubscribe(subscriber = this)
super.onDestroy() super.onDestroy()

View file

@ -2,15 +2,10 @@ package com.tangem.tap.features.welcome.redux
import android.content.Intent import android.content.Intent
import com.tangem.common.core.TangemError import com.tangem.common.core.TangemError
import kotlinx.coroutines.CoroutineScope
import org.rekotlin.Action import org.rekotlin.Action
internal sealed interface WelcomeAction : Action { internal sealed interface WelcomeAction : Action {
data class SetCoroutineScope(val scope: CoroutineScope) : WelcomeAction
object ClearCoroutineScope : WelcomeAction
data class ProceedWithBiometrics(val afterUnlockIntent: Intent? = null) : WelcomeAction { data class ProceedWithBiometrics(val afterUnlockIntent: Intent? = null) : WelcomeAction {
object Success : WelcomeAction object Success : WelcomeAction
data class Error(val error: TangemError) : WelcomeAction data class Error(val error: TangemError) : WelcomeAction

View file

@ -21,6 +21,7 @@ import com.tangem.tap.common.extensions.*
import com.tangem.tap.common.redux.AppState import com.tangem.tap.common.redux.AppState
import com.tangem.tap.features.intentHandler.handlers.BackgroundScanIntentHandler import com.tangem.tap.features.intentHandler.handlers.BackgroundScanIntentHandler
import com.tangem.tap.features.intentHandler.handlers.WalletConnectLinkIntentHandler import com.tangem.tap.features.intentHandler.handlers.WalletConnectLinkIntentHandler
import com.tangem.tap.mainScope
import com.tangem.tap.proxy.redux.DaggerGraphState import com.tangem.tap.proxy.redux.DaggerGraphState
import com.tangem.tap.scope import com.tangem.tap.scope
import com.tangem.tap.store import com.tangem.tap.store
@ -44,7 +45,7 @@ internal class WelcomeMiddleware {
} }
private fun handleAction(action: WelcomeAction, state: WelcomeState) { private fun handleAction(action: WelcomeAction, state: WelcomeState) {
state.scope?.launch { mainScope.launch {
when (action) { when (action) {
is WelcomeAction.ProceedWithIntent -> proceedWithIntent(action.intent, scope = this) is WelcomeAction.ProceedWithIntent -> proceedWithIntent(action.intent, scope = this)
is WelcomeAction.ProceedWithBiometrics -> proceedWithBiometrics( is WelcomeAction.ProceedWithBiometrics -> proceedWithBiometrics(

View file

@ -14,8 +14,6 @@ internal object WelcomeReducer {
private fun internalReduce(action: WelcomeAction, state: WelcomeState): WelcomeState { private fun internalReduce(action: WelcomeAction, state: WelcomeState): WelcomeState {
return when (action) { return when (action) {
is WelcomeAction.SetCoroutineScope -> state.copy(scope = action.scope)
is WelcomeAction.ClearCoroutineScope -> state.copy(scope = null)
is WelcomeAction.ProceedWithIntent -> state.copy(intent = action.intent) is WelcomeAction.ProceedWithIntent -> state.copy(intent = action.intent)
is WelcomeAction.ProceedWithBiometrics -> state.copy(isUnlockWithBiometricsInProgress = true) is WelcomeAction.ProceedWithBiometrics -> state.copy(isUnlockWithBiometricsInProgress = true)
is WelcomeAction.ProceedWithCard -> state.copy(isUnlockWithCardInProgress = true) is WelcomeAction.ProceedWithCard -> state.copy(isUnlockWithCardInProgress = true)

View file

@ -2,11 +2,9 @@ package com.tangem.tap.features.welcome.redux
import android.content.Intent import android.content.Intent
import com.tangem.common.core.TangemError import com.tangem.common.core.TangemError
import kotlinx.coroutines.CoroutineScope
import org.rekotlin.StateType import org.rekotlin.StateType
data class WelcomeState( data class WelcomeState(
val scope: CoroutineScope? = null,
val isUnlockWithBiometricsInProgress: Boolean = false, val isUnlockWithBiometricsInProgress: Boolean = false,
val isUnlockWithCardInProgress: Boolean = false, val isUnlockWithCardInProgress: Boolean = false,
val intent: Intent? = null, val intent: Intent? = null,

View file

@ -216,6 +216,8 @@ internal class ChildFactory @Inject constructor(
AppRoute.Onboarding.Mode.WelcomeOnlyTwin -> OnboardingEntryComponent.Mode.WelcomeOnlyTwin AppRoute.Onboarding.Mode.WelcomeOnlyTwin -> OnboardingEntryComponent.Mode.WelcomeOnlyTwin
AppRoute.Onboarding.Mode.RecreateWalletTwin -> AppRoute.Onboarding.Mode.RecreateWalletTwin ->
OnboardingEntryComponent.Mode.RecreateWalletTwin OnboardingEntryComponent.Mode.RecreateWalletTwin
AppRoute.Onboarding.Mode.ContinueFinalize ->
OnboardingEntryComponent.Mode.ContinueFinalize
}, },
), ),
componentFactory = onboardingEntryComponentFactory, componentFactory = onboardingEntryComponentFactory,
@ -729,6 +731,8 @@ internal class ChildFactory @Inject constructor(
AppRoute.Onboarding.Mode.WelcomeOnlyTwin -> OnboardingEntryComponent.Mode.WelcomeOnlyTwin AppRoute.Onboarding.Mode.WelcomeOnlyTwin -> OnboardingEntryComponent.Mode.WelcomeOnlyTwin
AppRoute.Onboarding.Mode.RecreateWalletTwin -> AppRoute.Onboarding.Mode.RecreateWalletTwin ->
OnboardingEntryComponent.Mode.RecreateWalletTwin OnboardingEntryComponent.Mode.RecreateWalletTwin
AppRoute.Onboarding.Mode.ContinueFinalize ->
OnboardingEntryComponent.Mode.ContinueFinalize
}, },
), ),
componentFactory = onboardingEntryComponentFactory, componentFactory = onboardingEntryComponentFactory,

View file

@ -268,6 +268,7 @@ sealed class AppRoute(val path: String) : Route {
AddBackupWallet1, // continue backup process for existing wallet 1 AddBackupWallet1, // continue backup process for existing wallet 1
WelcomeOnlyTwin, // show welcome screen and then navigate to wallet for twins WelcomeOnlyTwin, // show welcome screen and then navigate to wallet for twins
RecreateWalletTwin, // reset twins RecreateWalletTwin, // reset twins
ContinueFinalize, // continue finalize process (unfinished backup dialog)
} }
} }

View file

@ -7,12 +7,14 @@ import dagger.Module
import dagger.Provides import dagger.Provides
import dagger.hilt.InstallIn import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent import dagger.hilt.components.SingletonComponent
import javax.inject.Singleton
@Module @Module
@InstallIn(SingletonComponent::class) @InstallIn(SingletonComponent::class)
internal object TxHistoryItemsStoreModule { internal object TxHistoryItemsStoreModule {
@Provides @Provides
@Singleton
fun provideTxHistoryItemsStore(): TxHistoryItemsStore { fun provideTxHistoryItemsStore(): TxHistoryItemsStore {
return DefaultTxHistoryItemsStore( return DefaultTxHistoryItemsStore(
dataStore = RuntimeDataStore(), dataStore = RuntimeDataStore(),

View file

@ -2,7 +2,6 @@ package com.tangem.core.ui.utils
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 com.google.accompanist.permissions.ExperimentalPermissionsApi import com.google.accompanist.permissions.ExperimentalPermissionsApi
import com.google.accompanist.permissions.isGranted import com.google.accompanist.permissions.isGranted
import com.google.accompanist.permissions.rememberPermissionState import com.google.accompanist.permissions.rememberPermissionState
@ -16,7 +15,7 @@ import com.google.accompanist.permissions.rememberPermissionState
@Composable @Composable
fun requestPushPermission( fun requestPushPermission(
pushPermission: String?, pushPermission: String?,
isClicked: MutableState<Boolean>, isClicked: Boolean,
onAllow: () -> Unit, onAllow: () -> Unit,
onDeny: () -> Unit, onDeny: () -> Unit,
): () -> Unit { ): () -> Unit {
@ -26,7 +25,7 @@ fun requestPushPermission(
// Check if user granted permission and close bottom sheet // Check if user granted permission and close bottom sheet
LaunchedEffect(key1 = permissionState?.status, isClicked) { LaunchedEffect(key1 = permissionState?.status, isClicked) {
if (!isClicked.value) return@LaunchedEffect if (!isClicked) return@LaunchedEffect
if (permissionState?.status?.isGranted == true) { if (permissionState?.status?.isGranted == true) {
onAllow() onAllow()
} else { } else {

View file

@ -16,6 +16,7 @@ interface OnboardingEntryComponent : ComposableContentComponent {
AddBackupWallet1, AddBackupWallet1,
WelcomeOnlyTwin, WelcomeOnlyTwin,
RecreateWalletTwin, RecreateWalletTwin,
ContinueFinalize,
} }
interface Factory : ComponentFactory<Params, OnboardingEntryComponent> interface Factory : ComponentFactory<Params, OnboardingEntryComponent>

View file

@ -81,6 +81,7 @@ internal class OnboardingEntryModel @Inject constructor(
val multiWalletNavigationMode = when (params.mode) { val multiWalletNavigationMode = when (params.mode) {
Mode.Onboarding -> OnboardingMultiWalletComponent.Mode.Onboarding Mode.Onboarding -> OnboardingMultiWalletComponent.Mode.Onboarding
Mode.AddBackupWallet1 -> OnboardingMultiWalletComponent.Mode.AddBackup Mode.AddBackupWallet1 -> OnboardingMultiWalletComponent.Mode.AddBackup
Mode.ContinueFinalize -> OnboardingMultiWalletComponent.Mode.ContinueFinalize
else -> error("Incorrect onboarding type") else -> error("Incorrect onboarding type")
} }

View file

@ -20,6 +20,7 @@ interface OnboardingMultiWalletComponent : ComposableContentComponent, InnerNavi
enum class Mode { enum class Mode {
Onboarding, Onboarding,
AddBackup, AddBackup,
ContinueFinalize,
} }
interface Factory : ComponentFactory<Params, OnboardingMultiWalletComponent> interface Factory : ComponentFactory<Params, OnboardingMultiWalletComponent>

View file

@ -39,9 +39,8 @@ fun Wallet1ChooseOption(
Column( Column(
Modifier Modifier
.fillMaxWidth() .fillMaxWidth()
.verticalScroll(rememberScrollState())
.weight(1f) .weight(1f)
.padding(top = 32.dp, bottom = 16.dp), .padding(vertical = 16.dp),
horizontalAlignment = Alignment.CenterHorizontally, horizontalAlignment = Alignment.CenterHorizontally,
) { ) {
val pagerState = rememberPagerState { CarouselItems.size } val pagerState = rememberPagerState { CarouselItems.size }
@ -49,6 +48,8 @@ fun Wallet1ChooseOption(
HorizontalPager(pagerState) { selectedIndex -> HorizontalPager(pagerState) { selectedIndex ->
Column( Column(
modifier = Modifier modifier = Modifier
.fillMaxWidth()
.verticalScroll(rememberScrollState())
.padding(start = 32.dp, end = 32.dp, bottom = 16.dp), .padding(start = 32.dp, end = 32.dp, bottom = 16.dp),
horizontalAlignment = Alignment.CenterHorizontally, horizontalAlignment = Alignment.CenterHorizontally,
) { ) {

View file

@ -226,7 +226,9 @@ internal class MultiWalletFinalizeModel @Inject constructor(
val userWalletCreated = createUserWallet(scanResponse) val userWalletCreated = createUserWallet(scanResponse)
val userWallet = when (params.parentParams.mode) { val userWallet = when (params.parentParams.mode) {
OnboardingMultiWalletComponent.Mode.Onboarding -> { OnboardingMultiWalletComponent.Mode.Onboarding,
OnboardingMultiWalletComponent.Mode.ContinueFinalize,
-> {
userWalletsListManager.save( userWalletsListManager.save(
userWallet = userWalletCreated.copy( userWallet = userWalletCreated.copy(
scanResponse = scanResponse.updateScanResponseAfterBackup(), scanResponse = scanResponse.updateScanResponseAfterBackup(),

View file

@ -46,7 +46,7 @@ internal class OnboardingMultiWalletModel @Inject constructor(
currentStep = getInitialStep(), currentStep = getInitialStep(),
currentScanResponse = params.scanResponse, currentScanResponse = params.scanResponse,
accessCode = null, accessCode = null,
isThreeCards = true, isThreeCards = isThreeCardsInit(),
resultUserWallet = null, resultUserWallet = null,
startFromFinalize = getInitialStartFromFinalize(), startFromFinalize = getInitialStartFromFinalize(),
), ),
@ -102,6 +102,8 @@ internal class OnboardingMultiWalletModel @Inject constructor(
val card = scanResponse.card val card = scanResponse.card
return when { return when {
params.mode == OnboardingMultiWalletComponent.Mode.ContinueFinalize ->
OnboardingMultiWalletState.Step.Finalize
// Add backup button // Add backup button
// Wallet1 without backup and userwallet's scanResponse doesn't contain primary card. // Wallet1 without backup and userwallet's scanResponse doesn't contain primary card.
card.wallets.isNotEmpty() && card.backupStatus == CardDTO.BackupStatus.NoBackup && card.wallets.isNotEmpty() && card.backupStatus == CardDTO.BackupStatus.NoBackup &&
@ -134,6 +136,18 @@ internal class OnboardingMultiWalletModel @Inject constructor(
} }
} }
private fun isThreeCardsInit(): Boolean {
val backupService = backupServiceHolder.backupService.get() ?: return true
return when (backupService.currentState) {
BackupService.State.FinalizingPrimaryCard,
is BackupService.State.FinalizingBackupCard,
-> {
backupService.addedBackupCardsCount > 1
}
else -> true
}
}
private fun initScreenTitle() { private fun initScreenTitle() {
val title = screenTitleByStep(getInitialStep()) val title = screenTitleByStep(getInitialStep())
params.titleProvider.changeTitle(title) params.titleProvider.changeTitle(title)

View file

@ -17,7 +17,7 @@ import javax.inject.Inject
@Stable @Stable
@ModelScoped @ModelScoped
class PushNotificationsModel @Inject constructor( internal class PushNotificationsModel @Inject constructor(
override val dispatchers: CoroutineDispatcherProvider, override val dispatchers: CoroutineDispatcherProvider,
private val neverRequestPermissionUseCase: NeverRequestPermissionUseCase, private val neverRequestPermissionUseCase: NeverRequestPermissionUseCase,
private val neverToInitiallyAskPermissionUseCase: NeverToInitiallyAskPermissionUseCase, private val neverToInitiallyAskPermissionUseCase: NeverToInitiallyAskPermissionUseCase,

View file

@ -1,9 +1,7 @@
package com.tangem.features.pushnotifications.impl.presentation.ui package com.tangem.features.pushnotifications.impl.presentation.ui
import androidx.compose.foundation.layout.systemBarsPadding import androidx.compose.foundation.layout.systemBarsPadding
import androidx.compose.runtime.Composable import androidx.compose.runtime.*
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import com.tangem.core.ui.components.showcase.Showcase import com.tangem.core.ui.components.showcase.Showcase
import com.tangem.core.ui.components.showcase.model.ShowcaseButtonModel import com.tangem.core.ui.components.showcase.model.ShowcaseButtonModel
@ -21,7 +19,7 @@ internal fun PushNotificationsScreen(
onAllowPermission: () -> Unit, onAllowPermission: () -> Unit,
onDenyPermission: () -> Unit, onDenyPermission: () -> Unit,
) { ) {
val isClicked = remember { mutableStateOf(false) } var isClicked by remember { mutableStateOf(false) }
val requestPushPermission = requestPushPermission( val requestPushPermission = requestPushPermission(
isClicked = isClicked, isClicked = isClicked,
onAllow = onAllowPermission, onAllow = onAllowPermission,
@ -45,7 +43,7 @@ internal fun PushNotificationsScreen(
primaryButton = ShowcaseButtonModel( primaryButton = ShowcaseButtonModel(
buttonText = resourceReference(R.string.common_allow), buttonText = resourceReference(R.string.common_allow),
onClick = { onClick = {
isClicked.value = true isClicked = true
onRequest() onRequest()
requestPushPermission() requestPushPermission()
}, },

View file

@ -6,9 +6,7 @@ import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable import androidx.compose.runtime.*
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import com.tangem.core.ui.components.PrimaryButton import com.tangem.core.ui.components.PrimaryButton
@ -36,7 +34,7 @@ internal fun PushNotificationsBottomSheet(config: TangemBottomSheetConfig) {
@Composable @Composable
private fun PushNotificationsSheetContent(content: PushNotificationsBottomSheetConfig, onDismiss: () -> Unit) { private fun PushNotificationsSheetContent(content: PushNotificationsBottomSheetConfig, onDismiss: () -> Unit) {
val isClicked = remember { mutableStateOf(false) } var isClicked by remember { mutableStateOf(false) }
val requestPushPermission = requestPushPermission( val requestPushPermission = requestPushPermission(
pushPermission = getPushPermissionOrNull(), pushPermission = getPushPermissionOrNull(),
isClicked = isClicked, isClicked = isClicked,
@ -86,7 +84,7 @@ private fun PushNotificationsSheetContent(content: PushNotificationsBottomSheetC
PrimaryButton( PrimaryButton(
text = stringResourceSafe(R.string.common_allow), text = stringResourceSafe(R.string.common_allow),
onClick = { onClick = {
isClicked.value = true isClicked = true
content.onRequest() content.onRequest()
requestPushPermission() requestPushPermission()
}, },