diff --git a/app/src/main/java/com/tangem/tap/ApplicationEntryPoint.kt b/app/src/main/java/com/tangem/tap/ApplicationEntryPoint.kt index 923313f69f..b116caf952 100644 --- a/app/src/main/java/com/tangem/tap/ApplicationEntryPoint.kt +++ b/app/src/main/java/com/tangem/tap/ApplicationEntryPoint.kt @@ -28,6 +28,7 @@ import com.tangem.domain.walletmanager.WalletManagersFacade import com.tangem.domain.wallets.legacy.UserWalletsListManager import com.tangem.domain.wallets.repository.WalletsRepository import com.tangem.domain.wallets.usecase.GenerateWalletNameUseCase +import com.tangem.features.onboarding.v2.OnboardingV2FeatureToggles import com.tangem.features.onramp.OnrampFeatureToggles import com.tangem.tap.common.log.TangemAppLoggerInitializer import com.tangem.tap.domain.scanCard.CardScanningFeatureToggles @@ -110,4 +111,6 @@ interface ApplicationEntryPoint { fun getGetUserCountryCodeUseCase(): GetUserCountryUseCase fun getOnrampFeatureToggles(): OnrampFeatureToggles + + fun getOnboardingV2FeatureToggles(): OnboardingV2FeatureToggles } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/TangemApplication.kt b/app/src/main/java/com/tangem/tap/TangemApplication.kt index c30a00c30d..0e2e83f67f 100644 --- a/app/src/main/java/com/tangem/tap/TangemApplication.kt +++ b/app/src/main/java/com/tangem/tap/TangemApplication.kt @@ -42,6 +42,7 @@ import com.tangem.domain.walletmanager.WalletManagersFacade import com.tangem.domain.wallets.legacy.UserWalletsListManager import com.tangem.domain.wallets.repository.WalletsRepository import com.tangem.domain.wallets.usecase.GenerateWalletNameUseCase +import com.tangem.features.onboarding.v2.OnboardingV2FeatureToggles import com.tangem.features.onramp.OnrampFeatureToggles import com.tangem.tap.common.analytics.AnalyticsFactory import com.tangem.tap.common.analytics.api.AnalyticsHandlerBuilder @@ -176,6 +177,9 @@ abstract class TangemApplication : Application(), ImageLoaderFactory { private val onrampFeatureToggles: OnrampFeatureToggles get() = entryPoint.getOnrampFeatureToggles() + + private val onboardingV2FeatureToggles: OnboardingV2FeatureToggles + get() = entryPoint.getOnboardingV2FeatureToggles() // endregion override fun onCreate() { @@ -253,6 +257,7 @@ abstract class TangemApplication : Application(), ImageLoaderFactory { getUserCountryUseCase = getUserCountryUseCase, onrampFeatureToggles = onrampFeatureToggles, environmentConfigStorage = environmentConfigStorage, + onboardingV2FeatureToggles = onboardingV2FeatureToggles, ), ), ) diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/OnboardingHelper.kt b/app/src/main/java/com/tangem/tap/features/onboarding/OnboardingHelper.kt index 35007254c1..2f18b059ca 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/OnboardingHelper.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/OnboardingHelper.kt @@ -66,6 +66,10 @@ object OnboardingHelper { } fun whereToNavigate(scanResponse: ScanResponse): AppRoute { + if (store.inject(DaggerGraphState::onboardingV2FeatureToggles).isOnboardingV2Enabled) { + return AppRoute.Onboarding(scanResponse) + } + return when (val type = scanResponse.productType) { ProductType.Note -> AppRoute.OnboardingNote ProductType.Wallet, diff --git a/app/src/main/java/com/tangem/tap/proxy/redux/DaggerGraphState.kt b/app/src/main/java/com/tangem/tap/proxy/redux/DaggerGraphState.kt index fe6a63998e..075686701f 100644 --- a/app/src/main/java/com/tangem/tap/proxy/redux/DaggerGraphState.kt +++ b/app/src/main/java/com/tangem/tap/proxy/redux/DaggerGraphState.kt @@ -25,6 +25,7 @@ import com.tangem.domain.walletmanager.WalletManagersFacade import com.tangem.domain.wallets.legacy.UserWalletsListManager import com.tangem.domain.wallets.repository.WalletsRepository import com.tangem.domain.wallets.usecase.GenerateWalletNameUseCase +import com.tangem.features.onboarding.v2.OnboardingV2FeatureToggles import com.tangem.features.onramp.OnrampFeatureToggles import com.tangem.features.pushnotifications.api.navigation.PushNotificationsRouter import com.tangem.features.staking.api.navigation.StakingRouter @@ -69,4 +70,5 @@ data class DaggerGraphState( val getUserCountryUseCase: GetUserCountryUseCase? = null, val onrampFeatureToggles: OnrampFeatureToggles? = null, val environmentConfigStorage: EnvironmentConfigStorage? = null, + val onboardingV2FeatureToggles: OnboardingV2FeatureToggles? = null, ) : StateType \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/routing/utils/ChildFactory.kt b/app/src/main/java/com/tangem/tap/routing/utils/ChildFactory.kt index 5731dab42f..b031d03e46 100644 --- a/app/src/main/java/com/tangem/tap/routing/utils/ChildFactory.kt +++ b/app/src/main/java/com/tangem/tap/routing/utils/ChildFactory.kt @@ -12,6 +12,7 @@ import com.tangem.features.managetokens.component.ManageTokensComponent import com.tangem.features.managetokens.component.ManageTokensSource import com.tangem.features.markets.details.MarketsTokenDetailsComponent import com.tangem.features.onramp.component.BuyCryptoComponent +import com.tangem.features.onboarding.v2.entry.OnboardingEntryComponent import com.tangem.features.onramp.component.OnrampComponent import com.tangem.features.onramp.component.SellCryptoComponent import com.tangem.features.pushnotifications.api.navigation.PushNotificationsRouter @@ -52,6 +53,7 @@ internal class ChildFactory @Inject constructor( private val onrampComponentFactory: OnrampComponent.Factory, private val buyCryptoComponentFactory: BuyCryptoComponent.Factory, private val sellCryptoComponentFactory: SellCryptoComponent.Factory, + private val onboardingEntryComponentFactory: OnboardingEntryComponent.Factory, private val sendRouter: SendRouter, private val tokenDetailsRouter: TokenDetailsRouter, private val walletRouter: WalletRouter, @@ -213,6 +215,13 @@ internal class ChildFactory @Inject constructor( componentFactory = sellCryptoComponentFactory, ) } + is AppRoute.Onboarding -> { + route.asComponentChild( + contextProvider = contextProvider(route, contextFactory), + params = OnboardingEntryComponent.Params(route.scanResponse), + componentFactory = onboardingEntryComponentFactory, + ) + } } } diff --git a/common/routing/src/main/kotlin/com/tangem/common/routing/AppRoute.kt b/common/routing/src/main/kotlin/com/tangem/common/routing/AppRoute.kt index cb8be40a85..6744b6c0be 100644 --- a/common/routing/src/main/kotlin/com/tangem/common/routing/AppRoute.kt +++ b/common/routing/src/main/kotlin/com/tangem/common/routing/AppRoute.kt @@ -7,6 +7,7 @@ import com.tangem.common.routing.entity.SerializableIntent import com.tangem.core.decompose.navigation.Route import com.tangem.domain.appcurrency.model.AppCurrency import com.tangem.domain.markets.TokenMarketParams +import com.tangem.domain.models.scan.ScanResponse import com.tangem.domain.qrscanning.models.SourceType import com.tangem.domain.staking.model.stakekit.Yield import com.tangem.domain.tokens.model.CryptoCurrency @@ -297,4 +298,7 @@ sealed class AppRoute(val path: String) : Route { data class SellCrypto( val userWalletId: UserWalletId, ) : AppRoute(path = "/sell_crypto/${userWalletId.stringValue}") + + // Onboarding V2 + data class Onboarding(val scanResponse: ScanResponse) : AppRoute(path = "/onboarding_v2") } \ No newline at end of file diff --git a/features/onboarding-v2/api/build.gradle.kts b/features/onboarding-v2/api/build.gradle.kts index d6e9adffe8..92e55d627f 100644 --- a/features/onboarding-v2/api/build.gradle.kts +++ b/features/onboarding-v2/api/build.gradle.kts @@ -11,7 +11,7 @@ android { dependencies { /* Project - Domain */ - implementation(projects.domain.wallets.models) + implementation(projects.domain.models) /* Project - Core */ implementation(projects.core.decompose) diff --git a/features/onboarding-v2/api/src/main/kotlin/com/tangem/features/onboarding/v2/OnboardingV2FeatureToggles.kt b/features/onboarding-v2/api/src/main/kotlin/com/tangem/features/onboarding/v2/OnboardingV2FeatureToggles.kt index af4b3152e0..e86227d668 100644 --- a/features/onboarding-v2/api/src/main/kotlin/com/tangem/features/onboarding/v2/OnboardingV2FeatureToggles.kt +++ b/features/onboarding-v2/api/src/main/kotlin/com/tangem/features/onboarding/v2/OnboardingV2FeatureToggles.kt @@ -1,5 +1,5 @@ package com.tangem.features.onboarding.v2 interface OnboardingV2FeatureToggles { - val isRewrittenOnboardingCodeInUse: Boolean + val isOnboardingV2Enabled: Boolean } \ No newline at end of file diff --git a/features/onboarding-v2/api/src/main/kotlin/com/tangem/features/onboarding/v2/entry/OnboardingEntryComponent.kt b/features/onboarding-v2/api/src/main/kotlin/com/tangem/features/onboarding/v2/entry/OnboardingEntryComponent.kt index 93b12a1d21..847e64541e 100644 --- a/features/onboarding-v2/api/src/main/kotlin/com/tangem/features/onboarding/v2/entry/OnboardingEntryComponent.kt +++ b/features/onboarding-v2/api/src/main/kotlin/com/tangem/features/onboarding/v2/entry/OnboardingEntryComponent.kt @@ -2,11 +2,12 @@ package com.tangem.features.onboarding.v2.entry import com.tangem.core.decompose.factory.ComponentFactory import com.tangem.core.ui.decompose.ComposableContentComponent +import com.tangem.domain.models.scan.ScanResponse interface OnboardingEntryComponent : ComposableContentComponent { data class Params( - val todo: String, + val scanResponse: ScanResponse, ) interface Factory : ComponentFactory diff --git a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/DefaultOnboardingV2FeatureToggles.kt b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/DefaultOnboardingV2FeatureToggles.kt index 4245576b3e..fe67d84f57 100644 --- a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/DefaultOnboardingV2FeatureToggles.kt +++ b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/DefaultOnboardingV2FeatureToggles.kt @@ -6,6 +6,6 @@ import javax.inject.Inject internal class DefaultOnboardingV2FeatureToggles @Inject constructor( private val featureTogglesManager: FeatureTogglesManager, ) : OnboardingV2FeatureToggles { - override val isRewrittenOnboardingCodeInUse: Boolean + override val isOnboardingV2Enabled: Boolean get() = featureTogglesManager.isFeatureEnabled("ONBOARDING_CODE_REFACTORING_ENABLED") } \ No newline at end of file diff --git a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/entry/impl/DefaultOnboardingEntryComponent.kt b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/entry/impl/DefaultOnboardingEntryComponent.kt new file mode 100644 index 0000000000..df2a3fbde4 --- /dev/null +++ b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/entry/impl/DefaultOnboardingEntryComponent.kt @@ -0,0 +1,51 @@ +package com.tangem.features.onboarding.v2.entry.impl + +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import com.tangem.core.decompose.context.AppComponentContext +import com.tangem.core.decompose.context.child +import com.tangem.core.ui.extensions.stringReference +import com.tangem.features.onboarding.v2.entry.OnboardingEntryComponent +import com.tangem.features.onboarding.v2.entry.impl.ui.OnboardingEntry +import com.tangem.features.onboarding.v2.stepper.api.OnboardingStepperComponent +import dagger.assisted.Assisted +import dagger.assisted.AssistedFactory +import dagger.assisted.AssistedInject + +internal class DefaultOnboardingEntryComponent @AssistedInject constructor( + @Assisted val context: AppComponentContext, + @Assisted val params: OnboardingEntryComponent.Params, + stepperFactory: OnboardingStepperComponent.Factory, +) : OnboardingEntryComponent, AppComponentContext by context { + + private val stepperComponent = stepperFactory.create( + context = child("stepper"), + params = OnboardingStepperComponent.Params( + scanResponse = params.scanResponse, + initState = OnboardingStepperComponent.StepperState( + currentStep = 0, + steps = 3, + title = stringReference(""), + ), + popBack = { router.pop() }, + ), + ) + + @Composable + override fun Content(modifier: Modifier) { + OnboardingEntry( + modifier = modifier, + stepperContent = { modifierParam -> + stepperComponent.Content(modifierParam) + }, + ) + } + + @AssistedFactory + interface Factory : OnboardingEntryComponent.Factory { + override fun create( + context: AppComponentContext, + params: OnboardingEntryComponent.Params, + ): DefaultOnboardingEntryComponent + } +} \ No newline at end of file diff --git a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/entry/impl/di/ComponentModule.kt b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/entry/impl/di/ComponentModule.kt new file mode 100644 index 0000000000..f24d33ef05 --- /dev/null +++ b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/entry/impl/di/ComponentModule.kt @@ -0,0 +1,20 @@ +package com.tangem.features.onboarding.v2.entry.impl.di + +import com.tangem.features.onboarding.v2.entry.OnboardingEntryComponent +import com.tangem.features.onboarding.v2.entry.impl.DefaultOnboardingEntryComponent +import dagger.Binds +import dagger.Module +import dagger.hilt.InstallIn +import dagger.hilt.components.SingletonComponent +import javax.inject.Singleton + +@Module +@InstallIn(SingletonComponent::class) +internal interface ComponentModule { + + @Binds + @Singleton + fun bindOnboardingEntryComponent( + factory: DefaultOnboardingEntryComponent.Factory, + ): OnboardingEntryComponent.Factory +} \ No newline at end of file diff --git a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/entry/impl/ui/OnboardingEntry.kt b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/entry/impl/ui/OnboardingEntry.kt new file mode 100644 index 0000000000..5a17a8966e --- /dev/null +++ b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/entry/impl/ui/OnboardingEntry.kt @@ -0,0 +1,44 @@ +package com.tangem.features.onboarding.v2.entry.impl.ui + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.statusBarsPadding +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.tooling.preview.Preview +import com.tangem.core.ui.components.appbar.TangemTopAppBar +import com.tangem.core.ui.components.appbar.models.TopAppBarButtonUM +import com.tangem.core.ui.res.TangemTheme +import com.tangem.core.ui.res.TangemThemePreview +import com.tangem.features.onboarding.v2.impl.R + +@Composable +internal inline fun OnboardingEntry(modifier: Modifier = Modifier, stepperContent: @Composable (Modifier) -> Unit) { + Column( + modifier = modifier + .fillMaxSize() + .statusBarsPadding() + .background(TangemTheme.colors.background.primary), + ) { + stepperContent(Modifier.fillMaxWidth()) + } +} + +@Preview +@Composable +private fun Preview() { + TangemThemePreview { + OnboardingEntry { + TangemTopAppBar( + title = "Onboarding", + startButton = TopAppBarButtonUM( + iconRes = R.drawable.ic_back_24, + enabled = true, + onIconClicked = {}, + ), + ) + } + } +} \ No newline at end of file diff --git a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/stepper/api/OnboardingStepperComponent.kt b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/stepper/api/OnboardingStepperComponent.kt index 3a6cd92582..235ab31fc8 100644 --- a/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/stepper/api/OnboardingStepperComponent.kt +++ b/features/onboarding-v2/impl/src/main/kotlin/com/tangem/features/onboarding/v2/stepper/api/OnboardingStepperComponent.kt @@ -7,7 +7,7 @@ import com.tangem.core.ui.extensions.TextReference import com.tangem.domain.models.scan.ScanResponse import kotlinx.coroutines.flow.StateFlow -interface OnboardingStepperComponent : ComposableContentComponent { +internal interface OnboardingStepperComponent : ComposableContentComponent { data class StepperState( @IntRange(from = 0) val currentStep: Int,