Updated on 2026-08-14

This commit is contained in:
Tangem 2025-03-03 20:37:40 +02:00
commit da717845f0
538 changed files with 7350 additions and 5597 deletions

View file

@ -70,4 +70,6 @@ dependencies {
implementation(deps.kotlin.immutable.collections)
implementation(deps.reKotlin)
implementation(deps.timber)
implementation(deps.arrow.core)
implementation(deps.arrow.fx)
}

View file

@ -1,6 +1,6 @@
package com.tangem.features.details.di
import com.tangem.core.decompose.di.DecomposeComponent
import com.tangem.core.decompose.di.ModelComponent
import com.tangem.core.decompose.model.Model
import com.tangem.features.details.model.DetailsModel
import com.tangem.features.details.model.UserWalletListModel
@ -11,7 +11,7 @@ import dagger.multibindings.ClassKey
import dagger.multibindings.IntoMap
@Module
@InstallIn(DecomposeComponent::class)
@InstallIn(ModelComponent::class)
internal interface ModelModule {
@Binds

View file

@ -2,7 +2,7 @@ package com.tangem.features.details.model
import arrow.core.getOrElse
import com.tangem.core.analytics.AppInstanceIdProvider
import com.tangem.core.decompose.di.ComponentScoped
import com.tangem.core.decompose.di.ModelScoped
import com.tangem.core.decompose.model.Model
import com.tangem.core.decompose.model.ParamsContainer
import com.tangem.core.decompose.navigation.Router
@ -32,7 +32,7 @@ import kotlinx.coroutines.launch
import timber.log.Timber
import javax.inject.Inject
@ComponentScoped
@ModelScoped
@Suppress("LongParameterList")
internal class DetailsModel @Inject constructor(
socialsBuilder: SocialsBuilder,

View file

@ -1,7 +1,7 @@
package com.tangem.features.details.model
import com.tangem.common.ui.userwallet.state.UserWalletItemUM
import com.tangem.core.decompose.di.ComponentScoped
import com.tangem.core.decompose.di.ModelScoped
import com.tangem.core.decompose.model.Model
import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.extensions.resourceReference
@ -19,7 +19,7 @@ import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.update
import javax.inject.Inject
@ComponentScoped
@ModelScoped
internal class UserWalletListModel @Inject constructor(
userWalletsFetcher: UserWalletsFetcher,
shouldSaveUserWalletsUseCase: ShouldSaveUserWalletsUseCase,

View file

@ -1,7 +1,7 @@
package com.tangem.features.details.utils
import com.tangem.common.routing.AppRoute
import com.tangem.core.decompose.di.ComponentScoped
import com.tangem.core.decompose.di.ModelScoped
import com.tangem.core.decompose.navigation.Router
import com.tangem.core.ui.components.block.model.BlockUM
import com.tangem.core.ui.extensions.resourceReference
@ -14,7 +14,7 @@ import kotlinx.collections.immutable.persistentListOf
import kotlinx.collections.immutable.toImmutableList
import javax.inject.Inject
@ComponentScoped
@ModelScoped
internal class ItemsBuilder @Inject constructor(private val router: Router) {
fun buildAll(

View file

@ -1,7 +1,7 @@
package com.tangem.features.details.utils
import androidx.compose.ui.text.intl.Locale
import com.tangem.core.decompose.di.ComponentScoped
import com.tangem.core.decompose.di.ModelScoped
import com.tangem.core.navigation.url.UrlOpener
import com.tangem.features.details.entity.DetailsFooterUM
import com.tangem.features.details.impl.R
@ -9,7 +9,7 @@ import kotlinx.collections.immutable.ImmutableList
import kotlinx.collections.immutable.toImmutableList
import javax.inject.Inject
@ComponentScoped
@ModelScoped
internal class SocialsBuilder @Inject constructor(
private val urlOpener: UrlOpener,
) {

View file

@ -7,7 +7,7 @@ import arrow.core.raise.fold
import arrow.core.raise.recover
import com.tangem.common.routing.AppRoute
import com.tangem.core.analytics.models.AnalyticsParam
import com.tangem.core.decompose.di.ComponentScoped
import com.tangem.core.decompose.di.ModelScoped
import com.tangem.core.decompose.navigation.Router
import com.tangem.core.decompose.navigation.popTo
import com.tangem.core.decompose.ui.UiMessageSender
@ -33,7 +33,7 @@ import kotlinx.coroutines.suspendCancellableCoroutine
import javax.inject.Inject
import kotlin.coroutines.resume
@ComponentScoped
@ModelScoped
@Suppress("LongParameterList")
internal class UserWalletSaver @Inject constructor(
private val scanCardProcessor: ScanCardProcessor,

View file

@ -4,7 +4,7 @@ import arrow.core.Either
import com.tangem.common.routing.AppRoute
import com.tangem.common.ui.userwallet.converter.UserWalletItemUMConverter
import com.tangem.common.ui.userwallet.state.UserWalletItemUM
import com.tangem.core.decompose.di.ComponentScoped
import com.tangem.core.decompose.di.ModelScoped
import com.tangem.core.decompose.navigation.Router
import com.tangem.core.decompose.ui.UiMessageSender
import com.tangem.core.ui.extensions.resourceReference
@ -31,7 +31,7 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.*
import javax.inject.Inject
@ComponentScoped
@ModelScoped
internal class UserWalletsFetcher @Inject constructor(
getWalletsUseCase: GetWalletsUseCase,
private val getWalletTotalBalanceUseCase: GetWalletTotalBalanceUseCase,

View file

@ -1,6 +1,6 @@
package com.tangem.features.disclaimer.impl.di
import com.tangem.core.decompose.di.DecomposeComponent
import com.tangem.core.decompose.di.ModelComponent
import com.tangem.core.decompose.model.Model
import com.tangem.features.disclaimer.impl.model.DisclaimerModel
import dagger.Binds
@ -10,7 +10,7 @@ import dagger.multibindings.ClassKey
import dagger.multibindings.IntoMap
@Module
@InstallIn(DecomposeComponent::class)
@InstallIn(ModelComponent::class)
internal interface ModelModule {
@Binds

View file

@ -1,7 +1,7 @@
package com.tangem.features.disclaimer.impl.model
import com.tangem.common.routing.AppRoute
import com.tangem.core.decompose.di.ComponentScoped
import com.tangem.core.decompose.di.ModelScoped
import com.tangem.core.decompose.model.Model
import com.tangem.core.decompose.model.ParamsContainer
import com.tangem.core.decompose.navigation.Router
@ -17,7 +17,7 @@ import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.launch
import javax.inject.Inject
@ComponentScoped
@ModelScoped
@Suppress("LongParameterList")
internal class DisclaimerModel @Inject constructor(
override val dispatchers: CoroutineDispatcherProvider,

View file

@ -4,9 +4,9 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import com.arkivanov.decompose.ComponentContext
import com.arkivanov.decompose.extensions.compose.jetpack.stack.Children
import com.arkivanov.decompose.extensions.compose.jetpack.stack.animation.stackAnimation
import com.arkivanov.decompose.extensions.compose.jetpack.subscribeAsState
import com.arkivanov.decompose.extensions.compose.stack.Children
import com.arkivanov.decompose.extensions.compose.stack.animation.stackAnimation
import com.arkivanov.decompose.extensions.compose.subscribeAsState
import com.arkivanov.decompose.router.stack.*
import com.tangem.core.analytics.api.AnalyticsEventHandler
import com.tangem.core.decompose.context.AppComponentContext

View file

@ -5,7 +5,7 @@ import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.arkivanov.decompose.ComponentContext
import com.arkivanov.decompose.extensions.compose.jetpack.subscribeAsState
import com.arkivanov.decompose.extensions.compose.subscribeAsState
import com.arkivanov.decompose.router.slot.childSlot
import com.arkivanov.decompose.router.slot.dismiss
import com.tangem.core.decompose.context.AppComponentContext

View file

@ -6,7 +6,7 @@ import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.arkivanov.decompose.ComponentContext
import com.arkivanov.decompose.extensions.compose.jetpack.subscribeAsState
import com.arkivanov.decompose.extensions.compose.subscribeAsState
import com.arkivanov.decompose.router.slot.childSlot
import com.arkivanov.decompose.router.slot.dismiss
import com.tangem.core.decompose.context.AppComponentContext

View file

@ -1,6 +1,6 @@
package com.tangem.features.managetokens.di
import com.tangem.core.decompose.di.DecomposeComponent
import com.tangem.core.decompose.di.ModelComponent
import com.tangem.core.decompose.model.Model
import com.tangem.features.managetokens.model.CustomTokenFormModel
import com.tangem.features.managetokens.model.CustomTokenSelectorModel
@ -13,7 +13,7 @@ import dagger.multibindings.ClassKey
import dagger.multibindings.IntoMap
@Module
@InstallIn(DecomposeComponent::class)
@InstallIn(ModelComponent::class)
internal interface ModelModule {
@Binds

View file

@ -2,7 +2,7 @@ package com.tangem.features.managetokens.model
import arrow.core.getOrElse
import com.tangem.core.analytics.api.AnalyticsEventHandler
import com.tangem.core.decompose.di.ComponentScoped
import com.tangem.core.decompose.di.ModelScoped
import com.tangem.core.decompose.model.Model
import com.tangem.core.decompose.model.ParamsContainer
import com.tangem.core.decompose.ui.UiMessageSender
@ -37,7 +37,7 @@ import javax.inject.Inject
// TODO: Divide to sub-components: [REDACTED_JIRA]
@Suppress("LongParameterList", "LargeClass")
@ComponentScoped
@ModelScoped
internal class CustomTokenFormModel @Inject constructor(
override val dispatchers: CoroutineDispatcherProvider,
private val customCurrencyValidator: CustomCurrencyValidator,

View file

@ -3,7 +3,7 @@ package com.tangem.features.managetokens.model
import arrow.core.getOrElse
import com.arkivanov.decompose.router.slot.SlotNavigation
import com.arkivanov.decompose.router.slot.activate
import com.tangem.core.decompose.di.ComponentScoped
import com.tangem.core.decompose.di.ModelScoped
import com.tangem.core.decompose.model.Model
import com.tangem.core.decompose.model.ParamsContainer
import com.tangem.core.decompose.ui.UiMessageSender
@ -33,7 +33,7 @@ import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import javax.inject.Inject
@ComponentScoped
@ModelScoped
internal class CustomTokenSelectorModel @Inject constructor(
override val dispatchers: CoroutineDispatcherProvider,
private val getSupportedNetworksUseCase: GetSupportedNetworksUseCase,

View file

@ -5,7 +5,7 @@ import arrow.core.getOrElse
import com.arkivanov.decompose.router.slot.SlotNavigation
import com.arkivanov.decompose.router.slot.activate
import com.tangem.core.analytics.api.AnalyticsEventHandler
import com.tangem.core.decompose.di.ComponentScoped
import com.tangem.core.decompose.di.ModelScoped
import com.tangem.core.decompose.model.Model
import com.tangem.core.decompose.model.ParamsContainer
import com.tangem.core.decompose.navigation.Router
@ -42,7 +42,7 @@ import timber.log.Timber
import javax.inject.Inject
@Suppress("LongParameterList")
@ComponentScoped
@ModelScoped
internal class ManageTokensModel @Inject constructor(
override val dispatchers: CoroutineDispatcherProvider,
private val router: Router,

View file

@ -3,7 +3,7 @@ package com.tangem.features.managetokens.model
import arrow.core.flatten
import arrow.core.getOrElse
import com.tangem.core.analytics.api.AnalyticsEventHandler
import com.tangem.core.decompose.di.ComponentScoped
import com.tangem.core.decompose.di.ModelScoped
import com.tangem.core.decompose.model.Model
import com.tangem.core.decompose.model.ParamsContainer
import com.tangem.core.decompose.ui.UiMessageSender
@ -37,7 +37,7 @@ import timber.log.Timber
import javax.inject.Inject
@Suppress("LongParameterList")
@ComponentScoped
@ModelScoped
internal class OnboardingManageTokensModel @Inject constructor(
override val dispatchers: CoroutineDispatcherProvider,
private val manageTokensListManager: ManageTokensListManager,

View file

@ -3,7 +3,7 @@ package com.tangem.features.managetokens.utils
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.ui.text.input.KeyboardCapitalization
import androidx.compose.ui.text.input.KeyboardType
import com.tangem.core.decompose.di.ComponentScoped
import com.tangem.core.decompose.di.ModelScoped
import com.tangem.core.decompose.model.ParamsContainer
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.extensions.stringReference
@ -15,7 +15,7 @@ import com.tangem.features.managetokens.impl.R
import kotlinx.collections.immutable.persistentMapOf
import javax.inject.Inject
@ComponentScoped
@ModelScoped
internal class CustomCurrencyFormBuilder @Inject constructor(
paramsContainer: ParamsContainer,
) {

View file

@ -1,7 +1,7 @@
package com.tangem.features.managetokens.utils
import arrow.core.getOrElse
import com.tangem.core.decompose.di.ComponentScoped
import com.tangem.core.decompose.di.ModelScoped
import com.tangem.domain.managetokens.CheckIsCurrencyNotAddedUseCase
import com.tangem.domain.managetokens.CreateCurrencyUseCase
import com.tangem.domain.managetokens.FindTokenUseCase
@ -20,7 +20,7 @@ import kotlinx.coroutines.launch
import timber.log.Timber
import javax.inject.Inject
@ComponentScoped
@ModelScoped
internal class CustomCurrencyValidator @Inject constructor(
private val validateTokenFormUseCase: ValidateTokenFormUseCase,
private val createCustomCurrencyUseCase: CreateCurrencyUseCase,

View file

@ -4,7 +4,7 @@ import androidx.compose.ui.util.fastForEachIndexed
import androidx.compose.ui.util.fastMap
import arrow.core.getOrElse
import com.tangem.core.analytics.api.AnalyticsEventHandler
import com.tangem.core.decompose.di.ComponentScoped
import com.tangem.core.decompose.di.ModelScoped
import com.tangem.core.decompose.ui.UiMessageSender
import com.tangem.core.ui.clipboard.ClipboardManager
import com.tangem.core.ui.extensions.resourceReference
@ -40,7 +40,7 @@ import timber.log.Timber
import javax.inject.Inject
@Suppress("LongParameterList")
@ComponentScoped
@ModelScoped
internal class ManageTokensListManager @Inject constructor(
private val getManagedTokensUseCase: GetManagedTokensUseCase,
private val checkHasLinkedTokensUseCase: CheckHasLinkedTokensUseCase,

View file

@ -1,6 +1,6 @@
package com.tangem.features.markets.details.impl.di
import com.tangem.core.decompose.di.DecomposeComponent
import com.tangem.core.decompose.di.ModelComponent
import com.tangem.core.decompose.model.Model
import com.tangem.features.markets.details.impl.model.MarketsTokenDetailsModel
import dagger.Binds
@ -10,7 +10,7 @@ import dagger.multibindings.ClassKey
import dagger.multibindings.IntoMap
@Module
@InstallIn(DecomposeComponent::class)
@InstallIn(ModelComponent::class)
internal interface ModelModule {
@Binds

View file

@ -8,7 +8,7 @@ import com.tangem.common.ui.charts.state.MarketChartData
import com.tangem.common.ui.charts.state.MarketChartDataProducer
import com.tangem.common.ui.charts.state.sorted
import com.tangem.core.analytics.api.AnalyticsEventHandler
import com.tangem.core.decompose.di.ComponentScoped
import com.tangem.core.decompose.di.ModelScoped
import com.tangem.core.decompose.model.Model
import com.tangem.core.decompose.model.ParamsContainer
import com.tangem.core.navigation.url.UrlOpener
@ -53,7 +53,7 @@ import javax.inject.Inject
@Suppress("LargeClass", "LongParameterList")
@Stable
@ComponentScoped
@ModelScoped
internal class MarketsTokenDetailsModel @Inject constructor(
paramsContainer: ParamsContainer,
override val dispatchers: CoroutineDispatcherProvider,

View file

@ -6,7 +6,7 @@ import androidx.compose.runtime.State
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.Dp
import com.arkivanov.decompose.ExperimentalDecomposeApi
import com.arkivanov.decompose.extensions.compose.jetpack.subscribeAsState
import com.arkivanov.decompose.extensions.compose.subscribeAsState
import com.arkivanov.decompose.router.stack.ChildStack
import com.arkivanov.decompose.router.stack.StackNavigation
import com.arkivanov.decompose.router.stack.childStack

View file

@ -11,9 +11,9 @@ import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.Dp
import com.arkivanov.decompose.extensions.compose.jetpack.stack.Children
import com.arkivanov.decompose.extensions.compose.jetpack.stack.animation.slide
import com.arkivanov.decompose.extensions.compose.jetpack.stack.animation.stackAnimation
import com.arkivanov.decompose.extensions.compose.stack.Children
import com.arkivanov.decompose.extensions.compose.stack.animation.slide
import com.arkivanov.decompose.extensions.compose.stack.animation.stackAnimation
import com.arkivanov.decompose.router.stack.ChildStack
import com.tangem.core.ui.res.LocalMainBottomSheetColor
import com.tangem.core.ui.res.TangemTheme

View file

@ -1,6 +1,6 @@
package com.tangem.features.markets.portfolio.impl.di
import com.tangem.core.decompose.di.DecomposeComponent
import com.tangem.core.decompose.di.ModelComponent
import com.tangem.core.decompose.model.Model
import com.tangem.features.markets.portfolio.impl.model.MarketsPortfolioModel
import dagger.Binds
@ -10,7 +10,7 @@ import dagger.multibindings.ClassKey
import dagger.multibindings.IntoMap
@Module
@InstallIn(DecomposeComponent::class)
@InstallIn(ModelComponent::class)
internal interface ModelModule {
@Binds

View file

@ -3,7 +3,7 @@ package com.tangem.features.markets.portfolio.impl.model
import androidx.compose.runtime.Stable
import arrow.core.getOrElse
import com.tangem.core.analytics.api.AnalyticsEventHandler
import com.tangem.core.decompose.di.ComponentScoped
import com.tangem.core.decompose.di.ModelScoped
import com.tangem.core.decompose.model.Model
import com.tangem.core.decompose.model.ParamsContainer
import com.tangem.core.decompose.ui.UiMessageSender
@ -38,7 +38,7 @@ import javax.inject.Inject
@Suppress("LongParameterList")
@Stable
@ComponentScoped
@ModelScoped
internal class MarketsPortfolioModel @Inject constructor(
paramsContainer: ParamsContainer,
getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase,

View file

@ -2,7 +2,6 @@ package com.tangem.features.markets.portfolio.impl.model
import com.tangem.common.routing.AppRoute
import com.tangem.core.analytics.models.AnalyticsParam
import com.tangem.core.decompose.di.ComponentScoped
import com.tangem.core.decompose.navigation.Router
import com.tangem.core.decompose.ui.UiMessageSender
import com.tangem.core.ui.clipboard.ClipboardManager
@ -31,7 +30,6 @@ import dagger.assisted.AssistedInject
import kotlinx.collections.immutable.toImmutableList
@Suppress("LongParameterList")
@ComponentScoped
internal class TokenActionsHandler @AssistedInject constructor(
private val router: Router,
private val clipboardManager: ClipboardManager,

View file

@ -1,6 +1,6 @@
package com.tangem.features.markets.token.block.impl.di
import com.tangem.core.decompose.di.DecomposeComponent
import com.tangem.core.decompose.di.ModelComponent
import com.tangem.core.decompose.model.Model
import com.tangem.features.markets.token.block.impl.model.TokenMarketBlockModel
import dagger.Binds
@ -10,7 +10,7 @@ import dagger.multibindings.ClassKey
import dagger.multibindings.IntoMap
@Module
@InstallIn(DecomposeComponent::class)
@InstallIn(ModelComponent::class)
internal interface ModelModule {
@Binds

View file

@ -6,7 +6,7 @@ import com.tangem.common.routing.AppRoute
import com.tangem.common.ui.charts.state.MarketChartData
import com.tangem.common.ui.charts.state.converter.PriceAndTimePointValuesConverter
import com.tangem.common.ui.charts.state.sorted
import com.tangem.core.decompose.di.ComponentScoped
import com.tangem.core.decompose.di.ModelScoped
import com.tangem.core.decompose.model.Model
import com.tangem.core.decompose.model.ParamsContainer
import com.tangem.core.decompose.navigation.Router
@ -31,7 +31,7 @@ import kotlinx.coroutines.launch
import javax.inject.Inject
@Stable
@ComponentScoped
@ModelScoped
internal class TokenMarketBlockModel @Inject constructor(
paramsContainer: ParamsContainer,
override val dispatchers: CoroutineDispatcherProvider,

View file

@ -1,6 +1,6 @@
package com.tangem.features.markets.tokenlist.impl.di
import com.tangem.core.decompose.di.DecomposeComponent
import com.tangem.core.decompose.di.ModelComponent
import com.tangem.core.decompose.model.Model
import com.tangem.features.markets.tokenlist.impl.model.MarketsListModel
import dagger.Binds
@ -10,7 +10,7 @@ import dagger.multibindings.ClassKey
import dagger.multibindings.IntoMap
@Module
@InstallIn(DecomposeComponent::class)
@InstallIn(ModelComponent::class)
internal interface ModelModule {
@Binds

View file

@ -3,7 +3,7 @@ package com.tangem.features.markets.tokenlist.impl.model
import androidx.compose.runtime.Stable
import arrow.core.getOrElse
import com.tangem.core.analytics.api.AnalyticsEventHandler
import com.tangem.core.decompose.di.ComponentScoped
import com.tangem.core.decompose.di.ModelScoped
import com.tangem.core.decompose.model.Model
import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
import com.tangem.domain.appcurrency.model.AppCurrency
@ -29,7 +29,7 @@ private const val UPDATE_QUOTES_TIMER_MILLIS = 60000L
private const val SEARCH_QUERY_DEBOUNCE_MILLIS = 800L
@OptIn(FlowPreview::class, ExperimentalCoroutinesApi::class)
@ComponentScoped
@ModelScoped
@Stable
internal class MarketsListModel @Inject constructor(
override val dispatchers: CoroutineDispatcherProvider,

View file

@ -0,0 +1,22 @@
plugins {
alias(deps.plugins.android.library)
alias(deps.plugins.kotlin.android)
id("configuration")
}
android {
namespace = "com.tangem.features.nft.api"
}
dependencies {
/* Project - Domain */
implementation(projects.domain.models)
/* Project - Core */
implementation(projects.core.decompose)
implementation(projects.core.ui)
/* Compose */
implementation(deps.compose.runtime)
}

View file

@ -0,0 +1,5 @@
package com.tangem.features.nft
interface NFTFeatureToggles {
val isNFTEnabled: Boolean
}

1
features/nft/impl/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
/build

View file

@ -0,0 +1,66 @@
plugins {
alias(deps.plugins.android.library)
alias(deps.plugins.kotlin.android)
alias(deps.plugins.kotlin.kapt)
alias(deps.plugins.kotlin.serialization)
alias(deps.plugins.hilt.android)
id("configuration")
}
android {
namespace = "com.tangem.features.nft.impl"
}
dependencies {
/** Api */
implementation(projects.features.nft.api)
/** Core modules */
implementation(projects.core.configToggles)
implementation(projects.core.analytics)
implementation(projects.core.analytics.models)
implementation(projects.core.utils)
implementation(projects.core.ui)
implementation(projects.core.res)
implementation(projects.core.decompose)
implementation(projects.core.navigation)
implementation(projects.core.datasource)
/** Common */
implementation(projects.common.ui)
implementation(projects.common.routing)
/** Tangem libraries */
implementation(projects.libs.tangemSdkApi)
implementation(deps.tangem.card.core)
implementation(deps.tangem.card.android) {
exclude(module = "joda-time")
}
/** AndroidX libraries */
implementation(deps.androidx.core.ktx)
implementation(deps.lifecycle.runtime.ktx)
/** Compose libraries */
implementation(deps.compose.material) // to use buttons and text field in MultiWalletSeedPhraseImport.kt
implementation(deps.compose.material3)
implementation(deps.compose.animation)
implementation(deps.compose.foundation)
implementation(deps.compose.ui)
implementation(deps.compose.ui.tooling)
implementation(deps.compose.coil)
implementation(deps.lottie.compose)
implementation(deps.decompose.ext.compose)
implementation(deps.androidx.activity.compose)
implementation(deps.androidx.datastore)
/** Other libraries */
implementation(deps.kotlin.immutable.collections)
implementation(deps.kotlin.serialization)
implementation(deps.timber)
implementation(deps.firebase.crashlytics)
/** DI */
implementation(deps.hilt.android)
kapt(deps.hilt.kapt)
}

View file

@ -0,0 +1,10 @@
package com.tangem.features.nft
import com.tangem.core.configtoggle.feature.FeatureTogglesManager
internal class DefaultNFTFeatureToggles(
private val featureTogglesManager: FeatureTogglesManager,
) : NFTFeatureToggles {
override val isNFTEnabled: Boolean
get() = featureTogglesManager.isFeatureEnabled(name = "NFT_ENABLED")
}

View file

@ -0,0 +1,19 @@
package com.tangem.features.nft
import com.tangem.core.configtoggle.feature.FeatureTogglesManager
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import javax.inject.Singleton
@Module
@InstallIn(SingletonComponent::class)
internal object NFTFeatureModule {
@Provides
@Singleton
fun provideFeatureToggles(featureTogglesManager: FeatureTogglesManager): NFTFeatureToggles {
return DefaultNFTFeatureToggles(featureTogglesManager)
}
}

View file

@ -4,9 +4,11 @@ import androidx.activity.compose.BackHandler
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import com.arkivanov.decompose.extensions.compose.jetpack.subscribeAsState
import com.arkivanov.decompose.extensions.compose.subscribeAsState
import com.arkivanov.decompose.router.stack.*
import com.arkivanov.decompose.value.ObserveLifecycleMode
import com.arkivanov.decompose.value.Value
import com.arkivanov.decompose.value.subscribe
import com.tangem.core.decompose.context.AppComponentContext
import com.tangem.core.decompose.context.child
import com.tangem.core.decompose.context.childByContext
@ -87,7 +89,10 @@ internal class DefaultOnboardingEntryComponent @AssistedInject constructor(
@Suppress("MagicNumber")
private fun linkToInnerNavigation() {
// stepper linking
innerStack.observe { stack ->
innerStack.subscribe(
lifecycle = lifecycle,
mode = ObserveLifecycleMode.CREATE_DESTROY,
) { stack ->
val activeChild = stack.active.instance
if (activeChild is InnerNavigationHolder) {
componentScope.launch {

View file

@ -1,6 +1,6 @@
package com.tangem.features.onboarding.v2.entry.impl.di
import com.tangem.core.decompose.di.DecomposeComponent
import com.tangem.core.decompose.di.ModelComponent
import com.tangem.core.decompose.model.Model
import com.tangem.features.onboarding.v2.entry.OnboardingEntryComponent
import com.tangem.features.onboarding.v2.entry.impl.DefaultOnboardingEntryComponent
@ -25,7 +25,7 @@ internal interface ComponentModule {
}
@Module
@InstallIn(DecomposeComponent::class)
@InstallIn(ModelComponent::class)
internal interface ModelModule {
@Binds
@IntoMap

View file

@ -3,12 +3,13 @@ package com.tangem.features.onboarding.v2.entry.impl.model
import com.arkivanov.decompose.router.stack.StackNavigation
import com.arkivanov.decompose.router.stack.navigate
import com.tangem.common.routing.AppRoute
import com.tangem.core.decompose.di.ComponentScoped
import com.tangem.core.decompose.di.ModelScoped
import com.tangem.core.decompose.model.Model
import com.tangem.core.decompose.model.ParamsContainer
import com.tangem.core.decompose.navigation.Router
import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.extensions.stringReference
import com.tangem.domain.common.util.cardTypesResolver
import com.tangem.domain.models.scan.ProductType
import com.tangem.domain.models.scan.ScanResponse
import com.tangem.domain.settings.repositories.SettingsRepository
@ -25,7 +26,7 @@ import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.launch
import javax.inject.Inject
@ComponentScoped
@ModelScoped
internal class OnboardingEntryModel @Inject constructor(
paramsContainer: ParamsContainer,
override val dispatchers: CoroutineDispatcherProvider,
@ -79,8 +80,14 @@ internal class OnboardingEntryModel @Inject constructor(
}
private fun onMultiWalletOnboardingDone(userWallet: UserWallet) {
stackNavigation.navigate {
listOf(OnboardingRoute.ManageTokens(userWallet))
if (userWallet.scanResponse.cardTypesResolver.isMultiwalletAllowed()) {
stackNavigation.navigate {
listOf(OnboardingRoute.ManageTokens(userWallet))
}
} else {
stackNavigation.navigate {
listOf(OnboardingRoute.Done(onDone = ::navigateToWalletScreen))
}
}
}

View file

@ -4,9 +4,9 @@ import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import com.arkivanov.decompose.extensions.compose.jetpack.stack.Children
import com.arkivanov.decompose.extensions.compose.jetpack.stack.animation.slide
import com.arkivanov.decompose.extensions.compose.jetpack.stack.animation.stackAnimation
import com.arkivanov.decompose.extensions.compose.stack.Children
import com.arkivanov.decompose.extensions.compose.stack.animation.slide
import com.arkivanov.decompose.extensions.compose.stack.animation.stackAnimation
import com.arkivanov.decompose.router.stack.ChildStack
import com.tangem.core.ui.decompose.ComposableContentComponent
import com.tangem.core.ui.res.TangemTheme

View file

@ -6,11 +6,11 @@ import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.arkivanov.decompose.FaultyDecomposeApi
import com.arkivanov.decompose.extensions.compose.jetpack.stack.Children
import com.arkivanov.decompose.extensions.compose.jetpack.stack.animation.fade
import com.arkivanov.decompose.extensions.compose.jetpack.stack.animation.slide
import com.arkivanov.decompose.extensions.compose.jetpack.stack.animation.stackAnimation
import com.arkivanov.decompose.extensions.compose.jetpack.subscribeAsState
import com.arkivanov.decompose.extensions.compose.stack.Children
import com.arkivanov.decompose.extensions.compose.stack.animation.fade
import com.arkivanov.decompose.extensions.compose.stack.animation.slide
import com.arkivanov.decompose.extensions.compose.stack.animation.stackAnimation
import com.arkivanov.decompose.extensions.compose.subscribeAsState
import com.arkivanov.decompose.router.slot.SlotNavigation
import com.arkivanov.decompose.router.slot.childSlot
import com.arkivanov.decompose.router.slot.dismiss
@ -81,6 +81,8 @@ internal class DefaultOnboardingMultiWalletComponent @AssistedInject constructor
backups = model.backups,
)
val backButtonClickFlow = MutableSharedFlow<Unit>()
private val childStack: Value<ChildStack<OnboardingMultiWalletState.Step, ComposableContentComponent>> =
childStack(
key = "innerStack",
@ -96,8 +98,6 @@ internal class DefaultOnboardingMultiWalletComponent @AssistedInject constructor
},
)
val backButtonClickFlow = MutableSharedFlow<Unit>()
override val innerNavigation: InnerNavigation = object : InnerNavigation {
override val state = innerNavigationStateFlow
@ -117,7 +117,7 @@ internal class DefaultOnboardingMultiWalletComponent @AssistedInject constructor
source = bottomSheetNavigation,
serializer = null,
handleBackButton = false,
childFactory = { configuration, componentContext ->
childFactory = { _, componentContext ->
MultiWalletAccessCodeComponent(
context = childByContext(componentContext),
params = childParams,

View file

@ -3,7 +3,7 @@ package com.tangem.features.onboarding.v2.multiwallet.impl.child.accesscode.mode
import androidx.compose.runtime.Stable
import androidx.compose.ui.text.input.TextFieldValue
import com.tangem.core.analytics.api.AnalyticsEventHandler
import com.tangem.core.decompose.di.ComponentScoped
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.onboarding.v2.multiwallet.impl.analytics.OnboardingEvent
@ -22,7 +22,7 @@ import javax.inject.Inject
private const val MINIMUM_ACCESS_CODE_LENGTH = 4
@Stable
@ComponentScoped
@ModelScoped
internal class MultiWalletAccessCodeModel @Inject constructor(
paramsContainer: ParamsContainer,
override val dispatchers: CoroutineDispatcherProvider,

View file

@ -7,7 +7,7 @@ import com.tangem.common.core.TangemSdkError
import com.tangem.core.analytics.api.AnalyticsEventHandler
import com.tangem.core.analytics.models.AnalyticsParam
import com.tangem.core.analytics.models.event.OnboardingAnalyticsEvent
import com.tangem.core.decompose.di.ComponentScoped
import com.tangem.core.decompose.di.ModelScoped
import com.tangem.core.decompose.model.Model
import com.tangem.core.decompose.model.ParamsContainer
import com.tangem.core.decompose.ui.UiMessageSender
@ -38,7 +38,7 @@ import kotlinx.coroutines.launch
import javax.inject.Inject
@Stable
@ComponentScoped
@ModelScoped
@Suppress("LongParameterList")
class MultiWalletBackupModel @Inject constructor(
paramsContainer: ParamsContainer,

View file

@ -2,7 +2,7 @@ package com.tangem.features.onboarding.v2.multiwallet.impl.child.chooseoption.mo
import androidx.compose.runtime.Stable
import com.tangem.core.analytics.api.AnalyticsEventHandler
import com.tangem.core.decompose.di.ComponentScoped
import com.tangem.core.decompose.di.ModelScoped
import com.tangem.core.decompose.model.Model
import com.tangem.core.decompose.model.ParamsContainer
import com.tangem.domain.card.repository.CardRepository
@ -21,7 +21,7 @@ import kotlinx.coroutines.launch
import javax.inject.Inject
@Stable
@ComponentScoped
@ModelScoped
internal class Wallet1ChooseOptionModel @Inject constructor(
override val dispatchers: CoroutineDispatcherProvider,
paramsContainer: ParamsContainer,

View file

@ -0,0 +1,29 @@
package com.tangem.features.onboarding.v2.multiwallet.impl.child.chooseoption.ui
import com.tangem.core.ui.extensions.TextReference
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.features.onboarding.v2.impl.R
internal val CarouselItems = listOf(
CarouselItem(
title = resourceReference(R.string.onboarding_wallet_info_title_first),
subtitle = resourceReference(R.string.onboarding_wallet_info_subtitle_first),
),
CarouselItem(
title = resourceReference(R.string.onboarding_wallet_info_title_second),
subtitle = resourceReference(R.string.onboarding_wallet_info_subtitle_second),
),
CarouselItem(
title = resourceReference(R.string.onboarding_wallet_info_title_third),
subtitle = resourceReference(R.string.onboarding_wallet_info_subtitle_third),
),
CarouselItem(
title = resourceReference(R.string.onboarding_wallet_info_title_fourth),
subtitle = resourceReference(R.string.onboarding_wallet_info_subtitle_fourth),
),
)
internal data class CarouselItem(
val title: TextReference,
val subtitle: TextReference,
)

View file

@ -1,10 +1,15 @@
package com.tangem.features.onboarding.v2.multiwallet.impl.child.chooseoption.ui
import androidx.compose.animation.animateColorAsState
import androidx.compose.foundation.Canvas
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.pager.HorizontalPager
import androidx.compose.foundation.pager.rememberPagerState
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.style.TextAlign
@ -12,6 +17,7 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.tangem.core.ui.components.PrimaryButton
import com.tangem.core.ui.components.SecondaryButton
import com.tangem.core.ui.extensions.resolveReference
import com.tangem.core.ui.extensions.stringResourceSafe
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview
@ -30,30 +36,44 @@ fun Wallet1ChooseOption(
.navigationBarsPadding(),
verticalArrangement = Arrangement.Bottom,
) {
// val pagerState = rememberPagerState(pageCount = { 10 }) // TODO [REDACTED_TASK_KEY]
Column(
Modifier
.fillMaxWidth()
.verticalScroll(rememberScrollState())
.padding(start = 32.dp, end = 32.dp, bottom = 16.dp)
.weight(1f),
.weight(1f)
.padding(top = 32.dp, bottom = 16.dp),
horizontalAlignment = Alignment.CenterHorizontally,
) {
Text(
text = stringResourceSafe(R.string.onboarding_wallet_info_title_first),
style = TangemTheme.typography.h2,
color = TangemTheme.colors.text.primary1,
textAlign = TextAlign.Center,
modifier = Modifier.padding(top = 16.dp),
)
val pagerState = rememberPagerState { CarouselItems.size }
Text(
text = stringResourceSafe(R.string.onboarding_wallet_info_subtitle_first),
style = TangemTheme.typography.body1,
color = TangemTheme.colors.text.secondary,
textAlign = TextAlign.Center,
modifier = Modifier.padding(top = 12.dp),
HorizontalPager(pagerState) { selectedIndex ->
Column(
modifier = Modifier
.padding(start = 32.dp, end = 32.dp, bottom = 16.dp),
horizontalAlignment = Alignment.CenterHorizontally,
) {
val item = CarouselItems[selectedIndex]
Text(
text = item.title.resolveReference(),
style = TangemTheme.typography.h2,
color = TangemTheme.colors.text.primary1,
textAlign = TextAlign.Center,
modifier = Modifier.padding(top = 16.dp),
)
Text(
text = item.subtitle.resolveReference(),
style = TangemTheme.typography.body1,
color = TangemTheme.colors.text.secondary,
textAlign = TextAlign.Center,
modifier = Modifier.padding(top = 12.dp),
)
}
}
Dots(
modifier = Modifier.align(Alignment.CenterHorizontally),
count = CarouselItems.size,
selectedIndex = pagerState.currentPage,
)
}
@ -77,6 +97,28 @@ fun Wallet1ChooseOption(
}
}
@Composable
private fun Dots(count: Int, selectedIndex: Int, modifier: Modifier = Modifier) {
val generalColor = TangemTheme.colors.icon.informative
val selectedColor = TangemTheme.colors.icon.primary1
Row(
modifier = modifier,
horizontalArrangement = Arrangement.spacedBy(8.dp),
) {
repeat(count) { index ->
val color by animateColorAsState(if (index == selectedIndex) selectedColor else generalColor)
Canvas(Modifier.size(7.dp)) {
drawCircle(
color = color,
radius = size.width / 2f,
)
}
}
}
}
@Preview(showBackground = true)
@Composable
private fun Preview() {

View file

@ -4,7 +4,7 @@ import androidx.compose.runtime.Stable
import com.tangem.common.CompletionResult
import com.tangem.common.core.TangemSdkError
import com.tangem.core.analytics.api.AnalyticsEventHandler
import com.tangem.core.decompose.di.ComponentScoped
import com.tangem.core.decompose.di.ModelScoped
import com.tangem.core.decompose.model.Model
import com.tangem.core.decompose.model.ParamsContainer
import com.tangem.core.ui.extensions.resourceReference
@ -34,7 +34,7 @@ import javax.inject.Inject
@Suppress("LongParameterList")
@Stable
@ComponentScoped
@ModelScoped
internal class MultiWalletCreateWalletModel @Inject constructor(
paramsContainer: ParamsContainer,
override val dispatchers: CoroutineDispatcherProvider,

View file

@ -3,7 +3,7 @@ package com.tangem.features.onboarding.v2.multiwallet.impl.child.finalize.model
import androidx.compose.runtime.Stable
import com.tangem.common.CompletionResult
import com.tangem.common.core.TangemSdkError
import com.tangem.core.decompose.di.ComponentScoped
import com.tangem.core.decompose.di.ModelScoped
import com.tangem.core.decompose.model.Model
import com.tangem.core.decompose.model.ParamsContainer
import com.tangem.domain.card.repository.CardRepository
@ -39,7 +39,7 @@ import javax.inject.Inject
@Suppress("LongParameterList")
@Stable
@ComponentScoped
@ModelScoped
internal class MultiWalletFinalizeModel @Inject constructor(
paramsContainer: ParamsContainer,
override val dispatchers: CoroutineDispatcherProvider,

View file

@ -2,7 +2,7 @@ package com.tangem.features.onboarding.v2.multiwallet.impl.child.scanprimary.mod
import androidx.compose.runtime.Stable
import com.tangem.common.CompletionResult
import com.tangem.core.decompose.di.ComponentScoped
import com.tangem.core.decompose.di.ModelScoped
import com.tangem.core.decompose.model.Model
import com.tangem.core.decompose.model.ParamsContainer
import com.tangem.domain.common.util.cardTypesResolver
@ -15,7 +15,7 @@ import kotlinx.coroutines.launch
import javax.inject.Inject
@Stable
@ComponentScoped
@ModelScoped
internal class Wallet1ScanPrimaryModel @Inject constructor(
paramsContainer: ParamsContainer,
override val dispatchers: CoroutineDispatcherProvider,

View file

@ -4,7 +4,7 @@ import androidx.compose.runtime.Stable
import com.tangem.common.CompletionResult
import com.tangem.common.core.TangemSdkError
import com.tangem.core.analytics.api.AnalyticsEventHandler
import com.tangem.core.decompose.di.ComponentScoped
import com.tangem.core.decompose.di.ModelScoped
import com.tangem.core.decompose.model.Model
import com.tangem.core.decompose.model.ParamsContainer
import com.tangem.core.navigation.url.UrlOpener
@ -35,7 +35,7 @@ import javax.inject.Inject
// =============================================
@Suppress("LongParameterList")
@Stable
@ComponentScoped
@ModelScoped
internal class MultiWalletSeedPhraseModel @Inject constructor(
paramsContainer: ParamsContainer,
override val dispatchers: CoroutineDispatcherProvider,

View file

@ -7,7 +7,7 @@ import androidx.compose.foundation.lazy.LazyRow
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.OutlinedTextField
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
@ -137,7 +137,6 @@ private fun PhraseBlock(state: MultiWalletSeedPhraseUM.Import, modifier: Modifie
Column(
modifier = modifier.fillMaxWidth(),
) {
// TODO migrate to material3
OutlinedTextField(
modifier = Modifier
.fillMaxWidth()

View file

@ -84,8 +84,8 @@ private fun SegmentSeedBlock(state: MultiWalletSeedPhraseUM.GenerateSeedPhrase,
Text(
text = pluralStringResourceSafe(
id = R.plurals.onboarding_seed_generate_words_count,
count = state.option.length,
state.option.length,
count = it.length,
it.length,
),
modifier = Modifier
.padding(vertical = TangemTheme.dimens.spacing10)

View file

@ -1,6 +1,6 @@
package com.tangem.features.onboarding.v2.multiwallet.impl.di
import com.tangem.core.decompose.di.DecomposeComponent
import com.tangem.core.decompose.di.ModelComponent
import com.tangem.core.decompose.model.Model
import com.tangem.features.onboarding.v2.multiwallet.api.OnboardingMultiWalletComponent
import com.tangem.features.onboarding.v2.multiwallet.impl.DefaultOnboardingMultiWalletComponent
@ -30,7 +30,7 @@ internal interface ComponentModule {
}
@Module
@InstallIn(DecomposeComponent::class)
@InstallIn(ModelComponent::class)
internal interface ModelModule {
@Binds

View file

@ -1,13 +1,14 @@
package com.tangem.features.onboarding.v2.multiwallet.impl.model
import com.tangem.core.analytics.api.AnalyticsEventHandler
import com.tangem.core.decompose.di.ComponentScoped
import com.tangem.core.decompose.di.ModelScoped
import com.tangem.core.decompose.model.Model
import com.tangem.core.decompose.model.ParamsContainer
import com.tangem.core.decompose.navigation.Router
import com.tangem.datasource.local.preferences.AppPreferencesStore
import com.tangem.datasource.local.preferences.PreferencesKeys
import com.tangem.domain.models.scan.CardDTO
import com.tangem.domain.models.scan.ProductType
import com.tangem.domain.wallets.usecase.GetCardImageUseCase
import com.tangem.features.onboarding.v2.multiwallet.api.OnboardingMultiWalletComponent
import com.tangem.features.onboarding.v2.multiwallet.impl.analytics.OnboardingEvent
@ -22,7 +23,7 @@ import kotlinx.coroutines.flow.*
import kotlinx.coroutines.launch
import javax.inject.Inject
@ComponentScoped
@ModelScoped
internal class OnboardingMultiWalletModel @Inject constructor(
paramsContainer: ParamsContainer,
override val dispatchers: CoroutineDispatcherProvider,
@ -116,8 +117,13 @@ internal class OnboardingMultiWalletModel @Inject constructor(
card.wallets.isNotEmpty() && card.backupStatus == CardDTO.BackupStatus.NoBackup &&
scanResponse.primaryCard == null -> OnboardingMultiWalletState.Step.ScanPrimary
card.wallets.isNotEmpty() && card.backupStatus == CardDTO.BackupStatus.NoBackup ->
OnboardingMultiWalletState.Step.AddBackupDevice
card.wallets.isNotEmpty() && card.backupStatus == CardDTO.BackupStatus.NoBackup -> {
if (scanResponse.productType == ProductType.Wallet) {
OnboardingMultiWalletState.Step.ChooseBackupOption
} else {
OnboardingMultiWalletState.Step.AddBackupDevice
}
}
card.wallets.isNotEmpty() && card.backupStatus?.isActive == true ->
OnboardingMultiWalletState.Step.Finalize
else ->

View file

@ -5,13 +5,13 @@ import com.tangem.core.ui.extensions.resourceReference
import com.tangem.features.onboarding.v2.impl.R
fun screenTitleByStep(step: OnboardingMultiWalletState.Step): TextReference = when (step) {
OnboardingMultiWalletState.Step.CreateWallet ->
resourceReference(R.string.onboarding_create_wallet_header)
OnboardingMultiWalletState.Step.SeedPhrase,
OnboardingMultiWalletState.Step.CreateWallet,
-> resourceReference(R.string.onboarding_create_wallet_header)
OnboardingMultiWalletState.Step.ScanPrimary,
OnboardingMultiWalletState.Step.AddBackupDevice,
->
resourceReference(R.string.onboarding_navbar_title_creating_backup)
OnboardingMultiWalletState.Step.Finalize ->
resourceReference(R.string.onboarding_button_finalize_backup)
else -> error("No title for the step")
-> resourceReference(R.string.onboarding_navbar_title_creating_backup)
OnboardingMultiWalletState.Step.ChooseBackupOption -> resourceReference(R.string.onboarding_getting_started)
OnboardingMultiWalletState.Step.Finalize -> resourceReference(R.string.onboarding_button_finalize_backup)
OnboardingMultiWalletState.Step.Done -> resourceReference(R.string.common_done)
}

View file

@ -51,13 +51,13 @@ internal fun OnboardingMultiWallet(
modifier = Modifier
.padding(horizontal = 34.dp)
.padding(top = 20.dp)
.weight(.4f)
.weight(.48f)
.fillMaxWidth(),
state = artworksState,
)
Box(
modifier = Modifier.weight(.44f),
modifier = Modifier.weight(.52f),
contentAlignment = Alignment.BottomStart,
) {
childContent(Modifier)

View file

@ -2,10 +2,12 @@
package com.tangem.features.onboarding.v2.multiwallet.impl.ui
import android.content.res.Configuration
import androidx.compose.animation.core.Transition
import androidx.compose.animation.core.animateFloat
import androidx.compose.animation.core.updateTransition
import androidx.compose.foundation.Canvas
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.material3.Button
import androidx.compose.material3.Text
@ -13,6 +15,7 @@ import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.res.painterResource
@ -106,7 +109,7 @@ fun WalletArtworks(
}
}
val circleColor = TangemTheme.colors.background.secondary
val circleColor = TangemTheme.colors.button.secondary
Canvas(
modifier = Modifier
@ -252,6 +255,7 @@ private fun WalletCard(url: String?, modifier: Modifier = Modifier) {
placeholder = painterResource(R.drawable.card_placeholder_black),
error = painterResource(R.drawable.card_placeholder_black),
fallback = painterResource(R.drawable.card_placeholder_black),
contentScale = ContentScale.Fit,
contentDescription = null,
)
}
@ -261,16 +265,16 @@ private fun WalletArtworksState.toTransitionSetState(maxWidthDp: Float, maxHeigh
WalletArtworksState.Hidden -> listOf()
is WalletArtworksState.Folded -> listOf(
CardsTransitionState(
WalletCardTransitionState(),
WalletCardTransitionState(),
WalletCardTransitionState(),
WalletCardTransitionState(alpha = 1f),
WalletCardTransitionState(alpha = 0f),
WalletCardTransitionState(alpha = 0f),
),
)
is WalletArtworksState.Stack -> listOf(
CardsTransitionState(
walletCard1 = WalletCardTransitionState(),
walletCard2 = WalletCardTransitionState(),
walletCard3 = WalletCardTransitionState(),
WalletCardTransitionState(alpha = 1f),
WalletCardTransitionState(alpha = 0f),
WalletCardTransitionState(alpha = 0f),
),
CardsTransitionState(
walletCard1 = WalletCardTransitionState().copy(
@ -451,11 +455,14 @@ private fun WalletArtworksState.toTransitionSetState(maxWidthDp: Float, maxHeigh
}
@Preview(showBackground = true, widthDp = 360, heightDp = 640)
@Preview(showBackground = true, widthDp = 360, heightDp = 640, uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
private fun Preview() {
TangemThemePreview {
Box(
modifier = Modifier.fillMaxSize(),
modifier = Modifier
.background(TangemTheme.colors.background.primary)
.fillMaxSize(),
contentAlignment = Alignment.Center,
) {
var state: WalletArtworksState by remember { mutableStateOf(WalletArtworksState.Folded) }

View file

@ -3,13 +3,13 @@ package com.tangem.features.onboarding.v2.visa.impl
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import com.arkivanov.decompose.extensions.compose.jetpack.stack.Children
import com.arkivanov.decompose.extensions.compose.jetpack.stack.animation.slide
import com.arkivanov.decompose.extensions.compose.jetpack.stack.animation.stackAnimation
import com.arkivanov.decompose.extensions.compose.jetpack.subscribeAsState
import com.arkivanov.decompose.extensions.compose.stack.Children
import com.arkivanov.decompose.extensions.compose.stack.animation.slide
import com.arkivanov.decompose.extensions.compose.stack.animation.stackAnimation
import com.arkivanov.decompose.extensions.compose.subscribeAsState
import com.arkivanov.decompose.router.stack.*
import com.arkivanov.decompose.value.Value
import com.arkivanov.decompose.value.observe
import com.arkivanov.decompose.value.subscribe
import com.arkivanov.essenty.instancekeeper.getOrCreateSimple
import com.tangem.core.decompose.context.AppComponentContext
import com.tangem.core.decompose.context.childByContext
@ -85,7 +85,7 @@ internal class DefaultOnboardingVisaComponent @AssistedInject constructor(
}
// sets title and stepper value
childStack.observe(lifecycle) { stack ->
childStack.subscribe(lifecycle) { stack ->
val currentRoute = stack.active.configuration
params.titleProvider.changeTitle(currentRoute.screenTitle())
model.updateStepForNewRoute(currentRoute)

View file

@ -4,7 +4,7 @@ import androidx.compose.runtime.Stable
import androidx.compose.ui.text.input.TextFieldValue
import com.tangem.common.CompletionResult
import com.tangem.common.extensions.toHexString
import com.tangem.core.decompose.di.ComponentScoped
import com.tangem.core.decompose.di.ModelScoped
import com.tangem.core.decompose.model.Model
import com.tangem.core.decompose.model.ParamsContainer
import com.tangem.domain.visa.model.VisaCardActivationStatus
@ -26,7 +26,7 @@ import kotlinx.coroutines.launch
import javax.inject.Inject
@Stable
@ComponentScoped
@ModelScoped
internal class OnboardingVisaAccessCodeModel @Inject constructor(
paramsContainer: ParamsContainer,
visaActivationRepositoryFactory: VisaActivationRepository.Factory,

View file

@ -3,7 +3,7 @@ package com.tangem.features.onboarding.v2.visa.impl.child.approve.model
import androidx.compose.runtime.Stable
import com.tangem.common.CompletionResult
import com.tangem.common.extensions.toHexString
import com.tangem.core.decompose.di.ComponentScoped
import com.tangem.core.decompose.di.ModelScoped
import com.tangem.core.decompose.model.Model
import com.tangem.core.decompose.model.ParamsContainer
import com.tangem.domain.visa.model.VisaCardId
@ -21,7 +21,7 @@ import kotlinx.coroutines.launch
import javax.inject.Inject
@Stable
@ComponentScoped
@ModelScoped
internal class OnboardingVisaApproveModel @Inject constructor(
paramsContainer: ParamsContainer,
visaActivationRepositoryFactory: VisaActivationRepository.Factory,

View file

@ -1,7 +1,7 @@
package com.tangem.features.onboarding.v2.visa.impl.child.choosewallet.model
import androidx.compose.runtime.Stable
import com.tangem.core.decompose.di.ComponentScoped
import com.tangem.core.decompose.di.ModelScoped
import com.tangem.core.decompose.model.Model
import com.tangem.core.ui.extensions.TextReference
import com.tangem.features.onboarding.v2.impl.R
@ -18,7 +18,7 @@ import kotlinx.coroutines.launch
import javax.inject.Inject
@Stable
@ComponentScoped
@ModelScoped
internal class OnboardingVisaChooseWalletModel @Inject constructor(
override val dispatchers: CoroutineDispatcherProvider,
) : Model() {

View file

@ -2,7 +2,7 @@ package com.tangem.features.onboarding.v2.visa.impl.child.inprogress.model
import androidx.compose.runtime.Stable
import com.tangem.common.extensions.toHexString
import com.tangem.core.decompose.di.ComponentScoped
import com.tangem.core.decompose.di.ModelScoped
import com.tangem.core.decompose.model.Model
import com.tangem.core.decompose.model.ParamsContainer
import com.tangem.datasource.local.visa.VisaAuthTokenStorage
@ -27,7 +27,7 @@ import javax.inject.Inject
@Suppress("LongParameterList")
@Stable
@ComponentScoped
@ModelScoped
internal class OnboardingVisaInProgressModel @Inject constructor(
paramsContainer: ParamsContainer,
visaActivationRepositoryFactory: VisaActivationRepository.Factory,

View file

@ -2,7 +2,7 @@ package com.tangem.features.onboarding.v2.visa.impl.child.otherwallet.model
import androidx.compose.runtime.Stable
import com.tangem.common.extensions.toHexString
import com.tangem.core.decompose.di.ComponentScoped
import com.tangem.core.decompose.di.ModelScoped
import com.tangem.core.decompose.model.Model
import com.tangem.core.decompose.model.ParamsContainer
import com.tangem.core.navigation.share.ShareManager
@ -22,7 +22,7 @@ import kotlinx.coroutines.launch
import javax.inject.Inject
@Stable
@ComponentScoped
@ModelScoped
internal class OnboardingVisaOtherWalletModel @Inject constructor(
paramsContainer: ParamsContainer,
visaActivationRepositoryFactory: VisaActivationRepository.Factory,

View file

@ -2,7 +2,7 @@ package com.tangem.features.onboarding.v2.visa.impl.child.pincode.model
import androidx.compose.runtime.Stable
import com.tangem.common.extensions.toHexString
import com.tangem.core.decompose.di.ComponentScoped
import com.tangem.core.decompose.di.ModelScoped
import com.tangem.core.decompose.model.Model
import com.tangem.core.decompose.model.ParamsContainer
import com.tangem.datasource.local.visa.VisaAuthTokenStorage
@ -26,7 +26,7 @@ import kotlinx.coroutines.withContext
import javax.inject.Inject
@Stable
@ComponentScoped
@ModelScoped
@Suppress("LongParameterList")
internal class OnboardingVisaPinCodeModel @Inject constructor(
paramsContainer: ParamsContainer,

View file

@ -2,7 +2,7 @@ package com.tangem.features.onboarding.v2.visa.impl.child.welcome.model
import com.tangem.common.CompletionResult
import com.tangem.common.extensions.toHexString
import com.tangem.core.decompose.di.ComponentScoped
import com.tangem.core.decompose.di.ModelScoped
import com.tangem.core.decompose.model.Model
import com.tangem.core.decompose.model.ParamsContainer
import com.tangem.domain.visa.model.VisaCardId
@ -22,7 +22,7 @@ import kotlinx.coroutines.flow.update
import kotlinx.coroutines.launch
import javax.inject.Inject
@ComponentScoped
@ModelScoped
internal class OnboardingVisaWelcomeModel @Inject constructor(
paramsContainer: ParamsContainer,
override val dispatchers: CoroutineDispatcherProvider,

View file

@ -1,6 +1,6 @@
package com.tangem.features.onboarding.v2.visa.impl.di
import com.tangem.core.decompose.di.DecomposeComponent
import com.tangem.core.decompose.di.ModelComponent
import com.tangem.core.decompose.model.Model
import com.tangem.features.onboarding.v2.visa.api.OnboardingVisaComponent
import com.tangem.features.onboarding.v2.visa.impl.DefaultOnboardingVisaComponent
@ -30,7 +30,7 @@ internal interface ComponentModule {
}
@Module
@InstallIn(DecomposeComponent::class)
@InstallIn(ModelComponent::class)
internal interface ModelModule {
@Binds

View file

@ -6,7 +6,7 @@ import com.arkivanov.decompose.router.stack.StackNavigation
import com.arkivanov.decompose.router.stack.pop
import com.arkivanov.decompose.router.stack.push
import com.arkivanov.decompose.router.stack.pushNew
import com.tangem.core.decompose.di.ComponentScoped
import com.tangem.core.decompose.di.ModelScoped
import com.tangem.core.decompose.model.Model
import com.tangem.core.decompose.model.ParamsContainer
import com.tangem.domain.common.visa.VisaUtilities
@ -31,7 +31,7 @@ import kotlinx.coroutines.launch
import javax.inject.Inject
@Stable
@ComponentScoped
@ModelScoped
internal class OnboardingVisaModel @Inject constructor(
paramsContainer: ParamsContainer,
override val dispatchers: CoroutineDispatcherProvider,

View file

@ -6,8 +6,8 @@ import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.Icon
import androidx.compose.material.Text
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier

View file

@ -7,8 +7,8 @@ import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyRow
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.OutlinedTextField
import androidx.compose.material.Text
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember

View file

@ -5,8 +5,8 @@ import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.material.Icon
import androidx.compose.material.Text
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier

View file

@ -5,7 +5,7 @@ import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material.Text
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier

View file

@ -5,7 +5,7 @@ import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material.Text
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.style.TextAlign

View file

@ -5,7 +5,7 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.arkivanov.decompose.ComponentContext
import com.arkivanov.decompose.extensions.compose.jetpack.subscribeAsState
import com.arkivanov.decompose.extensions.compose.subscribeAsState
import com.arkivanov.decompose.router.slot.childSlot
import com.arkivanov.decompose.router.slot.dismiss
import com.tangem.core.decompose.context.AppComponentContext

View file

@ -1,6 +1,6 @@
package com.tangem.features.onramp.confirmresidency.di
import com.tangem.core.decompose.di.DecomposeComponent
import com.tangem.core.decompose.di.ModelComponent
import com.tangem.core.decompose.model.Model
import com.tangem.features.onramp.confirmresidency.model.ConfirmResidencyModel
import dagger.Binds
@ -10,7 +10,7 @@ import dagger.multibindings.ClassKey
import dagger.multibindings.IntoMap
@Module
@InstallIn(DecomposeComponent::class)
@InstallIn(ModelComponent::class)
internal interface OnrampConfirmResidencyModelModule {
@Binds
@IntoMap

View file

@ -3,7 +3,7 @@ package com.tangem.features.onramp.confirmresidency.model
import com.arkivanov.decompose.router.slot.SlotNavigation
import com.arkivanov.decompose.router.slot.activate
import com.tangem.core.analytics.api.AnalyticsEventHandler
import com.tangem.core.decompose.di.ComponentScoped
import com.tangem.core.decompose.di.ModelScoped
import com.tangem.core.decompose.model.Model
import com.tangem.core.decompose.model.ParamsContainer
import com.tangem.core.decompose.navigation.Router
@ -20,7 +20,7 @@ import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.launch
import javax.inject.Inject
@ComponentScoped
@ModelScoped
internal class ConfirmResidencyModel @Inject constructor(
override val dispatchers: CoroutineDispatcherProvider,
private val analyticsEventHandler: AnalyticsEventHandler,

View file

@ -5,7 +5,7 @@ import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.arkivanov.decompose.ComponentContext
import com.arkivanov.decompose.extensions.compose.jetpack.subscribeAsState
import com.arkivanov.decompose.extensions.compose.subscribeAsState
import com.arkivanov.decompose.router.slot.childSlot
import com.arkivanov.decompose.router.slot.dismiss
import com.tangem.core.decompose.context.AppComponentContext

View file

@ -1,6 +1,6 @@
package com.tangem.features.onramp.hottokens.di
import com.tangem.core.decompose.di.DecomposeComponent
import com.tangem.core.decompose.di.ModelComponent
import com.tangem.core.decompose.model.Model
import com.tangem.features.onramp.hottokens.model.HotCryptoModel
import dagger.Binds
@ -10,7 +10,7 @@ import dagger.multibindings.ClassKey
import dagger.multibindings.IntoMap
@Module
@InstallIn(DecomposeComponent::class)
@InstallIn(ModelComponent::class)
internal interface HotCryptoModelModule {
@Binds

View file

@ -4,7 +4,7 @@ import arrow.core.getOrElse
import com.arkivanov.decompose.router.slot.SlotNavigation
import com.arkivanov.decompose.router.slot.activate
import com.arkivanov.decompose.router.slot.dismiss
import com.tangem.core.decompose.di.ComponentScoped
import com.tangem.core.decompose.di.ModelScoped
import com.tangem.core.decompose.model.Model
import com.tangem.core.decompose.model.ParamsContainer
import com.tangem.core.ui.components.token.state.TokenItemState
@ -40,7 +40,7 @@ import javax.inject.Inject
*
[REDACTED_AUTHOR]
*/
@ComponentScoped
@ModelScoped
internal class HotCryptoModel @Inject constructor(
paramsContainer: ParamsContainer,
getHotCryptoUseCase: GetHotCryptoUseCase,

View file

@ -1,6 +1,6 @@
package com.tangem.features.onramp.hottokens.portfolio.di
import com.tangem.core.decompose.di.DecomposeComponent
import com.tangem.core.decompose.di.ModelComponent
import com.tangem.core.decompose.model.Model
import com.tangem.features.onramp.hottokens.portfolio.model.OnrampAddToPortfolioModel
import dagger.Binds
@ -10,7 +10,7 @@ import dagger.multibindings.ClassKey
import dagger.multibindings.IntoMap
@Module
@InstallIn(DecomposeComponent::class)
@InstallIn(ModelComponent::class)
internal interface OnrampAddToPortfolioModelModule {
@Binds

View file

@ -1,7 +1,7 @@
package com.tangem.features.onramp.hottokens.portfolio.model
import arrow.core.getOrElse
import com.tangem.core.decompose.di.ComponentScoped
import com.tangem.core.decompose.di.ModelScoped
import com.tangem.core.decompose.model.Model
import com.tangem.core.decompose.model.ParamsContainer
import com.tangem.domain.card.DerivePublicKeysUseCase
@ -29,7 +29,7 @@ import javax.inject.Inject
*
[REDACTED_AUTHOR]
*/
@ComponentScoped
@ModelScoped
internal class OnrampAddToPortfolioModel @Inject constructor(
paramsContainer: ParamsContainer,
override val dispatchers: CoroutineDispatcherProvider,

View file

@ -5,7 +5,7 @@ import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import com.arkivanov.decompose.ComponentContext
import com.arkivanov.decompose.extensions.compose.jetpack.subscribeAsState
import com.arkivanov.decompose.extensions.compose.subscribeAsState
import com.arkivanov.decompose.router.slot.childSlot
import com.arkivanov.decompose.router.slot.dismiss
import com.tangem.core.decompose.context.AppComponentContext

View file

@ -1,6 +1,6 @@
package com.tangem.features.onramp.main.di
import com.tangem.core.decompose.di.DecomposeComponent
import com.tangem.core.decompose.di.ModelComponent
import com.tangem.core.decompose.model.Model
import com.tangem.features.onramp.main.model.OnrampMainComponentModel
import dagger.Binds
@ -10,7 +10,7 @@ import dagger.multibindings.ClassKey
import dagger.multibindings.IntoMap
@Module
@InstallIn(DecomposeComponent::class)
@InstallIn(ModelComponent::class)
internal interface OnrampMainComponentModelModule {
@Binds

View file

@ -8,7 +8,7 @@ import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.arkivanov.decompose.ComponentContext
import com.arkivanov.decompose.extensions.compose.jetpack.subscribeAsState
import com.arkivanov.decompose.extensions.compose.subscribeAsState
import com.arkivanov.decompose.router.slot.childSlot
import com.arkivanov.decompose.router.slot.dismiss
import com.tangem.core.decompose.context.AppComponentContext

View file

@ -1,6 +1,6 @@
package com.tangem.features.onramp.providers.di
import com.tangem.core.decompose.di.DecomposeComponent
import com.tangem.core.decompose.di.ModelComponent
import com.tangem.core.decompose.model.Model
import com.tangem.features.onramp.providers.model.SelectProviderModel
import dagger.Binds
@ -10,7 +10,7 @@ import dagger.multibindings.ClassKey
import dagger.multibindings.IntoMap
@Module
@InstallIn(DecomposeComponent::class)
@InstallIn(ModelComponent::class)
internal interface SelectProviderModelModule {
@Binds

View file

@ -4,7 +4,7 @@ import com.arkivanov.decompose.router.slot.SlotNavigation
import com.arkivanov.decompose.router.slot.activate
import com.arkivanov.decompose.router.slot.dismiss
import com.tangem.core.analytics.api.AnalyticsEventHandler
import com.tangem.core.decompose.di.ComponentScoped
import com.tangem.core.decompose.di.ModelScoped
import com.tangem.core.decompose.model.Model
import com.tangem.core.decompose.model.ParamsContainer
import com.tangem.core.ui.extensions.resourceReference
@ -40,7 +40,7 @@ import java.math.BigDecimal
import javax.inject.Inject
@Suppress("LongParameterList")
@ComponentScoped
@ModelScoped
internal class SelectProviderModel @Inject constructor(
override val dispatchers: CoroutineDispatcherProvider,
private val analyticsEventHandler: AnalyticsEventHandler,

View file

@ -1,6 +1,6 @@
package com.tangem.features.onramp.redirect.di
import com.tangem.core.decompose.di.DecomposeComponent
import com.tangem.core.decompose.di.ModelComponent
import com.tangem.core.decompose.model.Model
import com.tangem.features.onramp.redirect.model.OnrampRedirectModel
import dagger.Binds
@ -10,7 +10,7 @@ import dagger.multibindings.ClassKey
import dagger.multibindings.IntoMap
@Module
@InstallIn(DecomposeComponent::class)
@InstallIn(ModelComponent::class)
internal interface OnrampRedirectModelModule {
@Binds

View file

@ -5,9 +5,9 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import com.arkivanov.decompose.ComponentContext
import com.arkivanov.decompose.extensions.compose.jetpack.stack.Children
import com.arkivanov.decompose.extensions.compose.jetpack.stack.animation.stackAnimation
import com.arkivanov.decompose.extensions.compose.jetpack.subscribeAsState
import com.arkivanov.decompose.extensions.compose.stack.Children
import com.arkivanov.decompose.extensions.compose.stack.animation.stackAnimation
import com.arkivanov.decompose.extensions.compose.subscribeAsState
import com.arkivanov.decompose.router.stack.StackNavigation
import com.arkivanov.decompose.router.stack.childStack
import com.arkivanov.decompose.router.stack.pop

View file

@ -1,6 +1,6 @@
package com.tangem.features.onramp.selectcountry.di
import com.tangem.core.decompose.di.DecomposeComponent
import com.tangem.core.decompose.di.ModelComponent
import com.tangem.core.decompose.model.Model
import com.tangem.features.onramp.selectcountry.model.OnrampSelectCountryModel
import dagger.Binds
@ -10,7 +10,7 @@ import dagger.multibindings.ClassKey
import dagger.multibindings.IntoMap
@Module
@InstallIn(DecomposeComponent::class)
@InstallIn(ModelComponent::class)
internal interface OnrampSelectCountryModelModule {
@Binds

View file

@ -1,7 +1,7 @@
package com.tangem.features.onramp.selectcountry.model
import com.tangem.core.analytics.api.AnalyticsEventHandler
import com.tangem.core.decompose.di.ComponentScoped
import com.tangem.core.decompose.di.ModelScoped
import com.tangem.core.decompose.model.Model
import com.tangem.core.decompose.model.ParamsContainer
import com.tangem.core.ui.components.fields.entity.SearchBarUM
@ -35,7 +35,7 @@ import kotlinx.coroutines.launch
import javax.inject.Inject
@Suppress("LongParameterList")
@ComponentScoped
@ModelScoped
internal class OnrampSelectCountryModel @Inject constructor(
override val dispatchers: CoroutineDispatcherProvider,
private val analyticsEventHandler: AnalyticsEventHandler,

View file

@ -1,6 +1,6 @@
package com.tangem.features.onramp.selectcurrency.di
import com.tangem.core.decompose.di.DecomposeComponent
import com.tangem.core.decompose.di.ModelComponent
import com.tangem.core.decompose.model.Model
import com.tangem.features.onramp.selectcurrency.model.OnrampSelectCurrencyModel
import dagger.Binds
@ -10,7 +10,7 @@ import dagger.multibindings.ClassKey
import dagger.multibindings.IntoMap
@Module
@InstallIn(DecomposeComponent::class)
@InstallIn(ModelComponent::class)
internal interface OnrampSelectCurrencyModelModule {
@Binds

View file

@ -1,7 +1,7 @@
package com.tangem.features.onramp.selectcurrency.model
import com.tangem.core.analytics.api.AnalyticsEventHandler
import com.tangem.core.decompose.di.ComponentScoped
import com.tangem.core.decompose.di.ModelScoped
import com.tangem.core.decompose.model.Model
import com.tangem.core.decompose.model.ParamsContainer
import com.tangem.core.ui.components.fields.entity.SearchBarUM
@ -35,7 +35,7 @@ import kotlinx.coroutines.launch
import javax.inject.Inject
@Suppress("LongParameterList")
@ComponentScoped
@ModelScoped
internal class OnrampSelectCurrencyModel @Inject constructor(
override val dispatchers: CoroutineDispatcherProvider,
private val analyticsEventHandler: AnalyticsEventHandler,

View file

@ -1,6 +1,6 @@
package com.tangem.features.onramp.selecttoken.di
import com.tangem.core.decompose.di.DecomposeComponent
import com.tangem.core.decompose.di.ModelComponent
import com.tangem.core.decompose.model.Model
import com.tangem.features.onramp.selecttoken.model.OnrampOperationModel
import dagger.Binds
@ -10,7 +10,7 @@ import dagger.multibindings.ClassKey
import dagger.multibindings.IntoMap
@Module
@InstallIn(DecomposeComponent::class)
@InstallIn(ModelComponent::class)
internal interface OnrampOperationModelModule {
@Binds

View file

@ -6,7 +6,7 @@ import com.tangem.common.ui.alerts.models.AlertDemoModeUM
import com.tangem.core.analytics.api.AnalyticsEventHandler
import com.tangem.core.analytics.models.AnalyticsParam
import com.tangem.core.analytics.models.event.MainScreenAnalyticsEvent
import com.tangem.core.decompose.di.ComponentScoped
import com.tangem.core.decompose.di.ModelScoped
import com.tangem.core.decompose.model.Model
import com.tangem.core.decompose.model.ParamsContainer
import com.tangem.core.decompose.ui.UiMessageSender
@ -33,7 +33,7 @@ import kotlinx.coroutines.launch
import javax.inject.Inject
@Suppress("LongParameterList")
@ComponentScoped
@ModelScoped
internal class OnrampOperationModel @Inject constructor(
paramsContainer: ParamsContainer,
getWalletsUseCase: GetWalletsUseCase,

View file

@ -6,7 +6,7 @@ import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.arkivanov.decompose.ComponentContext
import com.arkivanov.decompose.extensions.compose.jetpack.subscribeAsState
import com.arkivanov.decompose.extensions.compose.subscribeAsState
import com.arkivanov.decompose.router.slot.childSlot
import com.arkivanov.decompose.router.slot.dismiss
import com.tangem.core.decompose.context.AppComponentContext

View file

@ -1,6 +1,6 @@
package com.tangem.features.onramp.settings.di
import com.tangem.core.decompose.di.DecomposeComponent
import com.tangem.core.decompose.di.ModelComponent
import com.tangem.core.decompose.model.Model
import com.tangem.features.onramp.settings.model.OnrampSettingsModel
import dagger.Binds
@ -10,7 +10,7 @@ import dagger.multibindings.ClassKey
import dagger.multibindings.IntoMap
@Module
@InstallIn(DecomposeComponent::class)
@InstallIn(ModelComponent::class)
internal interface OnrampSettingsModelModule {
@Binds

View file

@ -4,7 +4,7 @@ import arrow.core.Either
import com.arkivanov.decompose.router.slot.SlotNavigation
import com.arkivanov.decompose.router.slot.activate
import com.tangem.core.analytics.api.AnalyticsEventHandler
import com.tangem.core.decompose.di.ComponentScoped
import com.tangem.core.decompose.di.ModelScoped
import com.tangem.core.decompose.model.Model
import com.tangem.core.decompose.model.ParamsContainer
import com.tangem.domain.onramp.GetOnrampCountryUseCase
@ -21,7 +21,7 @@ import kotlinx.collections.immutable.toImmutableList
import kotlinx.coroutines.flow.*
import javax.inject.Inject
@ComponentScoped
@ModelScoped
internal class OnrampSettingsModel @Inject constructor(
override val dispatchers: CoroutineDispatcherProvider,
private val analyticsEventHandler: AnalyticsEventHandler,

View file

@ -1,6 +1,6 @@
package com.tangem.features.onramp.success.di
import com.tangem.core.decompose.di.DecomposeComponent
import com.tangem.core.decompose.di.ModelComponent
import com.tangem.core.decompose.model.Model
import com.tangem.features.onramp.success.model.OnrampSuccessComponentModel
import dagger.Binds
@ -10,7 +10,7 @@ import dagger.multibindings.ClassKey
import dagger.multibindings.IntoMap
@Module
@InstallIn(DecomposeComponent::class)
@InstallIn(ModelComponent::class)
internal interface OnrampSuccessComponentModelModule {
@Binds
@IntoMap

Some files were not shown because too many files have changed in this diff Show more