Updated on 2026-08-14
This commit is contained in:
parent
70d2f5ee06
commit
93abd29e1a
32 changed files with 609 additions and 118 deletions
|
|
@ -29,4 +29,5 @@ dependencies {
|
|||
implementation(deps.material)
|
||||
implementation(deps.compose.shimmer)
|
||||
implementation(deps.kotlin.immutable.collections)
|
||||
implementation(deps.zxing.qrCore)
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
package com.tangem.core.ui.components
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.graphics.asImageBitmap
|
||||
import androidx.compose.ui.graphics.painter.BitmapPainter
|
||||
import androidx.compose.ui.platform.LocalDensity
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import com.tangem.core.ui.extensions.toQrCode
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
|
||||
@Composable
|
||||
fun rememberQrPainters(
|
||||
content: List<String>,
|
||||
size: Dp = TangemTheme.dimens.size248,
|
||||
padding: Dp = TangemTheme.dimens.spacing0,
|
||||
): List<BitmapPainter> {
|
||||
val density = LocalDensity.current
|
||||
return remember(content) {
|
||||
content.map { code ->
|
||||
BitmapPainter(
|
||||
code.toQrCode(
|
||||
sizePx = with(density) { size.roundToPx() },
|
||||
paddingPx = with(density) { padding.roundToPx() },
|
||||
).asImageBitmap(),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
package com.tangem.core.ui.components.bottomsheets
|
||||
|
||||
import androidx.compose.foundation.layout.ColumnScope
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.ModalBottomSheet
|
||||
import androidx.compose.material3.rememberModalBottomSheetState
|
||||
import androidx.compose.runtime.Composable
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
|
||||
/**
|
||||
* Tangem bottom sheet with custom draggable header and config
|
||||
*
|
||||
* @param config data model containing logic and ui models
|
||||
* @param content custom bottom sheet content
|
||||
*/
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun TangemBottomSheet(
|
||||
config: TangemBottomSheetConfig,
|
||||
content: @Composable ColumnScope.(TangemBottomSheetConfigContent) -> Unit,
|
||||
) {
|
||||
ModalBottomSheet(
|
||||
onDismissRequest = config.onDismissRequest,
|
||||
sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true),
|
||||
containerColor = TangemTheme.colors.background.primary,
|
||||
shape = TangemTheme.shapes.bottomSheetLarge,
|
||||
dragHandle = { TangemBottomSheetDraggableHeader() },
|
||||
) {
|
||||
content(config.content)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
package com.tangem.core.ui.components.bottomsheets
|
||||
|
||||
/**
|
||||
* Tangem bottom sheet config
|
||||
*
|
||||
* @property isShow flag that determine if bottom sheet is shown
|
||||
* @property onDismissRequest lambda be invoked when bottom sheet is dismissed
|
||||
* @property content content config
|
||||
*/
|
||||
data class TangemBottomSheetConfig(
|
||||
val isShow: Boolean,
|
||||
val onDismissRequest: () -> Unit,
|
||||
val content: TangemBottomSheetConfigContent,
|
||||
)
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
package com.tangem.core.ui.components.bottomsheets
|
||||
|
||||
/**
|
||||
* General interface for bottom sheet config model
|
||||
*/
|
||||
interface TangemBottomSheetConfigContent
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
package com.tangem.core.ui.components.bottomsheets
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.material.Surface
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
|
||||
@Composable
|
||||
fun TangemBottomSheetDraggableHeader() {
|
||||
Surface(
|
||||
modifier = Modifier
|
||||
.height(TangemTheme.dimens.size20),
|
||||
color = TangemTheme.colors.background.primary,
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.padding(vertical = TangemTheme.dimens.spacing8)
|
||||
.size(
|
||||
width = TangemTheme.dimens.size32,
|
||||
height = TangemTheme.dimens.size4,
|
||||
)
|
||||
.background(
|
||||
color = TangemTheme.colors.icon.inactive,
|
||||
shape = TangemTheme.shapes.roundedCornersSmall,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
package com.tangem.core.ui.components.bottomsheets.tokenreceive
|
||||
|
||||
data class AddressModel(
|
||||
val value: String,
|
||||
val type: Type = Type.Default,
|
||||
) {
|
||||
enum class Type {
|
||||
Legacy, Default
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,192 @@
|
|||
package com.tangem.core.ui.components.bottomsheets.tokenreceive
|
||||
|
||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.lazy.LazyRow
|
||||
import androidx.compose.foundation.lazy.rememberLazyListState
|
||||
import androidx.compose.foundation.pager.HorizontalPager
|
||||
import androidx.compose.foundation.pager.rememberPagerState
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.hapticfeedback.HapticFeedbackType
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.platform.LocalClipboardManager
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.platform.LocalHapticFeedback
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.AnnotatedString
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import com.tangem.core.ui.R
|
||||
import com.tangem.core.ui.components.MiddleEllipsisText
|
||||
import com.tangem.core.ui.components.SecondaryButtonIconStart
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheet
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
|
||||
import com.tangem.core.ui.components.rememberQrPainters
|
||||
import com.tangem.core.ui.extensions.shareText
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
|
||||
@Composable
|
||||
fun TokenReceiveBottomSheet(config: TangemBottomSheetConfig) {
|
||||
if (config.content is TokenReceiveBottomSheetConfig && config.isShow) {
|
||||
TangemBottomSheet(config) { content ->
|
||||
TokenReceiveBottomSheetContent(
|
||||
content = content as TokenReceiveBottomSheetConfig,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun TokenReceiveBottomSheetContent(content: TokenReceiveBottomSheetConfig) {
|
||||
var selectedAddress by remember { mutableStateOf(content.addresses.first()) }
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.padding(
|
||||
start = TangemTheme.dimens.spacing24,
|
||||
top = TangemTheme.dimens.spacing24,
|
||||
end = TangemTheme.dimens.spacing24,
|
||||
bottom = TangemTheme.dimens.spacing16,
|
||||
),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.spacedBy(space = TangemTheme.dimens.spacing24),
|
||||
) {
|
||||
QrCodeContent(
|
||||
content = content,
|
||||
onAddressChange = { selectedAddress = it },
|
||||
)
|
||||
Text(
|
||||
text = stringResource(R.string.receive_bottom_sheet_warning_message_full, content.name),
|
||||
color = TangemTheme.colors.text.secondary,
|
||||
textAlign = TextAlign.Center,
|
||||
style = TangemTheme.typography.caption,
|
||||
)
|
||||
Row(
|
||||
horizontalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing16),
|
||||
) {
|
||||
val clipboardManager = LocalClipboardManager.current
|
||||
val hapticFeedback = LocalHapticFeedback.current
|
||||
val context = LocalContext.current
|
||||
SecondaryButtonIconStart(
|
||||
modifier = Modifier.weight(1f),
|
||||
text = stringResource(id = R.string.common_copy),
|
||||
iconResId = R.drawable.ic_copy_24,
|
||||
onClick = {
|
||||
hapticFeedback.performHapticFeedback(HapticFeedbackType.LongPress)
|
||||
clipboardManager.setText(AnnotatedString(selectedAddress.value))
|
||||
},
|
||||
)
|
||||
SecondaryButtonIconStart(
|
||||
modifier = Modifier.weight(1f),
|
||||
text = stringResource(id = R.string.common_share),
|
||||
iconResId = R.drawable.ic_share_24,
|
||||
onClick = {
|
||||
hapticFeedback.performHapticFeedback(HapticFeedbackType.LongPress)
|
||||
context.shareText(selectedAddress.value)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("LongMethod")
|
||||
@OptIn(ExperimentalFoundationApi::class)
|
||||
@Composable
|
||||
private fun QrCodeContent(content: TokenReceiveBottomSheetConfig, onAddressChange: (AddressModel) -> Unit) {
|
||||
val qrCodes = rememberQrPainters(content.addresses.map(AddressModel::value))
|
||||
val pagerState = rememberPagerState()
|
||||
val pageCount = content.addresses.count()
|
||||
|
||||
LaunchedEffect(key1 = pagerState.currentPage) {
|
||||
onAddressChange.invoke(content.addresses[pagerState.currentPage])
|
||||
}
|
||||
|
||||
HorizontalPager(
|
||||
pageCount = pageCount,
|
||||
state = pagerState,
|
||||
) { currentPage ->
|
||||
Column(
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.spacedBy(TangemTheme.dimens.spacing24),
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(
|
||||
R.string.receive_bottom_sheet_warning_message,
|
||||
getName(content = content, index = pagerState.currentPage),
|
||||
content.symbol,
|
||||
content.network,
|
||||
),
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
textAlign = TextAlign.Center,
|
||||
style = TangemTheme.typography.h3,
|
||||
)
|
||||
Image(
|
||||
painter = qrCodes[currentPage],
|
||||
contentDescription = null,
|
||||
contentScale = ContentScale.Fit,
|
||||
modifier = Modifier
|
||||
.size(TangemTheme.dimens.size248),
|
||||
)
|
||||
MiddleEllipsisText(
|
||||
text = content.addresses[currentPage].value,
|
||||
color = TangemTheme.colors.text.primary1,
|
||||
textAlign = TextAlign.Center,
|
||||
style = TangemTheme.typography.subtitle1,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if (pageCount > 1) {
|
||||
val indicatorState = rememberLazyListState()
|
||||
val selectedColor = TangemTheme.colors.icon.primary1
|
||||
val unselectedColor = TangemTheme.colors.icon.informative
|
||||
LazyRow(
|
||||
modifier = Modifier
|
||||
.height(TangemTheme.dimens.size20),
|
||||
state = indicatorState,
|
||||
horizontalArrangement = Arrangement.Center,
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
repeat(pageCount) { iteration ->
|
||||
item(key = iteration) {
|
||||
val color = if (pagerState.currentPage == iteration) {
|
||||
selectedColor
|
||||
} else {
|
||||
unselectedColor
|
||||
}
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.padding(
|
||||
start = TangemTheme.dimens.spacing4,
|
||||
top = TangemTheme.dimens.spacing6,
|
||||
end = TangemTheme.dimens.spacing4,
|
||||
bottom = TangemTheme.dimens.spacing6,
|
||||
)
|
||||
.background(color, CircleShape)
|
||||
.size(TangemTheme.dimens.size7),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun getName(content: TokenReceiveBottomSheetConfig, index: Int): String {
|
||||
return if (content.addresses.size < 2) {
|
||||
content.name
|
||||
} else {
|
||||
"${
|
||||
stringResource(
|
||||
id = when (content.addresses[index].type) {
|
||||
AddressModel.Type.Default -> R.string.address_type_default
|
||||
AddressModel.Type.Legacy -> R.string.address_type_legacy
|
||||
},
|
||||
)
|
||||
} ${content.name}"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
package com.tangem.core.ui.components.bottomsheets.tokenreceive
|
||||
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfigContent
|
||||
|
||||
class TokenReceiveBottomSheetConfig(
|
||||
val name: String,
|
||||
val symbol: String,
|
||||
val network: String,
|
||||
val addresses: List<AddressModel>,
|
||||
) : TangemBottomSheetConfigContent
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
package com.tangem.core.ui.extensions
|
||||
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import androidx.core.content.ContextCompat
|
||||
|
||||
fun Context.shareText(text: String) {
|
||||
val sendIntent: Intent = Intent().apply {
|
||||
action = Intent.ACTION_SEND
|
||||
putExtra(Intent.EXTRA_TEXT, text)
|
||||
type = "text/plain"
|
||||
}
|
||||
val shareIntent = Intent.createChooser(sendIntent, null)
|
||||
ContextCompat.startActivity(this, shareIntent, null)
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
package com.tangem.core.ui.extensions
|
||||
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.Color
|
||||
import com.google.zxing.BarcodeFormat
|
||||
import com.google.zxing.EncodeHintType
|
||||
import com.google.zxing.qrcode.QRCodeWriter
|
||||
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel
|
||||
import java.util.Hashtable
|
||||
|
||||
@Suppress("MagicNumber")
|
||||
fun String.toQrCode(sizePx: Int = 256, paddingPx: Int = 0): Bitmap {
|
||||
val hintMap = Hashtable<EncodeHintType, Any>()
|
||||
hintMap[EncodeHintType.ERROR_CORRECTION] = ErrorCorrectionLevel.M // H = 30% damage
|
||||
hintMap[EncodeHintType.MARGIN] = paddingPx
|
||||
|
||||
val qrCodeWriter = QRCodeWriter()
|
||||
|
||||
val bitMatrix = qrCodeWriter.encode(this, BarcodeFormat.QR_CODE, sizePx, sizePx, hintMap)
|
||||
val width = bitMatrix.width
|
||||
val bmp = Bitmap.createBitmap(width, width, Bitmap.Config.RGB_565)
|
||||
for (x in 0 until width) {
|
||||
for (y in 0 until width) {
|
||||
bmp.setPixel(
|
||||
y,
|
||||
x,
|
||||
if (bitMatrix.get(x, y)) Color.BLACK else Color.WHITE,
|
||||
)
|
||||
}
|
||||
}
|
||||
return bmp
|
||||
}
|
||||
|
|
@ -81,6 +81,7 @@ data class TangemDimens internal constructor(
|
|||
val size158: Dp = 158.dp,
|
||||
val size164: Dp = 164.dp,
|
||||
val size200: Dp = 200.dp,
|
||||
val size248: Dp = 248.dp,
|
||||
// endregion Size
|
||||
// region Spacing
|
||||
val spacing0: Dp = 0.dp,
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ data class TangemShapes internal constructor(
|
|||
val roundedCornersXMedium: Shape,
|
||||
val roundedCornersLarge: Shape,
|
||||
val bottomSheet: Shape,
|
||||
val bottomSheetLarge: Shape,
|
||||
) {
|
||||
constructor(dimens: TangemDimens) : this(
|
||||
roundedCornersSmall = RoundedCornerShape(size = dimens.radius2),
|
||||
|
|
@ -25,5 +26,9 @@ data class TangemShapes internal constructor(
|
|||
topStart = dimens.radius16,
|
||||
topEnd = dimens.radius16,
|
||||
),
|
||||
bottomSheetLarge = RoundedCornerShape(
|
||||
topStart = dimens.radius24,
|
||||
topEnd = dimens.radius24,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
@ -3,6 +3,7 @@ package com.tangem.domain.walletmanager
|
|||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.blockchain.common.BlockchainSdkError
|
||||
import com.tangem.blockchain.common.WalletManager
|
||||
import com.tangem.blockchain.common.address.Address
|
||||
import com.tangem.blockchain.extensions.Result
|
||||
import com.tangem.crypto.hdWallet.DerivationPath
|
||||
import com.tangem.datasource.config.ConfigManager
|
||||
|
|
@ -202,6 +203,21 @@ class DefaultWalletManagersFacade(
|
|||
return walletManager
|
||||
}
|
||||
|
||||
override suspend fun getAddress(userWalletId: UserWalletId, network: Network): List<Address> {
|
||||
val userWallet = getUserWallet(userWalletId)
|
||||
val blockchain = Blockchain.fromId(network.id.value)
|
||||
|
||||
return getOrCreateWalletManager(
|
||||
userWallet = userWallet,
|
||||
blockchain = blockchain,
|
||||
derivationPath = network.derivationPath.value,
|
||||
)
|
||||
?.wallet
|
||||
?.addresses
|
||||
?.sortedBy { it.type }
|
||||
.orEmpty()
|
||||
}
|
||||
|
||||
private fun updateWalletManagerTokensIfNeeded(walletManager: WalletManager, tokens: Set<CryptoCurrency.Token>) {
|
||||
if (tokens.isEmpty()) return
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package com.tangem.domain.walletmanager
|
|||
|
||||
import com.tangem.blockchain.common.Blockchain
|
||||
import com.tangem.blockchain.common.WalletManager
|
||||
import com.tangem.blockchain.common.address.Address
|
||||
import com.tangem.domain.tokens.models.CryptoCurrency
|
||||
import com.tangem.domain.tokens.models.Network
|
||||
import com.tangem.domain.txhistory.models.PaginationWrapper
|
||||
|
|
@ -70,4 +71,12 @@ interface WalletManagersFacade {
|
|||
blockchain: Blockchain,
|
||||
derivationPath: String?,
|
||||
): WalletManager?
|
||||
|
||||
/**
|
||||
* Returns ordered list of addresses for selected wallet for given currency
|
||||
*
|
||||
* @param userWalletId selected wallet id
|
||||
* @param network network of currency
|
||||
*/
|
||||
suspend fun getAddress(userWalletId: UserWalletId, network: Network): List<Address>
|
||||
}
|
||||
|
|
@ -17,6 +17,7 @@ dependencies {
|
|||
// region Domain modules
|
||||
implementation(projects.domain.legacy)
|
||||
implementation(projects.domain.models)
|
||||
implementation(projects.domain.tokens)
|
||||
implementation(projects.domain.tokens.models)
|
||||
implementation(projects.domain.wallets.models)
|
||||
// endregion
|
||||
|
|
|
|||
|
|
@ -90,5 +90,6 @@ internal object TokenDetailsPreviewData {
|
|||
dialogConfig = null,
|
||||
pendingTxs = persistentListOf(),
|
||||
pullToRefreshConfig = pullToRefreshConfig,
|
||||
bottomSheetConfig = null,
|
||||
)
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
package com.tangem.feature.tokendetails.presentation.tokendetails.state
|
||||
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
|
||||
import com.tangem.core.ui.components.marketprice.MarketPriceBlockState
|
||||
import com.tangem.core.ui.components.transactions.state.TransactionState
|
||||
import com.tangem.core.ui.components.transactions.state.TxHistoryState
|
||||
|
|
@ -16,4 +17,5 @@ internal data class TokenDetailsState(
|
|||
val txHistoryState: TxHistoryState,
|
||||
val dialogConfig: TokenDetailsDialogConfig?,
|
||||
val pullToRefreshConfig: TokenDetailsPullToRefreshConfig,
|
||||
val bottomSheetConfig: TangemBottomSheetConfig?,
|
||||
)
|
||||
|
|
@ -51,6 +51,7 @@ internal class TokenDetailsSkeletonStateConverter(
|
|||
),
|
||||
dialogConfig = null,
|
||||
pullToRefreshConfig = createPullToRefresh(),
|
||||
bottomSheetConfig = null,
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,11 @@ package com.tangem.feature.tokendetails.presentation.tokendetails.state.factory
|
|||
|
||||
import androidx.paging.PagingData
|
||||
import arrow.core.Either
|
||||
import com.tangem.blockchain.common.address.Address
|
||||
import com.tangem.common.Provider
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
|
||||
import com.tangem.core.ui.components.bottomsheets.tokenreceive.AddressModel
|
||||
import com.tangem.core.ui.components.bottomsheets.tokenreceive.TokenReceiveBottomSheetConfig
|
||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.domain.tokens.error.CurrencyStatusError
|
||||
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
||||
|
|
@ -131,4 +135,31 @@ internal class TokenDetailsStateFactory(
|
|||
fun getRefreshedState(): TokenDetailsState {
|
||||
return refreshStateConverter.convert(false)
|
||||
}
|
||||
|
||||
fun getStateWithReceiveBottomSheet(currency: CryptoCurrency, addresses: List<Address>): TokenDetailsState {
|
||||
return currentStateProvider().copy(
|
||||
bottomSheetConfig = TangemBottomSheetConfig(
|
||||
isShow = true,
|
||||
onDismissRequest = clickIntents::onDismissBottomSheet,
|
||||
content = TokenReceiveBottomSheetConfig(
|
||||
name = currency.name,
|
||||
symbol = currency.symbol,
|
||||
network = currency.network.name,
|
||||
addresses = addresses.map {
|
||||
AddressModel(
|
||||
value = it.value,
|
||||
type = AddressModel.Type.valueOf(it.type.name),
|
||||
)
|
||||
},
|
||||
),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
fun getStateWithClosedBottomSheet(): TokenDetailsState {
|
||||
val state = currentStateProvider()
|
||||
return state.copy(
|
||||
bottomSheetConfig = state.bottomSheetConfig?.copy(isShow = false),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -15,6 +15,7 @@ import androidx.compose.ui.draw.clip
|
|||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.util.fastForEach
|
||||
import androidx.paging.compose.collectAsLazyPagingItems
|
||||
import com.tangem.core.ui.components.bottomsheets.tokenreceive.TokenReceiveBottomSheet
|
||||
import com.tangem.core.ui.components.marketprice.MarketPriceBlock
|
||||
import com.tangem.core.ui.components.marketprice.MarketPriceBlockState
|
||||
import com.tangem.core.ui.components.transactions.Transaction
|
||||
|
|
@ -95,6 +96,12 @@ internal fun TokenDetailsScreen(state: TokenDetailsState) {
|
|||
}
|
||||
|
||||
TokenDetailsDialogs(state = state)
|
||||
|
||||
state.bottomSheetConfig?.let { config ->
|
||||
TokenReceiveBottomSheet(
|
||||
config = config,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -25,4 +25,6 @@ interface TokenDetailsClickIntents {
|
|||
fun onReloadClick()
|
||||
|
||||
fun onExploreClick()
|
||||
|
||||
fun onDismissBottomSheet()
|
||||
}
|
||||
|
|
@ -16,6 +16,7 @@ import com.tangem.domain.tokens.model.CryptoCurrencyStatus
|
|||
import com.tangem.domain.tokens.models.CryptoCurrency
|
||||
import com.tangem.domain.txhistory.usecase.GetTxHistoryItemsCountUseCase
|
||||
import com.tangem.domain.txhistory.usecase.GetTxHistoryItemsUseCase
|
||||
import com.tangem.domain.walletmanager.WalletManagersFacade
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.domain.wallets.usecase.GetExploreUrlUseCase
|
||||
|
|
@ -48,6 +49,7 @@ internal class TokenDetailsViewModel @Inject constructor(
|
|||
private val getCryptoCurrencyActionsUseCase: GetCryptoCurrencyActionsUseCase,
|
||||
private val removeCurrencyUseCase: RemoveCurrencyUseCase,
|
||||
private val getNetworkCoinStatusUseCase: GetNetworkCoinStatusUseCase,
|
||||
private val walletManagersFacade: WalletManagersFacade,
|
||||
private val reduxStateHolder: ReduxStateHolder,
|
||||
savedStateHandle: SavedStateHandle,
|
||||
) : ViewModel(), DefaultLifecycleObserver, TokenDetailsClickIntents {
|
||||
|
|
@ -209,7 +211,17 @@ internal class TokenDetailsViewModel @Inject constructor(
|
|||
}
|
||||
|
||||
override fun onReceiveClick() {
|
||||
// TODO: [REDACTED_JIRA]
|
||||
viewModelScope.launch(dispatchers.io) {
|
||||
val addresses = walletManagersFacade.getAddress(
|
||||
userWalletId = wallet.walletId,
|
||||
network = cryptoCurrency.network,
|
||||
)
|
||||
|
||||
uiState = stateFactory.getStateWithReceiveBottomSheet(
|
||||
currency = cryptoCurrency,
|
||||
addresses = addresses,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onSellClick() {
|
||||
|
|
@ -274,4 +286,8 @@ internal class TokenDetailsViewModel @Inject constructor(
|
|||
uiState = stateFactory.getRefreshedState()
|
||||
}.saveIn(refreshStateJobHolder)
|
||||
}
|
||||
|
||||
override fun onDismissBottomSheet() {
|
||||
uiState = stateFactory.getStateWithClosedBottomSheet()
|
||||
}
|
||||
}
|
||||
|
|
@ -2,6 +2,7 @@ package com.tangem.feature.wallet.presentation.common
|
|||
|
||||
import androidx.paging.PagingData
|
||||
import com.tangem.core.ui.R
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
|
||||
import com.tangem.core.ui.components.marketprice.MarketPriceBlockState
|
||||
import com.tangem.core.ui.components.marketprice.PriceChangeConfig
|
||||
import com.tangem.core.ui.components.transactions.state.TransactionState
|
||||
|
|
@ -290,10 +291,10 @@ internal object WalletPreviewData {
|
|||
}
|
||||
|
||||
val bottomSheet by lazy {
|
||||
WalletBottomSheetConfig(
|
||||
TangemBottomSheetConfig(
|
||||
isShow = false,
|
||||
onDismissRequest = {},
|
||||
content = WalletBottomSheetConfig.BottomSheetContentConfig.UnlockWallets(
|
||||
content = WalletBottomSheetConfig.UnlockWallets(
|
||||
onUnlockClick = {},
|
||||
onScanClick = {},
|
||||
),
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package com.tangem.feature.wallet.presentation.wallet.state
|
||||
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.components.*
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
|
|
@ -20,7 +21,7 @@ internal sealed class WalletMultiCurrencyState : WalletState.ContentState() {
|
|||
override val walletsListConfig: WalletsListConfig,
|
||||
override val pullToRefreshConfig: WalletPullToRefreshConfig,
|
||||
override val notifications: ImmutableList<WalletNotification>,
|
||||
override val bottomSheetConfig: WalletBottomSheetConfig?,
|
||||
override val bottomSheetConfig: TangemBottomSheetConfig?,
|
||||
override val tokensListState: WalletTokensListState,
|
||||
val tokenActionsBottomSheet: ActionsBottomSheetConfig?,
|
||||
val onManageTokensClick: () -> Unit,
|
||||
|
|
@ -42,10 +43,10 @@ internal sealed class WalletMultiCurrencyState : WalletState.ContentState() {
|
|||
WalletNotification.UnlockWallets(onUnlockWalletsNotificationClick),
|
||||
)
|
||||
|
||||
override val bottomSheetConfig = WalletBottomSheetConfig(
|
||||
override val bottomSheetConfig = TangemBottomSheetConfig(
|
||||
isShow = isBottomSheetShow,
|
||||
onDismissRequest = onBottomSheetDismiss,
|
||||
content = WalletBottomSheetConfig.BottomSheetContentConfig.UnlockWallets(
|
||||
content = WalletBottomSheetConfig.UnlockWallets(
|
||||
onUnlockClick = onUnlockClick,
|
||||
onScanClick = onScanClick,
|
||||
),
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package com.tangem.feature.wallet.presentation.wallet.state
|
|||
|
||||
import androidx.compose.runtime.Immutable
|
||||
import androidx.paging.PagingData
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
|
||||
import com.tangem.core.ui.components.marketprice.MarketPriceBlockState
|
||||
import com.tangem.core.ui.components.transactions.state.TransactionState
|
||||
import com.tangem.core.ui.components.transactions.state.TxHistoryState
|
||||
|
|
@ -31,7 +32,7 @@ internal sealed class WalletSingleCurrencyState : WalletState.ContentState() {
|
|||
override val walletsListConfig: WalletsListConfig,
|
||||
override val pullToRefreshConfig: WalletPullToRefreshConfig,
|
||||
override val notifications: ImmutableList<WalletNotification>,
|
||||
override val bottomSheetConfig: WalletBottomSheetConfig?,
|
||||
override val bottomSheetConfig: TangemBottomSheetConfig?,
|
||||
override val buttons: PersistentList<WalletManageButton>,
|
||||
override val txHistoryState: TxHistoryState,
|
||||
val marketPriceBlockState: MarketPriceBlockState,
|
||||
|
|
@ -55,10 +56,10 @@ internal sealed class WalletSingleCurrencyState : WalletState.ContentState() {
|
|||
WalletNotification.UnlockWallets(onUnlockWalletsNotificationClick),
|
||||
)
|
||||
|
||||
override val bottomSheetConfig = WalletBottomSheetConfig(
|
||||
override val bottomSheetConfig = TangemBottomSheetConfig(
|
||||
isShow = isBottomSheetShow,
|
||||
onDismissRequest = onBottomSheetDismiss,
|
||||
content = WalletBottomSheetConfig.BottomSheetContentConfig.UnlockWallets(
|
||||
content = WalletBottomSheetConfig.UnlockWallets(
|
||||
onUnlockClick = onUnlockClick,
|
||||
onScanClick = onScanClick,
|
||||
),
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
package com.tangem.feature.wallet.presentation.wallet.state
|
||||
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.components.*
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
|
||||
|
|
@ -29,7 +30,7 @@ internal sealed class WalletState {
|
|||
abstract val notifications: ImmutableList<WalletNotification>
|
||||
|
||||
/** Bottom sheet config */
|
||||
abstract val bottomSheetConfig: WalletBottomSheetConfig?
|
||||
abstract val bottomSheetConfig: TangemBottomSheetConfig?
|
||||
|
||||
/**
|
||||
* Util function that allow to make a copy
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package com.tangem.feature.wallet.presentation.wallet.state.components
|
|||
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfigContent
|
||||
import com.tangem.core.ui.extensions.TextReference
|
||||
import com.tangem.core.ui.extensions.WrappedList
|
||||
import com.tangem.core.ui.res.TangemColorPalette
|
||||
|
|
@ -10,90 +11,79 @@ import com.tangem.feature.wallet.impl.R
|
|||
/**
|
||||
* Wallet bottom sheet config
|
||||
*
|
||||
* @property isShow flag that determine if bottom sheet is shown
|
||||
* @property onDismissRequest lambda be invoked when bottom sheet is dismissed
|
||||
* @property content content config
|
||||
*
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
// TODO: Finalize notification strings [REDACTED_JIRA]
|
||||
internal data class WalletBottomSheetConfig(
|
||||
val isShow: Boolean,
|
||||
val onDismissRequest: () -> Unit,
|
||||
val content: BottomSheetContentConfig,
|
||||
) {
|
||||
sealed class WalletBottomSheetConfig(
|
||||
open val title: TextReference,
|
||||
open val subtitle: TextReference,
|
||||
@DrawableRes open val iconResId: Int,
|
||||
open val tint: Color? = null,
|
||||
val primaryButtonConfig: ButtonConfig,
|
||||
val secondaryButtonConfig: ButtonConfig,
|
||||
) : TangemBottomSheetConfigContent {
|
||||
|
||||
sealed class BottomSheetContentConfig(
|
||||
open val title: TextReference,
|
||||
open val subtitle: TextReference,
|
||||
@DrawableRes open val iconResId: Int,
|
||||
open val tint: Color? = null,
|
||||
val primaryButtonConfig: ButtonConfig,
|
||||
val secondaryButtonConfig: ButtonConfig,
|
||||
) {
|
||||
data class ButtonConfig(
|
||||
val text: TextReference,
|
||||
val onClick: () -> Unit,
|
||||
@DrawableRes val iconResId: Int? = null,
|
||||
)
|
||||
|
||||
data class ButtonConfig(
|
||||
val text: TextReference,
|
||||
val onClick: () -> Unit,
|
||||
@DrawableRes val iconResId: Int? = null,
|
||||
)
|
||||
data class UnlockWallets(
|
||||
val onUnlockClick: () -> Unit,
|
||||
val onScanClick: () -> Unit,
|
||||
) : WalletBottomSheetConfig(
|
||||
title = TextReference.Str(value = "Unlock needed"),
|
||||
subtitle = TextReference.Str(
|
||||
value = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor " +
|
||||
"incididunt ut labore et dolore magna aliqua.",
|
||||
),
|
||||
iconResId = R.drawable.ic_locked_24,
|
||||
tint = TangemColorPalette.Black,
|
||||
primaryButtonConfig = ButtonConfig(text = TextReference.Str(value = "Unlock"), onClick = onUnlockClick),
|
||||
secondaryButtonConfig = ButtonConfig(
|
||||
text = TextReference.Str(value = "Scan card"),
|
||||
onClick = onScanClick,
|
||||
iconResId = R.drawable.ic_tangem_24,
|
||||
),
|
||||
)
|
||||
|
||||
data class UnlockWallets(
|
||||
val onUnlockClick: () -> Unit,
|
||||
val onScanClick: () -> Unit,
|
||||
) : BottomSheetContentConfig(
|
||||
title = TextReference.Str(value = "Unlock needed"),
|
||||
subtitle = TextReference.Str(
|
||||
value = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor " +
|
||||
"incididunt ut labore et dolore magna aliqua.",
|
||||
),
|
||||
iconResId = R.drawable.ic_locked_24,
|
||||
tint = TangemColorPalette.Black,
|
||||
primaryButtonConfig = ButtonConfig(text = TextReference.Str(value = "Unlock"), onClick = onUnlockClick),
|
||||
secondaryButtonConfig = ButtonConfig(
|
||||
text = TextReference.Str(value = "Scan card"),
|
||||
onClick = onScanClick,
|
||||
iconResId = R.drawable.ic_tangem_24,
|
||||
),
|
||||
)
|
||||
data class LikeTangemApp(
|
||||
val onRateTheAppClick: () -> Unit,
|
||||
val onShareClick: () -> Unit,
|
||||
) : WalletBottomSheetConfig(
|
||||
title = TextReference.Str(value = "Like Tangem App?"),
|
||||
subtitle = TextReference.Str(value = "How was your experience with our app? Let us know:"),
|
||||
iconResId = R.drawable.ic_star_24,
|
||||
tint = TangemColorPalette.Tangerine,
|
||||
primaryButtonConfig = ButtonConfig(
|
||||
text = TextReference.Str(value = "Rate the app"),
|
||||
onClick = onRateTheAppClick,
|
||||
),
|
||||
secondaryButtonConfig = ButtonConfig(
|
||||
text = TextReference.Str(value = "Share feedback"),
|
||||
onClick = onShareClick,
|
||||
),
|
||||
)
|
||||
|
||||
data class LikeTangemApp(
|
||||
val onRateTheAppClick: () -> Unit,
|
||||
val onShareClick: () -> Unit,
|
||||
) : BottomSheetContentConfig(
|
||||
title = TextReference.Str(value = "Like Tangem App?"),
|
||||
subtitle = TextReference.Str(value = "How was your experience with our app? Let us know:"),
|
||||
iconResId = R.drawable.ic_star_24,
|
||||
tint = TangemColorPalette.Tangerine,
|
||||
primaryButtonConfig = ButtonConfig(
|
||||
text = TextReference.Str(value = "Rate the app"),
|
||||
onClick = onRateTheAppClick,
|
||||
),
|
||||
secondaryButtonConfig = ButtonConfig(
|
||||
text = TextReference.Str(value = "Share feedback"),
|
||||
onClick = onShareClick,
|
||||
),
|
||||
)
|
||||
|
||||
data class CriticalWarningAlreadySignedHashes(
|
||||
val onOkClick: () -> Unit,
|
||||
val onCancelClick: () -> Unit,
|
||||
) : BottomSheetContentConfig(
|
||||
title = TextReference.Res(
|
||||
id = R.string.warning_important_security_info,
|
||||
formatArgs = WrappedList(listOf("\u26A0")),
|
||||
),
|
||||
subtitle = TextReference.Res(id = R.string.alert_signed_hashes_message),
|
||||
iconResId = R.drawable.img_attention_20,
|
||||
tint = null,
|
||||
primaryButtonConfig = ButtonConfig(
|
||||
text = TextReference.Res(id = R.string.common_ok),
|
||||
onClick = onOkClick,
|
||||
),
|
||||
secondaryButtonConfig = ButtonConfig(
|
||||
text = TextReference.Res(id = R.string.common_cancel),
|
||||
onClick = onCancelClick,
|
||||
),
|
||||
)
|
||||
}
|
||||
data class CriticalWarningAlreadySignedHashes(
|
||||
val onOkClick: () -> Unit,
|
||||
val onCancelClick: () -> Unit,
|
||||
) : WalletBottomSheetConfig(
|
||||
title = TextReference.Res(
|
||||
id = R.string.warning_important_security_info,
|
||||
formatArgs = WrappedList(listOf("\u26A0")),
|
||||
),
|
||||
subtitle = TextReference.Res(id = R.string.alert_signed_hashes_message),
|
||||
iconResId = R.drawable.img_attention_20,
|
||||
tint = null,
|
||||
primaryButtonConfig = ButtonConfig(
|
||||
text = TextReference.Res(id = R.string.common_ok),
|
||||
onClick = onOkClick,
|
||||
),
|
||||
secondaryButtonConfig = ButtonConfig(
|
||||
text = TextReference.Res(id = R.string.common_cancel),
|
||||
onClick = onCancelClick,
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
@ -3,6 +3,8 @@ package com.tangem.feature.wallet.presentation.wallet.state.factory
|
|||
import androidx.paging.PagingData
|
||||
import arrow.core.Either
|
||||
import com.tangem.common.Provider
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfigContent
|
||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.domain.common.CardTypesResolver
|
||||
import com.tangem.domain.tokens.error.CurrencyStatusError
|
||||
|
|
@ -18,7 +20,6 @@ import com.tangem.feature.wallet.presentation.wallet.state.ActionsBottomSheetCon
|
|||
import com.tangem.feature.wallet.presentation.wallet.state.WalletMultiCurrencyState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletSingleCurrencyState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.components.WalletBottomSheetConfig
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.components.WalletNotification
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.factory.txhistory.WalletLoadedTxHistoryConverter
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.factory.txhistory.WalletLoadingTxHistoryConverter
|
||||
|
|
@ -161,10 +162,10 @@ internal class WalletStateFactory(
|
|||
|
||||
fun getRefreshedState(): WalletState = refreshStateConverter.convert(value = false)
|
||||
|
||||
fun getStateWithOpenWalletBottomSheet(content: WalletBottomSheetConfig.BottomSheetContentConfig): WalletState {
|
||||
fun getStateWithOpenWalletBottomSheet(content: TangemBottomSheetConfigContent): WalletState {
|
||||
return when (val state = currentStateProvider() as WalletState.ContentState) {
|
||||
is WalletMultiCurrencyState.Content -> state.copy(
|
||||
bottomSheetConfig = WalletBottomSheetConfig(
|
||||
bottomSheetConfig = TangemBottomSheetConfig(
|
||||
isShow = true,
|
||||
onDismissRequest = clickIntents::onDismissBottomSheet,
|
||||
content = content,
|
||||
|
|
@ -175,7 +176,7 @@ internal class WalletStateFactory(
|
|||
onBottomSheetDismiss = clickIntents::onDismissBottomSheet,
|
||||
)
|
||||
is WalletSingleCurrencyState.Content -> state.copy(
|
||||
bottomSheetConfig = WalletBottomSheetConfig(
|
||||
bottomSheetConfig = TangemBottomSheetConfig(
|
||||
isShow = true,
|
||||
onDismissRequest = clickIntents::onDismissBottomSheet,
|
||||
content = content,
|
||||
|
|
|
|||
|
|
@ -18,6 +18,8 @@ import androidx.compose.ui.tooling.preview.PreviewParameter
|
|||
import androidx.compose.ui.tooling.preview.datasource.CollectionPreviewParameterProvider
|
||||
import androidx.paging.compose.collectAsLazyPagingItems
|
||||
import com.tangem.core.ui.components.PrimaryButton
|
||||
import com.tangem.core.ui.components.bottomsheets.tokenreceive.TokenReceiveBottomSheet
|
||||
import com.tangem.core.ui.components.bottomsheets.tokenreceive.TokenReceiveBottomSheetConfig
|
||||
import com.tangem.core.ui.components.transactions.state.TxHistoryState
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.feature.wallet.impl.R
|
||||
|
|
@ -25,6 +27,7 @@ import com.tangem.feature.wallet.presentation.common.WalletPreviewData
|
|||
import com.tangem.feature.wallet.presentation.wallet.state.WalletMultiCurrencyState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletSingleCurrencyState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.WalletState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.components.WalletBottomSheetConfig
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.components.WalletTokensListState
|
||||
import com.tangem.feature.wallet.presentation.wallet.state.components.WalletTokensListState.OrganizeTokensButtonState
|
||||
import com.tangem.feature.wallet.presentation.wallet.ui.components.TokenActionsBottomSheet
|
||||
|
|
@ -167,7 +170,15 @@ private fun ManageTokensButton(onManageTokensClick: () -> Unit) {
|
|||
private fun WalletBottomSheets(state: WalletState) {
|
||||
val bottomSheetConfig = (state as? WalletState.ContentState)?.bottomSheetConfig
|
||||
if (bottomSheetConfig != null && bottomSheetConfig.isShow) {
|
||||
WalletBottomSheet(config = bottomSheetConfig)
|
||||
when (bottomSheetConfig.content) {
|
||||
is WalletBottomSheetConfig -> {
|
||||
WalletBottomSheet(config = bottomSheetConfig)
|
||||
}
|
||||
|
||||
is TokenReceiveBottomSheetConfig -> {
|
||||
TokenReceiveBottomSheet(config = bottomSheetConfig)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
(state as? WalletMultiCurrencyState.Content)?.let { multiCurrencyState ->
|
||||
|
|
|
|||
|
|
@ -15,6 +15,8 @@ import com.tangem.core.ui.components.PrimaryButton
|
|||
import com.tangem.core.ui.components.PrimaryButtonIconStart
|
||||
import com.tangem.core.ui.components.SecondaryButton
|
||||
import com.tangem.core.ui.components.SecondaryButtonIconStart
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheet
|
||||
import com.tangem.core.ui.components.bottomsheets.TangemBottomSheetConfig
|
||||
import com.tangem.core.ui.extensions.resolveReference
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.feature.wallet.presentation.common.WalletPreviewData
|
||||
|
|
@ -27,21 +29,17 @@ import com.tangem.feature.wallet.presentation.wallet.state.components.WalletBott
|
|||
*
|
||||
[REDACTED_AUTHOR]
|
||||
*/
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
internal fun WalletBottomSheet(config: WalletBottomSheetConfig) {
|
||||
ModalBottomSheet(
|
||||
onDismissRequest = config.onDismissRequest,
|
||||
sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true),
|
||||
containerColor = TangemTheme.colors.background.primary,
|
||||
dragHandle = { BottomSheetDefaults.DragHandle() },
|
||||
) {
|
||||
BottomSheetContent(config = config.content)
|
||||
internal fun WalletBottomSheet(config: TangemBottomSheetConfig) {
|
||||
TangemBottomSheet(config) { content ->
|
||||
BottomSheetContent(
|
||||
config = content as WalletBottomSheetConfig,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun BottomSheetContent(config: WalletBottomSheetConfig.BottomSheetContentConfig) {
|
||||
private fun BottomSheetContent(config: WalletBottomSheetConfig) {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.padding(horizontal = TangemTheme.dimens.spacing16)
|
||||
|
|
@ -90,10 +88,7 @@ private fun BottomSheetContent(config: WalletBottomSheetConfig.BottomSheetConten
|
|||
}
|
||||
|
||||
@Composable
|
||||
private fun PrimaryButton(
|
||||
config: WalletBottomSheetConfig.BottomSheetContentConfig.ButtonConfig,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
private fun PrimaryButton(config: WalletBottomSheetConfig.ButtonConfig, modifier: Modifier = Modifier) {
|
||||
if (config.iconResId == null) {
|
||||
PrimaryButton(
|
||||
text = config.text.resolveReference(),
|
||||
|
|
@ -111,10 +106,7 @@ private fun PrimaryButton(
|
|||
}
|
||||
|
||||
@Composable
|
||||
private fun SecondaryButton(
|
||||
config: WalletBottomSheetConfig.BottomSheetContentConfig.ButtonConfig,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
private fun SecondaryButton(config: WalletBottomSheetConfig.ButtonConfig, modifier: Modifier = Modifier) {
|
||||
if (config.iconResId == null) {
|
||||
SecondaryButton(
|
||||
text = config.text.resolveReference(),
|
||||
|
|
@ -139,7 +131,7 @@ private fun WalletBottomSheetContent_Light(
|
|||
) {
|
||||
TangemTheme(isDark = false) {
|
||||
// Use preview of content because ModalBottomSheet isn't supported in Preview mode
|
||||
BottomSheetContent(config = config.content)
|
||||
BottomSheetContent(config = config)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -151,10 +143,10 @@ private fun WalletBottomSheetContent_Dark(
|
|||
) {
|
||||
TangemTheme(isDark = false) {
|
||||
// Use preview of content because ModalBottomSheet isn't supported in Preview mode
|
||||
BottomSheetContent(config = config.content)
|
||||
BottomSheetContent(config = config)
|
||||
}
|
||||
}
|
||||
|
||||
private class WalletBottomSheetConfigProvider : CollectionPreviewParameterProvider<WalletBottomSheetConfig>(
|
||||
private class WalletBottomSheetConfigProvider : CollectionPreviewParameterProvider<TangemBottomSheetConfig>(
|
||||
collection = listOf(WalletPreviewData.bottomSheet),
|
||||
)
|
||||
|
|
@ -7,6 +7,8 @@ import com.tangem.common.Provider
|
|||
import com.tangem.common.doOnFailure
|
||||
import com.tangem.common.doOnSuccess
|
||||
import com.tangem.core.navigation.AppScreen
|
||||
import com.tangem.core.ui.components.bottomsheets.tokenreceive.AddressModel
|
||||
import com.tangem.core.ui.components.bottomsheets.tokenreceive.TokenReceiveBottomSheetConfig
|
||||
import com.tangem.core.ui.components.marketprice.MarketPriceBlockState
|
||||
import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
|
||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
|
|
@ -27,6 +29,7 @@ import com.tangem.domain.tokens.models.Network
|
|||
import com.tangem.domain.txhistory.usecase.GetTxHistoryItemsCountUseCase
|
||||
import com.tangem.domain.txhistory.usecase.GetTxHistoryItemsUseCase
|
||||
import com.tangem.domain.userwallets.UserWalletBuilder
|
||||
import com.tangem.domain.walletmanager.WalletManagersFacade
|
||||
import com.tangem.domain.wallets.models.UserWallet
|
||||
import com.tangem.domain.wallets.models.UserWalletId
|
||||
import com.tangem.domain.wallets.usecase.*
|
||||
|
|
@ -86,6 +89,7 @@ internal class WalletViewModel @Inject constructor(
|
|||
private val shouldShowSaveWalletScreenUseCase: ShouldShowSaveWalletScreenUseCase,
|
||||
private val canUseBiometryUseCase: CanUseBiometryUseCase,
|
||||
private val shouldSaveUserWalletsUseCase: ShouldSaveUserWalletsUseCase,
|
||||
private val walletManagersFacade: WalletManagersFacade,
|
||||
private val reduxStateHolder: ReduxStateHolder,
|
||||
private val dispatchers: CoroutineDispatcherProvider,
|
||||
) : ViewModel(), DefaultLifecycleObserver, WalletClickIntents {
|
||||
|
|
@ -271,7 +275,7 @@ internal class WalletViewModel @Inject constructor(
|
|||
|
||||
override fun onCriticalWarningAlreadySignedHashesClick() {
|
||||
uiState = stateFactory.getStateWithOpenWalletBottomSheet(
|
||||
content = WalletBottomSheetConfig.BottomSheetContentConfig.CriticalWarningAlreadySignedHashes(
|
||||
content = WalletBottomSheetConfig.CriticalWarningAlreadySignedHashes(
|
||||
onOkClick = {},
|
||||
onCancelClick = {},
|
||||
),
|
||||
|
|
@ -284,7 +288,7 @@ internal class WalletViewModel @Inject constructor(
|
|||
|
||||
override fun onLikeTangemAppClick() {
|
||||
uiState = stateFactory.getStateWithOpenWalletBottomSheet(
|
||||
content = WalletBottomSheetConfig.BottomSheetContentConfig.LikeTangemApp(
|
||||
content = WalletBottomSheetConfig.LikeTangemApp(
|
||||
onRateTheAppClick = ::onRateTheAppClick,
|
||||
onShareClick = ::onShareClick,
|
||||
),
|
||||
|
|
@ -428,7 +432,31 @@ internal class WalletViewModel @Inject constructor(
|
|||
}
|
||||
|
||||
override fun onReceiveClick(cryptoCurrencyStatus: CryptoCurrencyStatus) {
|
||||
// TODO: [REDACTED_JIRA]
|
||||
val state = uiState as? WalletState.ContentState ?: return
|
||||
|
||||
viewModelScope.launch(dispatchers.io) {
|
||||
val userWallet = getWallet(index = state.walletsListConfig.selectedWalletIndex)
|
||||
|
||||
val addresses = walletManagersFacade.getAddress(
|
||||
userWalletId = userWallet.walletId,
|
||||
network = cryptoCurrencyStatus.currency.network,
|
||||
)
|
||||
|
||||
val currency = cryptoCurrencyStatus.currency
|
||||
uiState = stateFactory.getStateWithOpenWalletBottomSheet(
|
||||
content = TokenReceiveBottomSheetConfig(
|
||||
name = currency.name,
|
||||
symbol = currency.symbol,
|
||||
network = currency.network.name,
|
||||
addresses = addresses.map {
|
||||
AddressModel(
|
||||
value = it.value,
|
||||
type = AddressModel.Type.valueOf(it.type.name),
|
||||
)
|
||||
},
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onSellClick(cryptoCurrencyStatus: CryptoCurrencyStatus) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue