Updated on 2026-08-14

This commit is contained in:
Tangem 2025-09-29 12:42:14 +04:00
parent 77de05d05d
commit c8070ec66e
16 changed files with 345 additions and 0 deletions

36
.idea/file.template.settings.xml generated Normal file
View file

@ -0,0 +1,36 @@
<application>
<component name="ExportableFileTemplateSettings">
<default_templates>
<template name="Decompose component.kt" file-name="${NAME}Component" reformat="true" live-template-enabled="false">
<template name="Decompose component.kt.child.0.kt" file-name="entity/${NAME}UM" reformat="true" live-template-enabled="false" />
<template name="Decompose component.kt.child.1.kt" file-name="ui/${NAME}Content" reformat="true" live-template-enabled="false" />
<template name="Decompose component.kt.child.2.kt" file-name="model/${NAME}Model" reformat="true" live-template-enabled="false" />
<template name="Decompose component.kt.child.3.kt" file-name="Default${NAME}Component" reformat="true" live-template-enabled="false" />
</template>
<template name="Decompose component.kt.child.0.kt" file-name="entity/${NAME}UM" reformat="true" live-template-enabled="false" />
<template name="Decompose component.kt.child.1.kt" file-name="ui/${NAME}Content" reformat="true" live-template-enabled="false" />
<template name="Decompose component.kt.child.2.kt" file-name="model/${NAME}Model" reformat="true" live-template-enabled="false" />
<template name="Decompose component.kt.child.3.kt" file-name="Default${NAME}Component" reformat="true" live-template-enabled="false" />
<template name="FeatureToggles.kt" file-name="${NAME}FeatureToggles" reformat="true" live-template-enabled="false">
<template name="FeatureToggles.kt.child.0.kt" file-name="Default${NAME}FeatureToggles" reformat="true" live-template-enabled="false" />
</template>
<template name="FeatureToggles.kt.child.0.kt" file-name="Default${NAME}FeatureToggles" reformat="true" live-template-enabled="false" />
<template name="FlowPackaging.kt" file-name="producer/${NAME}Producer" reformat="true" live-template-enabled="false">
<template name="FlowPackaging.kt.child.0.kt" file-name="di/${NAME}FetcherModule" reformat="true" live-template-enabled="false" />
<template name="FlowPackaging.kt.child.1.kt" file-name="di/${NAME}ProducerFactoryModule" reformat="true" live-template-enabled="false" />
<template name="FlowPackaging.kt.child.2.kt" file-name="di/${NAME}SupplierModule" reformat="true" live-template-enabled="false" />
<template name="FlowPackaging.kt.child.3.kt" file-name="fetcher/Default${NAME}Fetcher" reformat="true" live-template-enabled="false" />
<template name="FlowPackaging.kt.child.4.kt" file-name="producer/Default${NAME}Producer" reformat="true" live-template-enabled="false" />
<template name="FlowPackaging.kt.child.5.kt" file-name="fetcher/${NAME}Fetcher" reformat="true" live-template-enabled="false" />
<template name="FlowPackaging.kt.child.6.kt" file-name="supplier/${NAME}Supplier" reformat="true" live-template-enabled="false" />
</template>
<template name="FlowPackaging.kt.child.0.kt" file-name="di/${NAME}FetcherModule" reformat="true" live-template-enabled="false" />
<template name="FlowPackaging.kt.child.1.kt" file-name="di/${NAME}ProducerFactoryModule" reformat="true" live-template-enabled="false" />
<template name="FlowPackaging.kt.child.2.kt" file-name="di/${NAME}SupplierModule" reformat="true" live-template-enabled="false" />
<template name="FlowPackaging.kt.child.3.kt" file-name="fetcher/Default${NAME}Fetcher" reformat="true" live-template-enabled="false" />
<template name="FlowPackaging.kt.child.4.kt" file-name="producer/Default${NAME}Producer" reformat="true" live-template-enabled="false" />
<template name="FlowPackaging.kt.child.5.kt" file-name="fetcher/${NAME}Fetcher" reformat="true" live-template-enabled="false" />
<template name="FlowPackaging.kt.child.6.kt" file-name="supplier/${NAME}Supplier" reformat="true" live-template-enabled="false" />
</default_templates>
</component>
</application>

View file

@ -0,0 +1,13 @@
#if (${PACKAGE_NAME} != "")package ${PACKAGE_NAME}#end
import com.tangem.core.decompose.factory.ComponentFactory
import com.tangem.core.ui.decompose.ComposableContentComponent
interface ${NAME}Component : ComposableContentComponent {
data class Params(
val data: Any, // TODO("Not yet implemented")
)
interface Factory : ComponentFactory<Params, ${NAME}Component>
}

