Updated on 2026-08-14

This commit is contained in:
Tangem 2024-11-20 14:34:19 +05:00
parent 851d9ffea9
commit 9f65e1b80c
18 changed files with 347 additions and 2 deletions

View file

@ -8,20 +8,23 @@ import com.tangem.core.decompose.model.ParamsContainer
import com.tangem.core.decompose.navigation.Router
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.domain.onramp.GetOnrampCountryUseCase
import com.tangem.domain.onramp.OnrampSaveDefaultCountryUseCase
import com.tangem.features.onramp.confirmresidency.ConfirmResidencyComponent
import com.tangem.features.onramp.confirmresidency.entity.ConfirmResidencyBottomSheetConfig
import com.tangem.features.onramp.confirmresidency.entity.ConfirmResidencyUM
import com.tangem.features.onramp.impl.R
import com.tangem.features.onramp.confirmresidency.entity.ConfirmResidencyBottomSheetConfig
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch
import javax.inject.Inject
@ComponentScoped
internal class ConfirmResidencyModel @Inject constructor(
override val dispatchers: CoroutineDispatcherProvider,
private val router: Router,
private val saveDefaultCountryUseCase: OnrampSaveDefaultCountryUseCase,
getOnrampCountryUseCase: GetOnrampCountryUseCase,
paramsContainer: ParamsContainer,
) : Model() {
@ -54,7 +57,9 @@ internal class ConfirmResidencyModel @Inject constructor(
private fun getPrimaryButtonConfig() = if (params.country.onrampAvailable) {
ConfirmResidencyUM.ActionButtonConfig(
onClick = { params.onDismiss(params.country) },
onClick = {
modelScope.launch { saveDefaultCountryUseCase.invoke(params.country) }
},
text = resourceReference(R.string.common_confirm),
)
} else {

View file

@ -0,0 +1,45 @@
package com.tangem.features.onramp.paymentmethod
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import com.tangem.core.decompose.context.AppComponentContext
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
import com.tangem.features.onramp.paymentmethod.entity.PaymentMethodsBottomSheetConfig
import com.tangem.features.onramp.paymentmethod.ui.SelectPaymentMethodBottomSheet
import dagger.assisted.Assisted
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import kotlinx.collections.immutable.toImmutableList
internal class DefaultSelectPaymentMethodComponent @AssistedInject constructor(
@Assisted context: AppComponentContext,
@Assisted private val params: SelectPaymentMethodComponent.Params,
) : SelectPaymentMethodComponent, AppComponentContext by context {
override fun dismiss() {
params.onDismiss()
}
@Composable
override fun BottomSheet() {
val bottomSheetConfig = remember(key1 = this) {
TangemBottomSheetConfig(
isShow = true,
onDismissRequest = ::dismiss,
content = PaymentMethodsBottomSheetConfig(
selectedMethodId = params.selectedMethodId,
paymentMethods = params.paymentMethods.toImmutableList(),
),
)
}
SelectPaymentMethodBottomSheet(bottomSheetConfig)
}
@AssistedFactory
interface Factory : SelectPaymentMethodComponent.Factory {
override fun create(
context: AppComponentContext,
params: SelectPaymentMethodComponent.Params,
): DefaultSelectPaymentMethodComponent
}
}

View file

@ -0,0 +1,16 @@
package com.tangem.features.onramp.paymentmethod
import com.tangem.core.decompose.factory.ComponentFactory
import com.tangem.core.ui.decompose.ComposableBottomSheetComponent
import com.tangem.features.onramp.paymentmethod.entity.PaymentMethodUM
internal interface SelectPaymentMethodComponent : ComposableBottomSheetComponent {
data class Params(
val selectedMethodId: String,
val paymentMethods: List<PaymentMethodUM>,
val onDismiss: () -> Unit,
)
interface Factory : ComponentFactory<Params, SelectPaymentMethodComponent>
}

View file

@ -0,0 +1,20 @@
package com.tangem.features.onramp.paymentmethod.di
import com.tangem.features.onramp.paymentmethod.DefaultSelectPaymentMethodComponent
import com.tangem.features.onramp.paymentmethod.SelectPaymentMethodComponent
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 SelectPaymentMethodComponentModule {
@Binds
@Singleton
fun bindSelectPaymentMethodComponentFactory(
factory: DefaultSelectPaymentMethodComponent.Factory,
): SelectPaymentMethodComponent.Factory
}

View file

@ -0,0 +1,8 @@
package com.tangem.features.onramp.paymentmethod.entity
data class PaymentMethodUM(
val id: String,
val imageUrl: String,
val name: String,
val onSelect: () -> Unit,
)

View file

@ -0,0 +1,9 @@
package com.tangem.features.onramp.paymentmethod.entity
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfigContent
import kotlinx.collections.immutable.ImmutableList
internal data class PaymentMethodsBottomSheetConfig(
val selectedMethodId: String,
val paymentMethods: ImmutableList<PaymentMethodUM>,
) : TangemBottomSheetConfigContent

View file

@ -0,0 +1,118 @@
package com.tangem.features.onramp.paymentmethod.ui
import androidx.compose.foundation.border
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import coil.compose.AsyncImage
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheet
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
import com.tangem.core.ui.extensions.resourceReference
import com.tangem.core.ui.res.TangemTheme
import com.tangem.features.onramp.impl.R
import com.tangem.features.onramp.paymentmethod.entity.PaymentMethodUM
import com.tangem.features.onramp.paymentmethod.entity.PaymentMethodsBottomSheetConfig
import kotlinx.collections.immutable.ImmutableList
@Composable
internal fun SelectPaymentMethodBottomSheet(config: TangemBottomSheetConfig) {
TangemBottomSheet<PaymentMethodsBottomSheetConfig>(
config = config,
addBottomInsets = true,
containerColor = TangemTheme.colors.background.tertiary,
titleText = resourceReference(R.string.onramp_pay_with),
content = { contentConfig ->
SelectPaymentMethodBottomSheetContent(
modifier = Modifier
.padding(horizontal = TangemTheme.dimens.spacing16)
.padding(top = TangemTheme.dimens.spacing12, bottom = TangemTheme.dimens.spacing24)
.fillMaxWidth()
.wrapContentHeight(),
selectedMethodId = contentConfig.selectedMethodId,
methods = contentConfig.paymentMethods,
)
},
)
}
@Composable
private fun SelectPaymentMethodBottomSheetContent(
selectedMethodId: String,
methods: ImmutableList<PaymentMethodUM>,
modifier: Modifier = Modifier,
) {
LazyColumn(
modifier = modifier,
) {
items(
items = methods,
key = { item -> item.id },
contentType = { item -> item::class.java },
itemContent = { item ->
val isSelected = remember(item, selectedMethodId) {
item.id == selectedMethodId
}
val itemModifier = if (isSelected) {
Modifier
.fillMaxWidth()
.border(
width = TangemTheme.dimens.size1,
color = TangemTheme.colors.text.accent,
shape = RoundedCornerShape(TangemTheme.dimens.radius16),
)
.clip(RoundedCornerShape(TangemTheme.dimens.radius16))
.clickable(onClick = item.onSelect)
.padding(
start = TangemTheme.dimens.spacing12,
top = TangemTheme.dimens.spacing10,
bottom = TangemTheme.dimens.spacing10,
)
} else {
Modifier
.fillMaxWidth()
.clip(RoundedCornerShape(TangemTheme.dimens.radius16))
.clickable(onClick = item.onSelect)
.padding(
start = TangemTheme.dimens.spacing12,
top = TangemTheme.dimens.spacing10,
bottom = TangemTheme.dimens.spacing10,
)
}
PaymentMethodItem(
modifier = itemModifier,
paymentMethod = item,
isSelected = isSelected,
)
},
)
}
}
@Composable
private fun PaymentMethodItem(paymentMethod: PaymentMethodUM, isSelected: Boolean, modifier: Modifier = Modifier) {
Row(
modifier = modifier,
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing12),
) {
AsyncImage(
modifier = Modifier
.size(TangemTheme.dimens.size40),
model = paymentMethod.imageUrl,
contentDescription = null,
)
Text(
text = paymentMethod.name,
style = TangemTheme.typography.subtitle2,
color = if (isSelected) TangemTheme.colors.text.primary1 else TangemTheme.colors.text.secondary,
)
}
}