diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/redux/TwinCardsMiddleware.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/redux/TwinCardsMiddleware.kt index 4b8ab7545a..9b0daea01d 100644 --- a/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/redux/TwinCardsMiddleware.kt +++ b/app/src/main/java/com/tangem/tap/features/onboarding/products/twins/redux/TwinCardsMiddleware.kt @@ -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() diff --git a/ci_resources/Dockerfile.android b/ci_resources/Dockerfile.android index 4573a0972d..bdd3dd2f52 100644 --- a/ci_resources/Dockerfile.android +++ b/ci_resources/Dockerfile.android @@ -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 ./ diff --git a/ci_resources/find-latest-pre-release-branch.sh b/ci_resources/find-latest-pre-release-branch.sh index f422f6d0ed..653cbdd467 100755 --- a/ci_resources/find-latest-pre-release-branch.sh +++ b/ci_resources/find-latest-pre-release-branch.sh @@ -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'" diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/ScanCardToUnlockWalletClickHandler.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/ScanCardToUnlockWalletClickHandler.kt index 9026867a47..a487bd79bd 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/ScanCardToUnlockWalletClickHandler.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/domain/ScanCardToUnlockWalletClickHandler.kt @@ -23,7 +23,7 @@ internal class ScanCardToUnlockWalletClickHandler @Inject constructor( suspend operator fun invoke(walletId: UserWalletId): Either { 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++ diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/RenameWalletTransformer.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/RenameWalletTransformer.kt deleted file mode 100644 index f0b5cf9e20..0000000000 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/RenameWalletTransformer.kt +++ /dev/null @@ -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 - } - } - } -} \ No newline at end of file diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/RenameWalletsTransformer.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/RenameWalletsTransformer.kt new file mode 100644 index 0000000000..9dd8ccb8f9 --- /dev/null +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/state/transformers/RenameWalletsTransformer.kt @@ -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, +) : 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 + } + } + } +} \ No newline at end of file diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/WalletViewModel.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/WalletViewModel.kt index 1d56ea3290..f06a3d46c4 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/WalletViewModel.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/WalletViewModel.kt @@ -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") diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/WalletsUpdateActionResolver.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/WalletsUpdateActionResolver.kt index 324b2fc7ca..2d675b4ca0 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/WalletsUpdateActionResolver.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/wallet/viewmodels/WalletsUpdateActionResolver.kt @@ -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): 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): 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, 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) : Action() { override fun toString(): String { - return "UpdateWalletName(selectedWalletId = $selectedWalletId, name = $name)" + return """ + RenameWallets( + renamedWallets = ${renamedWallets.joinToString { it.walletId.toString() }} + ) + """.trimIndent() } } diff --git a/gradle/dependencies.toml b/gradle/dependencies.toml index 57af152773..e27db46828 100644 --- a/gradle/dependencies.toml +++ b/gradle/dependencies.toml @@ -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 ^