Updated on 2026-08-14

This commit is contained in:
Tangem 2025-02-04 19:05:59 +03:00
commit fe96e930a2
9 changed files with 104 additions and 52 deletions

View file

@ -358,7 +358,9 @@ private fun handle(action: Action, dispatch: DispatchFunction) {
private fun showCardVerificationFailedDialog(error: TangemError) {
if (error is TangemSdkError.CardVerificationFailed) {
Analytics.send(
event = OnboardingAnalyticsEvent.Onboarding.OfflineAttestationFailed(AnalyticsParam.ScreensSources.Backup),
event = OnboardingAnalyticsEvent.Onboarding.OfflineAttestationFailed(
AnalyticsParam.ScreensSources.Onboarding,
),
)
val resource = error.localizedDescriptionRes()

View file

@ -39,7 +39,7 @@ RUN wget https://github.com/lzhiyong/android-sdk-tools/releases/download/34.0.3/
rm -rf /tmp/android-sdk-tools-static-arm /tmp/android-sdk-tools-static-aarch64.zip
RUN gem install bundler:2.5.23
RUN gem install fastlane -v 2.211.0 -N -V
RUN gem install fastlane -v 2.225.0 -N -V
RUN gem install fastlane-plugin-firebase_app_distribution -v 0.9.1 -N -V
COPY ../Gemfile Gemfile.lock ./

View file

@ -16,16 +16,17 @@ latest_merge_base=""
# Source refs to find branches from
local_refs="refs/heads/releases/*" # For debug and development
remote_refs=$(git for-each-ref --format="%(refname:short)" refs/remotes/origin/ | grep -E "origin/[a-zA-Z0-9._-]+_pre_release$")
remote_refs=$(git for-each-ref --sort=-committerdate --format="%(refname:short)" refs/remotes/origin/ | grep -E "origin/[a-zA-Z0-9._-]+_pre_release$")
# Iterate over all remote release branches sorted by commit date (most recent first)
for branch in $remote_refs; do
# Find the common ancestor (merge base) between the base branch and the current branch
merge_base=$(git merge-base "$base_branch" "$branch")
echo "Merge base for branches '$branch' and '$base_branch' is '$merge_base'"
if [ -z "$latest_merge_base" ] || git rev-list "$merge_base..$base_branch" | grep -q .; then
echo "Update"
# Update the latest branch and merge base if the current merge base is a descendant of the latest merge base
if [ -z "$latest_merge_base" ] || git merge-base --is-ancestor "$latest_merge_base" "$merge_base"; then
latest_branch="$branch"
latest_merge_base="$merge_base"
fi
@ -45,4 +46,4 @@ fi
latest_branch="${latest_branch#origin/}"
echo "$latest_branch" > "find-latest-pre-release-branch.output"
echo "Latest release branch created directly from '$base_branch' or its ancestor: '$latest_branch'"
echo "Latest 'pre_release' branch created from '$base_branch' or its ancestor: '$latest_branch'"

View file

@ -23,7 +23,7 @@ internal class ScanCardToUnlockWalletClickHandler @Inject constructor(
suspend operator fun invoke(walletId: UserWalletId): Either<ScanCardToUnlockWalletError, Unit> {
return either {
when (val result = scanCardProcessor.scan(analyticsSource = AnalyticsParam.ScreensSources.Main)) {
when (val result = scanCardProcessor.scan(analyticsSource = AnalyticsParam.ScreensSources.SignIn)) {
is CompletionResult.Failure -> {
if (result.error is TangemSdkError.UserCancelled) {
scanFailsCounter++

View file

@ -1,32 +0,0 @@
package com.tangem.feature.wallet.presentation.wallet.state.transformers
import com.tangem.domain.wallets.models.UserWalletId
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletState
import timber.log.Timber
internal class RenameWalletTransformer(
userWalletId: UserWalletId,
private val newName: String,
) : WalletStateTransformer(userWalletId) {
override fun transform(prevState: WalletState): WalletState {
return when (prevState) {
is WalletState.MultiCurrency.Content -> {
prevState.copy(walletCardState = prevState.walletCardState.copySealed(title = newName))
}
is WalletState.SingleCurrency.Content -> {
prevState.copy(walletCardState = prevState.walletCardState.copySealed(title = newName))
}
is WalletState.Visa.Content -> {
prevState.copy(walletCardState = prevState.walletCardState.copySealed(title = newName))
}
is WalletState.MultiCurrency.Locked,
is WalletState.SingleCurrency.Locked,
is WalletState.Visa.Locked,
-> {
Timber.e("Impossible to rename wallet in locked state")
prevState
}
}
}
}

View file

@ -0,0 +1,53 @@
package com.tangem.feature.wallet.presentation.wallet.state.transformers
import com.tangem.domain.wallets.models.UserWallet
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletScreenState
import com.tangem.feature.wallet.presentation.wallet.state.model.WalletState
import kotlinx.collections.immutable.toImmutableList
import timber.log.Timber
/**
* Transformer that renames wallets
*
* @property renamedWallets renamed wallets
*/
internal class RenameWalletsTransformer(
private val renamedWallets: List<UserWallet>,
) : WalletScreenStateTransformer {
override fun transform(prevState: WalletScreenState): WalletScreenState {
return prevState.copy(
wallets = prevState.wallets.map { walletState ->
val renamedWallet = renamedWallets.firstOrNull { it.walletId == walletState.walletCardState.id }
if (renamedWallet != null) {
transform(prevState = walletState, newName = renamedWallet.name)
} else {
walletState
}
}
.toImmutableList(),
)
}
private fun transform(prevState: WalletState, newName: String): WalletState {
return when (prevState) {
is WalletState.MultiCurrency.Content -> {
prevState.copy(walletCardState = prevState.walletCardState.copySealed(title = newName))
}
is WalletState.SingleCurrency.Content -> {
prevState.copy(walletCardState = prevState.walletCardState.copySealed(title = newName))
}
is WalletState.Visa.Content -> {
prevState.copy(walletCardState = prevState.walletCardState.copySealed(title = newName))
}
is WalletState.MultiCurrency.Locked,
is WalletState.SingleCurrency.Locked,
is WalletState.Visa.Locked,
-> {
Timber.e("Impossible to rename wallet in locked state")
prevState
}
}
}
}

View file

@ -308,8 +308,8 @@ internal class WalletViewModel @Inject constructor(
),
)
}
is WalletsUpdateActionResolver.Action.UpdateWalletName -> {
stateHolder.update(transformer = RenameWalletTransformer(action.selectedWalletId, action.name))
is WalletsUpdateActionResolver.Action.RenameWallets -> {
stateHolder.update(transformer = RenameWalletsTransformer(renamedWallets = action.renamedWallets))
}
is WalletsUpdateActionResolver.Action.Unknown -> {
Timber.w("Unable to perform action: $action")

View file

@ -67,6 +67,9 @@ internal class WalletsUpdateActionResolver @Inject constructor(
selectedWallet = selectedWallet,
)
}
isAnyWalletNameChanged(state, wallets) -> {
getRenameWalletsAction(state, wallets)
}
else -> getUpdateSelectedWalletAction(state, wallets, selectedWallet)
}
}
@ -121,15 +124,35 @@ internal class WalletsUpdateActionResolver @Inject constructor(
return state.getPrevSelectedWallet().id != selectedWallet.walletId
}
private fun isAnyWalletNameChanged(state: WalletScreenState, wallets: List<UserWallet>): Boolean {
val prevWallets = state.wallets.map { it.walletCardState.id to it.walletCardState.title }
val newWallets = wallets.map { it.walletId to it.name }
val prevWalletsIds = prevWallets.map { it.first }
val newWalletsIds = newWallets.map { it.first }
val isAnyNameChanged = (newWallets - prevWallets.toSet()).isNotEmpty()
return prevWalletsIds == newWalletsIds && isAnyNameChanged
}
private fun getRenameWalletsAction(state: WalletScreenState, wallets: List<UserWallet>): Action.RenameWallets {
val prevWallets = state.wallets.map { it.walletCardState.id to it.walletCardState.title }
val newWallets = wallets.map { it.walletId to it.name }
val renamedWallets = newWallets - prevWallets.toSet()
return Action.RenameWallets(
renamedWallets = wallets.filter { wallet -> renamedWallets.any { it.first == wallet.walletId } },
)
}
private fun getUpdateSelectedWalletAction(
state: WalletScreenState,
wallets: List<UserWallet>,
selectedWallet: UserWallet,
): Action {
return when {
isSelectedWalletNameChanged(state, selectedWallet) -> {
Action.UpdateWalletName(selectedWalletId = selectedWallet.walletId, name = selectedWallet.name)
}
isSelectedWalletUnlocked(state, selectedWallet) -> {
Action.UnlockWallet(
selectedWallet = selectedWallet,
@ -143,10 +166,6 @@ internal class WalletsUpdateActionResolver @Inject constructor(
}
}
private fun isSelectedWalletNameChanged(state: WalletScreenState, selectedWallet: UserWallet): Boolean {
return state.getPrevSelectedWallet().title != selectedWallet.name
}
private fun isSelectedWalletUnlocked(state: WalletScreenState, selectedWallet: UserWallet): Boolean {
return state.isSelectedWalletLocked() && !selectedWallet.isLocked
}
@ -215,10 +234,19 @@ internal class WalletsUpdateActionResolver @Inject constructor(
}
}
data class UpdateWalletName(val selectedWalletId: UserWalletId, val name: String) : Action() {
/**
* Rename wallets
*
* @property renamedWallets renamed wallets
*/
data class RenameWallets(val renamedWallets: List<UserWallet>) : Action() {
override fun toString(): String {
return "UpdateWalletName(selectedWalletId = $selectedWalletId, name = $name)"
return """
RenameWallets(
renamedWallets = ${renamedWallets.joinToString { it.walletId.toString() }}
)
""".trimIndent()
}
}

View file

@ -89,9 +89,9 @@ markdownComposeView = "0.5.4"
# endregion Other libraries
# region Tangem
tangemBlockchainSdk = "develop-936"
tangemBlockchainSdk = "develop-940"
#tangemBlockchainSdk = "0.0.1" # Keep it! - used for local builds
tangemCardSdk = "develop-429"
tangemCardSdk = "develop-432"
#tangemCardSdk = "0.0.1" # Keep it! - used for local builds ^
tangemVico = "2.0.0-alpha.25-tangem-developments8"
#tangemVico = "0.0.1" # Keep it! - used for local builds ^