Updated on 2026-08-14
This commit is contained in:
parent
096d1e40c9
commit
e10334a935
6 changed files with 76 additions and 4 deletions
|
|
@ -9,6 +9,7 @@ import androidx.work.WorkManager
|
|||
import com.tangem.common.routing.AppRoute
|
||||
import com.tangem.domain.common.wallets.UserWalletsListRepository
|
||||
import com.tangem.domain.settings.repositories.SettingsRepository
|
||||
import com.tangem.domain.wallets.hot.HotWalletPasswordRequester
|
||||
import com.tangem.domain.wallets.usecase.ClearAllHotWalletContextualUnlockUseCase
|
||||
import com.tangem.tap.LockTimerWorker.Companion.TAG
|
||||
import com.tangem.tap.common.extensions.dispatchNavigationAction
|
||||
|
|
@ -28,6 +29,7 @@ internal class LockUserWalletsTimer(
|
|||
private val userWalletsListRepository: UserWalletsListRepository,
|
||||
private val coroutineScope: CoroutineScope,
|
||||
private val clearAllHotWalletContextualUnlockUseCase: ClearAllHotWalletContextualUnlockUseCase,
|
||||
private val passwordRequester: HotWalletPasswordRequester,
|
||||
) : LifecycleOwner by context as LifecycleOwner,
|
||||
DefaultLifecycleObserver {
|
||||
|
||||
|
|
@ -53,6 +55,7 @@ internal class LockUserWalletsTimer(
|
|||
)
|
||||
|
||||
if (shouldOpenWelcomeScreenOnResume) {
|
||||
passwordRequester.dismiss()
|
||||
clearAllHotWalletContextualUnlockUseCase.invoke()
|
||||
store.dispatchNavigationAction { replaceAll(AppRoute.Welcome()) }
|
||||
settingsRepository.setShouldOpenWelcomeScreenOnResume(value = false)
|
||||
|
|
@ -116,6 +119,7 @@ internal class LockUserWalletsTimer(
|
|||
start()
|
||||
}
|
||||
.onRight {
|
||||
passwordRequester.dismiss()
|
||||
clearAllHotWalletContextualUnlockUseCase.invoke()
|
||||
store.dispatchNavigationAction { replaceAll(AppRoute.Welcome()) }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ import androidx.appcompat.app.AppCompatActivity
|
|||
import androidx.appcompat.app.AppCompatDelegate
|
||||
import androidx.appcompat.app.AppCompatDelegate.setDefaultNightMode
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.runtime.CompositionLocalProvider
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.toArgb
|
||||
|
|
@ -29,6 +30,8 @@ import com.tangem.common.routing.deeplink.DeeplinkConst.WEBLINK_KEY
|
|||
import com.tangem.common.routing.deeplink.PayloadToDeeplinkConverter
|
||||
import com.tangem.core.analytics.api.AnalyticsEventHandler
|
||||
import com.tangem.core.decompose.context.AppComponentContext
|
||||
import com.tangem.core.ui.extensions.LocalUserInteractionTracker
|
||||
import com.tangem.core.ui.extensions.UserInteractionTracker
|
||||
import com.tangem.core.decompose.di.RootAppComponentContext
|
||||
import com.tangem.core.navigation.url.UrlOpener
|
||||
import com.tangem.data.balancehiding.DefaultDeviceFlipDetector
|
||||
|
|
@ -43,6 +46,7 @@ import com.tangem.domain.settings.SetGoogleServicesAvailabilityUseCase
|
|||
import com.tangem.domain.settings.ShouldInitiallyAskPermissionUseCase
|
||||
import com.tangem.domain.settings.repositories.SettingsRepository
|
||||
import com.tangem.domain.staking.SendUnsubmittedHashesUseCase
|
||||
import com.tangem.domain.wallets.hot.HotWalletPasswordRequester
|
||||
import com.tangem.domain.wallets.usecase.ClearAllHotWalletContextualUnlockUseCase
|
||||
import com.tangem.features.tester.api.TesterMenuLauncher
|
||||
import com.tangem.google.GoogleServicesHelper
|
||||
|
|
@ -160,6 +164,9 @@ class MainActivity : AppCompatActivity(), ActivityResultCallbackHolder {
|
|||
@Inject
|
||||
internal lateinit var clearAllHotWalletContextualUnlockUseCase: ClearAllHotWalletContextualUnlockUseCase
|
||||
|
||||
@Inject
|
||||
internal lateinit var passwordRequester: HotWalletPasswordRequester
|
||||
|
||||
private val viewModel: MainViewModel by viewModels()
|
||||
|
||||
private lateinit var appThemeModeFlow: SharedFlow<AppThemeMode>
|
||||
|
|
@ -231,8 +238,16 @@ class MainActivity : AppCompatActivity(), ActivityResultCallbackHolder {
|
|||
launchMode = backgroundScanIntentHandler.getInitScreenLaunchMode(intent),
|
||||
)
|
||||
|
||||
val userInteractionTracker = object : UserInteractionTracker {
|
||||
override fun onUserInteraction() {
|
||||
lockUserWalletsTimer?.restart()
|
||||
}
|
||||
}
|
||||
|
||||
setContent {
|
||||
routingComponent.Content(Modifier.fillMaxSize())
|
||||
CompositionLocalProvider(LocalUserInteractionTracker provides userInteractionTracker) {
|
||||
routingComponent.Content(Modifier.fillMaxSize())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -249,6 +264,7 @@ class MainActivity : AppCompatActivity(), ActivityResultCallbackHolder {
|
|||
coroutineScope = mainScope,
|
||||
userWalletsListRepository = userWalletsListRepository,
|
||||
clearAllHotWalletContextualUnlockUseCase = clearAllHotWalletContextualUnlockUseCase,
|
||||
passwordRequester = passwordRequester,
|
||||
)
|
||||
|
||||
store.dispatch(
|
||||
|
|
|
|||
|
|
@ -0,0 +1,40 @@
|
|||
package com.tangem.core.ui.extensions
|
||||
|
||||
import androidx.compose.foundation.gestures.awaitEachGesture
|
||||
import androidx.compose.foundation.gestures.awaitFirstDown
|
||||
import androidx.compose.foundation.gestures.waitForUpOrCancellation
|
||||
import androidx.compose.runtime.staticCompositionLocalOf
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.input.key.KeyEventType
|
||||
import androidx.compose.ui.input.key.onPreviewKeyEvent
|
||||
import androidx.compose.ui.input.key.type
|
||||
import androidx.compose.ui.input.pointer.pointerInput
|
||||
|
||||
val LocalUserInteractionTracker = staticCompositionLocalOf<UserInteractionTracker?> { null }
|
||||
|
||||
interface UserInteractionTracker {
|
||||
fun onUserInteraction()
|
||||
}
|
||||
|
||||
fun Modifier.trackUserInteraction(tracker: UserInteractionTracker?): Modifier {
|
||||
if (tracker == null) return this
|
||||
|
||||
return this
|
||||
.pointerInput(Unit) {
|
||||
awaitEachGesture {
|
||||
val down = awaitFirstDown(requireUnconsumed = false)
|
||||
|
||||
if (down.pressed) {
|
||||
tracker.onUserInteraction()
|
||||
}
|
||||
|
||||
waitForUpOrCancellation()
|
||||
}
|
||||
}
|
||||
.onPreviewKeyEvent { event ->
|
||||
if (event.type == KeyEventType.KeyDown) {
|
||||
tracker.onUserInteraction()
|
||||
}
|
||||
false
|
||||
}
|
||||
}
|
||||
|
|
@ -9,6 +9,7 @@ import com.tangem.domain.models.wallet.UserWallet
|
|||
import com.tangem.domain.wallets.hot.HotWalletAccessor
|
||||
import com.tangem.hot.sdk.model.DataToSign
|
||||
import com.tangem.operations.sign.SignData
|
||||
import com.tangem.utils.coroutines.runSuspendCatching
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedFactory
|
||||
import dagger.assisted.AssistedInject
|
||||
|
|
@ -32,7 +33,7 @@ class TangemHotWalletSigner @AssistedInject constructor(
|
|||
TangemSdkError.ExceptionError(IllegalStateException("wallet is locked")),
|
||||
)
|
||||
|
||||
val result = runCatching {
|
||||
val result = runSuspendCatching {
|
||||
hotWalletAccessor.signHashes(
|
||||
hotWalletId = userWallet.hotWalletId,
|
||||
dataToSign = listOf(
|
||||
|
|
@ -59,7 +60,7 @@ class TangemHotWalletSigner @AssistedInject constructor(
|
|||
dataToSign: List<SignData>,
|
||||
publicKey: Wallet.PublicKey,
|
||||
): CompletionResult<Map<ByteArray, ByteArray>> {
|
||||
val result = runCatching {
|
||||
val result = runSuspendCatching {
|
||||
hotWalletAccessor.signHashes(
|
||||
hotWalletId = userWallet.hotWalletId,
|
||||
dataToSign = dataToSign.map { signData ->
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ import kotlinx.coroutines.CoroutineScope
|
|||
import kotlinx.coroutines.NonCancellable
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import kotlin.coroutines.cancellation.CancellationException
|
||||
|
||||
@Suppress("LongParameterList")
|
||||
class SendTransactionUseCase(
|
||||
|
|
@ -96,6 +97,8 @@ class SendTransactionUseCase(
|
|||
is Result.Success -> sendResult.data.right()
|
||||
}
|
||||
}
|
||||
} catch (e: CancellationException) {
|
||||
throw e
|
||||
} catch (ex: Exception) {
|
||||
cardSdkConfigRepository.setLinkedTerminal(linkedTerminal)
|
||||
SendTransactionError.DataError(ex.message).left()
|
||||
|
|
|
|||
|
|
@ -18,6 +18,8 @@ import androidx.compose.ui.text.style.TextAlign
|
|||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.tangem.core.ui.components.SecondaryButton
|
||||
import com.tangem.core.ui.extensions.LocalUserInteractionTracker
|
||||
import com.tangem.core.ui.extensions.trackUserInteraction
|
||||
import com.tangem.core.ui.components.SpacerH
|
||||
import com.tangem.core.ui.components.SpacerH24
|
||||
import com.tangem.core.ui.components.appbar.TangemTopAppBar
|
||||
|
|
@ -37,7 +39,13 @@ import com.tangem.features.hotwallet.impl.R
|
|||
@Suppress("MagicNumber", "LongMethod")
|
||||
@Composable
|
||||
internal fun HotAccessCodeRequestFullScreenContent(state: HotAccessCodeRequestUM, modifier: Modifier = Modifier) {
|
||||
Box(Modifier.fillMaxSize()) {
|
||||
val userInteractionTracker = LocalUserInteractionTracker.current
|
||||
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.trackUserInteraction(userInteractionTracker),
|
||||
) {
|
||||
AnimatedVisibility(
|
||||
modifier = modifier,
|
||||
visible = state.isShown,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue