Updated on 2026-08-14

This commit is contained in:
Tangem 2024-06-11 14:57:43 +04:00
parent 40c7d20bda
commit 768b44f44f
16 changed files with 62 additions and 27 deletions

View file

@ -6,6 +6,7 @@ import com.tangem.domain.common.extensions.withMainContext
import com.tangem.domain.wallets.models.UserWallet
import com.tangem.tap.common.redux.AppState
import com.tangem.tap.common.redux.global.GlobalAction
import com.tangem.tap.common.url.urlOpener
import com.tangem.tap.domain.TapError
import com.tangem.tap.proxy.redux.DaggerGraphState
import com.tangem.tap.scope
@ -83,7 +84,7 @@ suspend fun dispatchOnMain(vararg actions: Action) {
}
fun Store<*>.dispatchOpenUrl(url: String) {
dispatch(NavigationAction.OpenUrl(url))
urlOpener.openUrl(url)
}
fun Store<*>.dispatchShare(url: String) {

View file

@ -7,7 +7,6 @@ import android.provider.Settings
import com.tangem.core.navigation.AppScreen
import com.tangem.core.navigation.NavigationAction
import com.tangem.tap.activityResultCaller
import com.tangem.tap.common.CustomTabsManager
import com.tangem.tap.common.extensions.*
import com.tangem.tap.common.redux.AppState
import com.tangem.tap.store
@ -47,11 +46,6 @@ val navigationMiddleware: Middleware<AppState> = { _, state ->
}
}
}
is NavigationAction.OpenUrl -> {
navState?.activity?.get()?.let {
CustomTabsManager().openUrl(action.url, it)
}
}
is NavigationAction.OpenDocument -> {
val intent = Intent(Intent.ACTION_VIEW)
intent.data = action.url

View file

@ -5,11 +5,11 @@ import android.os.Bundle
import android.view.LayoutInflater
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.tangem.core.analytics.Analytics
import com.tangem.core.navigation.NavigationAction
import com.tangem.tap.common.analytics.events.Token
import com.tangem.tap.common.extensions.dispatchDialogHide
import com.tangem.tap.common.extensions.dispatchOpenUrl
import com.tangem.tap.common.redux.AppDialog
import com.tangem.tap.common.url.urlOpener
import com.tangem.tap.store
import com.tangem.wallet.databinding.DialogRussiansCardholdersWarningBinding
@ -44,7 +44,7 @@ class RussianCardholdersWarningBottomSheetDialog(
dismiss()
}
binding?.btnNo?.setOnClickListener {
store.dispatch(NavigationAction.OpenUrl(INSTRUCTION_URL))
urlOpener.openUrl(INSTRUCTION_URL)
dismiss()
}
}

View file

@ -1,4 +1,4 @@
package com.tangem.tap.common
package com.tangem.tap.common.url
import android.content.Context
import android.content.Intent.FLAG_ACTIVITY_NEW_TASK
@ -8,12 +8,24 @@ import androidx.browser.customtabs.CustomTabColorSchemeParams
import androidx.browser.customtabs.CustomTabsIntent
import androidx.browser.customtabs.CustomTabsIntent.COLOR_SCHEME_DARK
import androidx.browser.customtabs.CustomTabsIntent.COLOR_SCHEME_LIGHT
import com.tangem.core.navigation.url.UrlOpener
import com.tangem.tap.common.apptheme.MutableAppThemeModeHolder
import com.tangem.tap.common.extensions.getColorCompat
import com.tangem.tap.foregroundActivityObserver
import com.tangem.tap.withForegroundActivity
import com.tangem.wallet.R
class CustomTabsManager {
fun openUrl(url: String, context: Context) {
internal val urlOpener = CustomTabsUrlOpener
internal object CustomTabsUrlOpener : UrlOpener {
override fun openUrl(url: String) {
foregroundActivityObserver.withForegroundActivity {
openUrl(url, context = it)
}
}
private fun openUrl(url: String, context: Context) {
if (url.isEmpty()) return
val customTabsIntent = CustomTabsIntent.Builder()
.setDefaultColorSchemeParams(

View file

@ -1,7 +1,9 @@
package com.tangem.tap.di
import com.tangem.core.navigation.feedback.FeedbackManager
import com.tangem.core.navigation.url.UrlOpener
import com.tangem.tap.common.feedback.ProxyFeedbackManager
import com.tangem.tap.common.url.CustomTabsUrlOpener
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
@ -12,6 +14,10 @@ import javax.inject.Singleton
@InstallIn(SingletonComponent::class)
internal object UtilsModule {
@Provides
@Singleton
fun provideUrlOpener(): UrlOpener = CustomTabsUrlOpener
@Provides
@Singleton
fun provideFeedbackManager(): FeedbackManager = ProxyFeedbackManager()

View file

@ -22,6 +22,7 @@ import com.tangem.tap.common.extensions.dispatchWithMain
import com.tangem.tap.common.feedback.FeedbackEmail
import com.tangem.tap.common.redux.AppState
import com.tangem.tap.common.redux.global.GlobalAction
import com.tangem.tap.common.url.urlOpener
import com.tangem.tap.features.details.redux.DetailsAction
import com.tangem.tap.features.details.redux.DetailsState
import com.tangem.tap.features.disclaimer.redux.DisclaimerAction
@ -179,7 +180,7 @@ internal class DetailsViewModel(
private fun handleSocialNetworkClick(link: SocialNetworkLink) {
Analytics.send(Settings.ButtonSocialNetwork(link.network))
store.dispatchOnMain(NavigationAction.OpenUrl(link.url))
urlOpener.openUrl(link.url)
}
private fun getSocialLinks(): ImmutableList<SocialNetworkLink> {

View file

@ -17,8 +17,6 @@ sealed class NavigationAction : Action {
data class PopBackTo(val screen: AppScreen? = null, val inclusive: Boolean = false) : NavigationAction()
data class OpenUrl(val url: String) : NavigationAction()
data class OpenDocument(val url: Uri) : NavigationAction()
object OpenBiometricsSettings : NavigationAction()

View file

@ -0,0 +1,8 @@
package com.tangem.core.navigation.url
class DummyUrlOpener : UrlOpener {
override fun openUrl(url: String) {
/* no-op */
}
}

View file

@ -0,0 +1,6 @@
package com.tangem.core.navigation.url
interface UrlOpener {
fun openUrl(url: String)
}

View file

@ -6,7 +6,7 @@ import com.tangem.core.navigation.NavigationAction
import com.tangem.core.navigation.ReduxNavController
import com.tangem.core.navigation.feedback.FeedbackManager
import com.tangem.core.navigation.feedback.FeedbackType
import com.tangem.domain.redux.ReduxStateHolder
import com.tangem.core.navigation.url.UrlOpener
import com.tangem.features.details.routing.DetailsRoute
import com.tangem.features.tester.api.TesterRouter
import javax.inject.Inject
@ -14,9 +14,9 @@ import javax.inject.Inject
// TODO: Remove after [REDACTED_JIRA]
internal class DetailsRouter @Inject constructor(
private val reduxNavController: ReduxNavController,
private val reduxStateHolder: ReduxStateHolder,
private val feedbackManager: FeedbackManager,
private val testerRouter: TesterRouter,
private val urlOpener: UrlOpener,
) : Router {
override fun push(route: Route, onComplete: (isSuccess: Boolean) -> Unit) {
@ -32,7 +32,7 @@ internal class DetailsRouter @Inject constructor(
testerRouter.startTesterScreen()
}
is DetailsRoute.Url -> {
reduxNavController.navigate(NavigationAction.OpenUrl(route.url))
urlOpener.openUrl(route.url)
}
}
onComplete(true)

View file

@ -1,6 +1,7 @@
package com.tangem.features.send.impl.di
import com.tangem.core.navigation.ReduxNavController
import com.tangem.core.navigation.url.UrlOpener
import com.tangem.features.send.api.navigation.SendRouter
import com.tangem.features.send.impl.navigation.DefaultSendRouter
import dagger.Module
@ -18,7 +19,7 @@ internal object SendRouterModule {
@Provides
@ActivityScoped
fun provideSendRouter(reduxNavController: ReduxNavController): SendRouter {
return DefaultSendRouter(reduxNavController)
fun provideSendRouter(reduxNavController: ReduxNavController, urlOpener: UrlOpener): SendRouter {
return DefaultSendRouter(reduxNavController, urlOpener)
}
}

View file

@ -5,6 +5,7 @@ import androidx.fragment.app.Fragment
import com.tangem.core.navigation.AppScreen
import com.tangem.core.navigation.NavigationAction
import com.tangem.core.navigation.ReduxNavController
import com.tangem.core.navigation.url.UrlOpener
import com.tangem.domain.qrscanning.models.SourceType
import com.tangem.domain.tokens.model.CryptoCurrency
import com.tangem.domain.wallets.models.UserWalletId
@ -14,12 +15,13 @@ import com.tangem.features.tokendetails.navigation.TokenDetailsRouter
internal class DefaultSendRouter(
private val reduxNavController: ReduxNavController,
private val urlOpener: UrlOpener,
) : InnerSendRouter {
override fun getEntryFragment(): Fragment = SendFragment.create()
override fun openUrl(url: String) {
reduxNavController.navigate(NavigationAction.OpenUrl(url = url))
urlOpener.openUrl(url)
}
override fun openTokenDetails(userWalletId: UserWalletId, currency: CryptoCurrency) {

View file

@ -1,6 +1,7 @@
package com.tangem.feature.tokendetails.di
import com.tangem.core.navigation.ReduxNavController
import com.tangem.core.navigation.url.UrlOpener
import com.tangem.feature.tokendetails.presentation.router.DefaultTokenDetailsRouter
import com.tangem.features.tokendetails.navigation.TokenDetailsRouter
import dagger.Module
@ -15,7 +16,7 @@ internal object TokenDetailsRouterModule {
@Provides
@ActivityScoped
fun provideTokenDetailsRouter(reduxNavController: ReduxNavController): TokenDetailsRouter {
return DefaultTokenDetailsRouter(reduxNavController)
fun provideTokenDetailsRouter(reduxNavController: ReduxNavController, urlOpener: UrlOpener): TokenDetailsRouter {
return DefaultTokenDetailsRouter(reduxNavController, urlOpener)
}
}

View file

@ -5,6 +5,7 @@ import androidx.fragment.app.Fragment
import com.tangem.core.navigation.AppScreen
import com.tangem.core.navigation.NavigationAction
import com.tangem.core.navigation.ReduxNavController
import com.tangem.core.navigation.url.UrlOpener
import com.tangem.domain.tokens.model.CryptoCurrency
import com.tangem.domain.wallets.models.UserWalletId
import com.tangem.feature.tokendetails.presentation.TokenDetailsFragment
@ -12,6 +13,7 @@ import com.tangem.features.tokendetails.navigation.TokenDetailsRouter
internal class DefaultTokenDetailsRouter(
private val reduxNavController: ReduxNavController,
private val urlOpener: UrlOpener,
) : InnerTokenDetailsRouter {
override fun getEntryFragment(): Fragment = TokenDetailsFragment()
@ -21,7 +23,7 @@ internal class DefaultTokenDetailsRouter(
}
override fun openUrl(url: String) {
reduxNavController.navigate(NavigationAction.OpenUrl(url = url))
urlOpener.openUrl(url)
}
override fun share(text: String) {

View file

@ -1,6 +1,7 @@
package com.tangem.feature.wallet.di
import com.tangem.core.navigation.ReduxNavController
import com.tangem.core.navigation.url.UrlOpener
import com.tangem.feature.wallet.presentation.router.DefaultWalletRouter
import com.tangem.features.wallet.navigation.WalletRouter
import dagger.Module
@ -15,7 +16,7 @@ internal object WalletRouterModule {
@Provides
@ActivityScoped
fun provideWalletRouter(reduxNavController: ReduxNavController): WalletRouter {
return DefaultWalletRouter(reduxNavController = reduxNavController)
fun provideWalletRouter(reduxNavController: ReduxNavController, urlOpener: UrlOpener): WalletRouter {
return DefaultWalletRouter(reduxNavController, urlOpener)
}
}

View file

@ -20,6 +20,7 @@ import com.tangem.core.navigation.AppScreen
import com.tangem.core.navigation.NavigationAction
import com.tangem.core.navigation.ReduxNavController
import com.tangem.core.navigation.StateDialog
import com.tangem.core.navigation.url.UrlOpener
import com.tangem.domain.tokens.model.CryptoCurrencyStatus
import com.tangem.domain.wallets.models.UserWalletId
import com.tangem.feature.onboarding.navigation.OnboardingRouter
@ -37,6 +38,7 @@ import kotlin.properties.Delegates
/** Default implementation of wallet feature router */
internal class DefaultWalletRouter(
private val reduxNavController: ReduxNavController,
private val urlOpener: UrlOpener,
) : InnerWalletRouter {
private var navController: NavHostController by Delegates.notNull()
@ -138,7 +140,7 @@ internal class DefaultWalletRouter(
}
override fun openUrl(url: String) {
reduxNavController.navigate(action = NavigationAction.OpenUrl(url))
urlOpener.openUrl(url)
}
override fun openTokenDetails(userWalletId: UserWalletId, currencyStatus: CryptoCurrencyStatus) {