Updated on 2026-08-14

This commit is contained in:
Tangem 2025-09-05 17:22:08 +04:00
parent 96ce2fc718
commit fd7bc522f2
21 changed files with 289 additions and 1 deletions

View file

@ -0,0 +1 @@
/build

View 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)
}

View file

@ -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>
}

View file

@ -0,0 +1,10 @@
package com.tangem.features.tangempay.deeplink
import android.net.Uri
interface OnboardVisaDeepLinkHandler {
interface Factory {
fun create(uri: Uri): OnboardVisaDeepLinkHandler
}
}

View file

@ -0,0 +1 @@
/build

View 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)
}

View file

@ -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
}
}

View file

@ -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
}
}

View file

@ -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
}

View file

@ -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
}

View file

@ -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
}

View file

@ -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
}

View file

@ -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()
},
)
}

View file

@ -0,0 +1,3 @@
package com.tangem.features.tangempay.ui
internal object TangemPayOnboardingScreenState