Updated on 2026-08-14
This commit is contained in:
commit
5e687dbe6c
45 changed files with 1122 additions and 352 deletions
|
|
@ -70,17 +70,12 @@ dependencies {
|
|||
implementation 'com.google.android.material:material:1.2.1'
|
||||
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.0.10'
|
||||
|
||||
implementation 'com.tangem:blockchain:1.98.0'
|
||||
implementation('com.tangem:core') {
|
||||
version {
|
||||
strictly '1.73.0'
|
||||
}
|
||||
}
|
||||
implementation('com.tangem:sdk:') {
|
||||
version {
|
||||
strictly '1.73.0'
|
||||
}
|
||||
}
|
||||
implementation 'com.tangem:blockchain:1.106.0'
|
||||
implementation 'com.tangem:core:1.80.0'
|
||||
implementation 'com.tangem:sdk:1.80.0'
|
||||
|
||||
// WebView
|
||||
implementation "androidx.browser:browser:1.2.0"
|
||||
|
||||
//lifecycle
|
||||
implementation "androidx.lifecycle:lifecycle-runtime:2.2.0"
|
||||
|
|
@ -101,7 +96,9 @@ dependencies {
|
|||
implementation 'com.squareup.picasso:picasso:2.71828'
|
||||
|
||||
// Firebase
|
||||
implementation 'com.google.firebase:firebase-crashlytics:17.2.2'
|
||||
implementation platform('com.google.firebase:firebase-bom:26.0.0')
|
||||
implementation 'com.google.firebase:firebase-crashlytics'
|
||||
implementation 'com.google.firebase:firebase-analytics-ktx'
|
||||
|
||||
testImplementation 'junit:junit:4.13'
|
||||
testImplementation "com.google.truth:truth:1.0.1"
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@
|
|||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.USE_BIOMETRIC" />
|
||||
<uses-permission android:name="android.permission.CAMERA" />
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||
|
||||
<uses-feature android:name="android.hardware.camera" />
|
||||
<uses-feature android:name="android.hardware.camera.autofocus" />
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ import android.content.pm.ActivityInfo
|
|||
import android.nfc.NfcAdapter
|
||||
import android.nfc.Tag
|
||||
import android.os.Bundle
|
||||
import android.os.Handler
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import com.tangem.CardFilter
|
||||
import com.tangem.Config
|
||||
|
|
@ -78,7 +77,7 @@ class MainActivity : AppCompatActivity() {
|
|||
|
||||
override fun onNewIntent(intent: Intent?) {
|
||||
super.onNewIntent(intent)
|
||||
Handler(mainLooper).postDelayed( { handleBackgroundScan(intent) } , 200)
|
||||
handleBackgroundScan(intent)
|
||||
}
|
||||
|
||||
private fun handleBackgroundScan(intent: Intent?) {
|
||||
|
|
@ -88,6 +87,7 @@ class MainActivity : AppCompatActivity() {
|
|||
val tag = intent.getParcelableExtra<Tag>(NfcAdapter.EXTRA_TAG)
|
||||
if (tag != null) {
|
||||
intent.action = null
|
||||
store.dispatch(NavigationAction.NavigateTo(AppScreen.Home, false))
|
||||
store.dispatch(HomeAction.ReadCard)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,5 +2,8 @@ package com.tangem.tap
|
|||
|
||||
object TapConfig {
|
||||
const val usePayId: Boolean = true
|
||||
const val useTopUp: Boolean = true
|
||||
const val coinMarketCapKey = "f6622117-c043-47a0-8975-9d673ce484de"
|
||||
const val moonPayApiKey = "pk_test_kc90oYTANy7UQdBavDKGfL4K9l6VEPE"
|
||||
const val moonPayApiSecretKey = "sk_test_V8w4M19LbDjjYOt170s0tGuvXAgyEb1C"
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
package com.tangem.tap.common.analytics
|
||||
|
||||
enum class AnalyticsEvent(val event: String) {
|
||||
CARD_IS_SCANNED("card_is_scanned"),
|
||||
TRANSACTION_IS_SENT("transaction_is_sent"),
|
||||
READY_TO_SCAN("ready_to_scan"),
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
package com.tangem.tap.common.analytics
|
||||
|
||||
import com.tangem.commands.Card
|
||||
|
||||
interface AnalyticsHandler {
|
||||
fun triggerEvent(event: AnalyticsEvent, card: Card?)
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
package com.tangem.tap.common.analytics
|
||||
|
||||
import android.os.Bundle
|
||||
import androidx.core.os.bundleOf
|
||||
import com.google.firebase.analytics.ktx.analytics
|
||||
import com.google.firebase.ktx.Firebase
|
||||
import com.tangem.commands.Card
|
||||
|
||||
object FirebaseAnalyticsHandler: AnalyticsHandler {
|
||||
override fun triggerEvent(event: AnalyticsEvent, card: Card?) {
|
||||
Firebase.analytics
|
||||
.logEvent(event.event, setCardData(card))
|
||||
}
|
||||
|
||||
private fun setCardData(card: Card?): Bundle {
|
||||
if (card == null) return bundleOf()
|
||||
return bundleOf(
|
||||
AnalyticsParam.BLOCKCHAIN.param to card.cardData?.blockchainName,
|
||||
AnalyticsParam.BATCH_ID.param to card.cardData?.batchId,
|
||||
AnalyticsParam.FIRMWARE.param to card.firmwareVersion
|
||||
)
|
||||
}
|
||||
|
||||
private enum class AnalyticsParam(val param: String) {
|
||||
BLOCKCHAIN("blockchain"),
|
||||
BATCH_ID("batch_id"),
|
||||
FIRMWARE("firmware"),
|
||||
}
|
||||
}
|
||||
|
|
@ -11,6 +11,7 @@ import com.tangem.tap.features.disclaimer.ui.DisclaimerFragment
|
|||
import com.tangem.tap.features.home.HomeFragment
|
||||
import com.tangem.tap.features.send.ui.SendFragment
|
||||
import com.tangem.tap.features.wallet.ui.WalletFragment
|
||||
import com.tangem.tap.features.wallet.ui.topup.TopUpFragment
|
||||
import com.tangem.wallet.R
|
||||
|
||||
fun FragmentActivity.openFragment(screen: AppScreen, addToBackStack: Boolean = true) {
|
||||
|
|
@ -39,6 +40,7 @@ private fun fragmentFactory(screen: AppScreen): Fragment {
|
|||
return when (screen) {
|
||||
AppScreen.Home -> HomeFragment()
|
||||
AppScreen.Wallet -> WalletFragment()
|
||||
AppScreen.TopUp -> TopUpFragment()
|
||||
AppScreen.Send -> SendFragment()
|
||||
AppScreen.Details -> DetailsFragment()
|
||||
AppScreen.DetailsConfirm -> DetailsConfirmFragment()
|
||||
|
|
|
|||
|
|
@ -8,12 +8,12 @@ import com.tangem.tap.features.details.redux.DetailsMiddleware
|
|||
import com.tangem.tap.features.details.redux.DetailsState
|
||||
import com.tangem.tap.features.disclaimer.redux.DisclaimerMiddleware
|
||||
import com.tangem.tap.features.disclaimer.redux.DisclaimerState
|
||||
import com.tangem.tap.features.home.redux.HomeMiddleware
|
||||
import com.tangem.tap.features.home.redux.HomeState
|
||||
import com.tangem.tap.features.home.redux.homeMiddleware
|
||||
import com.tangem.tap.features.send.redux.middlewares.sendMiddleware
|
||||
import com.tangem.tap.features.send.redux.states.SendState
|
||||
import com.tangem.tap.features.wallet.redux.WalletMiddleware
|
||||
import com.tangem.tap.features.wallet.redux.WalletState
|
||||
import com.tangem.tap.features.wallet.redux.walletMiddleware
|
||||
import org.rekotlin.Middleware
|
||||
import org.rekotlin.StateType
|
||||
|
||||
|
|
@ -31,7 +31,9 @@ data class AppState(
|
|||
fun getMiddleware(): List<Middleware<AppState>> {
|
||||
return listOf(
|
||||
logMiddleware, navigationMiddleware, notificationsMiddleware, globalMiddleware,
|
||||
homeMiddleware, walletMiddleware, sendMiddleware,
|
||||
HomeMiddleware().homeMiddleware,
|
||||
WalletMiddleware().walletMiddleware,
|
||||
sendMiddleware,
|
||||
DetailsMiddleware().detailsMiddleware,
|
||||
DisclaimerMiddleware().disclaimerMiddleware
|
||||
)
|
||||
|
|
|
|||
|
|
@ -9,4 +9,4 @@ data class NavigationState(
|
|||
val activity: WeakReference<FragmentActivity>? = null
|
||||
) : StateType
|
||||
|
||||
enum class AppScreen { Home, Wallet, Send, Details, DetailsConfirm, DetailsSecurity, Disclaimer }
|
||||
enum class AppScreen { Home, Wallet, TopUp, Send, Details, DetailsConfirm, DetailsSecurity, Disclaimer }
|
||||
|
|
@ -7,6 +7,8 @@ import com.tangem.common.CompletionResult
|
|||
import com.tangem.common.extensions.CardType
|
||||
import com.tangem.common.extensions.calculateSha256
|
||||
import com.tangem.tangem_sdk_new.extensions.init
|
||||
import com.tangem.tap.common.analytics.AnalyticsEvent
|
||||
import com.tangem.tap.common.analytics.AnalyticsHandler
|
||||
import com.tangem.tap.domain.tasks.CreateWalletAndRescanTask
|
||||
import com.tangem.tap.domain.tasks.ScanNoteResponse
|
||||
import com.tangem.tap.domain.tasks.ScanNoteTask
|
||||
|
|
@ -22,7 +24,8 @@ class TangemSdkManager(val activity: ComponentActivity) {
|
|||
activity, Config(cardFilter = CardFilter(EnumSet.allOf(CardType::class.java)))
|
||||
)
|
||||
|
||||
suspend fun scanNote(): CompletionResult<ScanNoteResponse> {
|
||||
suspend fun scanNote(analyticsHandler: AnalyticsHandler): CompletionResult<ScanNoteResponse> {
|
||||
analyticsHandler.triggerEvent(AnalyticsEvent.READY_TO_SCAN, null)
|
||||
return runTaskAsyncReturnOnMain(ScanNoteTask(),
|
||||
initialMessage = Message(activity.getString(R.string.initial_message_scan_header)))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ import com.tangem.commands.CardStatus
|
|||
import com.tangem.commands.common.network.Result
|
||||
import com.tangem.common.extensions.toHexString
|
||||
import com.tangem.tap.TapConfig
|
||||
import com.tangem.tap.common.analytics.AnalyticsEvent
|
||||
import com.tangem.tap.common.analytics.FirebaseAnalyticsHandler
|
||||
import com.tangem.tap.common.redux.global.CryptoCurrencyName
|
||||
import com.tangem.tap.common.redux.global.FiatCurrencyName
|
||||
import com.tangem.tap.common.redux.global.GlobalAction
|
||||
|
|
@ -54,7 +56,8 @@ class TapWalletManager {
|
|||
}
|
||||
withContext(Dispatchers.Main) {
|
||||
when (result) {
|
||||
is Result.Success -> store.dispatch(WalletAction.UpdateWallet.Success(result.data))
|
||||
is Result.Success ->
|
||||
store.dispatch(WalletAction.UpdateWallet.Success(result.data))
|
||||
is Result.Failure ->
|
||||
store.dispatch(WalletAction.UpdateWallet.Failure(result.error?.localizedMessage))
|
||||
}
|
||||
|
|
@ -77,7 +80,10 @@ class TapWalletManager {
|
|||
handleFiatRatesResult(results)
|
||||
}
|
||||
|
||||
suspend fun onCardScanned(data: ScanNoteResponse) {
|
||||
suspend fun onCardScanned(data: ScanNoteResponse, addAnalyticsEvent: Boolean = false) {
|
||||
if (addAnalyticsEvent) {
|
||||
FirebaseAnalyticsHandler.triggerEvent(AnalyticsEvent.CARD_IS_SCANNED, data.card)
|
||||
}
|
||||
tapWorkarounds = TapWorkarounds(data.card)
|
||||
withContext(Dispatchers.Main) {
|
||||
store.dispatch(WalletAction.ResetState)
|
||||
|
|
@ -95,7 +101,10 @@ class TapWalletManager {
|
|||
store.dispatch(WalletAction.LoadData.Failure(TapError.NoInternetConnection))
|
||||
return@withContext
|
||||
}
|
||||
store.dispatch(WalletAction.LoadWallet)
|
||||
store.dispatch(WalletAction.LoadWallet(
|
||||
data.walletManager.wallet, data.verifyResponse?.artworkInfo?.id,
|
||||
tapWorkarounds?.isStart2Coin != true && TapConfig.useTopUp
|
||||
))
|
||||
store.dispatch(WalletAction.LoadArtwork(data.card, artworkId))
|
||||
store.dispatch(WalletAction.LoadFiatRate)
|
||||
store.dispatch(WalletAction.LoadPayId)
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ import com.tangem.commands.Card
|
|||
|
||||
class TapWorkarounds(val card: Card) {
|
||||
|
||||
private val isStart2Coin: Boolean = card.cardData?.issuerName == START_2_COIN_ISSUER
|
||||
val isStart2Coin: Boolean = card.cardData?.issuerName == START_2_COIN_ISSUER
|
||||
|
||||
fun isPayIdCreationEnabled(): Boolean {
|
||||
if (isStart2Coin) return false
|
||||
|
|
|
|||
44
app/src/main/java/com/tangem/tap/domain/TopUpHelper.kt
Normal file
44
app/src/main/java/com/tangem/tap/domain/TopUpHelper.kt
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
package com.tangem.tap.domain
|
||||
|
||||
import android.net.Uri
|
||||
import com.tangem.tap.TapConfig
|
||||
import com.tangem.tap.common.redux.global.CryptoCurrencyName
|
||||
import org.spongycastle.util.encoders.Base64
|
||||
import javax.crypto.Mac
|
||||
import javax.crypto.spec.SecretKeySpec
|
||||
|
||||
class TopUpHelper {
|
||||
|
||||
companion object {
|
||||
const val REDIRECT_URL = "https://success.tangem.com"
|
||||
|
||||
private const val BASE_URL = "https://buy-staging.moonpay.io"
|
||||
private const val API_KEY_PATH = "?apiKey="
|
||||
private const val CURRENCY_PATH = "¤cyCode="
|
||||
private const val WALLET_ADDRESS_PATH = "&walletAddress="
|
||||
private const val REDIRECT_URL_PATH = "&redirectUrl="
|
||||
private const val SIGNATURE_PATH = "&signature="
|
||||
|
||||
fun getUrl(cryptoCurrencyName: CryptoCurrencyName, walletAddress: String): String {
|
||||
val originalQuery = API_KEY_PATH + TapConfig.moonPayApiKey.urlEncode() +
|
||||
CURRENCY_PATH + cryptoCurrencyName.urlEncode() +
|
||||
WALLET_ADDRESS_PATH + walletAddress.urlEncode() +
|
||||
REDIRECT_URL_PATH + REDIRECT_URL.urlEncode()
|
||||
val signature = createSignature(originalQuery, TapConfig.moonPayApiSecretKey)
|
||||
|
||||
return BASE_URL + originalQuery + SIGNATURE_PATH + signature.urlEncode()
|
||||
}
|
||||
|
||||
private fun String.urlEncode(): String {
|
||||
return Uri.encode(this)
|
||||
}
|
||||
|
||||
|
||||
private fun createSignature(data: String, key: String): String {
|
||||
val sha256Hmac = Mac.getInstance("HmacSHA256")
|
||||
val secretKey = SecretKeySpec(key.toByteArray(), "HmacSHA256")
|
||||
sha256Hmac.init(secretKey)
|
||||
return Base64.toBase64String(sha256Hmac.doFinal(data.toByteArray()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4,6 +4,7 @@ import android.content.Intent
|
|||
import android.net.Uri
|
||||
import androidx.core.content.ContextCompat.startActivity
|
||||
import com.tangem.common.CompletionResult
|
||||
import com.tangem.tap.common.analytics.FirebaseAnalyticsHandler
|
||||
import com.tangem.tap.common.redux.AppState
|
||||
import com.tangem.tap.common.redux.global.GlobalAction
|
||||
import com.tangem.tap.common.redux.navigation.AppScreen
|
||||
|
|
@ -17,61 +18,54 @@ import kotlinx.coroutines.launch
|
|||
import kotlinx.coroutines.withContext
|
||||
import org.rekotlin.Middleware
|
||||
|
||||
val homeMiddleware: Middleware<AppState> = { dispatch, state ->
|
||||
{ next ->
|
||||
{ action ->
|
||||
when (action) {
|
||||
is HomeAction.CheckIfFirstLaunch -> {
|
||||
store.dispatch(
|
||||
HomeAction.CheckIfFirstLaunch.Result(preferencesStorage.isFirstLaunch())
|
||||
)
|
||||
}
|
||||
is HomeAction.ReadCard -> {
|
||||
scope.launch {
|
||||
val result = tangemSdkManager.scanNote()
|
||||
withContext(Dispatchers.Main) {
|
||||
when (result) {
|
||||
is CompletionResult.Success -> {
|
||||
store.dispatch(GlobalAction.RestoreAppCurrency)
|
||||
store.state.globalState.tapWalletManager.onCardScanned(result.data)
|
||||
showDisclaimerOrNavigateToWallet()
|
||||
class HomeMiddleware {
|
||||
val homeMiddleware: Middleware<AppState> = { dispatch, state ->
|
||||
{ next ->
|
||||
{ action ->
|
||||
when (action) {
|
||||
is HomeAction.CheckIfFirstLaunch -> {
|
||||
store.dispatch(
|
||||
HomeAction.CheckIfFirstLaunch.Result(preferencesStorage.isFirstLaunch())
|
||||
)
|
||||
}
|
||||
is HomeAction.ReadCard -> {
|
||||
scope.launch {
|
||||
val result = tangemSdkManager.scanNote(FirebaseAnalyticsHandler)
|
||||
withContext(Dispatchers.Main) {
|
||||
when (result) {
|
||||
is CompletionResult.Success -> {
|
||||
store.dispatch(GlobalAction.RestoreAppCurrency)
|
||||
store.state.globalState.tapWalletManager.onCardScanned(result.data)
|
||||
showDisclaimerOrNavigateToWallet()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
is HomeAction.GoToShop -> {
|
||||
val uri = Uri.parse(CARD_SHOP_URI)
|
||||
val intent = Intent(Intent.ACTION_VIEW, uri)
|
||||
startActivity(action.context, intent, null)
|
||||
}
|
||||
}
|
||||
is HomeAction.GoToShop -> {
|
||||
val uri = Uri.parse(CARD_SHOP_URI)
|
||||
val intent = Intent(Intent.ACTION_VIEW, uri)
|
||||
startActivity(action.context, intent, null)
|
||||
}
|
||||
next(action)
|
||||
}
|
||||
next(action)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun showDisclaimerOrNavigateToWallet() {
|
||||
if (preferencesStorage.wasDisclaimerAccepted()) {
|
||||
navigateToWallet()
|
||||
} else {
|
||||
store.dispatch(NavigationAction.NavigateTo(AppScreen.Disclaimer))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private fun navigateToWallet() {
|
||||
if (store.state.navigationState.backStack.isNotEmpty()) {
|
||||
val currentScreen = store.state.navigationState.backStack.last()
|
||||
if (currentScreen == AppScreen.Home) {
|
||||
store.dispatch(NavigationAction.NavigateTo(AppScreen.Wallet))
|
||||
} else if (currentScreen != AppScreen.Wallet) {
|
||||
store.dispatch(NavigationAction.PopBackTo(AppScreen.Home))
|
||||
private fun showDisclaimerOrNavigateToWallet() {
|
||||
if (preferencesStorage.wasDisclaimerAccepted()) {
|
||||
store.dispatch(NavigationAction.NavigateTo(AppScreen.Wallet))
|
||||
} else {
|
||||
store.dispatch(NavigationAction.NavigateTo(AppScreen.Disclaimer))
|
||||
}
|
||||
} else {
|
||||
store.dispatch(NavigationAction.NavigateTo(AppScreen.Wallet))
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val CARD_SHOP_URI =
|
||||
"https://shop.tangem.com/?afmc=1i&utm_campaign=1i&utm_source=leaddyno&utm_medium=affiliate"
|
||||
}
|
||||
}
|
||||
|
||||
private const val CARD_SHOP_URI = "https://shop.tangem.com/?afmc=1i&utm_campaign=1i&utm_source=leaddyno&utm_medium=affiliate"
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -4,6 +4,9 @@ import com.google.firebase.crashlytics.FirebaseCrashlytics
|
|||
import com.tangem.blockchain.common.*
|
||||
import com.tangem.blockchain.extensions.Result
|
||||
import com.tangem.blockchain.extensions.Signer
|
||||
import com.tangem.commands.Card
|
||||
import com.tangem.tap.common.analytics.AnalyticsEvent
|
||||
import com.tangem.tap.common.analytics.FirebaseAnalyticsHandler
|
||||
import com.tangem.tap.common.extensions.stripZeroPlainString
|
||||
import com.tangem.tap.common.redux.AppState
|
||||
import com.tangem.tap.common.redux.global.GlobalAction
|
||||
|
|
@ -47,6 +50,7 @@ private fun verifyAndSendTransaction(
|
|||
) {
|
||||
val sendState = appState?.sendState ?: return
|
||||
val walletManager = appState.globalState.scanNoteResponse?.walletManager ?: return
|
||||
val card = appState.globalState.scanNoteResponse.card
|
||||
val recipientAddress = sendState.addressPayIdState.recipientWalletAddress ?: return
|
||||
val typedAmount = sendState.amountState.amountToExtract ?: return
|
||||
val feeAmount = sendState.feeState.currentFee ?: return
|
||||
|
|
@ -62,14 +66,14 @@ private fun verifyAndSendTransaction(
|
|||
dispatch(AmountAction.SetAmount(typedAmount.value!!.minus(reduceAmount), false))
|
||||
dispatch(AmountActionUi.CheckAmountToSend)
|
||||
}, sendAllCallback = {
|
||||
sendTransaction(action, walletManager, amountToSend, feeAmount, recipientAddress, dispatch)
|
||||
sendTransaction(action, walletManager, amountToSend, feeAmount, recipientAddress, card, dispatch)
|
||||
}, reduceAmount))
|
||||
}
|
||||
transactionErrors.isNotEmpty() -> {
|
||||
dispatch(SendAction.SendError(createValidateTransactionError(transactionErrors, walletManager)))
|
||||
}
|
||||
else -> {
|
||||
sendTransaction(action, walletManager, amountToSend, feeAmount, recipientAddress, dispatch)
|
||||
sendTransaction(action, walletManager, amountToSend, feeAmount, recipientAddress, card, dispatch)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -80,6 +84,7 @@ private fun sendTransaction(
|
|||
amountToSend: Amount,
|
||||
feeAmount: Amount,
|
||||
recipientAddress: String,
|
||||
card: Card,
|
||||
dispatch: (Action) -> Unit
|
||||
) {
|
||||
dispatch(SendAction.ChangeSendButtonState(SendButtonState.PROGRESS))
|
||||
|
|
@ -91,6 +96,7 @@ private fun sendTransaction(
|
|||
withContext(Dispatchers.Main) {
|
||||
when (result) {
|
||||
is Result.Success -> {
|
||||
FirebaseAnalyticsHandler.triggerEvent(AnalyticsEvent.TRANSACTION_IS_SENT, card)
|
||||
dispatch(SendAction.SendSuccess)
|
||||
dispatch(GlobalAction.UpdateWalletSignedHashes(result.data.walletSignedHashes))
|
||||
dispatch(WalletAction.UpdateWallet)
|
||||
|
|
|
|||
|
|
@ -20,7 +20,9 @@ sealed class WalletAction : Action {
|
|||
data class Failure(val error: TapError) : WalletAction()
|
||||
}
|
||||
|
||||
object LoadWallet : WalletAction() {
|
||||
data class LoadWallet(
|
||||
val wallet: Wallet, val artworkId: String?, val allowTopUp: Boolean
|
||||
) : WalletAction() {
|
||||
data class Success(val wallet: Wallet) : WalletAction()
|
||||
data class NoAccount(val amountToCreateAccount: String) : WalletAction()
|
||||
data class Failure(val errorMessage: String? = null) : WalletAction()
|
||||
|
|
@ -50,7 +52,7 @@ sealed class WalletAction : Action {
|
|||
object Failure : WalletAction()
|
||||
}
|
||||
|
||||
object DisablePayId: WalletAction()
|
||||
object DisablePayId : WalletAction()
|
||||
|
||||
data class LoadArtwork(val card: Card, val artworkId: String?) : WalletAction() {
|
||||
data class Success(val artwork: Artwork) : WalletAction()
|
||||
|
|
@ -85,4 +87,10 @@ sealed class WalletAction : Action {
|
|||
data class ExploreAddress(val context: Context) : WalletAction()
|
||||
object CreateWallet : WalletAction()
|
||||
object EmptyWallet : WalletAction()
|
||||
|
||||
sealed class TopUpAction : WalletAction() {
|
||||
data class TopUp(val context: Context, val toolbarColor: Int?) : TopUpAction()
|
||||
data class Start(val url: String, val redirectUrl: String) : TopUpAction()
|
||||
data class Finish(val topUpCompleted: Boolean) : TopUpAction()
|
||||
}
|
||||
}
|
||||
|
|
@ -11,12 +11,14 @@ import com.tangem.common.CompletionResult
|
|||
import com.tangem.common.extensions.CardType
|
||||
import com.tangem.common.extensions.getType
|
||||
import com.tangem.common.extensions.toHexString
|
||||
import com.tangem.tap.common.analytics.FirebaseAnalyticsHandler
|
||||
import com.tangem.tap.common.extensions.copyToClipboard
|
||||
import com.tangem.tap.common.redux.AppState
|
||||
import com.tangem.tap.common.redux.navigation.AppScreen
|
||||
import com.tangem.tap.common.redux.navigation.NavigationAction
|
||||
import com.tangem.tap.domain.PayIdManager
|
||||
import com.tangem.tap.domain.TapError
|
||||
import com.tangem.tap.domain.TopUpHelper
|
||||
import com.tangem.tap.domain.extensions.toSendableAmounts
|
||||
import com.tangem.tap.features.send.redux.PrepareSendScreen
|
||||
import com.tangem.tap.features.wallet.models.toPendingTransactions
|
||||
|
|
@ -32,210 +34,239 @@ import kotlinx.coroutines.launch
|
|||
import kotlinx.coroutines.withContext
|
||||
import org.rekotlin.Action
|
||||
import org.rekotlin.Middleware
|
||||
import timber.log.Timber
|
||||
|
||||
class WalletMiddleware {
|
||||
private val topUpMiddleware = TopUpMiddleware()
|
||||
|
||||
val walletMiddleware: Middleware<AppState> = { dispatch, state ->
|
||||
{ next ->
|
||||
{ action ->
|
||||
when (action) {
|
||||
is WalletAction.LoadWallet -> {
|
||||
scope.launch {
|
||||
store.state.globalState.tapWalletManager.loadWalletData()
|
||||
}
|
||||
}
|
||||
is WalletAction.LoadPayId -> {
|
||||
scope.launch {
|
||||
store.state.globalState.tapWalletManager.loadPayId()
|
||||
}
|
||||
}
|
||||
is WalletAction.LoadFiatRate -> {
|
||||
scope.launch {
|
||||
store.state.globalState.tapWalletManager.loadFiatRate(store.state.globalState.appCurrency)
|
||||
}
|
||||
}
|
||||
is WalletAction.CreateWallet -> {
|
||||
scope.launch {
|
||||
val result = tangemSdkManager.createWallet(
|
||||
store.state.globalState.scanNoteResponse?.card?.cardId
|
||||
)
|
||||
when (result) {
|
||||
is CompletionResult.Success -> {
|
||||
store.state.globalState.tapWalletManager.onCardScanned(result.data)
|
||||
}
|
||||
|
||||
val walletMiddleware: Middleware<AppState> = { dispatch, state ->
|
||||
{ next ->
|
||||
{ action ->
|
||||
when (action) {
|
||||
is WalletAction.TopUpAction -> topUpMiddleware.handle(action)
|
||||
is WalletAction.LoadWallet -> {
|
||||
scope.launch {
|
||||
store.state.globalState.tapWalletManager.loadWalletData()
|
||||
}
|
||||
}
|
||||
}
|
||||
is WalletAction.UpdateWallet -> {
|
||||
scope.launch { store.state.globalState.tapWalletManager.updateWallet() }
|
||||
}
|
||||
is WalletAction.UpdateWallet.Success -> setupWalletUpdate(action.wallet)
|
||||
is WalletAction.LoadWallet.Success -> {
|
||||
store.dispatch(WalletAction.CheckHashesCountOnline)
|
||||
if (!store.state.walletState.updatingWallet) setupWalletUpdate(action.wallet)
|
||||
}
|
||||
is WalletAction.CreatePayId.CompleteCreatingPayId -> {
|
||||
scope.launch {
|
||||
val cardId = store.state.globalState.scanNoteResponse?.card?.cardId
|
||||
val wallet = store.state.globalState.scanNoteResponse?.walletManager?.wallet
|
||||
val publicKey = store.state.globalState.scanNoteResponse?.card?.cardPublicKey
|
||||
if (cardId != null && wallet != null && publicKey != null) {
|
||||
val result = PayIdManager().setPayId(
|
||||
cardId, publicKey.toHexString(),
|
||||
action.payId, wallet.address, wallet.blockchain
|
||||
is WalletAction.LoadPayId -> {
|
||||
scope.launch {
|
||||
store.state.globalState.tapWalletManager.loadPayId()
|
||||
}
|
||||
}
|
||||
is WalletAction.LoadFiatRate -> {
|
||||
scope.launch {
|
||||
store.state.globalState.tapWalletManager.loadFiatRate(store.state.globalState.appCurrency)
|
||||
}
|
||||
}
|
||||
is WalletAction.CreateWallet -> {
|
||||
scope.launch {
|
||||
val result = tangemSdkManager.createWallet(
|
||||
store.state.globalState.scanNoteResponse?.card?.cardId
|
||||
)
|
||||
withContext(Dispatchers.Main) {
|
||||
when (result) {
|
||||
is Result.Success ->
|
||||
store.dispatch(WalletAction.CreatePayId.Success(action.payId))
|
||||
is Result.Failure -> {
|
||||
val error = result.error as? TapError
|
||||
?: TapError.PayIdCreatingError
|
||||
store.dispatch(WalletAction.CreatePayId.Failure(error))
|
||||
when (result) {
|
||||
is CompletionResult.Success -> {
|
||||
store.state.globalState.tapWalletManager.onCardScanned(result.data)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
is WalletAction.UpdateWallet -> {
|
||||
scope.launch { store.state.globalState.tapWalletManager.updateWallet() }
|
||||
}
|
||||
is WalletAction.UpdateWallet.Success -> setupWalletUpdate(action.wallet)
|
||||
is WalletAction.LoadWallet.Success -> {
|
||||
store.dispatch(WalletAction.CheckHashesCountOnline)
|
||||
if (!store.state.walletState.updatingWallet) setupWalletUpdate(action.wallet)
|
||||
}
|
||||
is WalletAction.CreatePayId.CompleteCreatingPayId -> {
|
||||
scope.launch {
|
||||
val cardId = store.state.globalState.scanNoteResponse?.card?.cardId
|
||||
val wallet = store.state.globalState.scanNoteResponse?.walletManager?.wallet
|
||||
val publicKey = store.state.globalState.scanNoteResponse?.card?.cardPublicKey
|
||||
if (cardId != null && wallet != null && publicKey != null) {
|
||||
val result = PayIdManager().setPayId(
|
||||
cardId, publicKey.toHexString(),
|
||||
action.payId, wallet.address, wallet.blockchain
|
||||
)
|
||||
withContext(Dispatchers.Main) {
|
||||
when (result) {
|
||||
is Result.Success ->
|
||||
store.dispatch(WalletAction.CreatePayId.Success(action.payId))
|
||||
is Result.Failure -> {
|
||||
val error = result.error as? TapError
|
||||
?: TapError.PayIdCreatingError
|
||||
store.dispatch(WalletAction.CreatePayId.Failure(error))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
is WalletAction.Scan -> {
|
||||
scope.launch {
|
||||
val result = tangemSdkManager.scanNote()
|
||||
when (result) {
|
||||
is CompletionResult.Success -> {
|
||||
store.state.globalState.tapWalletManager.onCardScanned(result.data)
|
||||
is WalletAction.Scan -> {
|
||||
scope.launch {
|
||||
val result = tangemSdkManager.scanNote(FirebaseAnalyticsHandler)
|
||||
when (result) {
|
||||
is CompletionResult.Success -> {
|
||||
store.state.globalState.tapWalletManager
|
||||
.onCardScanned(result.data, true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
is WalletAction.LoadData -> {
|
||||
scope.launch {
|
||||
store.state.globalState.scanNoteResponse?.let {
|
||||
store.state.globalState.tapWalletManager.loadData(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
is NetworkStateChanged -> {
|
||||
store.state.globalState.scanNoteResponse?.let { scanNoteResponse ->
|
||||
store.dispatch(WalletAction.CheckHashesCountOnline)
|
||||
is WalletAction.LoadData -> {
|
||||
scope.launch {
|
||||
store.state.globalState.tapWalletManager.onCardScanned(scanNoteResponse)
|
||||
store.state.globalState.scanNoteResponse?.let {
|
||||
store.state.globalState.tapWalletManager.loadData(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
is WalletAction.CopyAddress -> {
|
||||
store.state.walletState.addressData?.address?.let {
|
||||
action.context.copyToClipboard(it)
|
||||
store.dispatch(WalletAction.CopyAddress.Success)
|
||||
is NetworkStateChanged -> {
|
||||
store.state.globalState.scanNoteResponse?.let { scanNoteResponse ->
|
||||
store.dispatch(WalletAction.CheckHashesCountOnline)
|
||||
scope.launch {
|
||||
store.state.globalState.tapWalletManager.onCardScanned(scanNoteResponse)
|
||||
}
|
||||
}
|
||||
}
|
||||
is WalletAction.CopyAddress -> {
|
||||
store.state.walletState.addressData?.address?.let {
|
||||
action.context.copyToClipboard(it)
|
||||
store.dispatch(WalletAction.CopyAddress.Success)
|
||||
}
|
||||
}
|
||||
is WalletAction.ExploreAddress -> {
|
||||
val uri = Uri.parse(store.state.walletState.addressData?.exploreUrl)
|
||||
val intent = Intent(Intent.ACTION_VIEW, uri)
|
||||
ContextCompat.startActivity(action.context, intent, null)
|
||||
}
|
||||
is WalletAction.Send -> {
|
||||
val newAction = prepareSendAction(action.amount)
|
||||
store.dispatch(newAction)
|
||||
if (newAction is PrepareSendScreen) {
|
||||
store.dispatch(NavigationAction.NavigateTo(AppScreen.Send))
|
||||
}
|
||||
}
|
||||
is WalletAction.CheckIfWarningNeeded -> {
|
||||
val card = store.state.globalState.scanNoteResponse?.card
|
||||
val validator = store.state.globalState.scanNoteResponse?.walletManager
|
||||
as? SignatureCountValidator
|
||||
if (card != null && !preferencesStorage.wasCardScannedBefore(card.cardId)) {
|
||||
val result = checkIfWarningNeeded(card, validator)
|
||||
if (result != null) store.dispatch(WalletAction.ShowWarning(result))
|
||||
}
|
||||
}
|
||||
is WalletAction.CheckHashesCountOnline -> checkHashesCountOnline()
|
||||
is WalletAction.SaveCardId -> {
|
||||
val cardId = store.state.globalState.scanNoteResponse?.card?.cardId
|
||||
cardId?.let { preferencesStorage.saveScannedCardId(it) }
|
||||
}
|
||||
}
|
||||
is WalletAction.ExploreAddress -> {
|
||||
val uri = Uri.parse(store.state.walletState.addressData?.exploreUrl)
|
||||
val intent = Intent(Intent.ACTION_VIEW, uri)
|
||||
ContextCompat.startActivity(action.context, intent, null)
|
||||
}
|
||||
is WalletAction.Send -> {
|
||||
val newAction = prepareSendAction(action.amount)
|
||||
store.dispatch(newAction)
|
||||
if (newAction is PrepareSendScreen) {
|
||||
store.dispatch(NavigationAction.NavigateTo(AppScreen.Send))
|
||||
}
|
||||
}
|
||||
is WalletAction.CheckIfWarningNeeded -> {
|
||||
val card = store.state.globalState.scanNoteResponse?.card
|
||||
val validator = store.state.globalState.scanNoteResponse?.walletManager
|
||||
as? SignatureCountValidator
|
||||
if (card != null && !preferencesStorage.wasCardScannedBefore(card.cardId)) {
|
||||
val result = checkIfWarningNeeded(card, validator)
|
||||
if (result != null) store.dispatch(WalletAction.ShowWarning(result))
|
||||
}
|
||||
}
|
||||
is WalletAction.CheckHashesCountOnline -> checkHashesCountOnline()
|
||||
is WalletAction.SaveCardId -> {
|
||||
val cardId = store.state.globalState.scanNoteResponse?.card?.cardId
|
||||
cardId?.let { preferencesStorage.saveScannedCardId(it) }
|
||||
}
|
||||
}
|
||||
next(action)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupWalletUpdate(wallet: Wallet) {
|
||||
if (!wallet.recentTransactions.toPendingTransactions(wallet.address).isNullOrEmpty()) {
|
||||
store.dispatch(WalletAction.UpdateWallet.ScheduleUpdatingWallet)
|
||||
scope.launch(Dispatchers.IO) {
|
||||
delay(10000)
|
||||
withContext(Dispatchers.Main) {
|
||||
store.dispatch(WalletAction.UpdateWallet)
|
||||
next(action)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private fun prepareSendAction(amount: Amount?): Action {
|
||||
return if (amount != null) {
|
||||
if (amount.type == AmountType.Token) {
|
||||
PrepareSendScreen(store.state.walletState.wallet?.amounts?.get(AmountType.Coin), amount)
|
||||
} else {
|
||||
PrepareSendScreen(amount)
|
||||
}
|
||||
} else {
|
||||
val amounts = store.state.walletState.wallet?.amounts?.toSendableAmounts()
|
||||
if (amounts?.size ?: 0 > 1) {
|
||||
WalletAction.Send.ChooseCurrency(amounts)
|
||||
} else {
|
||||
val amountToSend = amounts?.first()
|
||||
PrepareSendScreen(amountToSend)
|
||||
private fun setupWalletUpdate(wallet: Wallet) {
|
||||
if (!wallet.recentTransactions.toPendingTransactions(wallet.address).isNullOrEmpty()) {
|
||||
store.dispatch(WalletAction.UpdateWallet.ScheduleUpdatingWallet)
|
||||
scope.launch(Dispatchers.IO) {
|
||||
delay(10000)
|
||||
withContext(Dispatchers.Main) {
|
||||
store.dispatch(WalletAction.UpdateWallet)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkIfWarningNeeded(
|
||||
card: Card, signatureCountValidator: SignatureCountValidator? = null
|
||||
): WarningType? {
|
||||
|
||||
if (card.getType() != CardType.Release) {
|
||||
return WarningType.DevCard
|
||||
private fun prepareSendAction(amount: Amount?): Action {
|
||||
return if (amount != null) {
|
||||
if (amount.type == AmountType.Token) {
|
||||
PrepareSendScreen(store.state.walletState.wallet?.amounts?.get(AmountType.Coin), amount)
|
||||
} else {
|
||||
PrepareSendScreen(amount)
|
||||
}
|
||||
} else {
|
||||
val amounts = store.state.walletState.wallet?.amounts?.toSendableAmounts()
|
||||
if (amounts?.size ?: 0 > 1) {
|
||||
WalletAction.Send.ChooseCurrency(amounts)
|
||||
} else {
|
||||
val amountToSend = amounts?.first()
|
||||
PrepareSendScreen(amountToSend)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return if (signatureCountValidator == null) {
|
||||
if (card.walletSignedHashes ?: 0 > 0) {
|
||||
WarningType.CardSignedHashesBefore
|
||||
private fun checkIfWarningNeeded(
|
||||
card: Card, signatureCountValidator: SignatureCountValidator? = null
|
||||
): WarningType? {
|
||||
|
||||
if (card.getType() != CardType.Release) {
|
||||
return WarningType.DevCard
|
||||
}
|
||||
|
||||
return if (signatureCountValidator == null) {
|
||||
if (card.walletSignedHashes ?: 0 > 0) {
|
||||
WarningType.CardSignedHashesBefore
|
||||
} else {
|
||||
store.dispatch(WalletAction.SaveCardId)
|
||||
null
|
||||
}
|
||||
} else {
|
||||
store.dispatch(WalletAction.SaveCardId)
|
||||
store.dispatch(WalletAction.NeedToCheckHashesCountOnline)
|
||||
null
|
||||
}
|
||||
} else {
|
||||
store.dispatch(WalletAction.NeedToCheckHashesCountOnline)
|
||||
null
|
||||
}
|
||||
|
||||
private fun checkHashesCountOnline() {
|
||||
if (store.state.walletState.hashesCountVerified != false) return
|
||||
if (!NetworkConnectivity.getInstance().isOnlineOrConnecting()) return
|
||||
|
||||
val card = store.state.globalState.scanNoteResponse?.card
|
||||
if (card == null || preferencesStorage.wasCardScannedBefore(card.cardId)) return
|
||||
|
||||
val validator = store.state.globalState.scanNoteResponse?.walletManager
|
||||
as? SignatureCountValidator
|
||||
scope.launch {
|
||||
val result = validator?.validateSignatureCount(card.walletSignedHashes ?: 0)
|
||||
withContext(Dispatchers.Main) {
|
||||
when (result) {
|
||||
SimpleResult.Success -> {
|
||||
store.dispatch(WalletAction.ConfirmHashesCount)
|
||||
store.dispatch(WalletAction.SaveCardId)
|
||||
}
|
||||
is SimpleResult.Failure ->
|
||||
if (result.error is BlockchainSdkError.SignatureCountNotMatched) {
|
||||
store.dispatch(WalletAction.ShowWarning(WarningType.CardSignedHashesBefore))
|
||||
} else if (card.walletSignedHashes ?: 0 > 0) {
|
||||
store.dispatch(WalletAction.ShowWarning(WarningType.CardSignedHashesBefore))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkHashesCountOnline() {
|
||||
if (store.state.walletState.hashesCountVerified != false) return
|
||||
if (!NetworkConnectivity.getInstance().isOnlineOrConnecting()) return
|
||||
private class TopUpMiddleware {
|
||||
fun handle(action: WalletAction.TopUpAction) {
|
||||
when (action) {
|
||||
is WalletAction.TopUpAction.TopUp -> {
|
||||
val url = TopUpHelper.getUrl(
|
||||
store.state.walletState.currencyData.currencySymbol!!,
|
||||
store.state.walletState.addressData!!.address
|
||||
)
|
||||
Timber.d(url)
|
||||
store.dispatch(WalletAction.TopUpAction.Start(url, TopUpHelper.REDIRECT_URL))
|
||||
store.dispatch(NavigationAction.NavigateTo(AppScreen.TopUp))
|
||||
}
|
||||
is WalletAction.TopUpAction.Start -> {
|
||||
|
||||
val card = store.state.globalState.scanNoteResponse?.card
|
||||
if (card == null || preferencesStorage.wasCardScannedBefore(card.cardId)) return
|
||||
|
||||
val validator = store.state.globalState.scanNoteResponse?.walletManager
|
||||
as? SignatureCountValidator
|
||||
scope.launch {
|
||||
val result = validator?.validateSignatureCount(card.walletSignedHashes ?: 0)
|
||||
withContext(Dispatchers.Main) {
|
||||
when (result) {
|
||||
SimpleResult.Success -> {
|
||||
store.dispatch(WalletAction.ConfirmHashesCount)
|
||||
store.dispatch(WalletAction.SaveCardId)
|
||||
}
|
||||
is SimpleResult.Failure ->
|
||||
if (result.error is BlockchainSdkError.SignatureCountNotMatched) {
|
||||
store.dispatch(WalletAction.ShowWarning(WarningType.CardSignedHashesBefore))
|
||||
} else if (card.walletSignedHashes ?: 0 > 0) {
|
||||
store.dispatch(WalletAction.ShowWarning(WarningType.CardSignedHashesBefore))
|
||||
}
|
||||
}
|
||||
is WalletAction.TopUpAction.Finish -> {
|
||||
if (action.topUpCompleted) store.dispatch(WalletAction.UpdateWallet)
|
||||
store.dispatch(NavigationAction.PopBackTo())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,7 +36,8 @@ private fun internalReduce(action: Action, state: AppState): WalletState {
|
|||
is WalletAction.EmptyWallet -> newState = newState.copy(
|
||||
state = ProgressState.Done,
|
||||
currencyData = BalanceWidgetData(BalanceStatus.EmptyCard),
|
||||
mainButton = WalletMainButton.CreateWalletButton(true)
|
||||
mainButton = WalletMainButton.CreateWalletButton(true),
|
||||
topUpState = TopUpState(false)
|
||||
)
|
||||
is WalletAction.LoadData.Failure -> {
|
||||
when (action.error) {
|
||||
|
|
@ -53,28 +54,27 @@ private fun internalReduce(action: Action, state: AppState): WalletState {
|
|||
addressData = addressData,
|
||||
currencyData = BalanceWidgetData(
|
||||
status = BalanceStatus.Unreachable,
|
||||
currency = wallet?.blockchain?.fullName),
|
||||
mainButton = WalletMainButton.SendButton(false)
|
||||
currency = wallet?.blockchain?.fullName,
|
||||
token = wallet?.token?.symbol?.let {
|
||||
TokenData("", tokenSymbol = it)
|
||||
}),
|
||||
mainButton = WalletMainButton.SendButton(false),
|
||||
topUpState = TopUpState(false)
|
||||
)
|
||||
}
|
||||
is TapError.UnknownBlockchain -> {
|
||||
newState = newState.copy(
|
||||
state = ProgressState.Done,
|
||||
currencyData = BalanceWidgetData(BalanceStatus.UnknownBlockchain)
|
||||
currencyData = BalanceWidgetData(BalanceStatus.UnknownBlockchain),
|
||||
topUpState = TopUpState(false)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
is WalletAction.LoadWallet -> {
|
||||
val wallet = state.globalState.scanNoteResponse?.walletManager?.wallet
|
||||
val addressData = if (wallet == null) {
|
||||
null
|
||||
} else {
|
||||
AddressData(wallet.address, wallet.shareUrl, wallet.exploreUrl)
|
||||
}
|
||||
val currentArtworkId = state.globalState.scanNoteResponse?.verifyResponse?.artworkInfo?.id
|
||||
val cardImage = if (newState.cardImage?.artworkId == currentArtworkId) {
|
||||
val wallet = action.wallet
|
||||
val cardImage = if (newState.cardImage?.artworkId == action.artworkId) {
|
||||
newState.cardImage
|
||||
} else {
|
||||
null
|
||||
|
|
@ -84,11 +84,15 @@ private fun internalReduce(action: Action, state: AppState): WalletState {
|
|||
cardImage = cardImage,
|
||||
currencyData = BalanceWidgetData(
|
||||
BalanceStatus.Loading,
|
||||
wallet?.blockchain?.fullName
|
||||
wallet.blockchain.fullName,
|
||||
currencySymbol = wallet.blockchain.currency,
|
||||
token = wallet.token?.symbol?.let {
|
||||
TokenData("", tokenSymbol = it)
|
||||
}
|
||||
),
|
||||
addressData = addressData,
|
||||
mainButton = WalletMainButton.SendButton(false)
|
||||
|
||||
addressData = AddressData(wallet.address, wallet.shareUrl, wallet.exploreUrl),
|
||||
mainButton = WalletMainButton.SendButton(false),
|
||||
topUpState = TopUpState(allowed = action.allowTopUp)
|
||||
)
|
||||
}
|
||||
is WalletAction.LoadWallet.Success -> newState = onWalletLoaded(action.wallet, newState)
|
||||
|
|
@ -109,7 +113,8 @@ private fun internalReduce(action: Action, state: AppState): WalletState {
|
|||
currencyData = newState.currencyData.copy(
|
||||
status = BalanceStatus.Unreachable,
|
||||
errorMessage = action.errorMessage
|
||||
)
|
||||
),
|
||||
topUpState = TopUpState(false)
|
||||
)
|
||||
is WalletAction.UpdateWallet -> newState = newState.copy(updatingWallet = true)
|
||||
is WalletAction.UpdateWallet.ScheduleUpdatingWallet ->
|
||||
|
|
@ -204,11 +209,25 @@ private fun internalReduce(action: Action, state: AppState): WalletState {
|
|||
newState = newState.copy(hashesCountVerified = false)
|
||||
is WalletAction.ConfirmHashesCount ->
|
||||
newState = newState.copy(hashesCountVerified = true)
|
||||
is WalletAction.TopUpAction -> {
|
||||
newState = newState.copy(topUpState = handleTopUpActions(action, newState.topUpState))
|
||||
}
|
||||
}
|
||||
return newState
|
||||
}
|
||||
|
||||
private fun onWalletLoaded(wallet: Wallet, walletState: WalletState): WalletState {
|
||||
private fun handleTopUpActions(action: WalletAction.TopUpAction, state: TopUpState): TopUpState {
|
||||
return when (action) {
|
||||
is WalletAction.TopUpAction.TopUp -> state
|
||||
is WalletAction.TopUpAction.Start ->
|
||||
state.copy(url = action.url, redirectUrl = action.redirectUrl)
|
||||
is WalletAction.TopUpAction.Finish -> state.copy(url = null)
|
||||
}
|
||||
}
|
||||
|
||||
private fun onWalletLoaded(
|
||||
wallet: Wallet, walletState: WalletState, topUpAllowed: Boolean? = null
|
||||
): WalletState {
|
||||
val fiatCurrencySymbol = store.state.globalState.appCurrency
|
||||
val token = wallet.amounts[AmountType.Token]
|
||||
val tokenData = if (token != null) {
|
||||
|
|
|
|||
|
|
@ -21,7 +21,8 @@ data class WalletState(
|
|||
val payIdData: PayIdData = PayIdData(),
|
||||
val walletDialog: WalletDialog? = null,
|
||||
val updatingWallet: Boolean = false,
|
||||
val mainButton: WalletMainButton = WalletMainButton.SendButton(false)
|
||||
val mainButton: WalletMainButton = WalletMainButton.SendButton(false),
|
||||
val topUpState: TopUpState = TopUpState()
|
||||
) : StateType {
|
||||
val showDetails: Boolean =
|
||||
currencyData.status != com.tangem.tap.features.wallet.ui.BalanceStatus.EmptyCard &&
|
||||
|
|
@ -76,4 +77,10 @@ data class Artwork(
|
|||
const val SERGIO_CARD_ID = "BC01"
|
||||
const val MARTA_CARD_ID = "BC02"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data class TopUpState(
|
||||
val allowed: Boolean = true,
|
||||
val url: String? = null,
|
||||
val redirectUrl: String? = null
|
||||
)
|
||||
|
|
@ -8,7 +8,6 @@ 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 BalanceStatus {
|
||||
VerifiedOnline,
|
||||
|
|
@ -50,20 +49,21 @@ class BalanceWidget(
|
|||
fragment.l_balance.show()
|
||||
fragment.l_balance_error.hide()
|
||||
fragment.tv_fiat_amount.hide()
|
||||
fragment.l_token.hide()
|
||||
|
||||
fragment.tv_currency.text = data.currency
|
||||
fragment.tv_amount.text = ""
|
||||
|
||||
showStatus(R.id.tv_status_loading)
|
||||
|
||||
if (data.token != null) {
|
||||
showBalanceWithToken(data, false)
|
||||
} else {
|
||||
showBalanceWithoutToken(data, false)
|
||||
}
|
||||
}
|
||||
BalanceStatus.VerifiedOnline, BalanceStatus.TransactionInProgress -> {
|
||||
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()
|
||||
fragment.tv_fiat_amount.text = data.fiatAmount
|
||||
val statusView = if (data.status == BalanceStatus.VerifiedOnline) {
|
||||
R.id.tv_status_verified
|
||||
} else {
|
||||
|
|
@ -75,22 +75,21 @@ class BalanceWidget(
|
|||
fragment.tv_status_error_message.hide()
|
||||
|
||||
if (data.token != null) {
|
||||
fragment.l_token.show()
|
||||
fragment.l_token.tv_token_symbol.text = data.token.tokenSymbol
|
||||
fragment.l_token.tv_token_amount.text = data.token.amount
|
||||
fragment.l_token.tv_token_fiat_amount.text = data.token.fiatAmount
|
||||
showBalanceWithToken(data, true)
|
||||
} else {
|
||||
fragment.l_token.hide()
|
||||
showBalanceWithoutToken(data, true)
|
||||
}
|
||||
}
|
||||
BalanceStatus.Unreachable -> {
|
||||
fragment.l_balance.show()
|
||||
fragment.l_balance_error.hide()
|
||||
fragment.l_token.hide()
|
||||
fragment.tv_fiat_amount.hide()
|
||||
fragment.group_base_currency.hide()
|
||||
|
||||
fragment.tv_currency.text = data.currency
|
||||
val currency = if (data.token != null) data.token.tokenSymbol else data.currency
|
||||
fragment.tv_currency.text = currency
|
||||
fragment.tv_amount.text = ""
|
||||
|
||||
fragment.tv_status_error_message.text = data.errorMessage
|
||||
fragment.tv_status_error.text =
|
||||
fragment.getString(R.string.wallet_balance_blockchain_unreachable)
|
||||
|
|
@ -129,4 +128,26 @@ class BalanceWidget(
|
|||
fragment.tv_status_loading.show(viewRes == R.id.tv_status_loading)
|
||||
fragment.tv_status_verified.show(viewRes == R.id.tv_status_verified)
|
||||
}
|
||||
|
||||
private fun showBalanceWithToken(data: BalanceWidgetData, showAmount: Boolean) {
|
||||
fragment.group_base_currency.show()
|
||||
fragment.tv_currency.text = data.token?.tokenSymbol
|
||||
fragment.tv_base_currency.text = data.currency
|
||||
fragment.tv_amount.text = if (showAmount) data.token?.amount else ""
|
||||
fragment.tv_base_amount.text = if (showAmount) data.amount else ""
|
||||
if (showAmount) {
|
||||
fragment.tv_fiat_amount.show()
|
||||
fragment.tv_fiat_amount.text = data.token?.fiatAmount
|
||||
}
|
||||
}
|
||||
|
||||
private fun showBalanceWithoutToken(data: BalanceWidgetData, showAmount: Boolean) {
|
||||
fragment.group_base_currency.hide()
|
||||
fragment.tv_currency.text = data.currency
|
||||
fragment.tv_amount.text = if (showAmount) data.amount else ""
|
||||
if (showAmount) {
|
||||
fragment.tv_fiat_amount.show()
|
||||
fragment.tv_fiat_amount.text = data.fiatAmount
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -29,6 +29,8 @@ import com.tangem.wallet.R
|
|||
import kotlinx.android.synthetic.main.card_balance.*
|
||||
import kotlinx.android.synthetic.main.fragment_wallet.*
|
||||
import kotlinx.android.synthetic.main.layout_address.*
|
||||
import kotlinx.android.synthetic.main.layout_wallet_long_buttons.*
|
||||
import kotlinx.android.synthetic.main.layout_wallet_short_buttons.*
|
||||
import org.rekotlin.StoreSubscriber
|
||||
|
||||
|
||||
|
|
@ -39,7 +41,6 @@ class WalletFragment : Fragment(R.layout.fragment_wallet), StoreSubscriber<Walle
|
|||
|
||||
private lateinit var viewAdapter: PendingTransactionsAdapter
|
||||
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setHasOptionsMenu(true)
|
||||
|
|
@ -74,10 +75,6 @@ class WalletFragment : Fragment(R.layout.fragment_wallet), StoreSubscriber<Walle
|
|||
toolbar.setNavigationOnClickListener {
|
||||
store.dispatch(NavigationAction.PopBackTo(AppScreen.Home))
|
||||
}
|
||||
|
||||
btn_scan.setOnClickListener {
|
||||
store.dispatch(WalletAction.Scan)
|
||||
}
|
||||
setupTransactionsRecyclerView()
|
||||
}
|
||||
|
||||
|
|
@ -161,6 +158,29 @@ class WalletFragment : Fragment(R.layout.fragment_wallet), StoreSubscriber<Walle
|
|||
}
|
||||
|
||||
private fun setupButtons(state: WalletState) {
|
||||
if (state.topUpState.allowed) {
|
||||
l_buttons_long.hide()
|
||||
l_buttons_short.show()
|
||||
} else {
|
||||
l_buttons_long.show()
|
||||
l_buttons_short.hide()
|
||||
}
|
||||
|
||||
val btnConfirm = if (state.topUpState.allowed) {
|
||||
btn_confirm_short
|
||||
} else {
|
||||
btn_confirm_long
|
||||
}
|
||||
val btnScan = if (state.topUpState.allowed) {
|
||||
btn_scan_short
|
||||
} else {
|
||||
btn_scan_long
|
||||
}
|
||||
|
||||
btnScan.setOnClickListener {
|
||||
store.dispatch(WalletAction.Scan)
|
||||
}
|
||||
|
||||
btn_copy.setOnClickListener { store.dispatch(WalletAction.CopyAddress(requireContext())) }
|
||||
btn_show_qr.setOnClickListener { store.dispatch(WalletAction.ShowQrCode) }
|
||||
|
||||
|
|
@ -168,15 +188,20 @@ class WalletFragment : Fragment(R.layout.fragment_wallet), StoreSubscriber<Walle
|
|||
is WalletMainButton.SendButton -> R.string.wallet_button_send
|
||||
is WalletMainButton.CreateWalletButton -> R.string.wallet_button_create_wallet
|
||||
}
|
||||
btn_confirm.text = getString(buttonTitle)
|
||||
btn_confirm.isEnabled = state.mainButton.enabled
|
||||
btnConfirm.text = getString(buttonTitle)
|
||||
btnConfirm.isEnabled = state.mainButton.enabled
|
||||
|
||||
btn_confirm.setOnClickListener {
|
||||
btnConfirm.setOnClickListener {
|
||||
when (state.mainButton) {
|
||||
is WalletMainButton.SendButton -> store.dispatch(WalletAction.Send())
|
||||
is WalletMainButton.CreateWalletButton -> store.dispatch(WalletAction.CreateWallet)
|
||||
}
|
||||
}
|
||||
btn_top_up.setOnClickListener {
|
||||
store.dispatch(
|
||||
WalletAction.TopUpAction.TopUp(requireContext(), R.color.backgroundLightGray)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupAddressCard(state: WalletState) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,63 @@
|
|||
package com.tangem.tap.features.wallet.ui.topup
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import androidx.activity.OnBackPressedCallback
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.transition.TransitionInflater
|
||||
import com.tangem.tap.common.redux.navigation.NavigationAction
|
||||
import com.tangem.tap.features.wallet.redux.WalletState
|
||||
import com.tangem.tap.store
|
||||
import com.tangem.wallet.R
|
||||
import kotlinx.android.synthetic.main.fragment_topup.*
|
||||
import org.rekotlin.StoreSubscriber
|
||||
|
||||
|
||||
class TopUpFragment : Fragment(R.layout.fragment_topup), StoreSubscriber<WalletState> {
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
activity?.onBackPressedDispatcher?.addCallback(this, object : OnBackPressedCallback(true) {
|
||||
override fun handleOnBackPressed() {
|
||||
store.dispatch(NavigationAction.PopBackTo())
|
||||
}
|
||||
})
|
||||
val inflater = TransitionInflater.from(requireContext())
|
||||
enterTransition = inflater.inflateTransition(R.transition.slide_right)
|
||||
exitTransition = inflater.inflateTransition(R.transition.fade)
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
store.subscribe(this) { state ->
|
||||
state.skipRepeats { oldState, newState ->
|
||||
oldState.walletState == newState.walletState
|
||||
}.select { it.walletState }
|
||||
}
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
super.onStop()
|
||||
store.unsubscribe(this)
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
web_view.settings.javaScriptEnabled = true
|
||||
|
||||
toolbar.setNavigationOnClickListener {
|
||||
store.dispatch(NavigationAction.PopBackTo())
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override fun newState(state: WalletState) {
|
||||
if (activity == null) return
|
||||
|
||||
if (state.topUpState.url != null) {
|
||||
web_view.webViewClient = TopUpWebViewClient(progress_bar, state.topUpState.redirectUrl)
|
||||
web_view.loadUrl(state.topUpState.url)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
package com.tangem.tap.features.wallet.ui.topup
|
||||
|
||||
import android.webkit.WebView
|
||||
import android.webkit.WebViewClient
|
||||
import android.widget.ProgressBar
|
||||
import com.tangem.tap.common.extensions.hide
|
||||
import com.tangem.tap.common.extensions.show
|
||||
import com.tangem.tap.features.wallet.redux.WalletAction
|
||||
import com.tangem.tap.store
|
||||
|
||||
class TopUpWebViewClient(
|
||||
private val progressBar: ProgressBar, private val redirectUrl: String?
|
||||
) : WebViewClient() {
|
||||
override fun shouldOverrideUrlLoading(view: WebView, url: String): Boolean {
|
||||
if (redirectUrl != null && url.contains(redirectUrl)) {
|
||||
store.dispatch(WalletAction.TopUpAction.Finish(true))
|
||||
return true
|
||||
}
|
||||
view.loadUrl(url)
|
||||
return true
|
||||
}
|
||||
|
||||
override fun onPageFinished(view: WebView, url: String) {
|
||||
super.onPageFinished(view, url)
|
||||
progressBar.hide()
|
||||
}
|
||||
|
||||
init {
|
||||
progressBar.show()
|
||||
}
|
||||
}
|
||||
17
app/src/main/res/drawable/ic_arrow_up.xml
Normal file
17
app/src/main/res/drawable/ic_arrow_up.xml
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="14dp"
|
||||
android:height="14dp"
|
||||
android:viewportWidth="10"
|
||||
android:viewportHeight="12">
|
||||
<group
|
||||
android:scaleX="0.8"
|
||||
android:pivotX="5.3"
|
||||
android:pivotY="6"
|
||||
android:rotation="180"
|
||||
>
|
||||
<path
|
||||
android:pathData="M5.853,11.6645L9.7814,8.075C10.0495,7.8439 10.0734,7.3871 9.84,7.1191C9.6067,6.8511 9.1615,6.824 8.9084,7.0724L6.0712,9.6665L6.0712,0.8398C6.0712,0.468 5.7781,0.1667 5.4165,0.1667C5.0549,0.1667 4.7618,0.468 4.7618,0.8398L4.7618,9.6665L1.9246,7.0724C1.6715,6.824 1.2271,6.8576 0.9937,7.1256C0.7604,7.3936 0.7835,7.8439 1.0516,8.075L4.98,11.6645C5.2976,11.8989 5.5827,11.8802 5.853,11.6645L5.853,11.6645Z"
|
||||
android:fillColor="#1C1C1E"
|
||||
/>
|
||||
</group>
|
||||
</vector>
|
||||
9
app/src/main/res/drawable/ic_arrow_up_short_btn.xml
Normal file
9
app/src/main/res/drawable/ic_arrow_up_short_btn.xml
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="20dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="20">
|
||||
<path
|
||||
android:pathData="M11.4765,5.7026L6.7623,10.0101C6.4406,10.2874 6.412,10.8356 6.692,11.1572C6.972,11.4788 7.5063,11.5112 7.8099,11.2131L11.2146,8.1003L11.2146,18.6923C11.2146,19.1384 11.5664,19.5 12.0003,19.5C12.4342,19.5 12.7859,19.1384 12.7859,18.6923L12.7859,8.1003L16.1906,11.2131C16.4942,11.5112 17.0275,11.4709 17.3076,11.1493C17.5876,10.8277 17.5599,10.2874 17.2382,10.0101L12.524,5.7026C12.1429,5.4214 11.8008,5.4438 11.4765,5.7026L11.4765,5.7026Z"
|
||||
android:fillColor="#ffffff"/>
|
||||
</vector>
|
||||
10
app/src/main/res/drawable/ic_close.xml
Normal file
10
app/src/main/res/drawable/ic_close.xml
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M19,6.41L17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12z"/>
|
||||
</vector>
|
||||
15
app/src/main/res/drawable/ic_group_1243.xml
Normal file
15
app/src/main/res/drawable/ic_group_1243.xml
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="13dp"
|
||||
android:height="16dp"
|
||||
android:viewportWidth="13"
|
||||
android:viewportHeight="18">
|
||||
<path
|
||||
android:pathData="M11.7908,6.0129C10.9896,3.7531 9.3666,1.9247 7.1993,0.8873C5.032,-0.1502 2.5873,-0.2837 0.3275,0.5175L0.2762,0.538C0.1734,0.5791 0.081,0.651 0.0399,0.764C-0.0114,0.8667 -0.0114,0.99 0.0296,1.0927C0.1221,1.329 0.3789,1.442 0.6254,1.3598C2.6695,0.6408 4.8676,0.764 6.809,1.6988C8.7606,2.6335 10.2295,4.277 10.9485,6.3108C11.2566,7.1839 11.4107,8.0878 11.4107,9.002C11.4107,9.9162 11.2566,10.8201 10.9485,11.6932C10.2295,13.7372 8.7606,15.3704 6.809,16.3052C4.8573,17.2399 2.6592,17.3632 0.6151,16.6441C0.3789,16.562 0.1221,16.6749 0.0296,16.9112C-0.0114,17.0242 -0.0114,17.1372 0.0399,17.2399C0.0913,17.3426 0.1734,17.4248 0.2864,17.4659L0.3378,17.4864C1.3136,17.8254 2.3202,18 3.3269,18C4.6519,18 5.977,17.7021 7.2096,17.1166C9.3769,16.0792 11.0101,14.2611 11.801,11.991C12.14,11.0255 12.3146,10.0189 12.3146,9.0122C12.3044,7.9851 12.1297,6.9784 11.7908,6.0129Z"
|
||||
android:fillColor="#ffffff"/>
|
||||
<path
|
||||
android:pathData="M1.1703,14.0252C1.1183,14.1498 1.1287,14.2848 1.1806,14.4095C1.2326,14.5341 1.3364,14.6172 1.4715,14.6588C2.0532,14.8457 2.6556,14.9392 3.2581,14.9392C3.9644,14.9392 4.6707,14.8146 5.3251,14.5549C6.7689,14.0044 7.9115,12.9137 8.5347,11.5011C8.8671,10.7532 9.0333,9.9742 9.0333,9.1744V9.0082C9.0126,8.2499 8.8464,7.502 8.5347,6.7957C7.9011,5.383 6.7689,4.3028 5.3251,3.7419C4.0787,3.2641 2.6972,3.2329 1.4299,3.6484C1.3157,3.6899 1.2118,3.773 1.1599,3.8873C1.1079,4.0016 1.1079,4.1262 1.1495,4.2405C1.2326,4.4586 1.4819,4.5729 1.7104,4.5001C2.7803,4.147 3.954,4.1677 5.0031,4.5729C6.2184,5.0403 7.1844,5.9543 7.7142,7.1489C7.9946,7.7721 8.1296,8.4265 8.14,9.1017V9.1328C8.14,9.8184 7.9946,10.4831 7.7142,11.1167C7.1844,12.3113 6.2184,13.2253 5.0031,13.6928C3.9436,14.0979 2.7699,14.1186 1.6896,13.7551C1.4819,13.7135 1.243,13.8174 1.1703,14.0252Z"
|
||||
android:fillColor="#ffffff"/>
|
||||
<path
|
||||
android:pathData="M3.9148,10.5778C3.6136,10.692 3.2812,10.7128 2.9592,10.6297C2.7619,10.5778 2.5438,10.6816 2.471,10.879V10.8894C2.4191,11.014 2.4295,11.1594 2.5022,11.2841C2.5645,11.4087 2.6892,11.5022 2.8346,11.5334C3.0112,11.5749 3.1774,11.5853 3.3539,11.5853C3.6552,11.5853 3.9564,11.5334 4.2472,11.4191C5.2028,11.0556 5.8469,10.1207 5.8469,9.0924C5.8469,8.0641 5.2028,7.1396 4.2472,6.7657C3.7694,6.5787 3.2501,6.5476 2.7411,6.6722C2.6268,6.7034 2.523,6.7761 2.471,6.8903C2.4191,6.9942 2.4087,7.1188 2.4503,7.2331L2.4606,7.2539C2.5438,7.472 2.7723,7.5862 3.0008,7.5447C3.302,7.472 3.624,7.4928 3.9148,7.607C4.5277,7.8356 4.9328,8.438 4.9328,9.0924C4.9328,9.7468 4.5277,10.3492 3.9148,10.5778Z"
|
||||
android:fillColor="#ffffff"/>
|
||||
</vector>
|
||||
|
|
@ -1,15 +1,16 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="13dp"
|
||||
android:height="18dp"
|
||||
android:viewportWidth="13"
|
||||
android:viewportHeight="18">
|
||||
android:width="24dp"
|
||||
android:height="21dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="21"
|
||||
>
|
||||
<path
|
||||
android:pathData="M11.7908,6.0129C10.9896,3.7531 9.3666,1.9247 7.1993,0.8873C5.032,-0.1502 2.5873,-0.2837 0.3275,0.5175L0.2762,0.538C0.1734,0.5791 0.081,0.651 0.0399,0.764C-0.0114,0.8667 -0.0114,0.99 0.0296,1.0927C0.1221,1.329 0.3789,1.442 0.6254,1.3598C2.6695,0.6408 4.8676,0.764 6.809,1.6988C8.7606,2.6335 10.2295,4.277 10.9485,6.3108C11.2566,7.1839 11.4107,8.0878 11.4107,9.002C11.4107,9.9162 11.2566,10.8201 10.9485,11.6932C10.2295,13.7372 8.7606,15.3704 6.809,16.3052C4.8573,17.2399 2.6592,17.3632 0.6151,16.6441C0.3789,16.562 0.1221,16.6749 0.0296,16.9112C-0.0114,17.0242 -0.0114,17.1372 0.0399,17.2399C0.0913,17.3426 0.1734,17.4248 0.2864,17.4659L0.3378,17.4864C1.3136,17.8254 2.3202,18 3.3269,18C4.6519,18 5.977,17.7021 7.2096,17.1166C9.3769,16.0792 11.0101,14.2611 11.801,11.991C12.14,11.0255 12.3146,10.0189 12.3146,9.0122C12.3044,7.9851 12.1297,6.9784 11.7908,6.0129Z"
|
||||
android:pathData="M17.7908,9.0129C16.9896,6.7531 15.3666,4.9247 13.1993,3.8873C11.032,2.8498 8.5873,2.7163 6.3275,3.5175L6.2762,3.538C6.1734,3.5791 6.081,3.651 6.0399,3.764C5.9886,3.8667 5.9886,3.99 6.0296,4.0927C6.1221,4.329 6.3789,4.442 6.6254,4.3598C8.6695,3.6408 10.8676,3.764 12.809,4.6988C14.7606,5.6335 16.2295,7.277 16.9485,9.3108C17.2566,10.1839 17.4107,11.0878 17.4107,12.002C17.4107,12.9161 17.2566,13.8201 16.9485,14.6932C16.2295,16.7372 14.7606,18.3704 12.809,19.3052C10.8574,20.2399 8.6592,20.3632 6.6151,19.6441C6.3789,19.562 6.1221,19.6749 6.0296,19.9112C5.9886,20.0242 5.9886,20.1372 6.0399,20.2399C6.0913,20.3426 6.1734,20.4248 6.2864,20.4659L6.3378,20.4864C7.3136,20.8254 8.3202,21 9.3269,21C10.6519,21 11.977,20.7021 13.2096,20.1166C15.3769,19.0792 17.0101,17.2611 17.801,14.991C18.14,14.0255 18.3146,13.0189 18.3146,12.0122C18.3044,10.9851 18.1297,9.9784 17.7908,9.0129Z"
|
||||
android:fillColor="#ffffff"/>
|
||||
<path
|
||||
android:pathData="M1.1703,14.0252C1.1183,14.1498 1.1287,14.2848 1.1806,14.4095C1.2326,14.5341 1.3364,14.6172 1.4715,14.6588C2.0532,14.8457 2.6556,14.9392 3.2581,14.9392C3.9644,14.9392 4.6707,14.8146 5.3251,14.5549C6.7689,14.0044 7.9115,12.9137 8.5347,11.5011C8.8671,10.7532 9.0333,9.9742 9.0333,9.1744V9.0082C9.0126,8.2499 8.8464,7.502 8.5347,6.7957C7.9011,5.383 6.7689,4.3028 5.3251,3.7419C4.0787,3.2641 2.6972,3.2329 1.4299,3.6484C1.3157,3.6899 1.2118,3.773 1.1599,3.8873C1.1079,4.0016 1.1079,4.1262 1.1495,4.2405C1.2326,4.4586 1.4819,4.5729 1.7104,4.5001C2.7803,4.147 3.954,4.1677 5.0031,4.5729C6.2184,5.0403 7.1844,5.9543 7.7142,7.1489C7.9946,7.7721 8.1296,8.4265 8.14,9.1017V9.1328C8.14,9.8184 7.9946,10.4831 7.7142,11.1167C7.1844,12.3113 6.2184,13.2253 5.0031,13.6928C3.9436,14.0979 2.7699,14.1186 1.6896,13.7551C1.4819,13.7135 1.243,13.8174 1.1703,14.0252Z"
|
||||
android:pathData="M7.1702,17.0252C7.1183,17.1498 7.1287,17.2848 7.1806,17.4095C7.2326,17.5341 7.3365,17.6172 7.4715,17.6588C8.0532,17.8457 8.6556,17.9392 9.2581,17.9392C9.9644,17.9392 10.6707,17.8146 11.3251,17.5549C12.7689,17.0044 13.9115,15.9137 14.5347,14.5011C14.8671,13.7532 15.0333,12.9742 15.0333,12.1744V12.0082C15.0126,11.2499 14.8464,10.502 14.5347,9.7957C13.9011,8.383 12.7689,7.3028 11.3251,6.7419C10.0787,6.2641 8.6972,6.2329 7.4299,6.6484C7.3157,6.6899 7.2118,6.773 7.1599,6.8873C7.1079,7.0016 7.1079,7.1262 7.1495,7.2405C7.2326,7.4586 7.4819,7.5729 7.7104,7.5001C8.7803,7.147 9.954,7.1677 11.0031,7.5729C12.2184,8.0403 13.1844,8.9543 13.7142,10.1489C13.9946,10.7721 14.1296,11.4265 14.14,12.1017V12.1328C14.14,12.8184 13.9946,13.4831 13.7142,14.1167C13.1844,15.3113 12.2184,16.2253 11.0031,16.6928C9.9436,17.0979 8.7699,17.1186 7.6896,16.7551C7.4819,16.7135 7.243,16.8174 7.1702,17.0252Z"
|
||||
android:fillColor="#ffffff"/>
|
||||
<path
|
||||
android:pathData="M3.9148,10.5778C3.6136,10.692 3.2812,10.7128 2.9592,10.6297C2.7618,10.5778 2.5437,10.6816 2.471,10.879V10.8894C2.419,11.014 2.4294,11.1594 2.5021,11.2841C2.5645,11.4087 2.6891,11.5022 2.8345,11.5334C3.0111,11.5749 3.1773,11.5853 3.3539,11.5853C3.6551,11.5853 3.9563,11.5334 4.2472,11.4191C5.2028,11.0556 5.8468,10.1207 5.8468,9.0924C5.8468,8.0641 5.2028,7.1396 4.2472,6.7657C3.7694,6.5787 3.25,6.5476 2.741,6.6722C2.6268,6.7034 2.5229,6.7761 2.471,6.8903C2.419,6.9942 2.4086,7.1188 2.4502,7.2331L2.4606,7.2539C2.5437,7.472 2.7722,7.5862 3.0007,7.5447C3.3019,7.472 3.624,7.4928 3.9148,7.607C4.5276,7.8356 4.9327,8.438 4.9327,9.0924C4.9327,9.7468 4.5276,10.3492 3.9148,10.5778Z"
|
||||
android:pathData="M9.9148,13.5778C9.6136,13.692 9.2812,13.7128 8.9592,13.6297C8.7619,13.5778 8.5437,13.6816 8.471,13.879V13.8894C8.4191,14.014 8.4295,14.1594 8.5022,14.2841C8.5645,14.4087 8.6892,14.5022 8.8346,14.5334C9.0112,14.5749 9.1774,14.5853 9.3539,14.5853C9.6552,14.5853 9.9564,14.5334 10.2472,14.4191C11.2029,14.0556 11.8469,13.1207 11.8469,12.0924C11.8469,11.0641 11.2029,10.1396 10.2472,9.7657C9.7694,9.5787 9.2501,9.5476 8.7411,9.6722C8.6268,9.7034 8.523,9.7761 8.471,9.8903C8.4191,9.9942 8.4087,10.1188 8.4503,10.2331L8.4607,10.2539C8.5437,10.472 8.7723,10.5863 9.0008,10.5447C9.302,10.472 9.624,10.4928 9.9148,10.607C10.5277,10.8356 10.9328,11.438 10.9328,12.0924C10.9328,12.7468 10.5277,13.3492 9.9148,13.5778Z"
|
||||
android:fillColor="#ffffff"/>
|
||||
</vector>
|
||||
|
|
|
|||
4
app/src/main/res/drawable/ic_scan_for_short_btn.xml
Normal file
4
app/src/main/res/drawable/ic_scan_for_short_btn.xml
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector>
|
||||
|
||||
</selector>
|
||||
9
app/src/main/res/drawable/ic_send_short_btn.xml
Normal file
9
app/src/main/res/drawable/ic_send_short_btn.xml
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="19dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="19">
|
||||
<path
|
||||
android:pathData="M18.7974,10.9765L14.4899,6.2623C14.2126,5.9406 13.6644,5.912 13.3428,6.192C13.0212,6.472 12.9888,7.0063 13.2869,7.3099L16.3997,10.7146L5.8077,10.7146C5.3616,10.7146 5,11.0664 5,11.5003C5,11.9342 5.3616,12.2859 5.8077,12.2859L16.3997,12.2859L13.2869,15.6906C12.9888,15.9942 13.0291,16.5275 13.3507,16.8076C13.6723,17.0876 14.2126,17.0599 14.4899,16.7382L18.7974,12.024C19.0786,11.6429 19.0562,11.3008 18.7974,10.9765L18.7974,10.9765Z"
|
||||
android:fillColor="#ffffff"/>
|
||||
</vector>
|
||||
|
|
@ -63,7 +63,6 @@
|
|||
android:id="@+id/btn_shop"
|
||||
style="@style/TapBlackButton"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginBottom="33dp"
|
||||
android:text="@string/common_no"
|
||||
|
|
@ -85,7 +84,6 @@
|
|||
android:id="@+id/btn_yes"
|
||||
style="@style/TapButtonWithIcon"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginBottom="33dp"
|
||||
|
|
|
|||
|
|
@ -104,7 +104,6 @@
|
|||
android:id="@+id/btnSend"
|
||||
style="@style/TapButtonWithIcon"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
android:fontFamily="@font/saira_semi_condensed_regular"
|
||||
android:text="@string/send_title"
|
||||
app:icon="@drawable/ic_arrow_right" />
|
||||
|
|
|
|||
31
app/src/main/res/layout/fragment_topup.xml
Normal file
31
app/src/main/res/layout/fragment_topup.xml
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:fitsSystemWindows="true"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<com.google.android.material.appbar.MaterialToolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:navigationIcon="@drawable/ic_close"
|
||||
app:title="@string/wallet_button_topup" />
|
||||
|
||||
<WebView
|
||||
android:id="@+id/web_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/toolbar" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/progress_bar"
|
||||
style="@android:style/Widget.Material.ProgressBar.Horizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:indeterminateOnly="true"
|
||||
app:layout_constraintTop_toBottomOf="@id/toolbar" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
|
@ -49,7 +49,6 @@
|
|||
android:id="@+id/iv_card"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:maxHeight="215dp"
|
||||
android:layout_gravity="center"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="8dp"
|
||||
|
|
@ -57,6 +56,7 @@
|
|||
android:layout_marginBottom="12dp"
|
||||
android:adjustViewBounds="true"
|
||||
android:elevation="3dp"
|
||||
android:maxHeight="215dp"
|
||||
android:scaleType="fitCenter"
|
||||
android:src="@drawable/card_placeholder"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
|
@ -85,47 +85,21 @@
|
|||
android:layout_height="wrap_content"
|
||||
app:layout_constraintTop_toBottomOf="@id/l_card_balance" />
|
||||
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/btn_scan"
|
||||
style="@style/TapBlackButton"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="30dp"
|
||||
android:text="@string/wallet_button_scan"
|
||||
app:icon="@drawable/ic_scan"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/guideline"
|
||||
app:layout_constraintHorizontal_bias="0.5"
|
||||
app:layout_constraintHorizontal_chainStyle="packed"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/l_address"
|
||||
app:layout_constraintVertical_bias="1" />
|
||||
|
||||
<androidx.constraintlayout.widget.Guideline
|
||||
android:id="@+id/guideline"
|
||||
android:layout_width="wrap_content"
|
||||
<include
|
||||
android:id="@+id/l_buttons_long"
|
||||
layout="@layout/layout_wallet_long_buttons"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintGuide_percent="0.37" />
|
||||
android:visibility="gone"/>
|
||||
|
||||
<include
|
||||
android:id="@+id/l_buttons_short"
|
||||
layout="@layout/layout_wallet_short_buttons"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintBottom_toBottomOf="parent"/>
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/btn_confirm"
|
||||
style="@style/TapButtonWithIcon"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginTop="30dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:text="@string/wallet_button_send"
|
||||
app:icon="@drawable/ic_send"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@+id/guideline"
|
||||
app:layout_constraintTop_toBottomOf="@id/l_address"
|
||||
app:layout_constraintVertical_bias="1" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
|
|
|
|||
|
|
@ -103,10 +103,10 @@
|
|||
app:autoSizeMinTextSize="12sp"
|
||||
app:autoSizeStepGranularity="1sp"
|
||||
app:autoSizeTextType="uniform"
|
||||
app:layout_constraintBottom_toBottomOf="@id/tv_currency"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_weight="1"
|
||||
app:layout_constraintStart_toEndOf="@id/tv_currency"
|
||||
app:layout_constraintBottom_toBottomOf="@id/tv_currency"
|
||||
tools:text="0.43 BTC" />
|
||||
|
||||
<TextView
|
||||
|
|
@ -130,22 +130,64 @@
|
|||
android:paddingTop="4dp"
|
||||
android:paddingEnd="16dp"
|
||||
android:textSize="14sp"
|
||||
android:visibility="invisible"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/tv_amount"
|
||||
tools:text="USD 3 588"
|
||||
android:visibility="invisible"/>
|
||||
tools:text="USD 3 588" />
|
||||
|
||||
|
||||
<include
|
||||
android:id="@+id/l_token"
|
||||
layout="@layout/layout_token"
|
||||
<View
|
||||
android:id="@+id/v_divider"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0.5dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="12dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:background="@color/lightGray5"
|
||||
app:layout_constraintTop_toBottomOf="@id/tv_placeholder" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_base_currency"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="35dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:textColor="@color/darkGray6"
|
||||
android:textSize="14sp"
|
||||
android:textStyle="bold"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/v_divider"
|
||||
tools:text="Ethereum" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tv_base_amount"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:ellipsize="end"
|
||||
android:gravity="end"
|
||||
android:maxLines="1"
|
||||
android:textAlignment="textEnd"
|
||||
android:textColor="@color/darkGray6"
|
||||
android:textSize="14sp"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintTop_toBottomOf="@+id/tv_currency" />
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="1"
|
||||
app:layout_constraintStart_toEndOf="@id/tv_base_currency"
|
||||
app:layout_constraintTop_toBottomOf="@id/v_divider"
|
||||
tools:text="0.00434143 ETH"
|
||||
/>
|
||||
|
||||
<androidx.constraintlayout.widget.Group
|
||||
android:id="@+id/group_base_currency"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="gone"
|
||||
app:constraint_referenced_ids="v_divider, tv_base_currency, tv_base_amount" />
|
||||
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
45
app/src/main/res/layout/layout_wallet_long_buttons.xml
Normal file
45
app/src/main/res/layout/layout_wallet_long_buttons.xml
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/btn_scan_long"
|
||||
style="@style/TapBlackButton"
|
||||
android:layout_width="0dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="30dp"
|
||||
android:text="@string/wallet_button_scan"
|
||||
app:icon="@drawable/ic_scan"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/guideline"
|
||||
app:layout_constraintHorizontal_bias="0.5"
|
||||
app:layout_constraintHorizontal_chainStyle="packed"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintVertical_bias="1" />
|
||||
|
||||
<androidx.constraintlayout.widget.Guideline
|
||||
android:id="@+id/guideline"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintGuide_percent="0.37" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/btn_confirm_long"
|
||||
style="@style/TapButtonWithIcon"
|
||||
android:layout_width="0dp"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginTop="30dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:text="@string/wallet_button_send"
|
||||
app:icon="@drawable/ic_send"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@+id/guideline"
|
||||
app:layout_constraintVertical_bias="1" />
|
||||
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
55
app/src/main/res/layout/layout_wallet_short_buttons.xml
Normal file
55
app/src/main/res/layout/layout_wallet_short_buttons.xml
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<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">
|
||||
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/btn_scan_short"
|
||||
style="@style/TapBlackButton"
|
||||
android:layout_width="0dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="30dp"
|
||||
android:drawableTop="@drawable/ic_group_1243"
|
||||
android:gravity="bottom|center_horizontal"
|
||||
android:paddingTop="7dp"
|
||||
android:text="@string/wallet_button_scan"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@id/btn_top_up"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintVertical_bias="1" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/btn_top_up"
|
||||
style="@style/TapButton"
|
||||
android:layout_width="0dp"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginTop="30dp"
|
||||
android:drawableTop="@drawable/ic_arrow_up_short_btn"
|
||||
android:gravity="bottom|center_horizontal"
|
||||
android:paddingTop="1dp"
|
||||
android:text="@string/wallet_button_topup"
|
||||
app:drawableTint="@android:color/white"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/btn_confirm_short"
|
||||
app:layout_constraintStart_toEndOf="@+id/btn_scan_short"
|
||||
app:layout_constraintVertical_bias="1" />
|
||||
|
||||
<com.google.android.material.button.MaterialButton
|
||||
android:id="@+id/btn_confirm_short"
|
||||
style="@style/TapButton"
|
||||
android:layout_width="0dp"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginTop="30dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:drawableTop="@drawable/ic_send_short_btn"
|
||||
android:gravity="bottom|center_horizontal"
|
||||
android:paddingTop="2dp"
|
||||
android:text="@string/wallet_button_send"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@+id/btn_top_up"
|
||||
app:layout_constraintVertical_bias="1" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
|
@ -93,7 +93,7 @@
|
|||
<string name="details_manage_security_access_code">Zugangscode</string>
|
||||
<string name="details_manage_security_access_code_description">Sie müssen den richtigen Zugangscode eingeben, bevor Sie die Karte scannen.</string>
|
||||
<string name="alert_old_device_this_card">Sie können NFC-Probleme mit einigen iPhone 7/7+ während der Extraktion haben</string>
|
||||
<string name="alert_card_signed_transactions">Warnung: Diese Karte wurde früher bereits aufgeladen und Transaktionen wurden damit signiert.\n Ziehen Sie eine sofortige Auszahlung aller Beträge in Betracht, wenn Sie diese Karte von einer nicht vertrauenswürdigen Quelle erhalten haben.</string>
|
||||
<string name="alert_card_signed_transactions">Warnung: Diese Karte wurde früher bereits aufgeladen und Transaktionen wurden damit signiert. Ziehen Sie eine sofortige Auszahlung aller Beträge in Betracht, wenn Sie diese Karte von einer nicht vertrauenswürdigen Quelle erhalten haben.</string>
|
||||
|
||||
<string name="alert_unsupported_card">Diese Karte ist für die Zusammenarbeit mit Tangem Tap nicht geeignet</string>
|
||||
<string name="alert_developer_card">Die von Ihnen gescannte Karte ist eine Entwicklungskarte. Akzeptieren Sie sie nicht als Zahlungsmittel</string>
|
||||
|
|
@ -162,9 +162,35 @@ RECHTLICHER HAFTUNGSAUSSCHLUSS
|
|||
<string name="disclaimer_title">Nutzungsbedingungen</string>
|
||||
|
||||
<string name="wallet_notification_no_internet">Keine Internetverbindung</string>
|
||||
<string name="initial_message_scan_header">Tippen um zu scannen</string>
|
||||
<string name="initial_message_tap_header">Tippen um zu scannen</string>
|
||||
<string name="send_error_no_target_account">Das Zielkonto ist nicht erstellt. Der abzusendende Betrag soll %1$s %2$s + Gebühr oder mehr sein</string>
|
||||
<string name="send_error_fee_request_failed">Erhalt der Gebühr fehlgeschlagen</string>
|
||||
|
||||
<string name="send_error_unknown">Unbekannter Fehler</string>
|
||||
<string name="send_error_payid_verification_failed">Verifikation der PayID ist fehlgeschlagen</string>
|
||||
<string name="send_error_payid_unsupported_by_blockchain">PayID wird von der Blockchain nicht unterstützt</string>
|
||||
<string name="send_error_payid_not_registered">PayID ist nicht registriert</string>
|
||||
<string name="send_error_payid_request_failed">PayID-Anfrage ist fehlgeschlagen</string>
|
||||
|
||||
<string name="send_error_address_same_as_wallet">Die Adresse stimmt mit der Adresse Ihrer Brieftasche überein</string>
|
||||
<string name="send_error_insufficient_balance">Nicht genug Geld</string>
|
||||
<string name="send_error_blockchain_internal">Interner Fehler der Blockchain</string>
|
||||
<string name="send_error_invalid_fee_value">Falsche Gebühr</string>
|
||||
<string name="send_error_dust_amount_format">Minimaler Betrag ist %s</string>
|
||||
<string name="send_error_dust_change">Restbestand zu klein</string>
|
||||
|
||||
<string name="wallet_notification_address_copied">Die Adresse wurde erfolgreich kopiert</string>
|
||||
|
||||
|
||||
<string name="wallet_create_payid_empty">Zuerst geben Sie die gewünschte PayID ein</string>
|
||||
|
||||
<string name="initial_message_scan_header">Legen Sie die Karte zum Scannen an</string>
|
||||
<string name="initial_message_tap_header">Legen Sie die Karte an</string>
|
||||
|
||||
<string name="details_notification_erase_wallet_not_possible">Ihr Kontostand in dieser Brieftasche ist nicht Null, oder Sie haben unbestätigte Transaktionen. Es ist unmöglich die Funktion der Brieftasche zu löschen.</string>
|
||||
<string name="details_notification_security_option_already_active">Dies ist die derzeit aktive Wahl</string>
|
||||
|
||||
<string name="xtz_withdrawal_message_warning">Damit Sie beim nächsten Aufladen Ihrer Brieftasche keine erhöhte Provision zahlen, soll der Betrag um %s XTZ reduziert werden</string>
|
||||
<string name="xtz_withdrawal_message_reduce">Um %s XTZ reduzieren</string>
|
||||
<string name="xtz_withdrawal_message_ignore">Nein, alles senden</string>
|
||||
|
||||
</resources>
|
||||
|
|
@ -160,9 +160,29 @@ Avertissement
|
|||
<string name="disclaimer_title"> Conditions d\'utilisation</string>
|
||||
|
||||
<string name="wallet_notification_no_internet">Pas de connexion internet</string>
|
||||
<string name="initial_message_scan_header">Touchez pour scanner</string>
|
||||
<string name="initial_message_tap_header">Touchez pour scanner</string>
|
||||
<string name="send_error_no_target_account">Le compte cible n\'a pas été créé. Le montant à envoyer doit être de %1$s %2$s + commissions ou plus</string>
|
||||
<string name="send_error_fee_request_failed">Échec de réception des commissions</string>
|
||||
|
||||
<string name="send_error_unknown">Erreur inconnue</string>
|
||||
<string name="send_error_payid_verification_failed">La vérification de PayID a échoué</string>
|
||||
<string name="send_error_payid_unsupported_by_blockchain">PayID non pris en charge par la blockchain</string>
|
||||
<string name="send_error_payid_not_registered">PayID non enregistré</string>
|
||||
<string name="send_error_payid_request_failed">La demande de PayID a échoué</string>
|
||||
<string name="send_error_address_same_as_wallet">L’adresse est la même que celle de votre portefeuille</string>
|
||||
<string name="send_error_insufficient_balance">Solde insuffisant</string>
|
||||
<string name="send_error_blockchain_internal">Erreur interne de la blockchain</string>
|
||||
<string name="send_error_invalid_fee_value">Commission non valide</string>
|
||||
<string name="send_error_dust_amount_format">Le montant minimal est de %ы</string>
|
||||
<string name="send_error_dust_change">Le reste est trop petit</string>
|
||||
<string name="wallet_notification_address_copied">L’adresse a été copiée avec succès</string>
|
||||
<string name="wallet_create_payid_empty">Saisissez d’abord le PayID requis</string>
|
||||
<string name="initial_message_scan_header">Posez pour scanner</string>
|
||||
<string name="initial_message_tap_header">Posez la carte</string>
|
||||
<string name="details_notification_erase_wallet_not_possible">Votre solde sur ce portefeuille n\'est pas nul, ou vous avez des transactions non confirmées. Impossible de supprimer la fonction du portefeuille</string>
|
||||
<string name="details_notification_security_option_already_active">Cette option est déjà active</string>
|
||||
|
||||
<string name="xtz_withdrawal_message_warning">Pour ne pas payer une commission élevée la prochaine fois que vous rechargez votre portefeuille, veuillez réduire le montant de %s XTZ</string>
|
||||
<string name="xtz_withdrawal_message_reduce">Réduire de% s XTZ</string>
|
||||
<string name="xtz_withdrawal_message_ignore">Non, envoyer toute la somme</string>
|
||||
|
||||
</resources>
|
||||
195
app/src/main/res/values-it/strings.xml
Normal file
195
app/src/main/res/values-it/strings.xml
Normal file
|
|
@ -0,0 +1,195 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
|
||||
<string name="common_no">No</string>
|
||||
<string name="common_save_changes">Mantieni le modifiche</string>
|
||||
<string name="common_warning">Avviso</string>
|
||||
<string name="common_retry">Riprova</string>
|
||||
<string name="common_done">Fatto</string>
|
||||
<string name="common_cancel">Annulla</string>
|
||||
<string name="common_camera_denied_alert_title">Accesso alla videocamera negato</string>
|
||||
<string name="common_camera_denied_alert_message">Non hai fornito l\'accesso alla tua videocamera, modifica le tue impostazioni sulla privacy</string>
|
||||
<string name="common_camera_alert_button_settings">Impostazioni</string>
|
||||
<string name="home_welcome">Benvenuti in Tangem. Hai una delle nostre schede?</string>>
|
||||
<string name="home_welcome_back">Benevenuti di nuovo su Tangem Tap. Scansiona la tua scheda per iniziare.</string>
|
||||
<string name="home_button_yes">Si! Scansiona scheda.</string>
|
||||
<string name="home_button_shop">Shop</string>
|
||||
<string name="home_ready_title">Preparati ad avvicinare la tua scheda sul retro del telefono.</string>
|
||||
<string name="home_button_tapin">Avvicina</string>
|
||||
<string name="home_button_scan">Scansiona scheda</string>
|
||||
<string name="wallet_button_scan">Scansiona</string>
|
||||
<string name="wallet_button_send">Invia</string>
|
||||
<string name="wallet_button_create_wallet">Crea portafoglio</string>
|
||||
<string name="wallet_title">Tangem Tap</string>
|
||||
<string name="wallet_choice_wallet_option_title">Scegli l\'opzione del portafoglio</string>
|
||||
<string name="wallet_balance_token_title">Token</string>
|
||||
<string name="wallet_balance_tokens_title">Token</string>
|
||||
<string name="wallet_balance_verified">Saldo verificato</string>
|
||||
<string name="wallet_balance_loading">Il saldo sta per essere caricato…</string>
|
||||
<string name="wallet_balance_blockchain_unreachable">Blockchain non raggiungibile</string>
|
||||
<string name="wallet_error_no_account">Conto non creato</string>
|
||||
<string name="wallet_error_no_account_subtitle_format">Carica %1$s+ %2$s per creare un conto</string>
|
||||
<string name="wallet_error_empty_card">Scheda vuota</string>
|
||||
<string name="wallet_error_empty_card_subtitle">Crea un portafoglio per iniziare ad utilizzare la tua scheda Tangem </string>
|
||||
<string name="wallet_error_unsupported_blockchain">Questa scheda non è supportata</string>
|
||||
<string name="wallet_error_unsupported_blockchain_subtitle"> La tua scheda Tangem è stata creata per funzionare con un\'altra applicazione. Leggere il nome e le istruzioni sulla scheda e installare l\'applicazione corretta</string>
|
||||
<string name="wallet_balance_tx_in_progress">Transazione in corso…</string>
|
||||
<string name="wallet_pending_tx_sending">Invia\u0020</string>
|
||||
<string name="wallet_pending_tx_sending_address_format"> su %s </string>
|
||||
<string name="wallet_pending_tx_receiving">Ricevi\u0020</string>
|
||||
<string name="wallet_pending_tx_receiving_address_format"> da %s </string>
|
||||
<string name="wallet_address_button_explore">Cerca indirizzo</string>
|
||||
<string name="wallet_address_button_create_payid">Crea PayID</string>
|
||||
<string name="wallet_qr_title_format">portafoglio $s</string>
|
||||
<string name="wallet_create_payid">Crea PayID</string>
|
||||
<string name="wallet_create_payid_card_format">Scheda: %s</string>
|
||||
<string name="wallet_create_payid_hint">Nome PayID</string>
|
||||
<string name="wallet_create_payid_domain">$payid.tangem.com</string>
|
||||
<string name="wallet_create_payid_button_title">Crea</string>
|
||||
<string name="wallet_create_payid_info">Il tuo PayID – informazioni per te uniche, come il tuo numero di telefono, indirizzo email o ABN.</string>
|
||||
<string name="wallet_create_payid_success_message">PayID creato con successo e copiato negli appunti</string>
|
||||
<string name="wallet_create_payid_error_message">Errore di risposta durante la creazione del PayID</string>
|
||||
<string name="wallet_create_payid_error_already_created">Questo PayID esiste già. Scegline un altro.</string>
|
||||
<string name="send_destination_hint">Indirizzo o PayID</string>
|
||||
<string name="send_title">Invia</string>
|
||||
<string name="send_network_fee_title">Rete libera</string>
|
||||
<string name="send_amount_label">Importo</string>
|
||||
<string name="send_fee_label">Commissione</string>
|
||||
<string name="send_total_label">Totale</string>
|
||||
<string name="send_max_amount_label">Importo totale</string>
|
||||
<string name="send_validation_invalid_address">Indirizzo non valido</string>
|
||||
<string name="send_validation_invalid_amount">Importo non valido</string>
|
||||
<string name="send_validation_invalid_total">Il totale supera il saldo</string>
|
||||
<string name="send_validation_invalid_fee">La commissione supera il saldo </string>
|
||||
<string name="send_fee_picker_low">Insufficiente</string>
|
||||
<string name="send_fee_picker_normal">Normale</string>
|
||||
<string name="send_fee_picker_priority">Prioritario</string>
|
||||
<string name="send_fee_include_description">Includi commissione</string>
|
||||
<string name="send_total_subtitle_format">Sarà inviato %1$s %2$s</string>
|
||||
<string name="send_total_subtitle_fiat_format">≈ %1$s (inc. commissione: %2$s)</string>
|
||||
<string name="send_total_subtitle_asset_format">Sarà inviato %1$s %2$s e %1$s %2$s</string>
|
||||
<string name="send_balance_subtitle_format">Saldo: %1$s %2$s</string>
|
||||
<string name="send_transaction_success">La transazione è stata firmata con successo e inviata al nodo blockchain. Il saldo del portafoglio verrà aggiornato dopo un po\' di tempo </string>
|
||||
<string name="details_title">Requisiti</string>
|
||||
<string name="details_row_title_cid">ID scheda</string>
|
||||
<string name="details_row_title_issuer">Emittente</string>
|
||||
<string name="details_row_title_signed_hashes">Firmato</string>
|
||||
<string name="details_row_subtitle_signed_hashes_format">Hash %s</string>
|
||||
<string name="details_row_title_currency">Valuta dell\'applicazione</string>
|
||||
<string name="details_section_title_settings">Impostazioni</string>
|
||||
<string name="details_section_title_card">Scheda</string>
|
||||
<string name="details_row_title_validate">Convalidare la scheda</string>
|
||||
<string name="details_row_title_manage_security">Gestione del portafoglio</string>
|
||||
<string name="details_row_title_erase_wallet">Cancella il portafoglio</string>
|
||||
<string name="details_erase_wallet_warning">Questa azione è irreversibile. Se dopo aver eliminato il portafoglio qualcuno invia dei fondi, non potrai ritirarli.</string>
|
||||
<string name="details_security_management_warning">Se dimentichi il codice, perderai la possibilità di utilizzare la scheda. Non è possibile in alcun modo ripristinare o modificare il codice se lo perdi.</string>
|
||||
<string name="details_manage_security_title">Gestione della sicurezza</string>
|
||||
<string name="details_manage_security_long_tap">Mantenimento della scheda</string>
|
||||
<string name="details_manage_security_long_tap_description">Questo meccanismo protegge dagli avvicinamenti senza contatto sulla scheda. Attiva un ritardo tra la ricezione e l\'esecuzione di un comando. Dopo la prima transazione firmata, questo telefono verrà associato alla scheda e le transazioni verranno firmate immediatamente.</string>
|
||||
<string name="details_manage_security_passcode">Password</string>
|
||||
<string name="details_manage_security_passcode_description">Dovrai inserire una password prima di eseguire qualsiasi comando che modifichi lo stato della scheda.</string>
|
||||
<string name="details_manage_security_access_code">Codice di accesso</string>
|
||||
<string name="details_manage_security_access_code_description">Prima di scansionare la scheda sarà necessario inserire il codice di accesso corretto</string>
|
||||
<string name="alert_old_device_this_card">Potresti riscontrare problemi con l\'NFC su alcuni iPhone 7/7 + durante la rimozione</string>
|
||||
<string name="alert_card_signed_transactions">Attenzione: questa scheda è già stata ricaricata e ha firmato transazioni in passato. Valuta la possibilità di prelevare immediatamente tutti i fondi se hai ricevuto questa scheda da una fonte inaffidabile.</string>
|
||||
<string name="alert_unsupported_card">Questa scheda non è progettata per funzionare con Tangem Tap</string>
|
||||
<string name="alert_developer_card">La scheda che hai scansionato è una scheda di sviluppo. Non utilizzarla come strumento di pagamento</string>
|
||||
<string name="alert_old_card">Le schede emesse prima di settembre 2019 non possono attualmente essere utilizzate con un iPhone. Stiamo lavorando a stretto contatto con Apple per renderle disponibili nelle future versioni di iOS. </string>
|
||||
<string name="initial_message_sign_header">Avvicina per firmare</string>
|
||||
<string name="initial_message_sign_body">Avvicina la scheda al telefono come mostrato sopra </string>
|
||||
<string name="initial_message_purge_wallet_body">Avvicina per cancellare il portafoglio</string>
|
||||
<string name="initial_message_create_wallet_body">Avvicina per creare il portafoglio</string>
|
||||
<string name="initial_message_change_access_code_body">Avvicina per modificare il codice di accesso</string>
|
||||
<string name="initial_message_change_passcode_body">Avvicina per modificare la password</string>
|
||||
<string name="payid_service_error_loading">PayID non valido</string>
|
||||
|
||||
<string name="disclaimer_text">
|
||||
|
||||
NOTA LEGALE\n
|
||||
\n
|
||||
App Tangem Tap (software)\n
|
||||
\n
|
||||
1. Il software può essere utilizzato solo con i portafogli hardware Tangem (schede) tramite l\'interfaccia NFC. Il software NON esegue le seguenti operazioni:\n
|
||||
\n
|
||||
a) Generazione, archiviazione, trasferimento o accesso a chiavi crittografiche private (segrete) di portafogli blockchain contenenti risorse digitali, inclusa la criptovaluta.\n
|
||||
\n
|
||||
b) Generazione, archiviazione, trasferimento o accesso a chiavi segrete, password, passphrase, frasi di ripristino che possono essere utilizzate per recuperare o copiare chiavi private (segrete) su portafogli blockchain contenenti risorse digitali, inclusa la criptovaluta.\n
|
||||
\n
|
||||
c) Fornitura di servizi di scambio, negoziazione e investimento per conto di Tandem AG.\n
|
||||
\n
|
||||
2. Rischi associati al funzionamento del Software\n
|
||||
\n
|
||||
Tandem non sarà ritenuta responsabile per eventuali perdite, danni o reclami derivanti da eventi che rientrano nelle seguenti cinque categorie:\n
|
||||
\n
|
||||
a) Errori commessi dall\'utente di qualsiasi software o servizio relativo alla criptovaluta, ad esempio password dimenticate, pagamenti inviati a indirizzi errati e cancellazione accidentale di portafogli blockchain su Schede.\n
|
||||
\n
|
||||
b) Problemi con il software e/o qualsiasi software o servizio correlato a blockchain o criptovaluta, come file danneggiati, transazioni generate in modo improprio, librerie crittografiche non sicure, malware.\n
|
||||
\n
|
||||
c) Malfunzionamenti tecnici nell\'hardware dell\'utente, incluse le Schede, qualsiasi software o servizio relativo alla criptovaluta, ad esempio, perdita di dati a causa di un dispositivo di archiviazione difettoso o danneggiato.\n
|
||||
\n
|
||||
d) Problemi di sicurezza affrontati dall\'utente di qualsiasi software o servizio relativo alla criptovaluta, ad esempio l\'accesso non autorizzato a portafogli e/o account utente.\n
|
||||
\n
|
||||
e) Azioni o inattività di terze parti e/o eventi con cui si sono scontrate terze parti, come la bancarotta di fornitori di servizi, attacchi alla sicurezza delle informazioni relative ai fornitori di servizi e frodi perpetrate da terzi.\n
|
||||
\n
|
||||
3. Rischi commerciali e di investimento\n
|
||||
\n
|
||||
Qualsiasi transazione che coinvolge lo scambio di criptovalute o altre risorse digitali comporta rischi significativi. Qualsiasi transazione che include una valuta comporta dei rischi, inclusa ma non limitata alla possibilità di cambiamenti nelle condizioni economiche che potrebbero influenzare materialmente il valore o la liquidità della valuta. L\'investimento nella speculazione sui cambi di criptovaluta può anche essere soggetto a forti alti e bassi poiché i rispettivi prezzi di mercato fluttuano. È per questo motivo che è consigliabile utilizzare solo capitale di rischio quando si fanno affari in questi mercati.\n
|
||||
\n
|
||||
4. Rischi dell\'e-commerce\n
|
||||
\n
|
||||
Prima di effettuare transazioni utilizzando un sistema elettronico, è necessario leggere attentamente le norme e i regolamenti delle borse che offrono questo sistema e/o elencano i titoli che si intende negoziare. Il trading online presenta un rischio intrinseco dovuto alla risposta del sistema e ai tempi di accesso, che possono variare a seconda delle condizioni di mercato, delle prestazioni del sistema ed altri fattori. È necessario comprendere questi e altri rischi prima di fare trading.\n
|
||||
\n
|
||||
5. Rispetto degli obblighi fiscali\n
|
||||
\n
|
||||
Gli utenti del Software sono gli unici responsabili del determinare le eventuali tasse applicate alle loro transazioni in criptovaluta. I proprietari o i contributori del Software NON sono responsabili della determinazione delle tasse che si applicano alle transazioni in criptovaluta.\n
|
||||
\n
|
||||
6. Assenza di garanzie\n
|
||||
\n
|
||||
Il Software viene fornito "così com\'è" senza garanzia di alcun tipo riguardo al Software e/o a qualsiasi contenuto, dato, materiale e/o servizio fornito con il Software.\n
|
||||
\n
|
||||
7. Limitazione di responsabilità\n
|
||||
\n
|
||||
Salvo quanto diversamente previsto dalla legge, i proprietari o i contributori del Software non saranno in nessun caso responsabili per eventuali danni di qualsiasi tipo, inclusi, ma non limitati a, perdita di utilizzo, perdita di profitti o perdita di dati derivanti o in qualsiasi modo correlati all\'uso del Software. In nessun modo i proprietari o i contributori del Software sono responsabili delle azioni, decisioni o altri comportamenti presi o non presi da voi in relazione al Software.\n
|
||||
\n
|
||||
8. Ultima modifica\n
|
||||
\n
|
||||
Questa nota legale è stata modificata l\'ultima volta 01.10.2020.
|
||||
|
||||
</string>
|
||||
|
||||
<string name="send_error_no_target_account">Per creare un account, invia %1$s %2$s a questo indirizzo</string>
|
||||
<string name="send_error_fee_request_failed">Impossibile ottenere la commissione</string>
|
||||
<string name="common_accept">Accetta</string>
|
||||
<string name="send_validation_amount_exceeds_balance">Amount Exceeds Balance</string>
|
||||
<string name="disclaimer_title">Termini del servizio</string>
|
||||
<string name="wallet_notification_no_internet">Nessuna connessione a Internet</string>
|
||||
|
||||
<string name="send_error_unknown">Errore sconosciuto</string>
|
||||
<string name="send_error_payid_verification_failed">Verifica del PayID fallita</string>
|
||||
<string name="send_error_payid_unsupported_by_blockchain">PayID non supportato dalla blockchain</string>
|
||||
<string name="send_error_payid_not_registered">PayID non registrato</string>
|
||||
<string name="send_error_payid_request_failed">Richiesta PayID fallita</string>
|
||||
|
||||
<string name="send_error_address_same_as_wallet">L\'indirizzo corrisponde all\'indirizzo del tuo portafoglio</string>
|
||||
<string name="send_error_insufficient_balance">Saldo insufficiente</string>
|
||||
<string name="send_error_blockchain_internal">Errore interno della blockchain</string>
|
||||
<string name="send_error_invalid_fee_value">Commissione non valida</string>
|
||||
<string name="send_error_dust_amount_format">L\'importo minimo è di %s</string>
|
||||
<string name="send_error_dust_change">L\'importo residuo è molto basso</string>
|
||||
|
||||
<string name="wallet_notification_address_copied">L\'indirizzo è stato copiato con successo</string>
|
||||
|
||||
|
||||
<string name="wallet_create_payid_empty">Inserire prima il PayID desiderato</string>
|
||||
|
||||
<string name="initial_message_scan_header">Avvicina per scansionare</string>
|
||||
<string name="initial_message_tap_header">Avvicina la scheda</string>
|
||||
|
||||
<string name="details_notification_erase_wallet_not_possible">Il tuo saldo su questo portafoglio non è pari a zero o hai transazioni non confermate. Non è possibile eliminare la funzione portafoglio.</string>
|
||||
<string name="details_notification_security_option_already_active">E\' l\'opzione attualmente attiva</string>
|
||||
|
||||
<string name="xtz_withdrawal_message_warning">Per evitare di pagare una commissione maggiore la prossima volta che ricarichi il tuo portafoglio, riduci l\'importo di %s XTZ</string>
|
||||
<string name="xtz_withdrawal_message_reduce">Riduci di %s XTZ</string>
|
||||
<string name="xtz_withdrawal_message_ignore">No, invia l\'intero importo</string>
|
||||
|
||||
</resources>
|
||||
6
app/src/main/res/values-v29/styles.xml
Normal file
6
app/src/main/res/values-v29/styles.xml
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<style name="AppTheme" parent="BaseAppTheme">
|
||||
<item name="android:forceDarkAllowed">false</item>
|
||||
</style>
|
||||
</resources>
|
||||
|
|
@ -50,7 +50,7 @@
|
|||
|
||||
<string name="wallet_address_button_explore">Explore address</string>
|
||||
<string name="wallet_address_button_create_payid">Create PayID</string>
|
||||
<string name="wallet_qr_title_format">$s wallet</string>
|
||||
<string name="wallet_qr_title_format">%s wallet</string>
|
||||
|
||||
<string name="wallet_create_payid">Create PayID</string>
|
||||
<string name="wallet_create_payid_card_format">Card: %s</string>
|
||||
|
|
@ -106,7 +106,7 @@
|
|||
<string name="details_manage_security_access_code_description">You will have to submit the correct access code before scanning the card</string>
|
||||
|
||||
<string name="alert_old_device_this_card">You may experience NFC problems with some iPhone 7/7+ during the extraction</string>
|
||||
<string name="alert_card_signed_transactions">Warning: This card has been already topped up and signed transactions in the past.\n\u0020\u0020\u0020\u0020\u0020\u0020\u0020\u0020Consider immediate withdrawal of all funds if you have received this card from an untrusted source.</string>
|
||||
<string name="alert_card_signed_transactions">Warning: This card has been already topped up and signed transactions in the past. Consider immediate withdrawal of all funds if you have received this card from an untrusted source.</string>
|
||||
<string name="alert_unsupported_card">This card it is not designed to work with Tangem Tap</string>
|
||||
<string name="alert_developer_card">The card you scanned is a development card. Don’t accept it as a payment</string>
|
||||
<string name="alert_old_card">Tangem cards manufactured before September 2019 cannot currently be extracted with an iPhone. We’re working hard with Apple to make it possible in future versions of iOS.</string>
|
||||
|
|
@ -200,4 +200,11 @@
|
|||
<string name="details_notification_security_option_already_active">This is the currently active option</string>
|
||||
|
||||
|
||||
<string name="xtz_withdrawal_message_warning">To avoid paying an increased commission the next time you top up your wallet, reduce the amount by %s XTZ</string>
|
||||
<string name="xtz_withdrawal_message_reduce">Reduce by %s XTZ</string>
|
||||
<string name="xtz_withdrawal_message_ignore">No, send all</string>
|
||||
|
||||
|
||||
|
||||
|
||||
</resources>
|
||||
|
|
@ -1,7 +1,3 @@
|
|||
<resources>
|
||||
|
||||
<string name="xtz_withdrawal_message_warning" translatable="false">To avoid paying an increased commission the next time you top up your wallet, reduce the amount by %s XTZ</string>
|
||||
<string name="xtz_withdrawal_message_reduce" translatable="false">Reduce by %s XTZ</string>
|
||||
<string name="xtz_withdrawal_message_ignore" translatable="false">No, send all</string>
|
||||
|
||||
<string name="wallet_button_topup" translatable="false">Top Up</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<resources>
|
||||
<!-- Base application theme. -->
|
||||
<style name="AppTheme" parent="Theme.MaterialComponents.Light.NoActionBar">
|
||||
<style name="BaseAppTheme" parent="Theme.MaterialComponents.Light.NoActionBar">
|
||||
<!-- Customize your theme here. -->
|
||||
<item name="colorPrimary">@color/colorPrimary</item>
|
||||
<item name="colorSecondary">@color/colorSecondary</item>
|
||||
|
|
@ -10,6 +10,8 @@
|
|||
<item name="android:windowDrawsSystemBarBackgrounds">false</item>
|
||||
</style>
|
||||
|
||||
<style name="AppTheme" parent="BaseAppTheme" />
|
||||
|
||||
<!-- Toolbar -->
|
||||
<style name="DarkToolbarStyle" parent="Theme.AppCompat">
|
||||
<item name="android:textColorPrimary">@android:color/white</item>
|
||||
|
|
@ -34,7 +36,7 @@
|
|||
<item name="cornerRadius">@dimen/btn_corner_radius</item>
|
||||
<item name="android:fontFamily">@font/saira_semi_condensed_regular</item>
|
||||
<item name="android:layout_width">93dp</item>
|
||||
<item name="android:layout_height">48dp</item>
|
||||
<item name="android:layout_height">52dp</item>
|
||||
<item name="elevation">3dp</item>
|
||||
</style>
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue