Updated on 2026-08-14
This commit is contained in:
parent
5d13d36cb3
commit
29fb436bc2
10 changed files with 84 additions and 31 deletions
|
|
@ -1,6 +1,6 @@
|
|||
package com.tangem.tap.di
|
||||
|
||||
import com.tangem.core.navigation.NavigationStateHolder
|
||||
import com.tangem.core.navigation.ReduxNavController
|
||||
import com.tangem.domain.redux.ReduxStateHolder
|
||||
import com.tangem.domain.wallets.legacy.WalletsStateHolder
|
||||
import com.tangem.tap.proxy.AppStateHolder
|
||||
|
|
@ -20,7 +20,7 @@ internal interface AppStateHolderModule {
|
|||
|
||||
@Binds
|
||||
@Singleton
|
||||
fun bindsNavigationStateHolder(appStateHolder: AppStateHolder): NavigationStateHolder
|
||||
fun bindsNavigationStateHolder(appStateHolder: AppStateHolder): ReduxNavController
|
||||
|
||||
@Binds
|
||||
@Singleton
|
||||
|
|
|
|||
|
|
@ -1,7 +1,11 @@
|
|||
package com.tangem.tap.di.domain
|
||||
|
||||
import com.tangem.domain.settings.CanUseBiometryUseCase
|
||||
import com.tangem.domain.settings.IsUserAlreadyRateAppUseCase
|
||||
import com.tangem.domain.settings.ShouldShowSaveWalletScreenUseCase
|
||||
import com.tangem.domain.settings.repositories.SettingsRepository
|
||||
import com.tangem.tap.domain.TangemSdkManager
|
||||
import com.tangem.tap.domain.settings.DefaultLegacySettingsRepository
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
|
|
@ -17,4 +21,20 @@ internal object SettingsDomainModule {
|
|||
fun providesGetWalletsUseCase(settingsRepository: SettingsRepository): IsUserAlreadyRateAppUseCase {
|
||||
return IsUserAlreadyRateAppUseCase(settingsRepository = settingsRepository)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@ViewModelScoped
|
||||
fun providesShouldShowSaveWalletScreenUseCase(
|
||||
settingsRepository: SettingsRepository,
|
||||
): ShouldShowSaveWalletScreenUseCase {
|
||||
return ShouldShowSaveWalletScreenUseCase(settingsRepository = settingsRepository)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@ViewModelScoped
|
||||
fun providesCanUseBiometryUseCase(tangemSdkManager: TangemSdkManager): CanUseBiometryUseCase {
|
||||
return CanUseBiometryUseCase(
|
||||
legacySettingsRepository = DefaultLegacySettingsRepository(tangemSdkManager = tangemSdkManager),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +1,8 @@
|
|||
package com.tangem.tap.proxy
|
||||
|
||||
import com.tangem.core.navigation.AppScreen
|
||||
import com.tangem.core.navigation.NavigationAction
|
||||
import com.tangem.core.navigation.NavigationStateHolder
|
||||
import com.tangem.core.navigation.ReduxNavController
|
||||
import com.tangem.domain.models.scan.CardDTO
|
||||
import com.tangem.domain.models.scan.ScanResponse
|
||||
import com.tangem.domain.redux.ReduxStateHolder
|
||||
|
|
@ -23,7 +24,7 @@ import javax.inject.Inject
|
|||
* Holds objects from old modules, that missing in DI graph.
|
||||
* Object sets manually to use in new modules and [AppStateHolder] proxies its to DI.
|
||||
*/
|
||||
class AppStateHolder @Inject constructor() : WalletsStateHolder, NavigationStateHolder, ReduxStateHolder {
|
||||
class AppStateHolder @Inject constructor() : WalletsStateHolder, ReduxNavController, ReduxStateHolder {
|
||||
|
||||
override var userWalletsListManager: UserWalletsListManager? = null
|
||||
set(value) {
|
||||
|
|
@ -53,6 +54,8 @@ class AppStateHolder @Inject constructor() : WalletsStateHolder, NavigationState
|
|||
mainStore?.dispatch(action)
|
||||
}
|
||||
|
||||
override fun getBackStack(): List<AppScreen> = mainStore?.state?.navigationState?.backStack.orEmpty()
|
||||
|
||||
override fun dispatch(action: Action) {
|
||||
mainStore?.dispatch(action)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,14 @@
|
|||
package com.tangem.core.navigation
|
||||
|
||||
/**
|
||||
* Navigation state holder
|
||||
* Navigation controller that based on redux actions
|
||||
*
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
interface NavigationStateHolder {
|
||||
interface ReduxNavController {
|
||||
|
||||
/** Navigate by [action] */
|
||||
fun navigate(action: NavigationAction)
|
||||
|
||||
fun getBackStack(): List<AppScreen>
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
package com.tangem.feature.tokendetails.di
|
||||
|
||||
import com.tangem.core.navigation.NavigationStateHolder
|
||||
import com.tangem.core.navigation.ReduxNavController
|
||||
import com.tangem.feature.tokendetails.presentation.router.DefaultTokenDetailsRouter
|
||||
import com.tangem.features.tokendetails.navigation.TokenDetailsRouter
|
||||
import dagger.Module
|
||||
|
|
@ -15,7 +15,7 @@ internal object TokenDetailsRouterModule {
|
|||
|
||||
@Provides
|
||||
@ActivityScoped
|
||||
fun provideTokenDetailsRouter(navigationStateHolder: NavigationStateHolder): TokenDetailsRouter {
|
||||
return DefaultTokenDetailsRouter(navigationStateHolder)
|
||||
fun provideTokenDetailsRouter(reduxNavController: ReduxNavController): TokenDetailsRouter {
|
||||
return DefaultTokenDetailsRouter(reduxNavController)
|
||||
}
|
||||
}
|
||||
|
|
@ -2,20 +2,20 @@ package com.tangem.feature.tokendetails.presentation.router
|
|||
|
||||
import androidx.fragment.app.Fragment
|
||||
import com.tangem.core.navigation.NavigationAction
|
||||
import com.tangem.core.navigation.NavigationStateHolder
|
||||
import com.tangem.core.navigation.ReduxNavController
|
||||
import com.tangem.feature.tokendetails.presentation.TokenDetailsFragment
|
||||
|
||||
internal class DefaultTokenDetailsRouter(
|
||||
private val navigationStateHolder: NavigationStateHolder,
|
||||
private val reduxNavController: ReduxNavController,
|
||||
) : InnerTokenDetailsRouter {
|
||||
|
||||
override fun getEntryFragment(): Fragment = TokenDetailsFragment()
|
||||
|
||||
override fun popBackStack() {
|
||||
navigationStateHolder.navigate(NavigationAction.PopBackTo())
|
||||
reduxNavController.navigate(NavigationAction.PopBackTo())
|
||||
}
|
||||
|
||||
override fun openUrl(url: String) {
|
||||
navigationStateHolder.navigate(NavigationAction.OpenUrl(url = url))
|
||||
reduxNavController.navigate(NavigationAction.OpenUrl(url = url))
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
package com.tangem.feature.wallet.di
|
||||
|
||||
import com.tangem.core.navigation.NavigationStateHolder
|
||||
import com.tangem.core.navigation.ReduxNavController
|
||||
import com.tangem.feature.wallet.presentation.router.DefaultWalletRouter
|
||||
import com.tangem.features.wallet.navigation.WalletRouter
|
||||
import dagger.Module
|
||||
|
|
@ -15,7 +15,7 @@ internal object WalletRouterModule {
|
|||
|
||||
@Provides
|
||||
@ActivityScoped
|
||||
fun provideWalletRouter(navigationStateHolder: NavigationStateHolder): WalletRouter {
|
||||
return DefaultWalletRouter(navigationStateHolder = navigationStateHolder)
|
||||
fun provideWalletRouter(reduxNavController: ReduxNavController): WalletRouter {
|
||||
return DefaultWalletRouter(reduxNavController = reduxNavController)
|
||||
}
|
||||
}
|
||||
|
|
@ -18,7 +18,7 @@ import androidx.navigation.compose.rememberNavController
|
|||
import androidx.navigation.navArgument
|
||||
import com.tangem.core.navigation.AppScreen
|
||||
import com.tangem.core.navigation.NavigationAction
|
||||
import com.tangem.core.navigation.NavigationStateHolder
|
||||
import com.tangem.core.navigation.ReduxNavController
|
||||
import com.tangem.domain.tokens.models.CryptoCurrency
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.feature.wallet.presentation.WalletFragment
|
||||
|
|
@ -30,7 +30,7 @@ import com.tangem.features.tokendetails.navigation.TokenDetailsRouter
|
|||
import kotlin.properties.Delegates
|
||||
|
||||
/** Default implementation of wallet feature router */
|
||||
internal class DefaultWalletRouter(private val navigationStateHolder: NavigationStateHolder) : InnerWalletRouter {
|
||||
internal class DefaultWalletRouter(private val reduxNavController: ReduxNavController) : InnerWalletRouter {
|
||||
|
||||
private var navController: NavHostController by Delegates.notNull()
|
||||
private var fragmentManager: FragmentManager by Delegates.notNull()
|
||||
|
|
@ -71,7 +71,7 @@ internal class DefaultWalletRouter(private val navigationStateHolder: Navigation
|
|||
}
|
||||
}
|
||||
|
||||
override fun popBackStack() {
|
||||
override fun popBackStack(screen: AppScreen?) {
|
||||
/*
|
||||
* It's hack that avoid issue with closing the wallet screen.
|
||||
* We are using NavGraph only inside feature so first backstack's element is entry of NavGraph and
|
||||
|
|
@ -79,7 +79,11 @@ internal class DefaultWalletRouter(private val navigationStateHolder: Navigation
|
|||
* If backstack contains only NavGraph entry and wallet screen entry then we close the wallet fragment.
|
||||
*/
|
||||
if (navController.backQueue.size == BACKSTACK_ENTRY_COUNT_TO_CLOSE_WALLET_SCREEN) {
|
||||
fragmentManager.popBackStack()
|
||||
if (screen != null) {
|
||||
reduxNavController.navigate(action = NavigationAction.PopBackTo(screen))
|
||||
} else {
|
||||
fragmentManager.popBackStack()
|
||||
}
|
||||
} else {
|
||||
navController.popBackStack()
|
||||
}
|
||||
|
|
@ -92,19 +96,19 @@ internal class DefaultWalletRouter(private val navigationStateHolder: Navigation
|
|||
override fun openDetailsScreen() {
|
||||
// FIXME: Prepare details screen (e.g. dispatch action: `DetailsAction.PrepareScreen`)
|
||||
// [REDACTED_JIRA]
|
||||
navigationStateHolder.navigate(action = NavigationAction.NavigateTo(AppScreen.Details))
|
||||
reduxNavController.navigate(action = NavigationAction.NavigateTo(AppScreen.Details))
|
||||
}
|
||||
|
||||
override fun openOnboardingScreen() {
|
||||
navigationStateHolder.navigate(action = NavigationAction.NavigateTo(AppScreen.OnboardingWallet))
|
||||
reduxNavController.navigate(action = NavigationAction.NavigateTo(AppScreen.OnboardingWallet))
|
||||
}
|
||||
|
||||
override fun openTxHistoryWebsite(url: String) {
|
||||
navigationStateHolder.navigate(action = NavigationAction.OpenUrl(url))
|
||||
reduxNavController.navigate(action = NavigationAction.OpenUrl(url))
|
||||
}
|
||||
|
||||
override fun openTokenDetails(currency: CryptoCurrency) {
|
||||
navigationStateHolder.navigate(
|
||||
reduxNavController.navigate(
|
||||
action = NavigationAction.NavigateTo(
|
||||
screen = AppScreen.WalletDetails,
|
||||
// TODO: [REDACTED_JIRA]
|
||||
|
|
@ -113,10 +117,12 @@ internal class DefaultWalletRouter(private val navigationStateHolder: Navigation
|
|||
)
|
||||
}
|
||||
|
||||
override fun openStoriesScreen() {
|
||||
navigationStateHolder.navigate(action = NavigationAction.NavigateTo(screen = AppScreen.Home))
|
||||
override fun openSaveUserWalletScreen() {
|
||||
reduxNavController.navigate(action = NavigationAction.NavigateTo(AppScreen.SaveWallet))
|
||||
}
|
||||
|
||||
override fun isWalletLastScreen(): Boolean = reduxNavController.getBackStack().lastOrNull() == AppScreen.Wallet
|
||||
|
||||
private companion object {
|
||||
const val BACKSTACK_ENTRY_COUNT_TO_CLOSE_WALLET_SCREEN = 2
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package com.tangem.feature.wallet.presentation.router
|
|||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.Stable
|
||||
import androidx.fragment.app.FragmentManager
|
||||
import com.tangem.core.navigation.AppScreen
|
||||
import com.tangem.domain.tokens.models.CryptoCurrency
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.features.wallet.navigation.WalletRouter
|
||||
|
|
@ -28,7 +29,7 @@ internal interface InnerWalletRouter : WalletRouter {
|
|||
fun Initialize(fragmentManager: FragmentManager)
|
||||
|
||||
/** Pop back stack */
|
||||
fun popBackStack()
|
||||
fun popBackStack(screen: AppScreen? = null)
|
||||
|
||||
/** Open organize tokens screen */
|
||||
fun openOrganizeTokensScreen(userWalletId: UserWalletId)
|
||||
|
|
@ -45,6 +46,9 @@ internal interface InnerWalletRouter : WalletRouter {
|
|||
/** Open token details screen */
|
||||
fun openTokenDetails(currency: CryptoCurrency)
|
||||
|
||||
/** Open stories screen */
|
||||
fun openStoriesScreen()
|
||||
/** Open save user wallet screen */
|
||||
fun openSaveUserWalletScreen()
|
||||
|
||||
/** Is wallet last screen */
|
||||
fun isWalletLastScreen(): Boolean
|
||||
}
|
||||
|
|
@ -8,6 +8,7 @@ import com.tangem.blockchain.common.derivation.DerivationStyle
|
|||
import com.tangem.common.Provider
|
||||
import com.tangem.common.doOnFailure
|
||||
import com.tangem.common.doOnSuccess
|
||||
import com.tangem.core.navigation.AppScreen
|
||||
import com.tangem.core.ui.components.marketprice.MarketPriceBlockState
|
||||
import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
|
||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
|
|
@ -17,7 +18,9 @@ import com.tangem.domain.common.util.cardTypesResolver
|
|||
import com.tangem.domain.common.util.derivationStyleProvider
|
||||
import com.tangem.domain.demo.IsDemoCardUseCase
|
||||
import com.tangem.domain.redux.ReduxStateHolder
|
||||
import com.tangem.domain.settings.CanUseBiometryUseCase
|
||||
import com.tangem.domain.settings.IsUserAlreadyRateAppUseCase
|
||||
import com.tangem.domain.settings.ShouldShowSaveWalletScreenUseCase
|
||||
import com.tangem.domain.tokens.GetCryptoCurrencyActionsUseCase
|
||||
import com.tangem.domain.tokens.GetPrimaryCurrencyUseCase
|
||||
import com.tangem.domain.tokens.GetTokenListUseCase
|
||||
|
|
@ -81,6 +84,9 @@ internal class WalletViewModel @Inject constructor(
|
|||
private val unlockWalletsUseCase: UnlockWalletsUseCase,
|
||||
private val getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase,
|
||||
private val getCryptoCurrencyActionsUseCase: GetCryptoCurrencyActionsUseCase,
|
||||
private val shouldShowSaveWalletScreenUseCase: ShouldShowSaveWalletScreenUseCase,
|
||||
private val canUseBiometryUseCase: CanUseBiometryUseCase,
|
||||
private val shouldSaveUserWalletsUseCase: ShouldSaveUserWalletsUseCase,
|
||||
private val reduxStateHolder: ReduxStateHolder,
|
||||
private val dispatchers: CoroutineDispatcherProvider,
|
||||
) : ViewModel(), DefaultLifecycleObserver, WalletClickIntents {
|
||||
|
|
@ -123,6 +129,14 @@ internal class WalletViewModel @Inject constructor(
|
|||
private val notificationsJobHolder = JobHolder()
|
||||
|
||||
override fun onCreate(owner: LifecycleOwner) {
|
||||
viewModelScope.launch(dispatchers.main) {
|
||||
delay(timeMillis = 1_800)
|
||||
|
||||
if (router.isWalletLastScreen() && shouldShowSaveWalletScreenUseCase() && canUseBiometryUseCase()) {
|
||||
router.openSaveUserWalletScreen()
|
||||
}
|
||||
}
|
||||
|
||||
getWalletsUseCase()
|
||||
.flowWithLifecycle(owner.lifecycle)
|
||||
.distinctUntilChanged()
|
||||
|
|
@ -280,7 +294,11 @@ internal class WalletViewModel @Inject constructor(
|
|||
|
||||
private fun getCardTypeResolver(index: Int): CardTypesResolver = getWallet(index).scanResponse.cardTypesResolver
|
||||
|
||||
override fun onBackClick() = router.popBackStack()
|
||||
override fun onBackClick() {
|
||||
viewModelScope.launch(dispatchers.main) {
|
||||
router.popBackStack(screen = if (shouldSaveUserWalletsUseCase()) AppScreen.Welcome else AppScreen.Home)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onScanCardClick() {
|
||||
val prevRequestPolicyStatus = getBiometricsStatusUseCase()
|
||||
|
|
@ -525,7 +543,7 @@ internal class WalletViewModel @Inject constructor(
|
|||
val either = deleteWalletUseCase(userWalletId)
|
||||
|
||||
val state = requireNotNull(uiState as? WalletState.ContentState)
|
||||
if (state.walletsListConfig.wallets.size <= 1 && either.isRight()) router.openStoriesScreen()
|
||||
if (state.walletsListConfig.wallets.size <= 1 && either.isRight()) onBackClick()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue