Updated on 2026-08-14

This commit is contained in:
Tangem 2025-09-17 15:15:55 +05:00
parent 9d162d2092
commit 64c7c64b3a
7 changed files with 317 additions and 0 deletions

View file

@ -0,0 +1,18 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="22dp"
android:height="22dp"
android:viewportWidth="22"
android:viewportHeight="22">
<path
android:pathData="M11,22C17.075,22 22,17.075 22,11C22,4.925 17.075,0 11,0C4.925,0 0,4.925 0,11C0,17.075 4.925,22 11,22Z"
android:fillColor="#9391F7"/>
<path
android:pathData="M8.954,11.536C9.898,11.383 10.538,10.494 10.385,9.551C10.232,8.608 9.343,7.967 8.4,8.12C7.457,8.273 6.816,9.162 6.969,10.105C7.122,11.049 8.011,11.689 8.954,11.536Z"
android:fillColor="#ffffff"/>
<path
android:pathData="M13.477,11.536C14.42,11.383 15.061,10.494 14.908,9.551C14.754,8.608 13.866,7.967 12.922,8.12C11.979,8.273 11.339,9.162 11.492,10.105C11.645,11.049 12.534,11.689 13.477,11.536Z"
android:fillColor="#ffffff"/>
<path
android:pathData="M10.936,2.686C6.237,2.686 2.428,6.567 2.43,11.354H4.603C4.603,7.766 7.416,4.858 10.936,4.858C14.455,4.858 17.268,7.766 17.268,11.354H19.441C19.442,6.567 15.633,2.686 10.936,2.686Z"
android:fillColor="#ffffff"/>
</vector>

View file

@ -0,0 +1,23 @@
package com.tangem.features.yield.supply.api
import com.tangem.core.decompose.context.AppComponentContext
import com.tangem.core.decompose.factory.ComponentFactory
import com.tangem.core.ui.decompose.ComposableBottomSheetComponent
import com.tangem.domain.models.currency.CryptoCurrency
interface YieldSupplyDepositedWarningComponent : ComposableBottomSheetComponent {
data class Params(
val cryptoCurrency: CryptoCurrency,
val modelCallback: ModelCallback,
val onDismiss: () -> Unit,
)
interface ModelCallback {
fun onYieldSupplyWarningAcknowledged()
}
interface Factory : ComponentFactory<Params, YieldSupplyDepositedWarningComponent> {
override fun create(context: AppComponentContext, params: Params): YieldSupplyDepositedWarningComponent
}
}

View file

@ -0,0 +1,39 @@
package com.tangem.features.yield.supply.impl.warning
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import com.tangem.core.decompose.context.AppComponentContext
import com.tangem.core.decompose.model.getOrCreateModel
import com.tangem.features.yield.supply.api.YieldSupplyDepositedWarningComponent
import com.tangem.features.yield.supply.impl.warning.model.YieldSupplyDepositedWarningModel
import com.tangem.features.yield.supply.impl.warning.ui.YieldSupplyDepositedWarningContent
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
internal class DefaultYieldSupplyDepositedWarningComponent @AssistedInject constructor(
@Assisted private val appComponentContext: AppComponentContext,
@Assisted private val params: YieldSupplyDepositedWarningComponent.Params,
) : AppComponentContext by appComponentContext, YieldSupplyDepositedWarningComponent {
private val model: YieldSupplyDepositedWarningModel = getOrCreateModel(params = params)
override fun dismiss() {
params.onDismiss()
}
@Composable
override fun BottomSheet() {
val state by model.state.collectAsStateWithLifecycle()
YieldSupplyDepositedWarningContent(warningUM = state, onDismiss = params.onDismiss)
}
@AssistedFactory
interface Factory : YieldSupplyDepositedWarningComponent.Factory {
override fun create(
context: AppComponentContext,
params: YieldSupplyDepositedWarningComponent.Params,
): DefaultYieldSupplyDepositedWarningComponent
}
}

