Updated on 2026-08-14
This commit is contained in:
parent
96ce2fc718
commit
fd7bc522f2
21 changed files with 289 additions and 1 deletions
|
|
@ -270,6 +270,8 @@ dependencies {
|
|||
implementation(projects.features.tangempay.details.impl)
|
||||
implementation(projects.features.tangempay.main.api)
|
||||
implementation(projects.features.tangempay.main.impl)
|
||||
implementation(projects.features.tangempay.onboarding.api)
|
||||
implementation(projects.features.tangempay.onboarding.impl)
|
||||
implementation(projects.features.tokenRecieve.api)
|
||||
implementation(projects.features.tokenRecieve.impl)
|
||||
|
||||
|
|
|
|||
|
|
@ -264,6 +264,16 @@
|
|||
android:host="promo"
|
||||
android:scheme="tangem" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
|
||||
<data
|
||||
android:host="onboard-visa"
|
||||
android:scheme="tangem" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<!-- Disable android.startup completely. Used for Worker according doc -->
|
||||
|
|
|
|||
|
|
@ -55,6 +55,7 @@ import com.tangem.tap.features.details.ui.securitymode.api.SecurityModeComponent
|
|||
import com.tangem.tap.features.details.ui.walletconnect.api.WalletConnectComponent
|
||||
import com.tangem.tap.features.welcome.component.WelcomeComponent
|
||||
import com.tangem.tap.routing.component.RoutingComponent.Child
|
||||
import com.tangem.features.tangempay.components.TangemPayOnboardingComponent
|
||||
import dagger.hilt.android.scopes.ActivityScoped
|
||||
import javax.inject.Inject
|
||||
import com.tangem.features.walletconnect.components.WalletConnectEntryComponent as RedesignedWalletConnectComponent
|
||||
|
|
@ -114,6 +115,7 @@ internal class ChildFactory @Inject constructor(
|
|||
private val sendWithSwapComponentFactory: SendWithSwapComponent.Factory,
|
||||
private val sendEntryPointComponentFactory: SendEntryPointComponent.Factory,
|
||||
private val tangemPayDetailsComponentFactory: TangemPayDetailsComponent.Factory,
|
||||
private val tangemPayOnboardingComponentFactory: TangemPayOnboardingComponent.Factory,
|
||||
private val walletConnectFeatureToggles: WalletConnectFeatureToggles,
|
||||
private val hotWalletFeatureToggles: HotWalletFeatureToggles,
|
||||
) {
|
||||
|
|
@ -606,6 +608,13 @@ internal class ChildFactory @Inject constructor(
|
|||
componentFactory = tangemPayDetailsComponentFactory,
|
||||
)
|
||||
}
|
||||
is AppRoute.TangemPayOnboarding -> {
|
||||
createComponentChild(
|
||||
context = context,
|
||||
params = TangemPayOnboardingComponent.Params(route.deeplink),
|
||||
componentFactory = tangemPayOnboardingComponentFactory,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -14,6 +14,7 @@ import com.tangem.features.onramp.deeplink.SellDeepLinkHandler
|
|||
import com.tangem.features.onramp.deeplink.SwapDeepLinkHandler
|
||||
import com.tangem.features.send.v2.api.deeplink.SellRedirectDeepLinkHandler
|
||||
import com.tangem.features.staking.api.deeplink.StakingDeepLinkHandler
|
||||
import com.tangem.features.tangempay.deeplink.OnboardVisaDeepLinkHandler
|
||||
import com.tangem.features.tokendetails.deeplink.TokenDetailsDeepLinkHandler
|
||||
import com.tangem.features.wallet.deeplink.PromoDeeplinkHandler
|
||||
import com.tangem.features.wallet.deeplink.WalletDeepLinkHandler
|
||||
|
|
@ -48,6 +49,7 @@ internal class DeepLinkFactory @Inject constructor(
|
|||
private val sellDeepLink: SellDeepLinkHandler.Factory,
|
||||
private val swapDeepLink: SwapDeepLinkHandler.Factory,
|
||||
private val promoDeepLink: PromoDeeplinkHandler.Factory,
|
||||
private val onboardVisaDeepLink: OnboardVisaDeepLinkHandler.Factory,
|
||||
) {
|
||||
private val permittedAppRoute = MutableStateFlow(false)
|
||||
|
||||
|
|
@ -135,6 +137,7 @@ internal class DeepLinkFactory @Inject constructor(
|
|||
DeepLinkRoute.Swap.host -> swapDeepLink.create()
|
||||
DeepLinkRoute.WalletConnect.host -> walletConnectDeepLink.create(deeplinkUri)
|
||||
DeepLinkRoute.Promo.host -> promoDeepLink.create(coroutineScope, queryParams)
|
||||
DeepLinkRoute.OnboardVisa.host -> onboardVisaDeepLink.create(deeplinkUri)
|
||||
else -> {
|
||||
Timber.i(
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -375,4 +375,9 @@ sealed class AppRoute(val path: String) : Route {
|
|||
|
||||
@Serializable
|
||||
data class TangemPayDetails(val userWalletId: UserWalletId) : AppRoute(path = "/tangem_pay_details")
|
||||
|
||||
@Serializable
|
||||
data class TangemPayOnboarding(
|
||||
val deeplink: String,
|
||||
) : AppRoute(path = "/tangem_pay_onboarding/$deeplink")
|
||||
}
|
||||
|
|
@ -59,6 +59,10 @@ sealed class DeepLinkRoute {
|
|||
data object Promo : DeepLinkRoute() {
|
||||
override val host: String = "promo"
|
||||
}
|
||||
|
||||
data object OnboardVisa : DeepLinkRoute() {
|
||||
override val host: String = "onboard-visa"
|
||||
}
|
||||
}
|
||||
|
||||
enum class DeepLinkScheme(val scheme: String) {
|
||||
|
|
|
|||
1
features/tangempay/onboarding/api/.gitignore
vendored
Normal file
1
features/tangempay/onboarding/api/.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
/build
|
||||
18
features/tangempay/onboarding/api/build.gradle.kts
Normal file
18
features/tangempay/onboarding/api/build.gradle.kts
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
plugins {
|
||||
alias(deps.plugins.android.library)
|
||||
alias(deps.plugins.kotlin.android)
|
||||
id("configuration")
|
||||
}
|
||||
|
||||
android {
|
||||
namespace = "com.tangem.features.tangempay.onboarding.api"
|
||||
}
|
||||
|
||||
dependencies {
|
||||
/** Core */
|
||||
implementation(projects.core.decompose)
|
||||
implementation(projects.core.ui)
|
||||
|
||||
/** Compose */
|
||||
implementation(deps.compose.runtime)
|
||||
}
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
package com.tangem.features.tangempay.components
|
||||
|
||||
import com.tangem.core.decompose.factory.ComponentFactory
|
||||
import com.tangem.core.ui.decompose.ComposableContentComponent
|
||||
|
||||
interface TangemPayOnboardingComponent : ComposableContentComponent {
|
||||
|
||||
data class Params(
|
||||
val deeplink: String,
|
||||
)
|
||||
|
||||
interface Factory : ComponentFactory<Params, TangemPayOnboardingComponent>
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
package com.tangem.features.tangempay.deeplink
|
||||
|
||||
import android.net.Uri
|
||||
|
||||
interface OnboardVisaDeepLinkHandler {
|
||||
|
||||
interface Factory {
|
||||
fun create(uri: Uri): OnboardVisaDeepLinkHandler
|
||||
}
|
||||
}
|
||||
1
features/tangempay/onboarding/impl/.gitignore
vendored
Normal file
1
features/tangempay/onboarding/impl/.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
/build
|
||||
34
features/tangempay/onboarding/impl/build.gradle.kts
Normal file
34
features/tangempay/onboarding/impl/build.gradle.kts
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
plugins {
|
||||
alias(deps.plugins.android.library)
|
||||
alias(deps.plugins.kotlin.android)
|
||||
alias(deps.plugins.kotlin.serialization)
|
||||
alias(deps.plugins.kotlin.kapt)
|
||||
alias(deps.plugins.hilt.android)
|
||||
id("configuration")
|
||||
}
|
||||
|
||||
android {
|
||||
namespace = "com.tangem.features.tangempay.onboarding.impl"
|
||||
}
|
||||
|
||||
dependencies {
|
||||
/** Core */
|
||||
implementation(projects.core.decompose)
|
||||
implementation(projects.core.ui)
|
||||
|
||||
/** Common */
|
||||
implementation(projects.common.routing)
|
||||
|
||||
/** Features api */
|
||||
implementation(projects.features.tangempay.onboarding.api)
|
||||
|
||||
/** Compose */
|
||||
implementation(deps.compose.foundation)
|
||||
implementation(deps.compose.material3)
|
||||
implementation(deps.compose.ui)
|
||||
implementation(deps.compose.ui.tooling)
|
||||
|
||||
/** DI */
|
||||
implementation(deps.hilt.android)
|
||||
kapt(deps.hilt.kapt)
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
package com.tangem.features.tangempay.components
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.tangem.core.decompose.context.AppComponentContext
|
||||
import com.tangem.core.decompose.model.getOrCreateModel
|
||||
import com.tangem.features.tangempay.model.TangemPayOnboardingModel
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedFactory
|
||||
import dagger.assisted.AssistedInject
|
||||
import com.tangem.features.tangempay.ui.TandemPayOnboardingScreen
|
||||
|
||||
internal class DefaultTangemPayOnboardingComponent @AssistedInject constructor(
|
||||
@Assisted appComponentContext: AppComponentContext,
|
||||
@Assisted params: TangemPayOnboardingComponent.Params,
|
||||
) : TangemPayOnboardingComponent, AppComponentContext by appComponentContext {
|
||||
|
||||
private val model: TangemPayOnboardingModel = getOrCreateModel(params)
|
||||
|
||||
@Composable
|
||||
override fun Content(modifier: Modifier) {
|
||||
val state by model.screenState.collectAsStateWithLifecycle()
|
||||
TandemPayOnboardingScreen(modifier = modifier, state = state)
|
||||
}
|
||||
|
||||
@AssistedFactory
|
||||
interface Factory : TangemPayOnboardingComponent.Factory {
|
||||
override fun create(
|
||||
context: AppComponentContext,
|
||||
params: TangemPayOnboardingComponent.Params,
|
||||
): DefaultTangemPayOnboardingComponent
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
package com.tangem.features.tangempay.deeplink
|
||||
|
||||
import android.net.Uri
|
||||
import dagger.assisted.Assisted
|
||||
import com.tangem.common.routing.AppRoute
|
||||
import com.tangem.common.routing.AppRouter
|
||||
import dagger.assisted.AssistedFactory
|
||||
import dagger.assisted.AssistedInject
|
||||
|
||||
internal class DefaultOnboardVisaDeepLinkHandler @AssistedInject constructor(
|
||||
@Assisted uri: Uri,
|
||||
appRouter: AppRouter,
|
||||
) : OnboardVisaDeepLinkHandler {
|
||||
|
||||
init {
|
||||
appRouter.push(AppRoute.TangemPayOnboarding(uri.toString()))
|
||||
}
|
||||
|
||||
@AssistedFactory
|
||||
interface Factory : OnboardVisaDeepLinkHandler.Factory {
|
||||
override fun create(uri: Uri): DefaultOnboardVisaDeepLinkHandler
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
package com.tangem.features.tangempay.di
|
||||
|
||||
import com.tangem.features.tangempay.deeplink.DefaultOnboardVisaDeepLinkHandler
|
||||
import com.tangem.features.tangempay.deeplink.OnboardVisaDeepLinkHandler
|
||||
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 TangemPayDeeplinkModule {
|
||||
|
||||
@Binds
|
||||
@Singleton
|
||||
fun bindDeepLinkHandlerFactory(impl: DefaultOnboardVisaDeepLinkHandler.Factory): OnboardVisaDeepLinkHandler.Factory
|
||||
}
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
package com.tangem.features.tangempay.di
|
||||
|
||||
import com.tangem.features.tangempay.components.DefaultTangemPayOnboardingComponent
|
||||
import com.tangem.features.tangempay.components.TangemPayOnboardingComponent
|
||||
import dagger.Binds
|
||||
import dagger.Module
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
|
||||
@Module
|
||||
@InstallIn(SingletonComponent::class)
|
||||
internal interface TangemPayOnboardingFeatureModule {
|
||||
|
||||
@Binds
|
||||
fun bindFactory(impl: DefaultTangemPayOnboardingComponent.Factory): TangemPayOnboardingComponent.Factory
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
package com.tangem.features.tangempay.di
|
||||
|
||||
import com.tangem.core.decompose.di.ModelComponent
|
||||
import com.tangem.core.decompose.model.Model
|
||||
import com.tangem.features.tangempay.model.TangemPayOnboardingModel
|
||||
import dagger.Binds
|
||||
import dagger.Module
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.multibindings.ClassKey
|
||||
import dagger.multibindings.IntoMap
|
||||
|
||||
@Module
|
||||
@InstallIn(ModelComponent::class)
|
||||
internal interface TangemPayOnboardingModelsModule {
|
||||
|
||||
@Binds
|
||||
@IntoMap
|
||||
@ClassKey(TangemPayOnboardingModel::class)
|
||||
fun bindModel(model: TangemPayOnboardingModel): Model
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
package com.tangem.features.tangempay.model
|
||||
|
||||
import androidx.compose.runtime.Stable
|
||||
import com.tangem.core.decompose.di.ModelScoped
|
||||
import com.tangem.core.decompose.model.Model
|
||||
import com.tangem.core.decompose.model.ParamsContainer
|
||||
import com.tangem.features.tangempay.components.TangemPayOnboardingComponent
|
||||
import com.tangem.features.tangempay.ui.TangemPayOnboardingScreenState
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import javax.inject.Inject
|
||||
|
||||
@Stable
|
||||
@ModelScoped
|
||||
internal class TangemPayOnboardingModel @Inject constructor(
|
||||
paramsContainer: ParamsContainer,
|
||||
override val dispatchers: CoroutineDispatcherProvider,
|
||||
) : Model() {
|
||||
|
||||
@Suppress("UnusedPrivateMember")
|
||||
private val params = paramsContainer.require<TangemPayOnboardingComponent.Params>()
|
||||
|
||||
private val _screenState: MutableStateFlow<TangemPayOnboardingScreenState> = MutableStateFlow(getInitState())
|
||||
val screenState = _screenState.asStateFlow()
|
||||
|
||||
private fun getInitState() = TangemPayOnboardingScreenState
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
package com.tangem.features.tangempay.ui
|
||||
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.statusBarsPadding
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import com.tangem.core.ui.R
|
||||
import com.tangem.core.ui.components.appbar.AppBarWithBackButton
|
||||
|
||||
@Suppress("UnusedPrivateMember")
|
||||
@Composable
|
||||
internal fun TandemPayOnboardingScreen(state: TangemPayOnboardingScreenState, modifier: Modifier = Modifier) {
|
||||
Scaffold(
|
||||
modifier = modifier,
|
||||
topBar = {
|
||||
AppBarWithBackButton(
|
||||
modifier = Modifier.statusBarsPadding(),
|
||||
onBackClick = {},
|
||||
text = "",
|
||||
iconRes = R.drawable.ic_back_24,
|
||||
)
|
||||
},
|
||||
content = { paddingValues ->
|
||||
val contentModifier = Modifier
|
||||
.padding(paddingValues)
|
||||
.fillMaxSize()
|
||||
},
|
||||
)
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
package com.tangem.features.tangempay.ui
|
||||
|
||||
internal object TangemPayOnboardingScreenState
|
||||
|
|
@ -272,6 +272,9 @@ include(":features:tangempay:main:impl")
|
|||
include(":features:tangempay:details:api")
|
||||
include(":features:tangempay:details:impl")
|
||||
|
||||
include(":features:tangempay:onboarding:api")
|
||||
include(":features:tangempay:onboarding:impl")
|
||||
|
||||
include(":features:create-wallet-selection:api")
|
||||
include(":features:create-wallet-selection:impl")
|
||||
|
||||
|
|
@ -380,4 +383,5 @@ include(":data:blockaid")
|
|||
include(":data:swap")
|
||||
include(":data:express")
|
||||
include(":data:wallet-manager")
|
||||
// endregion Data modules
|
||||
// endregion Data modules
|
||||
include(":features:tangempay:onboarding")
|
||||
Loading…
Add table
Add a link
Reference in a new issue