View file

@ -0,0 +1,5 @@
#if (${PACKAGE_NAME} != "")package ${PACKAGE_NAME}.entity#end
internal data class ${NAME}UM(
val onBackClick: () -> Unit,
)

View file

@ -0,0 +1,56 @@
#if (${PACKAGE_NAME} != "")package ${PACKAGE_NAME}.ui#end
import android.content.res.Configuration
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider
import com.tangem.core.ui.components.appbar.AppBarWithBackButton
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview
import ${PACKAGE_NAME}.entity.${NAME}UM
@Composable
internal fun ${NAME}Content(state: ${NAME}UM, modifier: Modifier = Modifier) {
Column(
modifier = modifier
.background(color = TangemTheme.colors.background.secondary)
.fillMaxSize()
.imePadding()
.systemBarsPadding(),
horizontalAlignment = Alignment.CenterHorizontally,
) {
AppBarWithBackButton(
onBackClick = state.onBackClick,
modifier = Modifier.height(TangemTheme.dimens.size56),
)
Column(
modifier = Modifier
.fillMaxSize()
.padding(horizontal = TangemTheme.dimens.spacing16)
.weight(1f),
) {
}
}
}
@Preview(showBackground = true, widthDp = 360)
@Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
private fun ${NAME}ContentPreview(@PreviewParameter(PreviewStateProvider::class) state: ${NAME}UM) {
TangemThemePreview {
${NAME}Content(state = state)
}
}
private class PreviewStateProvider : CollectionPreviewParameterProvider<${NAME}UM>(
buildList {
TODO("Not yet implemented")
},
)

View file

@ -0,0 +1,31 @@
#if (${PACKAGE_NAME} != "")package ${PACKAGE_NAME}.model#end
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.decompose.ui.UiMessageSender
import ${PACKAGE_NAME}.${NAME}Component
import ${PACKAGE_NAME}.entity.${NAME}UM
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import javax.inject.Inject
@ModelScoped
internal class ${NAME}Model @Inject constructor(
paramsContainer: ParamsContainer,
private val messageSender: UiMessageSender,
private val router: Router,
override val dispatchers: CoroutineDispatcherProvider,
) : Model() {
private val params = paramsContainer.require<${NAME}Component.Params>()
val uiState: StateFlow<${NAME}UM>
field: MutableStateFlow<${NAME}UM> = MutableStateFlow(getInitialState())
private fun getInitialState(): ${NAME}UM {
TODO("Not yet implemented")
}
}

View file

@ -0,0 +1,39 @@
#if (${PACKAGE_NAME} != "")package ${PACKAGE_NAME}#end
import androidx.activity.compose.BackHandler
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 ${PACKAGE_NAME}.model.${NAME}Model
import ${PACKAGE_NAME}.ui.${NAME}Content
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
internal class Default${NAME}Component @AssistedInject constructor(
@Assisted appComponentContext: AppComponentContext,
@Assisted params: ${NAME}Component.Params,
) : AppComponentContext by appComponentContext, ${NAME}Component {
private val model: ${NAME}Model = getOrCreateModel(params)
@Composable
override fun Content(modifier: Modifier) {
val state by model.uiState.collectAsStateWithLifecycle()
${NAME}Content(modifier = modifier, state = state)
BackHandler(onBack = state.onBackClick)
}
@AssistedFactory
interface Factory : ${NAME}Component.Factory {
override fun create(
context: AppComponentContext,
params: ${NAME}Component.Params,
): Default${NAME}Component
}
}

6
.idea/fileTemplates/FeatureToggles.kt generated Normal file
View file

@ -0,0 +1,6 @@
#if (${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#end
interface ${NAME}FeatureToggles {
val isFeatureEnabled: Boolean
}

View file

@ -0,0 +1,11 @@
#if (${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#end
import com.tangem.core.configtoggle.feature.FeatureTogglesManager
internal class Default${NAME}FeatureToggles(
private val featureTogglesManager: FeatureTogglesManager,
) : ${NAME}FeatureToggles {
override val isFeatureEnabled: Boolean
get() = featureTogglesManager.isFeatureEnabled(name = TODO("add feature name"))
}

17
.idea/fileTemplates/FlowPackaging.kt generated Normal file
View file

@ -0,0 +1,17 @@
#if ($FlowType && $FlowType != "")
#set($Type = $FlowType)
#else
#set($Type = "TODO")
#end
#if (${PACKAGE_NAME} != "")package ${PACKAGE_NAME}.producer#end
import com.tangem.domain.core.flow.FlowProducer
interface ${NAME}Producer : FlowProducer<${FlowType}> {
data class Params(
val id: String, // TODO("Not yet implemented")
)
interface Factory : FlowProducer.Factory<Params, ${NAME}Producer>
}

View file

@ -0,0 +1,18 @@
#if (${PACKAGE_NAME} != "")package ${PACKAGE_NAME}.di#end
import ${PACKAGE_NAME}.fetcher.Default${NAME}Fetcher
import ${PACKAGE_NAME}.fetcher.${NAME}Fetcher
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 ${NAME}FetcherModule {
@Binds
@Singleton
fun bind${NAME}Fetcher(impl: Default${NAME}Fetcher): ${NAME}Fetcher
}

View file

@ -0,0 +1,20 @@
#if (${PACKAGE_NAME} != "")package ${PACKAGE_NAME}.di#end
import ${PACKAGE_NAME}.producer.Default${NAME}Producer
import ${PACKAGE_NAME}.producer.${NAME}Producer
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 ${NAME}ProducerFactoryModule {
@Binds
@Singleton
fun bind${NAME}ProducerFactory(
impl: Default${NAME}Producer.Factory,
): ${NAME}Producer.Factory
}

View file

@ -0,0 +1,23 @@
#if (${PACKAGE_NAME} != "")package ${PACKAGE_NAME}.di#end
import ${PACKAGE_NAME}.producer.${NAME}Producer
import ${PACKAGE_NAME}.supplier.${NAME}Supplier
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 ${NAME}SupplierModule {
@Provides
@Singleton
fun provide${NAME}Supplier(factory: ${NAME}Producer.Factory): ${NAME}Supplier {
return object : ${NAME}Supplier(
factory = factory,
keyCreator = { TODO("Not yet implemented") },
) {}
}
}

View file

@ -0,0 +1,14 @@
#if (${PACKAGE_NAME} != "")package ${PACKAGE_NAME}.fetcher#end
import arrow.core.Either
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import javax.inject.Inject
internal class Default${NAME}Fetcher @Inject constructor(
private val dispatchers: CoroutineDispatcherProvider,
) : ${NAME}Fetcher {
override suspend fun invoke(params: ${NAME}Fetcher.Params): Either<Throwable, Unit> {
TODO("Not yet implemented")
}
}

View file

@ -0,0 +1,31 @@
#if ($FlowType && $FlowType != "")
#set($Type = $FlowType)
#else
#set($Type = "TODO")
#end
#if (${PACKAGE_NAME} != "")package ${PACKAGE_NAME}.producer#end
import arrow.core.Option
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import kotlinx.coroutines.flow.Flow
internal class Default${NAME}Producer @AssistedInject constructor(
@Assisted val params: ${NAME}Producer.Params,
private val dispatchers: CoroutineDispatcherProvider,
) : TestProducer {
override val fallback: Option<$Type>
get() = TODO("Not yet implemented")
override fun produce(): Flow<$Type> {
TODO("Not yet implemented")
}
@AssistedFactory
interface Factory : ${NAME}Producer.Factory {
override fun create(params: ${NAME}Producer.Params): Default${NAME}Producer
}
}

View file

@ -0,0 +1,10 @@
#if (${PACKAGE_NAME} != "")package ${PACKAGE_NAME}.fetcher#end
import com.tangem.domain.core.flow.FlowFetcher
interface ${NAME}Fetcher : FlowFetcher<${NAME}Fetcher.Params> {
data class Params(
val id: String, // TODO("Not yet implemented")
)
}

View file

@ -0,0 +1,15 @@
#if ($FlowType && $FlowType != "")
#set($Type = $FlowType)
#else
#set($Type = "TODO")
#end
#if (${PACKAGE_NAME} != "")package ${PACKAGE_NAME}.supplier#end
import ${PACKAGE_NAME}.producer.${NAME}Producer
import com.tangem.domain.core.flow.FlowCachingSupplier
import kotlinx.coroutines.flow.Flow
abstract class ${NAME}Supplier(
override val factory: ${NAME}Producer.Factory,
override val keyCreator: (${NAME}Producer.Params) -> String,
) : FlowCachingSupplier<${NAME}Producer, ${NAME}Producer.Params, $Type>()