View file

@ -0,0 +1,34 @@
package com.tangem.features.yield.supply.impl.warning.di
import com.tangem.core.decompose.di.ModelComponent
import com.tangem.core.decompose.model.Model
import com.tangem.features.yield.supply.api.YieldSupplyDepositedWarningComponent
import com.tangem.features.yield.supply.impl.warning.DefaultYieldSupplyDepositedWarningComponent
import com.tangem.features.yield.supply.impl.warning.model.YieldSupplyDepositedWarningModel
import dagger.Binds
import dagger.Module
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import dagger.multibindings.ClassKey
import dagger.multibindings.IntoMap
import javax.inject.Singleton
@Module
@InstallIn(SingletonComponent::class)
internal interface YieldSupplyDepositedWarningModule {
@Binds
@Singleton
fun provideYieldSupplyWarningComponentFactory(
impl: DefaultYieldSupplyDepositedWarningComponent.Factory,
): YieldSupplyDepositedWarningComponent.Factory
}
@Module
@InstallIn(ModelComponent::class)
internal interface YieldSupplyDepositedWarningModelModule {
@Binds
@IntoMap
@ClassKey(YieldSupplyDepositedWarningModel::class)
fun provideYieldSupplyWarningModel(impl: YieldSupplyDepositedWarningModel): Model
}

View file

@ -0,0 +1,35 @@
package com.tangem.features.yield.supply.impl.warning.model
import androidx.compose.runtime.Stable
import com.tangem.core.decompose.di.ModelScoped
import com.tangem.core.decompose.model.Model
import com.tangem.core.decompose.model.ParamsContainer
import com.tangem.core.ui.components.currency.icon.converter.CryptoCurrencyToIconStateConverter
import com.tangem.features.yield.supply.api.YieldSupplyDepositedWarningComponent
import com.tangem.features.yield.supply.impl.warning.ui.YieldSupplyDepositedWarningUM
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import javax.inject.Inject
@Stable
@ModelScoped
internal class YieldSupplyDepositedWarningModel @Inject constructor(
paramsContainer: ParamsContainer,
override val dispatchers: CoroutineDispatcherProvider,
) : Model() {
private val params =
paramsContainer.require<YieldSupplyDepositedWarningComponent.Params>()
private val iconStateConverter by lazy(::CryptoCurrencyToIconStateConverter)
internal val state: StateFlow<YieldSupplyDepositedWarningUM>
field = MutableStateFlow(
YieldSupplyDepositedWarningUM(
iconState = iconStateConverter.convert(params.cryptoCurrency),
onWarningAcknowledged = params.modelCallback::onYieldSupplyWarningAcknowledged,
network = params.cryptoCurrency.name,
),
)
}

View file

@ -0,0 +1,159 @@
package com.tangem.features.yield.supply.impl.warning.ui
import android.content.res.Configuration
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.CircleShape
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.painterResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import androidx.compose.ui.unit.dp
import com.tangem.core.ui.R as CoreUiR
import com.tangem.core.ui.components.SecondaryButton
import com.tangem.core.ui.components.SpacerH
import com.tangem.core.ui.components.SpacerH24
import com.tangem.core.ui.components.SpacerH8
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfigContent
import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheetTitle
import com.tangem.core.ui.components.bottomsheets.modal.TangemModalBottomSheetWithFooter
import com.tangem.core.ui.components.currency.icon.CurrencyIcon
import com.tangem.core.ui.components.currency.icon.CurrencyIconState
import com.tangem.core.ui.extensions.stringResourceSafe
import com.tangem.core.ui.res.TangemColorPalette
import com.tangem.core.ui.res.TangemTheme
import com.tangem.core.ui.res.TangemThemePreview
import com.tangem.features.yield.supply.impl.R
@Composable
internal fun YieldSupplyDepositedWarningContent(warningUM: YieldSupplyDepositedWarningUM, onDismiss: () -> Unit) {
TangemModalBottomSheetWithFooter<TangemBottomSheetConfigContent.Empty>(
config = TangemBottomSheetConfig(
isShown = true,
onDismissRequest = onDismiss,
content = TangemBottomSheetConfigContent.Empty,
),
containerColor = TangemTheme.colors.background.primary,
onBack = null,
title = {
TangemModalBottomSheetTitle(
endIconRes = CoreUiR.drawable.ic_close_24,
onEndClick = onDismiss,
)
},
content = {
Content(warningUM)
},
footer = {
SecondaryButton(
modifier = Modifier
.padding(horizontal = 16.dp)
.fillMaxWidth(),
text = stringResourceSafe(CoreUiR.string.balance_hidden_got_it_button),
onClick = onDismiss,
)
},
)
}
@Composable
private fun Content(warningUM: YieldSupplyDepositedWarningUM) {
Column(
modifier = Modifier
.fillMaxWidth()
.background(color = TangemTheme.colors.background.primary)
.padding(
start = 16.dp,
end = 16.dp,
bottom = 16.dp,
),
horizontalAlignment = Alignment.CenterHorizontally,
) {
Box(
modifier = Modifier
.size(height = 56.dp, width = 80.dp),
contentAlignment = Alignment.Center,
) {
CurrencyIcon(
modifier = Modifier
.align(Alignment.CenterStart)
.size(48.dp),
state = warningUM.iconState,
shouldDisplayNetwork = true,
iconSize = 48.dp,
)
Box(
modifier = Modifier
.size(54.dp)
.align(Alignment.CenterEnd)
.background(TangemTheme.colors.background.primary, CircleShape),
)
Image(
painter = painterResource(id = CoreUiR.drawable.img_aave_22),
contentDescription = null,
modifier = Modifier
.padding(3.dp)
.align(Alignment.CenterEnd)
.size(48.dp),
)
}
SpacerH24()
Text(
textAlign = TextAlign.Center,
text = stringResourceSafe(R.string.yield_module_explore_sheet_title, warningUM.network),
style = TangemTheme.typography.h3,
color = TangemTheme.colors.text.primary1,
)
SpacerH8()
Text(
textAlign = TextAlign.Center,
text = stringResourceSafe(R.string.yield_module_explore_sheet_description),
style = TangemTheme.typography.body2,
color = TangemTheme.colors.text.secondary,
)
SpacerH(8.dp)
}
}
@Composable
@Preview(showBackground = true, widthDp = 360)
@Preview(showBackground = true, widthDp = 360, uiMode = Configuration.UI_MODE_NIGHT_YES)
private fun PreviewYieldSupplyDepositedWarningContent(
@PreviewParameter(YieldSupplyWarningContentProvider::class) warningUM: YieldSupplyDepositedWarningUM,
) {
TangemThemePreview {
YieldSupplyDepositedWarningContent(warningUM = warningUM, onDismiss = {})
}
}
private class YieldSupplyWarningContentProvider : PreviewParameterProvider<YieldSupplyDepositedWarningUM> {
private val iconState = CurrencyIconState.TokenIcon(
url = null,
topBadgeIconResId = null,
fallbackTint = TangemColorPalette.Black,
fallbackBackground = TangemColorPalette.Meadow,
isGrayscale = false,
showCustomBadge = false,
)
override val values: Sequence<YieldSupplyDepositedWarningUM>
get() = sequenceOf(
YieldSupplyDepositedWarningUM(
iconState = iconState,
onWarningAcknowledged = {},
network = "Ethereum",
),
)
}

View file

@ -0,0 +1,9 @@
package com.tangem.features.yield.supply.impl.warning.ui
import com.tangem.core.ui.components.currency.icon.CurrencyIconState
internal data class YieldSupplyDepositedWarningUM(
val network: String,
val iconState: CurrencyIconState,
val onWarningAcknowledged: () -> Unit,
)