Updated on 2026-08-14

This commit is contained in:
Tangem 2020-09-30 13:39:07 +00:00
commit 8cc67d6858
17 changed files with 104 additions and 52 deletions

View file

@ -64,7 +64,7 @@ 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.67.0'
implementation 'com.tangem:blockchain:1.68.0'
implementation 'com.tangem:core:1.63.0'
implementation 'com.tangem:sdk:1.63.0'

View file

@ -81,6 +81,12 @@ class TapWalletManager {
withContext(Dispatchers.Main) {
store.dispatch(WalletAction.ResetState)
store.dispatch(GlobalAction.SaveScanNoteResponse(data))
loadData(data)
}
}
suspend fun loadData(data: ScanNoteResponse) {
withContext(Dispatchers.Main) {
store.dispatch(WalletAction.CheckIfWarningNeeded)
val artworkId = data.verifyResponse?.artworkInfo?.id
if (data.walletManager != null) {

View file

@ -31,7 +31,10 @@ class ScanNoteTask(val card: Card? = null) : CardSessionRunnable<ScanNoteRespons
is CompletionResult.Failure -> callback(CompletionResult.Failure(result.error))
is CompletionResult.Success -> {
val card = this.card ?: result.data
val card = this.card?.copy(
isPin1Default = result.data.isPin1Default,
isPin2Default = result.data.isPin2Default
) ?: result.data
val error = getErrorIfExcludedCard(card)
if (error != null) {

View file

@ -134,7 +134,8 @@ private fun handleSecurityAction(
}
state.copy(securityScreenState = state.securityScreenState?.copy(
allowedOptions = allowedSecurityOptions
allowedOptions = allowedSecurityOptions,
selectedOption = state.securityScreenState.currentOption
))
}
is DetailsAction.ManageSecurity.SelectOption -> {

View file

@ -47,7 +47,6 @@ class DetailsSecurityFragment : Fragment(R.layout.fragment_details_security),
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
toolbar.setNavigationOnClickListener {
store.dispatch(NavigationAction.PopBackTo())
}
@ -55,15 +54,6 @@ class DetailsSecurityFragment : Fragment(R.layout.fragment_details_security),
}
private fun setOnClickListeners() {
v_long_tap.setOnClickListener {
store.dispatch(DetailsAction.ManageSecurity.SelectOption(SecurityOption.LongTap))
}
v_passcode.setOnClickListener {
store.dispatch(DetailsAction.ManageSecurity.SelectOption(SecurityOption.PassCode))
}
v_access_code.setOnClickListener {
store.dispatch(DetailsAction.ManageSecurity.SelectOption(SecurityOption.AccessCode))
}
btn_save_changes.setOnClickListener {
store.state.detailsState.securityScreenState?.selectedOption?.let {
store.dispatch(DetailsAction.ManageSecurity.ConfirmSelection(it))
@ -75,7 +65,7 @@ class DetailsSecurityFragment : Fragment(R.layout.fragment_details_security),
if (activity == null) return
selectSecurityOption(state.securityScreenState?.selectedOption)
for (option in SecurityOption.values()) {
enableOptions(
setupOption(
option,
state.securityScreenState?.allowedOptions
?: EnumSet.noneOf(SecurityOption::class.java)
@ -92,11 +82,11 @@ class DetailsSecurityFragment : Fragment(R.layout.fragment_details_security),
securityOption == SecurityOption.AccessCode && radiobutton_access_code.isEnabled
}
private fun enableOptions(option: SecurityOption, allowedOptions: EnumSet<SecurityOption>) {
private fun setupOption(option: SecurityOption, allowedOptions: EnumSet<SecurityOption>) {
when (option) {
SecurityOption.LongTap -> enableLongTap(allowedOptions.contains(option))
SecurityOption.PassCode -> enablePasscode(allowedOptions.contains(option))
SecurityOption.AccessCode -> enableAccessCode(allowedOptions.contains(option))
SecurityOption.LongTap -> { enableLongTap(allowedOptions.contains(option)) }
SecurityOption.PassCode -> { enablePasscode(allowedOptions.contains(option)) }
SecurityOption.AccessCode -> { enableAccessCode(allowedOptions.contains(option)) }
}
}
@ -106,6 +96,12 @@ class DetailsSecurityFragment : Fragment(R.layout.fragment_details_security),
tv_long_tap_title.alpha = alpha
radiobutton_long_tap.alpha = alpha
radiobutton_long_tap.isEnabled = enable
v_long_tap.isClickable = enable
if (enable) {
v_long_tap.setOnClickListener {
store.dispatch(DetailsAction.ManageSecurity.SelectOption(SecurityOption.LongTap))
}
}
}
private fun enablePasscode(enable: Boolean) {
@ -114,6 +110,12 @@ class DetailsSecurityFragment : Fragment(R.layout.fragment_details_security),
tv_passcode_title.alpha = alpha
radiobutton_passcode.alpha = alpha
radiobutton_passcode.isEnabled = enable
v_passcode.isClickable = enable
if (enable) {
v_passcode.setOnClickListener {
store.dispatch(DetailsAction.ManageSecurity.SelectOption(SecurityOption.PassCode))
}
}
}
private fun enableAccessCode(enable: Boolean) {
@ -122,5 +124,11 @@ class DetailsSecurityFragment : Fragment(R.layout.fragment_details_security),
tv_access_code_title.alpha = alpha
radiobutton_access_code.alpha = alpha
radiobutton_access_code.isEnabled = enable
v_access_code.isClickable = enable
if (enable) {
v_access_code.setOnClickListener {
store.dispatch(DetailsAction.ManageSecurity.SelectOption(SecurityOption.AccessCode))
}
}
}
}

View file

@ -34,6 +34,7 @@ sealed class WalletAction : Action {
object SaveCardId : WalletAction()
object UpdateWallet : WalletAction() {
object ScheduleUpdatingWallet : WalletAction()
data class Success(val wallet: Wallet) : WalletAction()
data class Failure(val errorMessage: String? = null) : WalletAction()
}

View file

@ -22,6 +22,7 @@ import com.tangem.tap.domain.PayIdManager
import com.tangem.tap.domain.TapError
import com.tangem.tap.domain.extensions.toSendableAmounts
import com.tangem.tap.features.send.redux.PrepareSendScreen
import com.tangem.tap.features.wallet.models.toPendingTransactions
import com.tangem.tap.network.NetworkConnectivity
import com.tangem.tap.network.NetworkStateChanged
import com.tangem.tap.preferencesStorage
@ -74,7 +75,7 @@ val walletMiddleware: Middleware<AppState> = { dispatch, state ->
is WalletAction.UpdateWallet.Success -> setupWalletUpdate(action.wallet)
is WalletAction.LoadWallet.Success -> {
store.dispatch(WalletAction.CheckHashesCountOnline)
setupWalletUpdate(action.wallet)
if (!store.state.walletState.updatingWallet) setupWalletUpdate(action.wallet)
}
is WalletAction.CreatePayId.CompleteCreatingPayId -> {
scope.launch {
@ -113,7 +114,7 @@ val walletMiddleware: Middleware<AppState> = { dispatch, state ->
is WalletAction.LoadData -> {
scope.launch {
store.state.globalState.scanNoteResponse?.let {
store.state.globalState.tapWalletManager.onCardScanned(it)
store.state.globalState.tapWalletManager.loadData(it)
}
}
}
@ -164,7 +165,8 @@ val walletMiddleware: Middleware<AppState> = { dispatch, state ->
}
private fun setupWalletUpdate(wallet: Wallet) {
if (!wallet.recentTransactions.isNullOrEmpty() && !store.state.walletState.updatingWallet) {
if (!wallet.recentTransactions.toPendingTransactions(wallet.address).isNullOrEmpty()) {
store.dispatch(WalletAction.UpdateWallet.ScheduleUpdatingWallet)
scope.launch(Dispatchers.IO) {
delay(10000)
withContext(Dispatchers.Main) {

View file

@ -111,7 +111,12 @@ private fun internalReduce(action: Action, state: AppState): WalletState {
)
)
is WalletAction.UpdateWallet -> newState = newState.copy(updatingWallet = true)
is WalletAction.UpdateWallet.Success -> newState = onWalletLoaded(action.wallet, newState)
is WalletAction.UpdateWallet.ScheduleUpdatingWallet ->
newState = newState.copy(updatingWallet = true)
is WalletAction.UpdateWallet.Success -> {
newState = onWalletLoaded(action.wallet, newState)
newState = newState.copy(updatingWallet = newState.pendingTransactions.isNotEmpty())
}
is WalletAction.UpdateWallet.Failure -> newState = newState.copy(updatingWallet = false)
is WalletAction.LoadFiatRate -> {
newState.copy(currencyData = newState.currencyData.copy(
@ -237,7 +242,6 @@ private fun onWalletLoaded(wallet: Wallet, walletState: WalletState): WalletStat
fiatAmount = fiatAmount
),
pendingTransactions = pendingTransactions,
updatingWallet = false,
mainButton = WalletMainButton.SendButton(sendButtonEnabled)
)
}

View file

@ -49,8 +49,8 @@ class PendingTransactionsAdapter
PendingTransactionType.Outcoming -> R.string.wallet_pending_transaction_outcoming_address
}
val image = when (transaction.type) {
PendingTransactionType.Incoming -> R.drawable.ic_arrow_down
PendingTransactionType.Outcoming -> R.drawable.ic_arrow_right
PendingTransactionType.Incoming -> R.drawable.ic_arrow_left
PendingTransactionType.Outcoming -> R.drawable.ic_arrow_right_20
}
view.tv_pending_transaction.text = view.context.getString(transactionDescriptionRes)

View file

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="20dp"
android:height="20dp"
android:viewportWidth="20"
android:viewportHeight="20">
<path
android:pathData="M4.3355,10.853L7.925,14.7814C8.1561,15.0495 8.6129,15.0734 8.8809,14.84C9.1489,14.6067 9.176,14.1615 8.9276,13.9084L6.3335,11.0712L15.1602,11.0712C15.532,11.0712 15.8333,10.7781 15.8333,10.4165C15.8333,10.0549 15.532,9.7618 15.1602,9.7618L6.3335,9.7618L8.9276,6.9246C9.176,6.6715 9.1424,6.2271 8.8744,5.9937C8.6064,5.7604 8.1561,5.7835 7.925,6.0515L4.3355,9.98C4.1011,10.2976 4.1198,10.5827 4.3355,10.853L4.3355,10.853Z"
android:fillColor="#1C1C1E"/>
</vector>

View file

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="20dp"
android:height="20dp"
android:viewportWidth="20"
android:viewportHeight="20">
<path
android:pathData="M15.6645,9.147L12.075,5.2186C11.8439,4.9505 11.3871,4.9266 11.1191,5.16C10.8511,5.3933 10.824,5.8385 11.0724,6.0916L13.6665,8.9288L4.8398,8.9288C4.4681,8.9288 4.1667,9.2219 4.1667,9.5835C4.1667,9.9451 4.4681,10.2382 4.8398,10.2382L13.6665,10.2382L11.0724,13.0754C10.824,13.3285 10.8576,13.7729 11.1256,14.0063C11.3936,14.2396 11.8439,14.2165 12.075,13.9484L15.6645,10.02C15.8989,9.7024 15.8802,9.4172 15.6645,9.147L15.6645,9.147Z"
android:fillColor="#1C1C1E"/>
</vector>

View 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.14,12.94c0.04,-0.3 0.06,-0.61 0.06,-0.94c0,-0.32 -0.02,-0.64 -0.07,-0.94l2.03,-1.58c0.18,-0.14 0.23,-0.41 0.12,-0.61l-1.92,-3.32c-0.12,-0.22 -0.37,-0.29 -0.59,-0.22l-2.39,0.96c-0.5,-0.38 -1.03,-0.7 -1.62,-0.94L14.4,2.81c-0.04,-0.24 -0.24,-0.41 -0.48,-0.41h-3.84c-0.24,0 -0.43,0.17 -0.47,0.41L9.25,5.35C8.66,5.59 8.12,5.92 7.63,6.29L5.24,5.33c-0.22,-0.08 -0.47,0 -0.59,0.22L2.74,8.87C2.62,9.08 2.66,9.34 2.86,9.48l2.03,1.58C4.84,11.36 4.8,11.69 4.8,12s0.02,0.64 0.07,0.94l-2.03,1.58c-0.18,0.14 -0.23,0.41 -0.12,0.61l1.92,3.32c0.12,0.22 0.37,0.29 0.59,0.22l2.39,-0.96c0.5,0.38 1.03,0.7 1.62,0.94l0.36,2.54c0.05,0.24 0.24,0.41 0.48,0.41h3.84c0.24,0 0.44,-0.17 0.47,-0.41l0.36,-2.54c0.59,-0.24 1.13,-0.56 1.62,-0.94l2.39,0.96c0.22,0.08 0.47,0 0.59,-0.22l1.92,-3.32c0.12,-0.22 0.07,-0.47 -0.12,-0.61L19.14,12.94zM12,15.6c-1.98,0 -3.6,-1.62 -3.6,-3.6s1.62,-3.6 3.6,-3.6s3.6,1.62 3.6,3.6S13.98,15.6 12,15.6z"/>
</vector>

View file

@ -56,7 +56,7 @@
android:layout_marginEnd="16dp"
android:layout_marginBottom="12dp"
android:adjustViewBounds="true"
android:elevation="4dp"
android:elevation="3dp"
android:scaleType="fitCenter"
android:src="@drawable/card_placeholder"
app:layout_constraintTop_toTopOf="parent" />

View file

@ -9,49 +9,49 @@
android:id="@+id/card_pending_transaction"
android:layout_width="match_parent"
android:layout_height="36dp"
android:background="@android:color/white"
android:layout_marginStart="16dp"
android:layout_marginEnd="16dp"
android:layout_marginTop="2dp"
android:layout_marginEnd="16dp"
android:layout_marginBottom="2dp"
android:background="@android:color/white"
android:elevation="3dp">
<LinearLayout
android:gravity="center_vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical"
android:paddingStart="16dp"
android:paddingEnd="16dp"
>
android:paddingEnd="16dp">
<ImageView
android:id="@+id/iv_pending_transaction"
android:layout_marginEnd="12dp"
android:layout_width="11dp"
android:layout_height="11dp"
android:src="@drawable/ic_arrow_right"
/>
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:src="@drawable/ic_arrow_left" />
<TextView
android:id="@+id/tv_pending_transaction"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="Receiving "
android:textSize="12sp"/>
android:textSize="13sp"
tools:text="Receiving " />
<TextView
android:id="@+id/tv_pending_transaction_amount"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="0.001 "
android:textSize="12sp"/>
android:textSize="13sp"
android:textStyle="bold"
tools:text="0.001 " />
<TextView
android:id="@+id/tv_pending_transaction_currency"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="BTS"
android:textSize="12sp"/>
android:textSize="13sp"
android:textStyle="bold"
tools:text="BTS" />
<TextView
@ -59,10 +59,10 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="middle"
android:singleLine="true"
android:textSize="12sp"
android:paddingStart="2dp"
tools:text=" from 0x4313bcd3425235bda1232141"/>
android:singleLine="true"
android:textSize="13sp"
tools:text=" from 0x4313bcd3425235bda1232141" />
</LinearLayout>

View file

@ -91,12 +91,11 @@
<TextView
android:id="@+id/tv_amount"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="16dp"
android:ellipsize="end"
android:gravity="end|bottom"
android:gravity="end"
android:maxLines="1"
android:paddingTop="16dp"
android:textColor="@color/darkGray6"
android:textSize="20sp"
android:textStyle="bold"
@ -107,7 +106,6 @@
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_weight="1"
app:layout_constraintStart_toEndOf="@id/tv_currency"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="@id/tv_currency"
tools:text="0.43 BTC" />

View file

@ -4,5 +4,6 @@
<item
android:id="@+id/details_menu"
android:title="@string/details_toolbar_title"
app:showAsAction="never" />
android:icon="@drawable/ic_settings"
app:showAsAction="ifRoom" />
</menu>

View file

@ -35,7 +35,7 @@
<string name="wallet_create_payid">Create PayID</string>
<string name="wallet_verified_balance">Verified Balance</string>
<string name="wallet_blockchain_is_unreachable">Blockchain is unreachable</string>
<string name="wallet_transaction_in_progress">Transaction in progress</string>
<string name="wallet_transaction_in_progress">Transaction is in progress</string>
<string name="wallet_unknown_blockchain">Your Tangem card was made to work with a different application. Please see the name and instructions on your card, and install the correct app.</string>
<string name="wallet_unknown_blockchain_title">Uh oh!</string>
<string name="wallet_balance_is_loading">Balance is loading…</string>