Updated on 2026-08-14
This commit is contained in:
parent
400d625df1
commit
a6141bbbe5
18 changed files with 175 additions and 59 deletions
|
|
@ -60,11 +60,11 @@ dependencies {
|
|||
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin"
|
||||
implementation 'androidx.core:core-ktx:1.3.1'
|
||||
implementation 'androidx.appcompat:appcompat:1.2.0'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.0.0'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.0.1'
|
||||
implementation 'com.google.android.material:material:1.2.0'
|
||||
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.0.10'
|
||||
|
||||
implementation 'com.tangem:blockchain:1.25.0'
|
||||
implementation 'com.tangem:blockchain:1.27.0'
|
||||
|
||||
//lifecycle
|
||||
implementation "androidx.lifecycle:lifecycle-runtime:2.2.0"
|
||||
|
|
|
|||
|
|
@ -4,40 +4,44 @@ import com.tangem.blockchain.common.Blockchain
|
|||
import com.tangem.commands.common.network.Result
|
||||
import com.tangem.tap.network.payid.PayIdService
|
||||
import com.tangem.tap.network.payid.SetPayIdResponse
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import retrofit2.HttpException
|
||||
import java.util.*
|
||||
|
||||
class PayIdManager {
|
||||
private val payIdService = PayIdService()
|
||||
|
||||
suspend fun getPayId(cardId: String, publicKey: String): Result<String?> {
|
||||
suspend fun getPayId(cardId: String, publicKey: String): Result<String?> = withContext(Dispatchers.IO) {
|
||||
val result = payIdService.getPayId(cardId, publicKey)
|
||||
when (result) {
|
||||
is Result.Success -> return Result.Success(result.data.payId)
|
||||
is Result.Success -> return@withContext Result.Success(result.data.payId)
|
||||
is Result.Failure -> {
|
||||
(result.error as? HttpException)?.let {
|
||||
if (it.code() == 404) return Result.Success(null)
|
||||
if (it.code() == 404) return@withContext Result.Success(null)
|
||||
}
|
||||
return result
|
||||
return@withContext result
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
suspend fun setPayId(
|
||||
cardId: String, publicKey: String, payId: String, address: String, blockchain: Blockchain
|
||||
): Result<SetPayIdResponse> {
|
||||
): Result<SetPayIdResponse> = withContext(Dispatchers.IO) {
|
||||
val result = payIdService.setPayId(cardId, publicKey, payId, address, blockchain.getPayIdNetwork())
|
||||
when (result) {
|
||||
is Result.Success -> return result
|
||||
is Result.Success -> return@withContext result
|
||||
is Result.Failure -> {
|
||||
(result.error as? HttpException)?.let {
|
||||
if (it.code() == 409) return Result.Failure(TapError.PayIdAlreadyCreated)
|
||||
if (it.code() == 409) return@withContext Result.Failure(TapError.PayIdAlreadyCreated)
|
||||
}
|
||||
return result
|
||||
return@withContext result
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private fun Blockchain.getPayIdNetwork(): String {
|
||||
return when (this) {
|
||||
Blockchain.XRP -> "XRPL"
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import com.tangem.commands.CommandResponse
|
|||
import com.tangem.common.CompletionResult
|
||||
import com.tangem.common.extensions.CardType
|
||||
import com.tangem.tangem_sdk_new.extensions.init
|
||||
import com.tangem.tap.domain.tasks.CreateWalletAndRescanTask
|
||||
import com.tangem.tap.domain.tasks.ScanNoteResponse
|
||||
import com.tangem.tap.domain.tasks.ScanNoteTask
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
|
|
@ -23,12 +24,18 @@ class TangemSdkManager(val activity: ComponentActivity) {
|
|||
return runTaskAsyncReturnOnMain(ScanNoteTask())
|
||||
}
|
||||
|
||||
suspend fun createWallet(): CompletionResult<ScanNoteResponse> {
|
||||
return runTaskAsyncReturnOnMain(CreateWalletAndRescanTask())
|
||||
}
|
||||
|
||||
private suspend fun <T : CommandResponse> runTaskAsync(
|
||||
runnable: CardSessionRunnable<T>, cardId: String? = null, initialMessage: Message? = null
|
||||
): CompletionResult<T> =
|
||||
suspendCoroutine { continuation ->
|
||||
tangemSdk.startSessionWithRunnable(runnable, cardId, initialMessage) { result ->
|
||||
continuation.resume(result)
|
||||
withContext(Dispatchers.IO) {
|
||||
suspendCoroutine { continuation ->
|
||||
tangemSdk.startSessionWithRunnable(runnable, cardId, initialMessage) { result ->
|
||||
continuation.resume(result)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import com.tangem.commands.common.network.Result
|
|||
import com.tangem.common.extensions.toHexString
|
||||
import com.tangem.tap.TapConfig
|
||||
import com.tangem.tap.common.redux.global.GlobalAction
|
||||
import com.tangem.tap.domain.tasks.ScanNoteResponse
|
||||
import com.tangem.tap.features.wallet.redux.PayIdState
|
||||
import com.tangem.tap.features.wallet.redux.WalletAction
|
||||
import com.tangem.tap.network.coinmarketcap.CoinMarketCapService
|
||||
|
|
@ -47,12 +48,26 @@ class TapWalletManager {
|
|||
handleFiatRatesResult(results)
|
||||
}
|
||||
|
||||
suspend fun onCardScanned(data: ScanNoteResponse) {
|
||||
withContext(Dispatchers.Main) {
|
||||
store.dispatch(GlobalAction.LoadCard(data.card))
|
||||
if (data.walletManager != null) {
|
||||
store.dispatch(GlobalAction.LoadWalletManager(data.walletManager))
|
||||
store.dispatch(WalletAction.LoadWallet)
|
||||
store.dispatch(WalletAction.LoadFiatRate)
|
||||
store.dispatch(WalletAction.LoadPayId)
|
||||
} else {
|
||||
store.dispatch(WalletAction.EmptyWallet)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun updateWallet(walletManager: WalletManager) {
|
||||
val result = try {
|
||||
walletManager.update()
|
||||
Result.Success(walletManager.wallet)
|
||||
} catch (exeption: Exception) {
|
||||
Result.Failure(exeption)
|
||||
} catch (exception: Exception) {
|
||||
Result.Failure(exception)
|
||||
}
|
||||
handleUpdateWalletResult(result)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,28 @@
|
|||
package com.tangem.tap.domain.tasks
|
||||
|
||||
import com.tangem.CardSession
|
||||
import com.tangem.CardSessionRunnable
|
||||
import com.tangem.commands.ReadCommand
|
||||
import com.tangem.common.CompletionResult
|
||||
import com.tangem.tasks.CreateWalletTask
|
||||
|
||||
class CreateWalletAndRescanTask : CardSessionRunnable<ScanNoteResponse> {
|
||||
override val requiresPin2 = false
|
||||
|
||||
override fun run(session: CardSession, callback: (result: CompletionResult<ScanNoteResponse>) -> Unit) {
|
||||
CreateWalletTask().run(session) { result ->
|
||||
when (result) {
|
||||
is CompletionResult.Success -> ReadCommand().run(session) { readResult ->
|
||||
when (readResult) {
|
||||
is CompletionResult.Success -> {
|
||||
callback(readResult.data.toScanNoteCompletionResult())
|
||||
}
|
||||
is CompletionResult.Failure -> callback(CompletionResult.Failure(readResult.error))
|
||||
}
|
||||
}
|
||||
|
||||
is CompletionResult.Failure -> callback(CompletionResult.Failure(result.error))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -6,11 +6,12 @@ import com.tangem.TangemSdkError
|
|||
import com.tangem.blockchain.common.WalletManager
|
||||
import com.tangem.blockchain.common.WalletManagerFactory
|
||||
import com.tangem.commands.Card
|
||||
import com.tangem.commands.CardStatus
|
||||
import com.tangem.commands.CommandResponse
|
||||
import com.tangem.common.CompletionResult
|
||||
|
||||
data class ScanNoteResponse(
|
||||
val walletManager: WalletManager,
|
||||
val walletManager: WalletManager?,
|
||||
val card: Card
|
||||
) : CommandResponse
|
||||
|
||||
|
|
@ -19,11 +20,16 @@ class ScanNoteTask : CardSessionRunnable<ScanNoteResponse> {
|
|||
|
||||
override fun run(session: CardSession, callback: (result: CompletionResult<ScanNoteResponse>) -> Unit) {
|
||||
val card = session.environment.card
|
||||
val walletManager = card?.let { WalletManagerFactory.makeWalletManager(it) }
|
||||
if (card == null || walletManager == null) {
|
||||
callback(CompletionResult.Failure(TangemSdkError.CardError()))
|
||||
return
|
||||
}
|
||||
callback(CompletionResult.Success(ScanNoteResponse(walletManager, card)))
|
||||
callback(card.toScanNoteCompletionResult())
|
||||
}
|
||||
}
|
||||
|
||||
fun Card?.toScanNoteCompletionResult(): CompletionResult<ScanNoteResponse> {
|
||||
this ?: return CompletionResult.Failure(TangemSdkError.CardError())
|
||||
if (this.status == CardStatus.Empty) {
|
||||
return CompletionResult.Success(ScanNoteResponse(null, this))
|
||||
}
|
||||
val walletManager = WalletManagerFactory.makeWalletManager(this)
|
||||
?: return CompletionResult.Failure(TangemSdkError.CardError())
|
||||
return CompletionResult.Success(ScanNoteResponse(walletManager, this))
|
||||
}
|
||||
|
|
@ -5,10 +5,8 @@ import android.net.Uri
|
|||
import androidx.core.content.ContextCompat.startActivity
|
||||
import com.tangem.common.CompletionResult
|
||||
import com.tangem.tap.common.redux.AppState
|
||||
import com.tangem.tap.common.redux.global.GlobalAction
|
||||
import com.tangem.tap.common.redux.navigation.AppScreen
|
||||
import com.tangem.tap.common.redux.navigation.NavigationAction
|
||||
import com.tangem.tap.features.wallet.redux.WalletAction
|
||||
import com.tangem.tap.scope
|
||||
import com.tangem.tap.store
|
||||
import com.tangem.tap.tangemSdkManager
|
||||
|
|
@ -27,11 +25,7 @@ val homeMiddleware: Middleware<AppState> = { dispatch, state ->
|
|||
withContext(Dispatchers.Main) {
|
||||
when (result) {
|
||||
is CompletionResult.Success -> {
|
||||
store.dispatch(GlobalAction.LoadCard(result.data.card))
|
||||
store.dispatch(GlobalAction.LoadWalletManager(result.data.walletManager))
|
||||
store.dispatch(WalletAction.LoadWallet)
|
||||
store.dispatch(WalletAction.LoadFiatRate)
|
||||
store.dispatch(WalletAction.LoadPayId)
|
||||
store.state.globalState.tapWalletManager.onCardScanned(result.data)
|
||||
store.dispatch(NavigationAction.NavigateTo(AppScreen.Wallet))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,4 +43,5 @@ sealed class WalletAction : Action {
|
|||
object HideQrCode : WalletAction()
|
||||
data class ExploreAddress(val context: Context) : WalletAction()
|
||||
object CreateWallet : WalletAction()
|
||||
object EmptyWallet : WalletAction()
|
||||
}
|
||||
|
|
@ -8,7 +8,6 @@ import com.tangem.common.CompletionResult
|
|||
import com.tangem.common.extensions.toHexString
|
||||
import com.tangem.tap.common.extensions.copyToClipboard
|
||||
import com.tangem.tap.common.redux.AppState
|
||||
import com.tangem.tap.common.redux.global.GlobalAction
|
||||
import com.tangem.tap.domain.PayIdManager
|
||||
import com.tangem.tap.domain.TapError
|
||||
import com.tangem.tap.scope
|
||||
|
|
@ -39,6 +38,17 @@ val walletMiddleware: Middleware<AppState> = { dispatch, state ->
|
|||
store.state.globalState.tapWalletManager.loadFiatRate()
|
||||
}
|
||||
}
|
||||
is WalletAction.CreateWallet -> {
|
||||
scope.launch {
|
||||
val result = tangemSdkManager.createWallet()
|
||||
when (result) {
|
||||
is CompletionResult.Success -> {
|
||||
store.state.globalState.tapWalletManager.onCardScanned(result.data)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
is WalletAction.CreatePayId.CompleteCreatingPayId -> {
|
||||
scope.launch {
|
||||
val cardId = store.state.globalState.card?.cardId
|
||||
|
|
@ -68,13 +78,7 @@ val walletMiddleware: Middleware<AppState> = { dispatch, state ->
|
|||
val result = tangemSdkManager.scanNote()
|
||||
when (result) {
|
||||
is CompletionResult.Success -> {
|
||||
withContext(Dispatchers.Main) {
|
||||
store.dispatch(GlobalAction.LoadCard(result.data.card))
|
||||
store.dispatch(GlobalAction.LoadWalletManager(result.data.walletManager))
|
||||
store.dispatch(WalletAction.LoadWallet)
|
||||
store.dispatch(WalletAction.LoadFiatRate)
|
||||
store.dispatch(WalletAction.LoadPayId)
|
||||
}
|
||||
store.state.globalState.tapWalletManager.onCardScanned(result.data)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package com.tangem.tap.features.wallet.redux
|
||||
|
||||
import com.tangem.blockchain.common.AmountType
|
||||
import com.tangem.common.extensions.isZero
|
||||
import com.tangem.tap.common.extensions.toFiatString
|
||||
import com.tangem.tap.common.extensions.toFormattedString
|
||||
import com.tangem.tap.common.extensions.toQrCode
|
||||
|
|
@ -17,12 +18,19 @@ fun walletReducer(action: Action, state: AppState): WalletState {
|
|||
var newState = state.walletState
|
||||
|
||||
when (action) {
|
||||
is WalletAction.EmptyWallet -> newState = WalletState(
|
||||
state = ProgressState.Done,
|
||||
currencyData = BalanceWidgetData(BalanceStatus.EmptyCard),
|
||||
mainButton = WalletMainButton.CreateWalletButton(true)
|
||||
)
|
||||
is WalletAction.LoadWallet -> newState = WalletState(
|
||||
state = ProgressState.Loading,
|
||||
currencyData = BalanceWidgetData(
|
||||
BalanceStatus.Loading,
|
||||
state.globalState.walletManager?.wallet?.blockchain?.fullName
|
||||
)
|
||||
),
|
||||
mainButton = WalletMainButton.SendButton(false)
|
||||
|
||||
)
|
||||
is WalletAction.LoadWallet.Success -> {
|
||||
val token = action.wallet.amounts[AmountType.Token]
|
||||
|
|
@ -38,6 +46,8 @@ fun walletReducer(action: Action, state: AppState): WalletState {
|
|||
val amount = action.wallet.amounts[AmountType.Coin]?.value
|
||||
val fiatRate = state.globalState.fiatRates.getRateForCryptoCurrency(action.wallet.blockchain.currency)
|
||||
val fiatAmount = fiatRate?.let { amount?.toFiatString(it) }
|
||||
|
||||
val sendButtonEnabled = amount?.isZero() == false || token?.value?.isZero() == false
|
||||
newState = newState.copy(
|
||||
state = ProgressState.Done, wallet = action.wallet,
|
||||
currencyData = BalanceWidgetData(
|
||||
|
|
@ -45,14 +55,15 @@ fun walletReducer(action: Action, state: AppState): WalletState {
|
|||
amount?.toFormattedString(action.wallet.blockchain),
|
||||
token = tokenData,
|
||||
fiatAmount = fiatAmount
|
||||
)
|
||||
),
|
||||
mainButton = WalletMainButton.SendButton(sendButtonEnabled)
|
||||
)
|
||||
}
|
||||
is WalletAction.LoadFiatRate.Success -> {
|
||||
val rate = action.fiatRates.second
|
||||
val currency = action.fiatRates.first
|
||||
val fiatAmount = if (currency == newState.wallet?.blockchain?.currency) {
|
||||
newState.wallet?.amounts?.get(AmountType.Coin)?.value?.toFiatString(rate)
|
||||
newState.wallet?.amounts?.get(AmountType.Coin)?.value?.toFiatString(rate)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package com.tangem.tap.features.wallet.redux
|
|||
|
||||
import android.graphics.Bitmap
|
||||
import com.tangem.blockchain.common.Wallet
|
||||
import com.tangem.tap.common.entities.Button
|
||||
import com.tangem.tap.features.wallet.ui.BalanceWidgetData
|
||||
import org.rekotlin.StateType
|
||||
|
||||
|
|
@ -12,7 +13,8 @@ data class WalletState(
|
|||
val currencyData: BalanceWidgetData = BalanceWidgetData(),
|
||||
val payIdData: PayIdData = PayIdData(),
|
||||
val qrCode: Bitmap? = null,
|
||||
val creatingPayIdState: CreatingPayIdState? = null
|
||||
val creatingPayIdState: CreatingPayIdState? = null,
|
||||
val mainButton: WalletMainButton = WalletMainButton.SendButton(false)
|
||||
) : StateType
|
||||
|
||||
|
||||
|
|
@ -25,4 +27,9 @@ data class PayIdData(
|
|||
val payId: String? = null
|
||||
)
|
||||
|
||||
enum class CreatingPayIdState { EnterPayId, Waiting }
|
||||
enum class CreatingPayIdState { EnterPayId, Waiting }
|
||||
|
||||
sealed class WalletMainButton(enabled: Boolean) : Button(enabled) {
|
||||
class SendButton(enabled: Boolean) : WalletMainButton(enabled)
|
||||
class CreateWalletButton(enabled: Boolean) : WalletMainButton(enabled)
|
||||
}
|
||||
|
|
@ -5,7 +5,9 @@ import androidx.fragment.app.Fragment
|
|||
import com.tangem.tap.common.extensions.hide
|
||||
import com.tangem.tap.common.extensions.show
|
||||
import com.tangem.wallet.R
|
||||
import kotlinx.android.synthetic.main.card_balance.*
|
||||
import kotlinx.android.synthetic.main.layout_balance.*
|
||||
import kotlinx.android.synthetic.main.layout_balance_error.*
|
||||
import kotlinx.android.synthetic.main.layout_token.view.*
|
||||
|
||||
enum class PayIdState {
|
||||
|
|
@ -18,7 +20,8 @@ enum class PayIdState {
|
|||
enum class BalanceStatus {
|
||||
VerifiedOnline,
|
||||
Unreachable,
|
||||
Loading
|
||||
Loading,
|
||||
EmptyCard
|
||||
}
|
||||
|
||||
data class BalanceWidgetData(
|
||||
|
|
@ -45,6 +48,8 @@ class BalanceWidget(
|
|||
|
||||
when (data.status) {
|
||||
BalanceStatus.Loading -> {
|
||||
fragment.l_balance.show()
|
||||
fragment.l_balance_error.hide()
|
||||
fragment.tv_currency.text = data.currency
|
||||
fragment.tv_amount.text = "-"
|
||||
fragment.tv_fiat_amount.hide()
|
||||
|
|
@ -52,6 +57,8 @@ class BalanceWidget(
|
|||
fragment.l_token.hide()
|
||||
}
|
||||
BalanceStatus.VerifiedOnline -> {
|
||||
fragment.l_balance.show()
|
||||
fragment.l_balance_error.hide()
|
||||
fragment.tv_currency.text = data.currency
|
||||
fragment.tv_amount.text = data.amount
|
||||
fragment.tv_fiat_amount.show()
|
||||
|
|
@ -70,9 +77,16 @@ class BalanceWidget(
|
|||
|
||||
}
|
||||
BalanceStatus.Unreachable -> {
|
||||
fragment.l_balance.show()
|
||||
fragment.l_balance_error.hide()
|
||||
fragment.l_token.hide()
|
||||
showStatus(R.id.tv_status_error)
|
||||
|
||||
}
|
||||
BalanceStatus.EmptyCard -> {
|
||||
fragment.l_balance.hide()
|
||||
fragment.l_balance_error.show()
|
||||
fragment.tv_error_title.text = fragment.getText(R.string.wallet_empty_card)
|
||||
fragment.tv_error_descriptions.text = fragment.getText(R.string.wallet_empty_card_description)
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,14 +60,34 @@ class WalletFragment : Fragment(R.layout.fragment_wallet), StoreSubscriber<Walle
|
|||
override fun newState(state: WalletState) {
|
||||
if (activity == null) return
|
||||
|
||||
state.wallet?.address?.let { tv_address.text = it }
|
||||
tv_explore?.setOnClickListener {
|
||||
store.dispatch(WalletAction.ExploreAddress(requireContext()))
|
||||
if (state.wallet?.address != null) {
|
||||
l_address?.show()
|
||||
tv_address.text = state.wallet.address
|
||||
tv_explore?.setOnClickListener {
|
||||
store.dispatch(WalletAction.ExploreAddress(requireContext()))
|
||||
}
|
||||
} else {
|
||||
l_address?.hide()
|
||||
}
|
||||
|
||||
|
||||
btn_copy.setOnClickListener { store.dispatch(WalletAction.CopyAddress(requireContext())) }
|
||||
btn_show_qr.setOnClickListener { store.dispatch(WalletAction.ShowQrCode) }
|
||||
|
||||
val buttonTitle = when (state.mainButton) {
|
||||
is WalletMainButton.SendButton -> R.string.wallet_button_send
|
||||
is WalletMainButton.CreateWalletButton -> R.string.wallet_button_create_wallet
|
||||
}
|
||||
btn_main.text = getString(buttonTitle)
|
||||
btn_main.isEnabled = state.mainButton.enabled
|
||||
|
||||
btn_main.setOnClickListener {
|
||||
when (state.mainButton) {
|
||||
is WalletMainButton.SendButton -> TODO()
|
||||
is WalletMainButton.CreateWalletButton -> store.dispatch(WalletAction.CreateWallet)
|
||||
}
|
||||
}
|
||||
|
||||
if (state.qrCode != null && state.wallet?.shareUrl != null) {
|
||||
qrDialog = QrDialog(requireContext())
|
||||
qrDialog?.showQr(state.qrCode, state.wallet.shareUrl)
|
||||
|
|
|
|||
|
|
@ -2,14 +2,16 @@ package com.tangem.tap.network.coinmarketcap
|
|||
|
||||
import com.tangem.commands.common.network.Result
|
||||
import com.tangem.commands.common.network.performRequest
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import java.math.BigDecimal
|
||||
|
||||
class CoinMarketCapService {
|
||||
private val api: CoinMarketCapApi by lazy { CoinMarketCapApi.create() }
|
||||
|
||||
suspend fun getRate(currency: String): Result<BigDecimal> {
|
||||
suspend fun getRate(currency: String): Result<BigDecimal> = withContext(Dispatchers.IO) {
|
||||
val response = performRequest { api.getRateInfo(1, currency) }
|
||||
return when (response) {
|
||||
return@withContext when (response) {
|
||||
is Result.Success -> Result.Success(response.data.data.quote.usd.price)
|
||||
is Result.Failure -> response
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,8 +2,7 @@
|
|||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginTop="24dp">
|
||||
android:layout_height="match_parent">
|
||||
|
||||
|
||||
<ImageView
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@
|
|||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/btn_send"
|
||||
android:id="@+id/btn_main"
|
||||
style="@style/TapButtonWithIcon"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="48dp"
|
||||
|
|
|
|||
|
|
@ -9,14 +9,15 @@
|
|||
android:id="@+id/iv_balance_error"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingStart="16dp"
|
||||
android:paddingTop="16dp"
|
||||
android:layout_width="26dp"
|
||||
android:layout_height="26dp"
|
||||
android:scaleType="fitXY"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:src="@drawable/ic_baseline_error_outline_24" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_error_description"
|
||||
android:id="@+id/tv_error_title"
|
||||
app:layout_constraintStart_toEndOf="@id/iv_balance_error"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:text="@string/wallet_account_not_created"
|
||||
|
|
@ -29,9 +30,9 @@
|
|||
android:textStyle="bold" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_fiat_amount"
|
||||
android:id="@+id/tv_error_descriptions"
|
||||
app:layout_constraintStart_toEndOf="@id/iv_balance_error"
|
||||
app:layout_constraintTop_toBottomOf="@id/tv_error_description"
|
||||
app:layout_constraintTop_toBottomOf="@id/tv_error_title"
|
||||
tools:text="Load10+ XLM to create account"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
|
|
|
|||
|
|
@ -12,12 +12,15 @@
|
|||
<string name="wallet_toolbar_title" translatable="false">Tangem Tap</string>
|
||||
<string name="wallet_button_scan">Scan</string>
|
||||
<string name="wallet_button_send">Send</string>
|
||||
<string name="wallet_button_create_wallet">Create Wallet</string>
|
||||
<string name="wallet_explore_address">Explore address</string>
|
||||
<string name="wallet_create_payid">Create PayID</string>
|
||||
<string name="wallet_verified_balance">Verified Balance</string>
|
||||
<string name="wallet_blockchain_is_unreachable">Blockchain is unreachable</string>
|
||||
<string name="wallet_balance_is_loading">Balance is loading…</string>
|
||||
<string name="wallet_account_not_created">Account is not created</string>
|
||||
<string name="wallet_empty_card">Empty Card</string>
|
||||
<string name="wallet_empty_card_description">Create wallet to start using Tangem card</string>
|
||||
<string name="wallet_tokens">Tokens</string>
|
||||
|
||||
<string name="wallet_dialog_pay_id_button">Create PayID</string>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue