Updated on 2026-08-14
This commit is contained in:
parent
8a51041f7f
commit
52eddd3ac6
15 changed files with 639 additions and 33 deletions
|
|
@ -1,16 +1,21 @@
|
|||
package com.tangem.core.ui.components.bottomsheets
|
||||
|
||||
import androidx.activity.compose.BackHandler
|
||||
import androidx.activity.compose.LocalOnBackPressedDispatcherOwner
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.focusable
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.ModalBottomSheet
|
||||
import androidx.compose.material3.SheetState
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.material3.SheetValue.Expanded
|
||||
import androidx.compose.material3.rememberModalBottomSheetState
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.focus.FocusRequester
|
||||
import androidx.compose.ui.focus.focusRequester
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.graphics.Shape
|
||||
import androidx.compose.ui.input.key.*
|
||||
import androidx.compose.ui.platform.LocalDensity
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.tangem.core.ui.components.appbar.models.TopAppBarButtonUM
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
|
|
@ -18,6 +23,7 @@ import com.tangem.core.ui.res.LocalBottomSheetAlwaysVisible
|
|||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.utils.WindowInsetsZero
|
||||
import kotlinx.coroutines.coroutineScope
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
/**
|
||||
|
|
@ -31,6 +37,7 @@ inline fun <reified T : TangemBottomSheetConfigContent> TangemBottomSheet(
|
|||
containerColor: Color = TangemTheme.colors.background.primary,
|
||||
addBottomInsets: Boolean = true,
|
||||
skipPartiallyExpanded: Boolean = true,
|
||||
noinline onBack: (() -> Unit)? = null,
|
||||
crossinline content: @Composable ColumnScope.(T) -> Unit,
|
||||
) {
|
||||
TangemBottomSheet(
|
||||
|
|
@ -39,6 +46,7 @@ inline fun <reified T : TangemBottomSheetConfigContent> TangemBottomSheet(
|
|||
addBottomInsets = addBottomInsets,
|
||||
title = { TangemBottomSheetTitle(title = titleText, endButton = titleAction) },
|
||||
skipPartiallyExpanded = skipPartiallyExpanded,
|
||||
onBack = onBack,
|
||||
content = content,
|
||||
)
|
||||
}
|
||||
|
|
@ -52,6 +60,7 @@ inline fun <reified T : TangemBottomSheetConfigContent> TangemBottomSheet(
|
|||
containerColor: Color = TangemTheme.colors.background.primary,
|
||||
addBottomInsets: Boolean = true,
|
||||
skipPartiallyExpanded: Boolean = true,
|
||||
noinline onBack: (() -> Unit)? = null,
|
||||
crossinline title: @Composable BoxScope.(T) -> Unit = {},
|
||||
crossinline content: @Composable ColumnScope.(T) -> Unit,
|
||||
) {
|
||||
|
|
@ -73,6 +82,7 @@ inline fun <reified T : TangemBottomSheetConfigContent> TangemBottomSheet(
|
|||
addBottomInsets = addBottomInsets,
|
||||
title = title,
|
||||
content = content,
|
||||
onBack = onBack,
|
||||
skipPartiallyExpanded = skipPartiallyExpanded,
|
||||
)
|
||||
}
|
||||
|
|
@ -85,6 +95,7 @@ inline fun <reified T : TangemBottomSheetConfigContent> DefaultBottomSheet(
|
|||
containerColor: Color,
|
||||
addBottomInsets: Boolean,
|
||||
skipPartiallyExpanded: Boolean = true,
|
||||
noinline onBack: (() -> Unit)? = null,
|
||||
crossinline title: @Composable (BoxScope.(T) -> Unit),
|
||||
crossinline content: @Composable (ColumnScope.(T) -> Unit),
|
||||
) {
|
||||
|
|
@ -98,6 +109,7 @@ inline fun <reified T : TangemBottomSheetConfigContent> DefaultBottomSheet(
|
|||
containerColor = containerColor,
|
||||
addBottomInsets = addBottomInsets,
|
||||
title = title,
|
||||
onBack = onBack,
|
||||
content = content,
|
||||
)
|
||||
}
|
||||
|
|
@ -129,6 +141,7 @@ inline fun <reified T : TangemBottomSheetConfigContent> PreviewBottomSheet(
|
|||
initialValue = Expanded,
|
||||
density = LocalDensity.current,
|
||||
),
|
||||
onBack = null,
|
||||
containerColor = containerColor,
|
||||
addBottomInsets = addBottomInsets,
|
||||
title = title,
|
||||
|
|
@ -144,6 +157,7 @@ inline fun <reified T : TangemBottomSheetConfigContent> BasicBottomSheet(
|
|||
sheetState: SheetState,
|
||||
containerColor: Color,
|
||||
addBottomInsets: Boolean,
|
||||
noinline onBack: (() -> Unit)? = null,
|
||||
crossinline title: @Composable (BoxScope.(T) -> Unit),
|
||||
crossinline content: @Composable (ColumnScope.(T) -> Unit),
|
||||
modifier: Modifier = Modifier,
|
||||
|
|
@ -152,15 +166,7 @@ inline fun <reified T : TangemBottomSheetConfigContent> BasicBottomSheet(
|
|||
|
||||
val bottomBarHeight = with(LocalDensity.current) { WindowInsets.systemBars.getBottom(this).toDp() }
|
||||
|
||||
ModalBottomSheet(
|
||||
modifier = modifier.statusBarsPadding(),
|
||||
onDismissRequest = config.onDismissRequest,
|
||||
sheetState = sheetState,
|
||||
containerColor = containerColor,
|
||||
shape = TangemTheme.shapes.bottomSheetLarge,
|
||||
contentWindowInsets = { WindowInsetsZero },
|
||||
dragHandle = { TangemBottomSheetDraggableHeader(color = containerColor) },
|
||||
) {
|
||||
val bsContent: @Composable ColumnScope.() -> Unit = {
|
||||
Column(
|
||||
modifier = Modifier.let {
|
||||
if (addBottomInsets) {
|
||||
|
|
@ -179,6 +185,90 @@ inline fun <reified T : TangemBottomSheetConfigContent> BasicBottomSheet(
|
|||
content(model)
|
||||
}
|
||||
}
|
||||
|
||||
if (onBack != null) {
|
||||
ModalBottomSheetWithBackHandling(
|
||||
modifier = modifier.statusBarsPadding(),
|
||||
onDismissRequest = config.onDismissRequest,
|
||||
sheetState = sheetState,
|
||||
containerColor = containerColor,
|
||||
shape = TangemTheme.shapes.bottomSheetLarge,
|
||||
contentWindowInsets = { WindowInsetsZero },
|
||||
dragHandle = { TangemBottomSheetDraggableHeader(color = containerColor) },
|
||||
onBack = onBack,
|
||||
content = bsContent,
|
||||
)
|
||||
} else {
|
||||
ModalBottomSheet(
|
||||
modifier = modifier.statusBarsPadding(),
|
||||
onDismissRequest = config.onDismissRequest,
|
||||
sheetState = sheetState,
|
||||
containerColor = containerColor,
|
||||
shape = TangemTheme.shapes.bottomSheetLarge,
|
||||
contentWindowInsets = { WindowInsetsZero },
|
||||
dragHandle = { TangemBottomSheetDraggableHeader(color = containerColor) },
|
||||
content = bsContent,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun ModalBottomSheetWithBackHandling(
|
||||
onDismissRequest: () -> Unit,
|
||||
onBack: (() -> Unit),
|
||||
modifier: Modifier = Modifier,
|
||||
sheetState: SheetState = rememberModalBottomSheetState(),
|
||||
sheetMaxWidth: Dp = BottomSheetDefaults.SheetMaxWidth,
|
||||
shape: Shape = BottomSheetDefaults.ExpandedShape,
|
||||
containerColor: Color = BottomSheetDefaults.ContainerColor,
|
||||
contentColor: Color = contentColorFor(containerColor),
|
||||
tonalElevation: Dp = 0.dp,
|
||||
scrimColor: Color = BottomSheetDefaults.ScrimColor,
|
||||
dragHandle: @Composable (() -> Unit)? = { BottomSheetDefaults.DragHandle() },
|
||||
contentWindowInsets: @Composable () -> WindowInsets = { BottomSheetDefaults.windowInsets },
|
||||
content: @Composable ColumnScope.() -> Unit,
|
||||
) {
|
||||
BackHandler(enabled = sheetState.targetValue != SheetValue.Hidden) {
|
||||
onBack()
|
||||
}
|
||||
|
||||
val requester = remember { FocusRequester() }
|
||||
val backPressedDispatcherOwner = LocalOnBackPressedDispatcherOwner.current
|
||||
|
||||
ModalBottomSheet(
|
||||
onDismissRequest = onDismissRequest,
|
||||
modifier = modifier
|
||||
.focusRequester(requester)
|
||||
.focusable()
|
||||
.onPreviewKeyEvent {
|
||||
if (it.key == Key.Back && it.type == KeyEventType.KeyUp && !it.nativeKeyEvent.isCanceled) {
|
||||
backPressedDispatcherOwner?.onBackPressedDispatcher?.onBackPressed()
|
||||
return@onPreviewKeyEvent true
|
||||
}
|
||||
return@onPreviewKeyEvent false
|
||||
},
|
||||
sheetState = sheetState,
|
||||
sheetMaxWidth = sheetMaxWidth,
|
||||
shape = shape,
|
||||
containerColor = containerColor,
|
||||
contentColor = contentColor,
|
||||
tonalElevation = tonalElevation,
|
||||
scrimColor = scrimColor,
|
||||
dragHandle = dragHandle,
|
||||
contentWindowInsets = contentWindowInsets,
|
||||
properties = ModalBottomSheetDefaults.properties(
|
||||
// Set false otherwise the onPreviewKeyEvent doesn't work at all.
|
||||
// The functionality of shouldDismissOnBackPress is achieved by the BackHandler.
|
||||
shouldDismissOnBackPress = false,
|
||||
),
|
||||
content = content,
|
||||
)
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
delay(timeMillis = 200)
|
||||
requester.requestFocus()
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
|
|
|
|||
|
|
@ -7,8 +7,6 @@ import androidx.compose.runtime.*
|
|||
@Immutable
|
||||
object TangemAnimations {
|
||||
|
||||
val transitionSpecs = TransitionSpecs
|
||||
|
||||
@Composable
|
||||
@NonRestartableComposable
|
||||
fun horizontalIndicatorAsState(targetFraction: Float): State<Float> {
|
||||
|
|
@ -19,8 +17,18 @@ object TangemAnimations {
|
|||
)
|
||||
}
|
||||
|
||||
@Immutable
|
||||
object TransitionSpecs {
|
||||
// TODO add more transition specs
|
||||
object AnimatedContent {
|
||||
fun <S> slide(
|
||||
forwardWhen: (initial: S, target: S) -> Boolean,
|
||||
): AnimatedContentTransitionScope<S>.() -> ContentTransform = {
|
||||
val direction = if (forwardWhen(initialState, targetState)) {
|
||||
AnimatedContentTransitionScope.SlideDirection.End
|
||||
} else {
|
||||
AnimatedContentTransitionScope.SlideDirection.Start
|
||||
}
|
||||
|
||||
slideIntoContainer(towards = direction, animationSpec = tween())
|
||||
.togetherWith(slideOutOfContainer(towards = direction, animationSpec = tween()))
|
||||
}
|
||||
}
|
||||
}
|
||||
24
core/ui/src/main/res/drawable/ic_access_code.xml
Normal file
24
core/ui/src/main/res/drawable/ic_access_code.xml
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="119dp"
|
||||
android:height="119dp"
|
||||
android:viewportWidth="119"
|
||||
android:viewportHeight="119">
|
||||
<path
|
||||
android:pathData="M111.664,30.74H7.336C3.291,30.74 0,34.03 0,38.075V60.431C0,64.476 3.291,67.767 7.336,67.767H72.541C73.506,67.767 74.288,66.985 74.288,66.021C74.288,65.056 73.506,64.274 72.541,64.274H7.336C5.217,64.274 3.493,62.55 3.493,60.431V38.075C3.493,35.957 5.217,34.233 7.336,34.233H111.664C113.783,34.233 115.507,35.957 115.507,38.075V54.842C115.507,55.807 116.289,56.589 117.253,56.589C118.218,56.589 119,55.807 119,54.842V38.075C119,34.03 115.709,30.74 111.664,30.74Z"
|
||||
android:fillColor="#060606"/>
|
||||
<path
|
||||
android:pathData="M111.548,58.972V56.706C111.548,48.552 104.914,41.918 96.76,41.918C88.606,41.918 81.973,48.552 81.973,56.706V58.972C79.809,59.703 78.247,61.751 78.247,64.158V82.788C78.247,85.805 80.702,88.26 83.719,88.26H109.801C112.819,88.26 115.274,85.805 115.274,82.788V64.158C115.274,61.751 113.711,59.703 111.548,58.972ZM96.76,45.411C102.988,45.411 108.055,50.478 108.055,56.706V58.685H85.466V56.706C85.466,50.478 90.533,45.411 96.76,45.411ZM111.781,82.788C111.781,83.879 110.893,84.767 109.801,84.767H83.719C82.628,84.767 81.74,83.879 81.74,82.788V64.158C81.74,63.066 82.628,62.178 83.719,62.178H109.801C110.893,62.178 111.781,63.066 111.781,64.158V82.788Z"
|
||||
android:fillColor="#060606"/>
|
||||
<path
|
||||
android:pathData="M28.343,44.654C27.861,43.819 26.793,43.533 25.957,44.015L22.123,46.228V41.801C22.123,40.837 21.341,40.055 20.377,40.055C19.412,40.055 18.63,40.837 18.63,41.801V46.228L14.796,44.015C13.961,43.532 12.893,43.819 12.411,44.654C11.928,45.489 12.215,46.558 13.05,47.04L16.884,49.253L13.05,51.467C12.215,51.949 11.928,53.017 12.411,53.853C12.734,54.413 13.321,54.726 13.925,54.726C14.221,54.726 14.521,54.651 14.796,54.492L18.63,52.278V56.706C18.63,57.67 19.412,58.452 20.377,58.452C21.341,58.452 22.123,57.67 22.123,56.706V52.278L25.957,54.492C26.232,54.651 26.533,54.726 26.829,54.726C27.433,54.726 28.02,54.413 28.343,53.853C28.825,53.017 28.539,51.949 27.704,51.467L23.87,49.253L27.704,47.04C28.539,46.558 28.825,45.489 28.343,44.654Z"
|
||||
android:fillColor="#060606"/>
|
||||
<path
|
||||
android:pathData="M50.699,44.654C50.217,43.819 49.149,43.533 48.313,44.015L44.48,46.228V41.801C44.48,40.837 43.698,40.055 42.733,40.055C41.768,40.055 40.986,40.837 40.986,41.801V46.228L37.153,44.015C36.317,43.532 35.249,43.819 34.767,44.654C34.285,45.489 34.571,46.558 35.406,47.04L39.24,49.253L35.406,51.467C34.571,51.949 34.285,53.017 34.767,53.853C35.09,54.413 35.677,54.726 36.281,54.726C36.577,54.726 36.877,54.651 37.153,54.492L40.986,52.278V56.706C40.986,57.67 41.768,58.452 42.733,58.452C43.698,58.452 44.48,57.67 44.48,56.706V52.278L48.313,54.492C48.588,54.651 48.889,54.726 49.185,54.726C49.789,54.726 50.376,54.413 50.699,53.853C51.181,53.017 50.895,51.949 50.06,51.467L46.226,49.253L50.06,47.04C50.895,46.558 51.181,45.489 50.699,44.654Z"
|
||||
android:fillColor="#060606"/>
|
||||
<path
|
||||
android:pathData="M73.055,44.654C72.573,43.819 71.505,43.533 70.67,44.015L66.836,46.228V41.801C66.836,40.837 66.054,40.055 65.089,40.055C64.125,40.055 63.343,40.837 63.343,41.801V46.228L59.509,44.015C58.673,43.532 57.605,43.819 57.123,44.654C56.641,45.489 56.927,46.558 57.762,47.04L61.596,49.253L57.762,51.467C56.927,51.949 56.641,53.017 57.123,53.853C57.446,54.413 58.034,54.726 58.637,54.726C58.933,54.726 59.234,54.651 59.509,54.492L63.343,52.278V56.706C63.343,57.67 64.125,58.452 65.089,58.452C66.054,58.452 66.836,57.67 66.836,56.706V52.278L70.67,54.492C70.945,54.651 71.245,54.726 71.541,54.726C72.145,54.726 72.732,54.413 73.055,53.853C73.538,53.017 73.252,51.949 72.416,51.467L68.582,49.253L72.416,47.04C73.252,46.558 73.538,45.489 73.055,44.654Z"
|
||||
android:fillColor="#060606"/>
|
||||
<path
|
||||
android:pathData="M96.76,66.137C93.743,66.137 91.288,68.592 91.288,71.61C91.288,74.017 92.85,76.064 95.014,76.795V79.062C95.014,80.026 95.796,80.808 96.76,80.808C97.725,80.808 98.507,80.026 98.507,79.062V76.795C100.67,76.064 102.233,74.017 102.233,71.61C102.233,68.592 99.778,66.137 96.76,66.137ZM96.76,73.589C95.669,73.589 94.781,72.701 94.781,71.61C94.781,70.518 95.669,69.63 96.76,69.63C97.852,69.63 98.74,70.518 98.74,71.61C98.74,72.701 97.852,73.589 96.76,73.589Z"
|
||||
android:fillColor="#060606"/>
|
||||
</vector>
|
||||
22
core/ui/src/main/res/drawable/ic_feature_1.xml
Normal file
22
core/ui/src/main/res/drawable/ic_feature_1.xml
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="25dp"
|
||||
android:height="25dp"
|
||||
android:viewportWidth="25"
|
||||
android:viewportHeight="25">
|
||||
<path
|
||||
android:pathData="M3,11H11C12.6569,11 14,12.3431 14,14V22C14,23.6569 12.6569,25 11,25H3C1.3432,25 0,23.6569 0,22V14C0,12.3431 1.3432,11 3,11Z"
|
||||
android:fillColor="#1ACE80"
|
||||
android:fillType="evenOdd"/>
|
||||
<path
|
||||
android:pathData="M18.7143,11H23.2857C24.2325,11 25,11.7675 25,12.7143V17.2857C25,18.2325 24.2325,19 23.2857,19H18.7143C17.7675,19 17,18.2325 17,17.2857V12.7143C17,11.7675 17.7675,11 18.7143,11Z"
|
||||
android:strokeAlpha="0.15"
|
||||
android:fillColor="#1ACE80"
|
||||
android:fillType="evenOdd"
|
||||
android:fillAlpha="0.15"/>
|
||||
<path
|
||||
android:pathData="M7.7143,0H19.2857C20.2325,0 21,0.7675 21,1.7143V6.2857C21,7.2325 20.2325,8 19.2857,8H7.7143C6.7675,8 6,7.2325 6,6.2857V1.7143C6,0.7675 6.7675,0 7.7143,0Z"
|
||||
android:strokeAlpha="0.5"
|
||||
android:fillColor="#1ACE80"
|
||||
android:fillType="evenOdd"
|
||||
android:fillAlpha="0.5"/>
|
||||
</vector>
|
||||
22
core/ui/src/main/res/drawable/ic_feature_2.xml
Normal file
22
core/ui/src/main/res/drawable/ic_feature_2.xml
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="25dp"
|
||||
android:height="25dp"
|
||||
android:viewportWidth="25"
|
||||
android:viewportHeight="25">
|
||||
<path
|
||||
android:pathData="M18,25C21.866,25 25,21.866 25,18C25,14.134 21.866,11 18,11C14.134,11 11,14.134 11,18C11,21.866 14.134,25 18,25Z"
|
||||
android:fillColor="#1ACE80"
|
||||
android:fillType="evenOdd"/>
|
||||
<path
|
||||
android:pathData="M9,10C11.7614,10 14,7.7614 14,5C14,2.2386 11.7614,0 9,0C6.2386,0 4,2.2386 4,5C4,7.7614 6.2386,10 9,10Z"
|
||||
android:strokeAlpha="0.5"
|
||||
android:fillColor="#1ACE80"
|
||||
android:fillType="evenOdd"
|
||||
android:fillAlpha="0.5"/>
|
||||
<path
|
||||
android:pathData="M4,21C6.2091,21 8,19.2091 8,17C8,14.7909 6.2091,13 4,13C1.7909,13 0,14.7909 0,17C0,19.2091 1.7909,21 4,21Z"
|
||||
android:strokeAlpha="0.15"
|
||||
android:fillColor="#1ACE80"
|
||||
android:fillType="evenOdd"
|
||||
android:fillAlpha="0.15"/>
|
||||
</vector>
|
||||
22
core/ui/src/main/res/drawable/ic_feature_3.xml
Normal file
22
core/ui/src/main/res/drawable/ic_feature_3.xml
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="26dp"
|
||||
android:height="22dp"
|
||||
android:viewportWidth="26"
|
||||
android:viewportHeight="22">
|
||||
<path
|
||||
android:pathData="M19.3989,4.1971L13.3558,4.1971C12.3137,4.1512 11.3955,4.9319 11.3048,5.9408C11.2723,6.3027 11.3515,6.6613 11.5324,6.9712L14.7623,12.5027C15.2667,13.3667 16.4185,13.6429 17.3349,13.1197C17.6423,12.9442 17.8966,12.6917 18.0696,12.3902L21.041,6.9712C21.5566,6.0725 21.1048,4.9181 20.1946,4.4571C19.9583,4.3374 19.6695,4.209 19.3989,4.1971Z"
|
||||
android:strokeAlpha="0.5"
|
||||
android:fillColor="#1ACE80"
|
||||
android:fillType="evenOdd"
|
||||
android:fillAlpha="0.5"/>
|
||||
<path
|
||||
android:pathData="M20.1304,14.9339L17.4396,19.051C16.9906,19.738 17.1702,20.6677 17.8409,21.1276C18.0815,21.2926 18.3644,21.3806 18.6539,21.3806H23.8216C24.6287,21.3806 25.2829,20.7105 25.2829,19.8837C25.2829,19.6064 25.2077,19.3345 25.0657,19.0984L22.5889,14.9813C22.1655,14.2775 21.2652,14.0586 20.5781,14.4923C20.3997,14.6049 20.247,14.7555 20.1304,14.9339Z"
|
||||
android:strokeAlpha="0.15"
|
||||
android:fillColor="#1ACE80"
|
||||
android:fillType="evenOdd"
|
||||
android:fillAlpha="0.15"/>
|
||||
<path
|
||||
android:pathData="M5.1416,10.4031L0.4325,17.4279C-0.3532,18.6 -0.0387,20.1864 1.1349,20.9711C1.5559,21.2526 2.051,21.4029 2.5576,21.4029H11.6011C13.0135,21.4029 14.1585,20.2594 14.1585,18.8488C14.1585,18.3756 14.0269,17.9117 13.7783,17.5089L9.4439,10.4841C8.7029,9.2832 7.1275,8.9096 5.925,9.6496C5.6128,9.8417 5.3456,10.0987 5.1416,10.4031Z"
|
||||
android:fillColor="#1ACE80"
|
||||
android:fillType="evenOdd"/>
|
||||
</vector>
|
||||
|
|
@ -10,6 +10,10 @@ 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.router.slot.SlotNavigation
|
||||
import com.arkivanov.decompose.router.slot.childSlot
|
||||
import com.arkivanov.decompose.router.slot.dismiss
|
||||
import com.arkivanov.decompose.router.slot.navigate
|
||||
import com.arkivanov.decompose.router.stack.*
|
||||
import com.arkivanov.decompose.value.Value
|
||||
import com.arkivanov.essenty.instancekeeper.getOrCreateSimple
|
||||
|
|
@ -21,6 +25,7 @@ import com.tangem.core.decompose.navigation.inner.InnerNavigationState
|
|||
import com.tangem.features.onboarding.v2.multiwallet.api.OnboardingMultiWalletComponent
|
||||
import com.tangem.features.onboarding.v2.multiwallet.impl.child.MultiWalletChildComponent
|
||||
import com.tangem.features.onboarding.v2.multiwallet.impl.child.MultiWalletChildParams
|
||||
import com.tangem.features.onboarding.v2.multiwallet.impl.child.accesscode.MultiWalletAccessCodeComponent
|
||||
import com.tangem.features.onboarding.v2.multiwallet.impl.child.backup.MultiWalletBackupComponent
|
||||
import com.tangem.features.onboarding.v2.multiwallet.impl.child.chooseoption.Wallet1ChooseOptionComponent
|
||||
import com.tangem.features.onboarding.v2.multiwallet.impl.child.createwallet.MultiWalletCreateWalletComponent
|
||||
|
|
@ -56,6 +61,11 @@ internal class DefaultOnboardingMultiWalletComponent @AssistedInject constructor
|
|||
)
|
||||
}
|
||||
|
||||
private val childParams = MultiWalletChildParams(
|
||||
multiWalletState = model.state,
|
||||
parentParams = params,
|
||||
)
|
||||
|
||||
override val innerNavigation: InnerNavigation = object : InnerNavigation {
|
||||
override val state = MutableStateFlow(
|
||||
MultiWalletInnerNavigationState(1, 5),
|
||||
|
|
@ -82,6 +92,24 @@ internal class DefaultOnboardingMultiWalletComponent @AssistedInject constructor
|
|||
},
|
||||
)
|
||||
|
||||
private val bottomSheetNavigation = SlotNavigation<Unit>()
|
||||
private val accessCodeBottomSheetSlot = childSlot(
|
||||
source = bottomSheetNavigation,
|
||||
serializer = null,
|
||||
handleBackButton = false,
|
||||
childFactory = { configuration, componentContext ->
|
||||
MultiWalletAccessCodeComponent(
|
||||
context = childByContext(componentContext),
|
||||
params = childParams,
|
||||
onDismiss = { bottomSheetNavigation.dismiss() },
|
||||
)
|
||||
},
|
||||
)
|
||||
|
||||
init {
|
||||
bottomSheetNavigation.navigate {}
|
||||
}
|
||||
|
||||
private fun createChild(
|
||||
step: OnboardingMultiWalletState.Step,
|
||||
childContext: AppComponentContext,
|
||||
|
|
@ -121,7 +149,7 @@ internal class DefaultOnboardingMultiWalletComponent @AssistedInject constructor
|
|||
}
|
||||
}
|
||||
|
||||
fun handleNavigationEvent(nextStep: OnboardingMultiWalletState.Step) {
|
||||
private fun handleNavigationEvent(nextStep: OnboardingMultiWalletState.Step) {
|
||||
when (nextStep) {
|
||||
ChooseBackupOption -> {
|
||||
artworksState.value = WalletArtworksState.Fan
|
||||
|
|
@ -141,7 +169,7 @@ internal class DefaultOnboardingMultiWalletComponent @AssistedInject constructor
|
|||
stackNavigation.push(nextStep)
|
||||
}
|
||||
|
||||
fun handleBackupComponentEvent(event: MultiWalletBackupComponent.Event) {
|
||||
private fun handleBackupComponentEvent(event: MultiWalletBackupComponent.Event) {
|
||||
when (event) {
|
||||
MultiWalletBackupComponent.Event.Done -> {
|
||||
// TODO navigate to finalize
|
||||
|
|
@ -184,6 +212,9 @@ internal class DefaultOnboardingMultiWalletComponent @AssistedInject constructor
|
|||
}
|
||||
},
|
||||
)
|
||||
|
||||
val bottomSheetState by accessCodeBottomSheetSlot.subscribeAsState()
|
||||
bottomSheetState.child?.instance?.BottomSheet()
|
||||
}
|
||||
|
||||
@AssistedFactory
|
||||
|
|
|
|||
|
|
@ -0,0 +1,58 @@
|
|||
package com.tangem.features.onboarding.v2.multiwallet.impl.child.accesscode
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||
import com.tangem.core.decompose.context.AppComponentContext
|
||||
import com.tangem.core.decompose.model.getOrCreateModel
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfigContent
|
||||
import com.tangem.core.ui.decompose.ComposableBottomSheetComponent
|
||||
import com.tangem.features.onboarding.v2.multiwallet.impl.child.MultiWalletChildParams
|
||||
import com.tangem.features.onboarding.v2.multiwallet.impl.child.accesscode.model.MultiWalletAccessCodeModel
|
||||
import com.tangem.features.onboarding.v2.multiwallet.impl.child.accesscode.ui.MultiWalletAccessCodeBS
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@Suppress("UnusedPrivateMember")
|
||||
class MultiWalletAccessCodeComponent(
|
||||
context: AppComponentContext,
|
||||
private val params: MultiWalletChildParams,
|
||||
private val onDismiss: () -> Unit,
|
||||
) : AppComponentContext by context, ComposableBottomSheetComponent {
|
||||
|
||||
private val model = getOrCreateModel<MultiWalletAccessCodeModel>()
|
||||
|
||||
init {
|
||||
componentScope.launch {
|
||||
model.onDismiss.collect {
|
||||
onDismiss()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun dismiss() {
|
||||
onDismiss()
|
||||
}
|
||||
|
||||
@Composable
|
||||
override fun BottomSheet() {
|
||||
val state by model.uiState.collectAsStateWithLifecycle()
|
||||
val bsConfig = remember(this) {
|
||||
TangemBottomSheetConfig(
|
||||
isShow = true,
|
||||
onDismissRequest = onDismiss,
|
||||
content = TangemBottomSheetConfigContent.Empty,
|
||||
)
|
||||
}
|
||||
|
||||
MultiWalletAccessCodeBS(
|
||||
config = bsConfig,
|
||||
state = state,
|
||||
onBack = { model.onBack() },
|
||||
)
|
||||
}
|
||||
|
||||
@JvmInline
|
||||
value class AccessCode(val value: String)
|
||||
}
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
package com.tangem.features.onboarding.v2.multiwallet.impl.child.accesscode.model
|
||||
|
||||
import com.tangem.core.decompose.di.ComponentScoped
|
||||
import com.tangem.core.decompose.model.Model
|
||||
import com.tangem.features.onboarding.v2.multiwallet.impl.child.accesscode.ui.state.MultiWalletAccessCodeUM
|
||||
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import kotlinx.coroutines.flow.update
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
@ComponentScoped
|
||||
internal class MultiWalletAccessCodeModel @Inject constructor(
|
||||
override val dispatchers: CoroutineDispatcherProvider,
|
||||
) : Model() {
|
||||
|
||||
private val _uiState = MutableStateFlow(getInitialState())
|
||||
|
||||
val uiState = _uiState.asStateFlow()
|
||||
val onDismiss = MutableSharedFlow<Unit>()
|
||||
|
||||
fun onBack() {
|
||||
when (_uiState.value.step) {
|
||||
MultiWalletAccessCodeUM.Step.Intro -> {
|
||||
modelScope.launch { onDismiss.emit(Unit) }
|
||||
}
|
||||
MultiWalletAccessCodeUM.Step.AccessCode -> {
|
||||
_uiState.update {
|
||||
it.copy(step = MultiWalletAccessCodeUM.Step.Intro)
|
||||
}
|
||||
}
|
||||
MultiWalletAccessCodeUM.Step.ConfirmAccessCode -> {
|
||||
_uiState.update {
|
||||
it.copy(step = MultiWalletAccessCodeUM.Step.AccessCode)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getInitialState() = MultiWalletAccessCodeUM(
|
||||
onContinue = ::onContinue,
|
||||
)
|
||||
|
||||
private fun onContinue() {
|
||||
when (_uiState.value.step) {
|
||||
MultiWalletAccessCodeUM.Step.Intro -> {
|
||||
_uiState.update { it.copy(step = MultiWalletAccessCodeUM.Step.AccessCode) }
|
||||
}
|
||||
MultiWalletAccessCodeUM.Step.AccessCode -> {
|
||||
_uiState.update { it.copy(step = MultiWalletAccessCodeUM.Step.ConfirmAccessCode) }
|
||||
}
|
||||
MultiWalletAccessCodeUM.Step.ConfirmAccessCode -> {
|
||||
// TODO check
|
||||
modelScope.launch { onDismiss.emit(Unit) }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
package com.tangem.features.onboarding.v2.multiwallet.impl.child.accesscode.ui
|
||||
|
||||
import androidx.compose.animation.AnimatedContent
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.tangem.core.ui.components.PrimaryButton
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheet
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfigContent
|
||||
import com.tangem.core.ui.res.TangemAnimations
|
||||
import com.tangem.features.onboarding.v2.impl.R
|
||||
import com.tangem.features.onboarding.v2.multiwallet.impl.child.accesscode.ui.state.MultiWalletAccessCodeUM
|
||||
import com.tangem.features.onboarding.v2.multiwallet.impl.child.accesscode.ui.state.MultiWalletAccessCodeUM.Step.*
|
||||
|
||||
@Composable
|
||||
internal fun MultiWalletAccessCodeBS(
|
||||
config: TangemBottomSheetConfig,
|
||||
state: MultiWalletAccessCodeUM,
|
||||
onBack: () -> Unit,
|
||||
) {
|
||||
TangemBottomSheet<TangemBottomSheetConfigContent.Empty>(
|
||||
config = config,
|
||||
onBack = onBack,
|
||||
) { _ ->
|
||||
Content(state)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun Content(state: MultiWalletAccessCodeUM, modifier: Modifier = Modifier) {
|
||||
Column(
|
||||
modifier = modifier
|
||||
.fillMaxSize(),
|
||||
) {
|
||||
AnimatedContent(
|
||||
modifier = Modifier.weight(1f),
|
||||
targetState = state.step,
|
||||
transitionSpec = TangemAnimations.AnimatedContent
|
||||
.slide { initial, target -> initial.ordinal > target.ordinal },
|
||||
label = "AnimatedContent",
|
||||
) { step ->
|
||||
when (step) {
|
||||
Intro -> MultiWalletAccessCodeIntro(
|
||||
modifier = Modifier.padding(top = 56.dp),
|
||||
)
|
||||
AccessCode -> MultiWalletAccessCodeEnter(
|
||||
modifier = Modifier.padding(top = 16.dp),
|
||||
state = state,
|
||||
reEnterAccessCodeState = false,
|
||||
)
|
||||
ConfirmAccessCode -> MultiWalletAccessCodeEnter(
|
||||
modifier = Modifier.padding(top = 16.dp),
|
||||
state = state,
|
||||
reEnterAccessCodeState = true,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
PrimaryButton(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.padding(start = 16.dp, end = 16.dp, bottom = 16.dp)
|
||||
.imePadding(),
|
||||
text = if (state.step == ConfirmAccessCode) {
|
||||
stringResource(R.string.common_confirm)
|
||||
} else {
|
||||
stringResource(R.string.common_continue)
|
||||
},
|
||||
onClick = state.onContinue,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
package com.tangem.features.onboarding.v2.multiwallet.impl.child.accesscode.ui
|
||||
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.tangem.core.ui.components.OutlineTextField
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.features.onboarding.v2.impl.R
|
||||
import com.tangem.features.onboarding.v2.multiwallet.impl.child.accesscode.ui.state.MultiWalletAccessCodeUM
|
||||
|
||||
@Composable
|
||||
internal fun MultiWalletAccessCodeEnter(
|
||||
state: MultiWalletAccessCodeUM,
|
||||
reEnterAccessCodeState: Boolean,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
Column(
|
||||
modifier = modifier
|
||||
.padding(horizontal = 16.dp),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.spacedBy(32.dp),
|
||||
) {
|
||||
Text(
|
||||
text = if (reEnterAccessCodeState) {
|
||||
stringResource(R.string.onboarding_access_code_repeat_code_title)
|
||||
} else {
|
||||
stringResource(R.string.onboarding_access_code_intro_title)
|
||||
},
|
||||
style = TangemTheme.typography.subtitle1,
|
||||
)
|
||||
Text(
|
||||
text = if (reEnterAccessCodeState) {
|
||||
stringResource(R.string.onboarding_access_code_repeat_code_hint)
|
||||
} else {
|
||||
stringResource(R.string.onboarding_access_code_hint)
|
||||
},
|
||||
style = TangemTheme.typography.body1,
|
||||
)
|
||||
|
||||
OutlineTextField(
|
||||
modifier = modifier.fillMaxWidth(),
|
||||
value = if (reEnterAccessCodeState) {
|
||||
state.accessCodeSecond
|
||||
} else {
|
||||
state.accessCodeFirst
|
||||
},
|
||||
onValueChange = if (reEnterAccessCodeState) {
|
||||
state.onAccessCodeSecondChange
|
||||
} else {
|
||||
state.onAccessCodeFirstChange
|
||||
},
|
||||
label = stringResource(id = R.string.onboarding_wallet_info_title_third),
|
||||
isError = state.codesNotMatchError,
|
||||
caption = if (state.codesNotMatchError && reEnterAccessCodeState) {
|
||||
stringResource(R.string.onboarding_access_codes_doesnt_match)
|
||||
} else {
|
||||
null
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(showBackground = true)
|
||||
@Composable
|
||||
private fun Preview() {
|
||||
TangemThemePreview {
|
||||
MultiWalletAccessCodeEnter(
|
||||
reEnterAccessCodeState = false,
|
||||
state = MultiWalletAccessCodeUM(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(showBackground = true)
|
||||
@Composable
|
||||
private fun Preview2() {
|
||||
TangemThemePreview {
|
||||
MultiWalletAccessCodeEnter(
|
||||
reEnterAccessCodeState = true,
|
||||
state = MultiWalletAccessCodeUM(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
package com.tangem.features.onboarding.v2.multiwallet.impl.child.accesscode.ui
|
||||
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.compose.foundation.layout.*
|
||||
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
|
||||
import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.res.vectorResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.tangem.core.ui.components.SpacerH
|
||||
import com.tangem.core.ui.components.SpacerW
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.res.TangemThemePreview
|
||||
import com.tangem.features.onboarding.v2.impl.R
|
||||
|
||||
@Composable
|
||||
internal fun MultiWalletAccessCodeIntro(modifier: Modifier = Modifier) {
|
||||
Column(
|
||||
modifier = modifier,
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.spacedBy(12.dp),
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(R.string.onboarding_access_code_intro_title),
|
||||
style = TangemTheme.typography.h2,
|
||||
)
|
||||
Icon(
|
||||
imageVector = ImageVector.vectorResource(R.drawable.ic_access_code),
|
||||
tint = TangemTheme.colors.icon.informative,
|
||||
contentDescription = null,
|
||||
)
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.padding(horizontal = 46.dp)
|
||||
.fillMaxWidth(),
|
||||
verticalArrangement = Arrangement.spacedBy(24.dp),
|
||||
) {
|
||||
DescriptionItem(
|
||||
title = stringResource(R.string.onboarding_access_code_feature_1_title),
|
||||
body = stringResource(R.string.onboarding_access_code_feature_1_description),
|
||||
iconRes = R.drawable.ic_feature_1,
|
||||
)
|
||||
DescriptionItem(
|
||||
title = stringResource(R.string.onboarding_access_code_feature_2_title),
|
||||
body = stringResource(R.string.onboarding_access_code_feature_2_description),
|
||||
iconRes = R.drawable.ic_feature_2,
|
||||
)
|
||||
DescriptionItem(
|
||||
title = stringResource(R.string.onboarding_access_code_feature_3_title),
|
||||
body = stringResource(R.string.onboarding_access_code_feature_3_description),
|
||||
iconRes = R.drawable.ic_feature_3,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun DescriptionItem(title: String, body: String, @DrawableRes iconRes: Int, modifier: Modifier = Modifier) {
|
||||
Row(modifier) {
|
||||
Icon(
|
||||
imageVector = ImageVector.vectorResource(iconRes),
|
||||
tint = TangemTheme.colors.icon.primary1,
|
||||
contentDescription = null,
|
||||
)
|
||||
SpacerW(20.dp)
|
||||
Column {
|
||||
Text(
|
||||
text = title,
|
||||
style = TangemTheme.typography.subtitle1,
|
||||
)
|
||||
SpacerH(3.dp)
|
||||
Text(
|
||||
text = body,
|
||||
style = TangemTheme.typography.body2,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(showBackground = true)
|
||||
@Composable
|
||||
private fun Preview() {
|
||||
TangemThemePreview {
|
||||
MultiWalletAccessCodeIntro()
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
package com.tangem.features.onboarding.v2.multiwallet.impl.child.accesscode.ui.state
|
||||
|
||||
import androidx.compose.ui.text.input.TextFieldValue
|
||||
|
||||
internal data class MultiWalletAccessCodeUM(
|
||||
val step: Step = Step.Intro,
|
||||
val accessCodeFirst: TextFieldValue = TextFieldValue(""),
|
||||
val accessCodeSecond: TextFieldValue = TextFieldValue(""),
|
||||
val codesNotMatchError: Boolean = false,
|
||||
val onAccessCodeFirstChange: (TextFieldValue) -> Unit = {},
|
||||
val onAccessCodeSecondChange: (TextFieldValue) -> Unit = {},
|
||||
val onContinue: () -> Unit = {},
|
||||
) {
|
||||
enum class Step {
|
||||
Intro,
|
||||
AccessCode,
|
||||
ConfirmAccessCode,
|
||||
}
|
||||
}
|
||||
|
|
@ -1,12 +1,10 @@
|
|||
package com.tangem.features.onboarding.v2.multiwallet.impl.child.seedphrase.ui
|
||||
|
||||
import androidx.compose.animation.AnimatedContent
|
||||
import androidx.compose.animation.AnimatedContentTransitionScope
|
||||
import androidx.compose.animation.core.tween
|
||||
import androidx.compose.animation.togetherWith
|
||||
import androidx.compose.foundation.layout.navigationBarsPadding
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import com.tangem.core.ui.res.TangemAnimations
|
||||
import com.tangem.features.onboarding.v2.multiwallet.impl.child.seedphrase.ui.state.MultiWalletSeedPhraseUM
|
||||
|
||||
@Composable
|
||||
|
|
@ -14,16 +12,7 @@ internal fun MultiWalletSeedPhrase(state: MultiWalletSeedPhraseUM, modifier: Mod
|
|||
AnimatedContent(
|
||||
modifier = modifier.navigationBarsPadding(),
|
||||
targetState = state,
|
||||
transitionSpec = {
|
||||
val direction = if (initialState.order < targetState.order) {
|
||||
AnimatedContentTransitionScope.SlideDirection.Start
|
||||
} else {
|
||||
AnimatedContentTransitionScope.SlideDirection.End
|
||||
}
|
||||
|
||||
slideIntoContainer(towards = direction, animationSpec = tween())
|
||||
.togetherWith(slideOutOfContainer(towards = direction, animationSpec = tween()))
|
||||
},
|
||||
transitionSpec = TangemAnimations.AnimatedContent.slide { from, to -> to.order > from.order },
|
||||
contentKey = { st -> st::class.java },
|
||||
label = "animatedContent",
|
||||
) { st ->
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import com.tangem.core.decompose.di.DecomposeComponent
|
|||
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
|
||||
import com.tangem.features.onboarding.v2.multiwallet.impl.child.accesscode.model.MultiWalletAccessCodeModel
|
||||
import com.tangem.features.onboarding.v2.multiwallet.impl.child.backup.model.MultiWalletBackupModel
|
||||
import com.tangem.features.onboarding.v2.multiwallet.impl.child.createwallet.model.MultiWalletCreateWalletModel
|
||||
import com.tangem.features.onboarding.v2.multiwallet.impl.child.seedphrase.model.MultiWalletSeedPhraseModel
|
||||
|
|
@ -48,4 +49,9 @@ internal interface ModelModule {
|
|||
@IntoMap
|
||||
@ClassKey(MultiWalletSeedPhraseModel::class)
|
||||
fun provideModel4(model: MultiWalletSeedPhraseModel): Model
|
||||
|
||||
@Binds
|
||||
@IntoMap
|
||||
@ClassKey(MultiWalletAccessCodeModel::class)
|
||||
fun provideModel5(model: MultiWalletAccessCodeModel): Model
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue