From 88f720529364c9d525aa391dc3489e23ffdb9802 Mon Sep 17 00:00:00 2001 From: Tangem Date: Wed, 25 Mar 2026 16:03:41 +0400 Subject: [PATCH] Updated on 2026-08-14 --- .../main/java/com/tangem/tap/MainActivity.kt | 5 -- .../com/tangem/tap/common/DialogManager.kt | 52 ------------ .../com/tangem/tap/common/extensions/Store.kt | 33 -------- .../tap/common/redux/global/GlobalAction.kt | 5 -- .../tap/common/redux/global/GlobalReducer.kt | 6 -- .../tap/common/redux/global/GlobalState.kt | 10 +-- .../tangem/tap/common/ui/ScanFailsDialog.kt | 84 ------------------- .../features/onboarding/OnboardingDialog.kt | 10 --- .../ui/dialogs/WalletActivationErrorDialog.kt | 45 ---------- .../com/tangem/tap/proxy/AppStateHolder.kt | 6 -- app/src/main/res/layout/dialog_scan_fails.xml | 84 ------------------- .../tangem/domain/redux/ReduxStateHolder.kt | 2 - .../com/tangem/domain/redux/StateDialog.kt | 10 --- .../router/DefaultWalletRouter.kt | 7 -- .../presentation/router/InnerWalletRouter.kt | 3 - 15 files changed, 1 insertion(+), 361 deletions(-) delete mode 100644 app/src/main/java/com/tangem/tap/common/DialogManager.kt delete mode 100644 app/src/main/java/com/tangem/tap/common/ui/ScanFailsDialog.kt delete mode 100644 app/src/main/java/com/tangem/tap/features/onboarding/OnboardingDialog.kt delete mode 100644 app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/ui/dialogs/WalletActivationErrorDialog.kt delete mode 100644 app/src/main/res/layout/dialog_scan_fails.xml delete mode 100644 domain/legacy/src/main/java/com/tangem/domain/redux/StateDialog.kt diff --git a/app/src/main/java/com/tangem/tap/MainActivity.kt b/app/src/main/java/com/tangem/tap/MainActivity.kt index 2d3a35f48c..5372f06248 100644 --- a/app/src/main/java/com/tangem/tap/MainActivity.kt +++ b/app/src/main/java/com/tangem/tap/MainActivity.kt @@ -54,7 +54,6 @@ import com.tangem.operations.backup.BackupService import com.tangem.sdk.api.BackupServiceHolder import com.tangem.sdk.api.TangemSdkManager import com.tangem.tap.common.ActivityResultCallbackHolder -import com.tangem.tap.common.DialogManager import com.tangem.tap.common.OnActivityResultCallback import com.tangem.tap.common.analytics.events.Push import com.tangem.tap.common.apptheme.MutableAppThemeModeHolder @@ -171,8 +170,6 @@ class MainActivity : AppCompatActivity(), ActivityResultCallbackHolder { private lateinit var appThemeModeFlow: SharedFlow - private val dialogManager = DialogManager() - private val onActivityResultCallbacks = mutableListOf() override fun onCreate(savedInstanceState: Bundle?) { @@ -324,11 +321,9 @@ class MainActivity : AppCompatActivity(), ActivityResultCallbackHolder { override fun onStart() { super.onStart() TangemLogger.i("onStart") - dialogManager.onStart(this) } override fun onStop() { - dialogManager.onStop() super.onStop() TangemLogger.i("onStop") } diff --git a/app/src/main/java/com/tangem/tap/common/DialogManager.kt b/app/src/main/java/com/tangem/tap/common/DialogManager.kt deleted file mode 100644 index 7c984b6d60..0000000000 --- a/app/src/main/java/com/tangem/tap/common/DialogManager.kt +++ /dev/null @@ -1,52 +0,0 @@ -package com.tangem.tap.common - -import android.app.Dialog -import android.content.Context -import com.tangem.domain.redux.StateDialog -import com.tangem.tap.common.redux.global.GlobalState -import com.tangem.tap.common.ui.ScanFailsDialog -import com.tangem.tap.features.onboarding.OnboardingDialog -import com.tangem.tap.features.onboarding.products.wallet.ui.dialogs.WalletActivationErrorDialog -import com.tangem.tap.store -import org.rekotlin.StoreSubscriber - -class DialogManager : StoreSubscriber { - var context: Context? = null - private var dialog: Dialog? = null - - fun onStart(context: Context) { - this.context = context - store.subscribe(this) { state -> - state.skipRepeats { oldState, newState -> - oldState.globalState == newState.globalState - }.select { it.globalState } - } - } - - fun onStop() { - this.context = null - store.unsubscribe(this) - } - - @Suppress("LongMethod", "ComplexMethod") - override fun newState(state: GlobalState) { - if (state.dialog == null) { - dialog?.dismiss() - dialog = null - return - } - val context = context ?: return - if (dialog != null) return - - dialog = when (state.dialog) { - is StateDialog.ScanFailsDialog -> ScanFailsDialog.create( - context = context, - source = state.dialog.source, - onTryAgain = state.dialog.onTryAgain, - ) - is OnboardingDialog.WalletActivationError -> WalletActivationErrorDialog.create(context, state.dialog) - else -> null - } - dialog?.show() - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/common/extensions/Store.kt b/app/src/main/java/com/tangem/tap/common/extensions/Store.kt index 62bf0eb950..8d38cb9f3a 100644 --- a/app/src/main/java/com/tangem/tap/common/extensions/Store.kt +++ b/app/src/main/java/com/tangem/tap/common/extensions/Store.kt @@ -1,14 +1,9 @@ package com.tangem.tap.common.extensions import com.tangem.common.routing.AppRouter -import com.tangem.core.ui.extensions.stringReference -import com.tangem.core.ui.message.SnackbarMessage import com.tangem.domain.common.extensions.withMainContext import com.tangem.domain.models.wallet.UserWallet -import com.tangem.domain.redux.StateDialog import com.tangem.tap.common.redux.AppState -import com.tangem.tap.common.redux.global.GlobalAction -import com.tangem.tap.domain.TapError import com.tangem.tap.proxy.redux.DaggerGraphState import com.tangem.tap.scope import com.tangem.tap.store @@ -45,26 +40,6 @@ suspend fun Store.onUserWalletSelected(userWallet: UserWallet) { state.globalState.tapWalletManager.onWalletSelected(userWallet) } -/** - * @param fatal used to indicate errors that should not normally occur - */ -fun Store.dispatchDebugErrorNotification(message: String, fatal: Boolean = false) { - val prefix = if (fatal) "FATAL ERROR: " else "DEBUG ERROR: " - dispatchDebugErrorNotification(TapError.CustomError("$prefix $message")) -} - -fun Store.dispatchDebugErrorNotification(error: TapError) { - inject(DaggerGraphState::uiMessageSender).send(SnackbarMessage(stringReference(error.message ?: "debug error"))) -} - -fun Store<*>.dispatchDialogShow(dialog: StateDialog) { - dispatchOnMain(GlobalAction.ShowDialog(dialog)) -} - -fun Store<*>.dispatchDialogHide() { - dispatchOnMain(GlobalAction.HideDialog) -} - /** * Dispatch action inside a coroutine with the Main dispatcher */ @@ -76,14 +51,6 @@ suspend fun dispatchOnMain(vararg actions: Action) { withMainContext { actions.forEach { store.dispatch(it) } } } -fun Store.dispatchOpenUrl(url: String) { - inject(DaggerGraphState::urlOpener).openUrl(url) -} - -fun Store.dispatchShare(url: String) { - inject(DaggerGraphState::shareManager).shareText(url) -} - fun Store.dispatchNavigationAction(action: AppRouter.() -> Unit) { inject(DaggerGraphState::appRouter).action() } diff --git a/app/src/main/java/com/tangem/tap/common/redux/global/GlobalAction.kt b/app/src/main/java/com/tangem/tap/common/redux/global/GlobalAction.kt index 404c7150f4..315fe98387 100644 --- a/app/src/main/java/com/tangem/tap/common/redux/global/GlobalAction.kt +++ b/app/src/main/java/com/tangem/tap/common/redux/global/GlobalAction.kt @@ -4,15 +4,10 @@ import com.tangem.common.CompletionResult import com.tangem.core.analytics.models.AnalyticsParam import com.tangem.domain.appcurrency.model.AppCurrency import com.tangem.domain.models.scan.ScanResponse -import com.tangem.domain.redux.StateDialog import org.rekotlin.Action sealed class GlobalAction : Action { - // dialogs - data class ShowDialog(val stateDialog: StateDialog) : GlobalAction() - object HideDialog : GlobalAction() - object ScanFailsCounter { data class ChooseBehavior( val result: CompletionResult, diff --git a/app/src/main/java/com/tangem/tap/common/redux/global/GlobalReducer.kt b/app/src/main/java/com/tangem/tap/common/redux/global/GlobalReducer.kt index a1ed71be61..b381df3054 100644 --- a/app/src/main/java/com/tangem/tap/common/redux/global/GlobalReducer.kt +++ b/app/src/main/java/com/tangem/tap/common/redux/global/GlobalReducer.kt @@ -26,12 +26,6 @@ fun globalReducer(action: Action, state: AppState): GlobalState { globalState.copy(appCurrency = action.appCurrency) } is GlobalAction.IsSignWithRing -> globalState.copy(isLastSignWithRing = action.isSignWithRing) - is GlobalAction.ShowDialog -> { - globalState.copy(dialog = action.stateDialog) - } - is GlobalAction.HideDialog -> { - globalState.copy(dialog = null) - } else -> globalState } } \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/common/redux/global/GlobalState.kt b/app/src/main/java/com/tangem/tap/common/redux/global/GlobalState.kt index 598ad3be24..3c7906a1e5 100644 --- a/app/src/main/java/com/tangem/tap/common/redux/global/GlobalState.kt +++ b/app/src/main/java/com/tangem/tap/common/redux/global/GlobalState.kt @@ -2,24 +2,16 @@ package com.tangem.tap.common.redux.global import com.tangem.domain.appcurrency.model.AppCurrency import com.tangem.domain.models.scan.ScanResponse -import com.tangem.domain.redux.StateDialog import com.tangem.tap.domain.TapWalletManager import org.rekotlin.StateType data class GlobalState( @Deprecated("Use scan response from selected user wallet") val scanResponse: ScanResponse? = null, - val onboardingState: OnboardingState = OnboardingState(), val tapWalletManager: TapWalletManager = TapWalletManager(), val appCurrency: AppCurrency = AppCurrency.Default, val scanCardFailsCounter: Int = 0, - val dialog: StateDialog? = null, val isLastSignWithRing: Boolean = false, ) : StateType -typealias CryptoCurrencyName = String - -data class OnboardingState( - val isOnboardingStarted: Boolean = false, - val shouldResetOnCreate: Boolean = false, -) \ No newline at end of file +typealias CryptoCurrencyName = String \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/common/ui/ScanFailsDialog.kt b/app/src/main/java/com/tangem/tap/common/ui/ScanFailsDialog.kt deleted file mode 100644 index 61b24a7d63..0000000000 --- a/app/src/main/java/com/tangem/tap/common/ui/ScanFailsDialog.kt +++ /dev/null @@ -1,84 +0,0 @@ -package com.tangem.tap.common.ui - -import android.content.Context -import android.view.View -import android.widget.TextView -import androidx.appcompat.app.AlertDialog -import androidx.compose.ui.text.intl.Locale -import androidx.core.view.isVisible -import com.tangem.core.analytics.Analytics -import com.tangem.core.analytics.models.AnalyticsParam -import com.tangem.core.analytics.models.Basic -import com.tangem.domain.feedback.models.FeedbackEmailType -import com.tangem.domain.redux.StateDialog -import com.tangem.tap.common.analytics.events.ScanFailsDialogAnalytics -import com.tangem.tap.common.extensions.dispatchDialogHide -import com.tangem.tap.common.extensions.dispatchOpenUrl -import com.tangem.tap.common.extensions.inject -import com.tangem.tap.proxy.redux.DaggerGraphState -import com.tangem.tap.scope -import com.tangem.tap.store -import com.tangem.wallet.R -import kotlinx.coroutines.launch - -/** -[REDACTED_AUTHOR] - */ -internal object ScanFailsDialog { - - private const val HOW_TO_SCAN_RU_LINK = "https://tangem.com/ru/blog/post/scan-tangem-card/" - private const val HOW_TO_SCAN_LINK = "https://tangem.com/en/blog/post/scan-tangem-card/" - private const val RUSSIA_LOCALE = "ru" - - fun create(context: Context, source: StateDialog.ScanFailsSource, onTryAgain: (() -> Unit)? = null): AlertDialog { - return AlertDialog.Builder(context, R.style.CustomMaterialDialog).apply { - val customView = View.inflate(context, R.layout.dialog_scan_fails, null) - val sourceAnalytics = when (source) { - StateDialog.ScanFailsSource.MAIN -> AnalyticsParam.ScreensSources.Main - StateDialog.ScanFailsSource.SIGN_IN -> AnalyticsParam.ScreensSources.SignIn - StateDialog.ScanFailsSource.SETTINGS -> AnalyticsParam.ScreensSources.Settings - StateDialog.ScanFailsSource.INTRO -> AnalyticsParam.ScreensSources.Intro - } - val tryAgainBtn: TextView? = customView.findViewById(R.id.try_again_button) - if (onTryAgain != null) { - tryAgainBtn?.isVisible = true - tryAgainBtn?.setOnClickListener { - store.dispatchDialogHide() - Analytics.send( - ScanFailsDialogAnalytics( - button = ScanFailsDialogAnalytics.Buttons.TRY_AGAIN, - source = sourceAnalytics, - ), - ) - onTryAgain() - } - } else { - tryAgainBtn?.isVisible = false - } - customView.findViewById(R.id.how_to_scan_button)?.setOnClickListener { - Analytics.send( - ScanFailsDialogAnalytics( - button = ScanFailsDialogAnalytics.Buttons.HOW_TO_SCAN, - source = sourceAnalytics, - ), - ) - val locale = Locale.current.region - val link = if (locale.lowercase() == RUSSIA_LOCALE) HOW_TO_SCAN_RU_LINK else HOW_TO_SCAN_LINK - store.dispatchOpenUrl(link) - } - customView.findViewById(R.id.request_support_button)?.setOnClickListener { - Analytics.send(Basic.ButtonSupport(sourceAnalytics)) - - scope.launch { - store.inject(DaggerGraphState::sendFeedbackEmailUseCase) - .invoke(type = FeedbackEmailType.ScanningProblem) - } - } - customView.findViewById(R.id.cancel_button)?.setOnClickListener { - store.dispatchDialogHide() - } - setView(customView) - setOnDismissListener { store.dispatchDialogHide() } - }.create() - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/OnboardingDialog.kt b/app/src/main/java/com/tangem/tap/features/onboarding/OnboardingDialog.kt deleted file mode 100644 index e2de5c257b..0000000000 --- a/app/src/main/java/com/tangem/tap/features/onboarding/OnboardingDialog.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.tangem.tap.features.onboarding - -import com.tangem.domain.redux.StateDialog - -/** -[REDACTED_AUTHOR] - */ -sealed class OnboardingDialog : StateDialog { - data class WalletActivationError(val onConfirm: () -> Unit) : OnboardingDialog() -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/ui/dialogs/WalletActivationErrorDialog.kt b/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/ui/dialogs/WalletActivationErrorDialog.kt deleted file mode 100644 index 880f9177a0..0000000000 --- a/app/src/main/java/com/tangem/tap/features/onboarding/products/wallet/ui/dialogs/WalletActivationErrorDialog.kt +++ /dev/null @@ -1,45 +0,0 @@ -package com.tangem.tap.features.onboarding.products.wallet.ui.dialogs - -import android.app.Dialog -import android.content.Context -import com.google.android.material.dialog.MaterialAlertDialogBuilder -import com.tangem.core.analytics.Analytics -import com.tangem.core.analytics.models.AnalyticsParam -import com.tangem.core.analytics.models.Basic -import com.tangem.domain.feedback.models.FeedbackEmailType -import com.tangem.tap.common.extensions.dispatchDialogHide -import com.tangem.tap.common.extensions.inject -import com.tangem.tap.features.onboarding.OnboardingDialog -import com.tangem.tap.proxy.redux.DaggerGraphState -import com.tangem.tap.scope -import com.tangem.tap.store -import com.tangem.wallet.R -import kotlinx.coroutines.launch - -object WalletActivationErrorDialog { - - fun create(context: Context, dialog: OnboardingDialog.WalletActivationError): Dialog { - return MaterialAlertDialogBuilder(context, R.style.CustomMaterialDialog).apply { - setTitle(context.getString(R.string.onboarding_activation_error_title)) - setMessage(context.getString(R.string.onboarding_activation_error_message)) - setPositiveButton(R.string.common_ok) { _, _ -> dialog.onConfirm() } - setNegativeButton(R.string.common_support) { _, _ -> - // changed on email support [REDACTED_TASK_KEY] - Analytics.send(Basic.ButtonSupport(AnalyticsParam.ScreensSources.Intro)) - - val scanResponse = store.state.globalState.scanResponse - ?: error("ScanResponse must be not null") - - val cardInfo = store.inject(DaggerGraphState::getWalletMetaInfoUseCase).invoke(scanResponse).getOrNull() - ?: error("CardInfo must be not null") - - scope.launch { - store.inject(DaggerGraphState::sendFeedbackEmailUseCase) - .invoke(type = FeedbackEmailType.DirectUserRequest(cardInfo)) - } - } - setOnDismissListener { store.dispatchDialogHide() } - setCancelable(false) - }.create() - } -} \ No newline at end of file diff --git a/app/src/main/java/com/tangem/tap/proxy/AppStateHolder.kt b/app/src/main/java/com/tangem/tap/proxy/AppStateHolder.kt index c3261b1873..e85f806bdc 100644 --- a/app/src/main/java/com/tangem/tap/proxy/AppStateHolder.kt +++ b/app/src/main/java/com/tangem/tap/proxy/AppStateHolder.kt @@ -2,8 +2,6 @@ package com.tangem.tap.proxy import com.tangem.domain.models.wallet.UserWallet import com.tangem.domain.redux.ReduxStateHolder -import com.tangem.domain.redux.StateDialog -import com.tangem.tap.common.extensions.dispatchDialogShow import com.tangem.tap.common.extensions.dispatchWithMain import com.tangem.tap.common.extensions.onUserWalletSelected import com.tangem.tap.common.redux.AppState @@ -32,8 +30,4 @@ class AppStateHolder @Inject constructor() : ReduxStateHolder { override suspend fun onUserWalletSelected(userWallet: UserWallet) { mainStore?.onUserWalletSelected(userWallet) } - - override fun dispatchDialogShow(dialog: StateDialog) { - mainStore?.dispatchDialogShow(dialog) - } } \ No newline at end of file diff --git a/app/src/main/res/layout/dialog_scan_fails.xml b/app/src/main/res/layout/dialog_scan_fails.xml deleted file mode 100644 index dd5924f8c5..0000000000 --- a/app/src/main/res/layout/dialog_scan_fails.xml +++ /dev/null @@ -1,84 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/domain/legacy/src/main/java/com/tangem/domain/redux/ReduxStateHolder.kt b/domain/legacy/src/main/java/com/tangem/domain/redux/ReduxStateHolder.kt index f955b2d658..3a96226153 100644 --- a/domain/legacy/src/main/java/com/tangem/domain/redux/ReduxStateHolder.kt +++ b/domain/legacy/src/main/java/com/tangem/domain/redux/ReduxStateHolder.kt @@ -10,6 +10,4 @@ interface ReduxStateHolder { suspend fun dispatchWithMain(action: Action) suspend fun onUserWalletSelected(userWallet: UserWallet) - - fun dispatchDialogShow(dialog: StateDialog) } \ No newline at end of file diff --git a/domain/legacy/src/main/java/com/tangem/domain/redux/StateDialog.kt b/domain/legacy/src/main/java/com/tangem/domain/redux/StateDialog.kt deleted file mode 100644 index 5299850377..0000000000 --- a/domain/legacy/src/main/java/com/tangem/domain/redux/StateDialog.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.tangem.domain.redux - -interface StateDialog { - - data class ScanFailsDialog(val source: ScanFailsSource, val onTryAgain: (() -> Unit)? = null) : StateDialog - - enum class ScanFailsSource { - MAIN, SIGN_IN, SETTINGS, INTRO - } -} \ No newline at end of file diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/router/DefaultWalletRouter.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/router/DefaultWalletRouter.kt index decb5b77df..95c94d246c 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/router/DefaultWalletRouter.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/router/DefaultWalletRouter.kt @@ -17,8 +17,6 @@ import com.tangem.domain.qrscanning.models.QrSendTarget import com.tangem.domain.models.wallet.UserWallet import com.tangem.domain.models.wallet.UserWalletId import com.tangem.domain.pay.TangemPayDetailsConfig -import com.tangem.domain.redux.ReduxStateHolder -import com.tangem.domain.redux.StateDialog import com.tangem.domain.tokens.model.details.NavigationAction import com.tangem.domain.tokens.model.details.TokenAction import com.tangem.feature.wallet.child.organizetokens.OrganizeTokensComponent @@ -35,7 +33,6 @@ import javax.inject.Inject internal class DefaultWalletRouter @Inject constructor( private val router: AppRouter, private val urlOpener: UrlOpener, - private val reduxStateHolder: ReduxStateHolder, private val designFeatureToggles: DesignFeatureToggles, ) : InnerWalletRouter { @@ -117,10 +114,6 @@ internal class DefaultWalletRouter @Inject constructor( return router.stack.lastOrNull() is AppRoute.Wallet } - override fun openScanFailedDialog(onTryAgain: () -> Unit) { - reduxStateHolder.dispatchDialogShow(StateDialog.ScanFailsDialog(StateDialog.ScanFailsSource.MAIN, onTryAgain)) - } - override fun openNFT(userWallet: UserWallet) { router.push( AppRoute.NFT( diff --git a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/router/InnerWalletRouter.kt b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/router/InnerWalletRouter.kt index 56f3e54725..fb55f96999 100644 --- a/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/router/InnerWalletRouter.kt +++ b/features/wallet/impl/src/main/java/com/tangem/feature/wallet/presentation/router/InnerWalletRouter.kt @@ -66,9 +66,6 @@ internal interface InnerWalletRouter { /** Is wallet last screen */ fun isWalletLastScreen(): Boolean - /** Open scan failed dialog */ - fun openScanFailedDialog(onTryAgain: () -> Unit) - /** Open NFT collections screen */ fun openNFT(userWallet: UserWallet)