Updated on 2026-08-14
This commit is contained in:
commit
8cc67d6858
17 changed files with 104 additions and 52 deletions
|
|
@ -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'
|
||||
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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 -> {
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
)
|
||||
}
|
||||
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
9
app/src/main/res/drawable/ic_arrow_left.xml
Normal file
9
app/src/main/res/drawable/ic_arrow_left.xml
Normal 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>
|
||||
9
app/src/main/res/drawable/ic_arrow_right_20.xml
Normal file
9
app/src/main/res/drawable/ic_arrow_right_20.xml
Normal 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>
|
||||
10
app/src/main/res/drawable/ic_settings.xml
Normal file
10
app/src/main/res/drawable/ic_settings.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.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>
|
||||
|
|
@ -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" />
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
||||
|
|
|
|||
|
|
@ -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" />
|
||||
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
@ -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>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue