diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/depositcex/DepositQrCodeScreen.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/depositcex/DepositQrCodeScreen.kt index ac0827f517b..b387bd7ed09 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/depositcex/DepositQrCodeScreen.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/depositcex/DepositQrCodeScreen.kt @@ -1,18 +1,37 @@ package io.horizontalsystems.bankwallet.modules.depositcex import androidx.compose.animation.Crossfade -import androidx.compose.foundation.* -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.Image +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.foundation.verticalScroll +import androidx.compose.material.ExperimentalMaterialApi +import androidx.compose.material.ModalBottomSheetLayout +import androidx.compose.material.ModalBottomSheetValue import androidx.compose.material.Scaffold +import androidx.compose.material.rememberModalBottomSheetState import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.ColorFilter import androidx.compose.ui.graphics.asImageBitmap import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalView +import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.unit.dp @@ -24,10 +43,27 @@ import io.horizontalsystems.bankwallet.modules.coin.overview.ui.Loading import io.horizontalsystems.bankwallet.modules.evmfee.ButtonsGroupWithShade import io.horizontalsystems.bankwallet.ui.compose.ComposeAppTheme import io.horizontalsystems.bankwallet.ui.compose.TranslatableString -import io.horizontalsystems.bankwallet.ui.compose.components.* +import io.horizontalsystems.bankwallet.ui.compose.components.AppBar +import io.horizontalsystems.bankwallet.ui.compose.components.ButtonPrimaryDefault +import io.horizontalsystems.bankwallet.ui.compose.components.ButtonPrimaryYellow +import io.horizontalsystems.bankwallet.ui.compose.components.ButtonSecondaryCircle +import io.horizontalsystems.bankwallet.ui.compose.components.CellSingleLineLawrenceSection +import io.horizontalsystems.bankwallet.ui.compose.components.HSpacer +import io.horizontalsystems.bankwallet.ui.compose.components.HsBackButton +import io.horizontalsystems.bankwallet.ui.compose.components.ListEmptyView +import io.horizontalsystems.bankwallet.ui.compose.components.MenuItem +import io.horizontalsystems.bankwallet.ui.compose.components.TextImportantError +import io.horizontalsystems.bankwallet.ui.compose.components.TextImportantWarning +import io.horizontalsystems.bankwallet.ui.compose.components.VSpacer +import io.horizontalsystems.bankwallet.ui.compose.components.body_grey +import io.horizontalsystems.bankwallet.ui.compose.components.subhead1_leah +import io.horizontalsystems.bankwallet.ui.compose.components.subhead2_grey +import io.horizontalsystems.bankwallet.ui.extensions.BottomSheetHeader import io.horizontalsystems.bankwallet.ui.helpers.TextHelper import io.horizontalsystems.core.helpers.HudHelper +import kotlinx.coroutines.launch +@OptIn(ExperimentalMaterialApi::class) @Composable fun DepositQrCodeScreen( onNavigateBack: (() -> Unit)?, @@ -39,135 +75,238 @@ fun DepositQrCodeScreen( viewModel(factory = DepositAddressViewModel.Factory(cexAsset, networkId)) val uiState = viewModel.uiState + val address = uiState.address + val coroutineScope = rememberCoroutineScope() + val modalBottomSheetState = rememberModalBottomSheetState(ModalBottomSheetValue.Hidden) + + if(address?.tag != null && address.tag.isNotEmpty()) { + LaunchedEffect(Unit) { + modalBottomSheetState.show() + } + } - val address = uiState.address?.address ComposeAppTheme { - Scaffold( - backgroundColor = ComposeAppTheme.colors.tyler, - topBar = { - val navigationIcon: @Composable (() -> Unit)? = onNavigateBack?.let { - { - HsBackButton(onClick = onNavigateBack) + ModalBottomSheetLayout( + sheetState = modalBottomSheetState, + sheetBackgroundColor = ComposeAppTheme.colors.transparent, + sheetContent = { + WarningBottomSheet( + text = stringResource(R.string.CexDeposit_MemoAlertText,), + onButtonClick = { + coroutineScope.launch { modalBottomSheetState.hide() } } - } - AppBar( - title = TranslatableString.PlainString(cexAsset.id), - navigationIcon = navigationIcon, - menuItems = listOf( - MenuItem( - title = TranslatableString.ResString(R.string.Button_Done), - onClick = onClose - ) - ) ) - } + }, ) { - Crossfade(targetState = uiState.loading) { loading -> - Column(modifier = Modifier.padding(it)) { - if (loading) { - Loading() - } else if (address != null) { - val qrBitmap = TextHelper.getQrCodeBitmap(address) - val view = LocalView.current - val context = LocalContext.current - - Column( - modifier = Modifier - .weight(1f) - .verticalScroll(rememberScrollState()), - horizontalAlignment = Alignment.CenterHorizontally, - ) { - TextImportantWarning( - modifier = Modifier.padding(vertical = 12.dp, horizontal = 16.dp), - text = "Please make sure that only CoinCode is deposited to this address. Sending other types of tokens to this address will result in their ultimate loss." + Scaffold( + backgroundColor = ComposeAppTheme.colors.tyler, + topBar = { + val navigationIcon: @Composable (() -> Unit)? = onNavigateBack?.let { + { + HsBackButton(onClick = onNavigateBack) + } + } + AppBar( + title = TranslatableString.ResString(R.string.CexDeposit_Title, cexAsset.id), + navigationIcon = navigationIcon, + menuItems = listOf( + MenuItem( + title = TranslatableString.ResString(R.string.Button_Done), + onClick = onClose ) - VSpacer(40.dp) - Box( + ) + ) + } + ) { + Crossfade(targetState = uiState.loading) { loading -> + Column(modifier = Modifier.padding(it)) { + if (loading) { + Loading() + } else if (address != null) { + val qrBitmap = TextHelper.getQrCodeBitmap(address.address) + val view = LocalView.current + val context = LocalContext.current + + Column( modifier = Modifier - .clip(RoundedCornerShape(16.dp)) - .background(ComposeAppTheme.colors.white) - .size(231.dp), - contentAlignment = Alignment.Center + .weight(1f) + .verticalScroll(rememberScrollState()), + horizontalAlignment = Alignment.CenterHorizontally, ) { - qrBitmap?.let { - Image( + VSpacer(12.dp) + Column( + modifier = Modifier + .padding(horizontal = 16.dp) + .border(1.dp, ComposeAppTheme.colors.steel20, RoundedCornerShape(24.dp)) + .padding(top = 32.dp, start = 24.dp, end = 24.dp, bottom = 24.dp) + .fillMaxWidth(), + horizontalAlignment = Alignment.CenterHorizontally, + ) { + Box( modifier = Modifier - .clickable { - TextHelper.copyText(address) - HudHelper.showSuccessMessage( - view, - R.string.Hud_Text_Copied - ) - } - .padding(8.dp) - .fillMaxSize(), - bitmap = it.asImageBitmap(), - contentScale = ContentScale.FillWidth, - contentDescription = null + .clip(RoundedCornerShape(8.dp)) + .background(ComposeAppTheme.colors.white) + .size(150.dp), + contentAlignment = Alignment.Center + ) { + qrBitmap?.let { + Image( + modifier = Modifier + .clickable { + TextHelper.copyText(address.address) + HudHelper.showSuccessMessage( + view, + R.string.Hud_Text_Copied + ) + } + .padding(8.dp) + .fillMaxSize(), + bitmap = it.asImageBitmap(), + contentScale = ContentScale.FillWidth, + contentDescription = null + ) + } + } + VSpacer(12.dp) + subhead2_grey( + text = stringResource(R.string.CexDeposit_AddressDescription, cexAsset.id), + textAlign = TextAlign.Center ) } - } - VSpacer(24.dp) - subhead2_grey( - modifier = Modifier.padding(horizontal = 32.dp), - text = "Your address for depositing CoinCode into the Coin Network", - textAlign = TextAlign.Center - ) - VSpacer(12.dp) - subhead1_leah( - text = address, - textAlign = TextAlign.Center, - modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 24.dp) - .clickable { - TextHelper.copyText(address) - HudHelper.showSuccessMessage(view, R.string.Hud_Text_Copied) - }, - ) - VSpacer(24.dp) - Row( - modifier = Modifier.fillMaxWidth(), - horizontalArrangement = Arrangement.Center - ) { - ButtonSecondaryDefault( - modifier = Modifier.padding(end = 6.dp), - title = stringResource(R.string.Alert_Copy), - onClick = { - TextHelper.copyText(address) - HudHelper.showSuccessMessage(view, R.string.Hud_Text_Copied) + VSpacer(12.dp) + val composableItems: MutableList<@Composable () -> Unit> = mutableListOf() + composableItems.add { + DetailCell( + title = stringResource(R.string.Deposit_Address), + value = address.address, + ) + } + networkId?.let { networkId -> + composableItems.add { + DetailCell( + title = stringResource(R.string.CexDeposit_Network), + value = networkId, + ) } - ) - ButtonSecondaryDefault( - modifier = Modifier.padding(start = 6.dp), - title = stringResource(R.string.Deposit_Share), - onClick = { - ShareCompat.IntentBuilder(context) - .setType("text/plain") - .setText(address) - .startChooser() + } + if (address.tag.isNotEmpty()) { + composableItems.add { + DetailCell( + title = stringResource(R.string.CexDeposit_Memo), + value = address.tag, + onCopy = { + TextHelper.copyText(address.tag) + HudHelper.showSuccessMessage(view, R.string.Hud_Text_Copied) + } + ) } - ) + } + + CellSingleLineLawrenceSection(composableItems = composableItems) + + if (address.tag.isNotEmpty()) { + TextImportantError( + modifier = Modifier.padding(16.dp), + text = stringResource(R.string.CexDeposit_MemoWarning, cexAsset.id) + ) + } else { + TextImportantWarning( + modifier = Modifier.padding(16.dp), + text = stringResource(R.string.CexDeposit_DepositWarning, cexAsset.id) + ) + } + + VSpacer(24.dp) } - VSpacer(24.dp) - } - ButtonsGroupWithShade { - ButtonPrimaryYellow( - modifier = Modifier - .fillMaxWidth() - .padding(start = 16.dp, end = 16.dp, bottom = 32.dp), - title = stringResource(R.string.Button_Close), - onClick = onClose, + ButtonsGroupWithShade { + Column(Modifier.padding(horizontal = 24.dp)) { + ButtonPrimaryYellow( + modifier = Modifier.fillMaxWidth(), + title = stringResource(R.string.CexDeposit_CopyAddress), + onClick = { + TextHelper.copyText(address.address) + HudHelper.showSuccessMessage(view, R.string.Hud_Text_Copied) + }, + ) + VSpacer(16.dp) + ButtonPrimaryDefault( + modifier = Modifier.fillMaxWidth(), + title = stringResource(R.string.CexDeposit_ShareAddress), + onClick = { + ShareCompat.IntentBuilder(context) + .setType("text/plain") + .setText(address.address) + .startChooser() + } + ) + } + } + } else if (uiState.error != null) { + ListEmptyView( + text = uiState.error.localizedMessage ?: stringResource(R.string.Error), + icon = R.drawable.ic_sync_error ) } - } else if (uiState.error != null) { - ListEmptyView( - text = uiState.error.localizedMessage ?: stringResource(R.string.Error), - icon = R.drawable.ic_sync_error - ) } } } } } } + +@Composable +private fun DetailCell( + title: String, + value: String, + onCopy: (() -> Unit)? = null +) { + Row( + modifier = Modifier + .fillMaxSize() + .padding(horizontal = 16.dp), + verticalAlignment = Alignment.CenterVertically + ) { + body_grey(text = title) + + subhead1_leah( + modifier = Modifier + .weight(1f) + .padding(start = 8.dp), + text = value, + textAlign = TextAlign.End, + ) + onCopy?.let { copy -> + HSpacer(16.dp) + ButtonSecondaryCircle( + icon = R.drawable.ic_copy_20, + onClick = copy + ) + } + } +} + +@Composable +private fun WarningBottomSheet( + text: String, + onButtonClick: () -> Unit, +) { + BottomSheetHeader( + iconPainter = painterResource(R.drawable.ic_attention_24), + title = stringResource(R.string.CexDeposit_Important), + iconTint = ColorFilter.tint(ComposeAppTheme.colors.lucian), + onCloseClick = onButtonClick + ) { + VSpacer(12.dp) + TextImportantError( + modifier = Modifier.padding(horizontal = 16.dp), + text = text + ) + ButtonPrimaryYellow( + modifier = Modifier + .fillMaxWidth() + .padding(24.dp), + title = stringResource(id = R.string.Button_Understand), + onClick = onButtonClick + ) + } +} \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index c806b0b1519..843cda317c5 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1671,6 +1671,16 @@ Choose Network Choose a network and get an address to deposit. Name or code + Deposit %s + Copy Address + Share Address + Memo (Tag) + Network + Your address for depositing %s + Send only %s to this address. Sending other types of tokens to this address will result in their ultimate loss. + Memo (tag) is required, or your will lose your coins.\n\nSend only %s to this address. Sending other types of tokens to this address will result in their ultimate loss. + Important + Both a memo (tag) and the address are needed to ensure that assets are received. Otherwise your funds will be lost. Withdraw %s