Updated on 2026-08-14
This commit is contained in:
parent
fc73f08b5e
commit
c763f84aad
9 changed files with 202 additions and 7 deletions
|
|
@ -186,6 +186,28 @@
|
|||
android:host="staking"
|
||||
android:scheme="tangem" />
|
||||
</intent-filter>
|
||||
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
|
||||
<data
|
||||
android:host="markets"
|
||||
android:scheme="tangem" />
|
||||
</intent-filter>
|
||||
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
|
||||
<data
|
||||
android:host="token_chart"
|
||||
android:scheme="tangem" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<!-- Disable android.startup completely. Used for Worker according doc -->
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@ import com.tangem.common.routing.AppRoute
|
|||
import com.tangem.common.routing.DeepLinkRoute
|
||||
import com.tangem.common.routing.DeepLinkScheme
|
||||
import com.tangem.feature.referral.api.deeplink.ReferralDeepLinkHandler
|
||||
import com.tangem.features.markets.deeplink.MarketsDeepLinkHandler
|
||||
import com.tangem.features.markets.deeplink.MarketsTokenDetailDeepLinkHandler
|
||||
import com.tangem.features.onramp.deeplink.BuyDeepLinkHandler
|
||||
import com.tangem.features.onramp.deeplink.OnrampDeepLinkHandler
|
||||
import com.tangem.features.send.v2.api.deeplink.SellDeepLinkHandler
|
||||
|
|
@ -35,6 +37,8 @@ internal class DeepLinkFactory @Inject constructor(
|
|||
private val walletDeepLink: WalletDeepLinkHandler.Factory,
|
||||
private val tokenDetailsDeepLink: TokenDetailsDeepLinkHandler.Factory,
|
||||
private val stakingDeepLink: StakingDeepLinkHandler.Factory,
|
||||
private val marketsDeepLink: MarketsDeepLinkHandler.Factory,
|
||||
private val marketsTokenDetailDeepLink: MarketsTokenDetailDeepLinkHandler.Factory,
|
||||
) {
|
||||
private val permittedAppRoute = MutableStateFlow(false)
|
||||
|
||||
|
|
@ -109,6 +113,8 @@ internal class DeepLinkFactory @Inject constructor(
|
|||
isFromOnNewIntent = isFromOnNewIntent,
|
||||
)
|
||||
DeepLinkRoute.Staking.host -> stakingDeepLink.create(coroutineScope, queryParams)
|
||||
DeepLinkRoute.Markets.host -> marketsDeepLink.create()
|
||||
DeepLinkRoute.MarketTokenDetail.host -> marketsTokenDetailDeepLink.create(coroutineScope, queryParams)
|
||||
else -> {
|
||||
Timber.i(
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@ package com.tangem.tap.routing.utils
|
|||
import android.net.Uri
|
||||
import com.tangem.common.routing.AppRoute
|
||||
import com.tangem.feature.referral.api.deeplink.ReferralDeepLinkHandler
|
||||
import com.tangem.features.markets.deeplink.MarketsDeepLinkHandler
|
||||
import com.tangem.features.markets.deeplink.MarketsTokenDetailDeepLinkHandler
|
||||
import com.tangem.features.onramp.deeplink.BuyDeepLinkHandler
|
||||
import com.tangem.features.onramp.deeplink.OnrampDeepLinkHandler
|
||||
import com.tangem.features.send.v2.api.deeplink.SellDeepLinkHandler
|
||||
|
|
@ -49,6 +51,12 @@ class DeepLinkFactoryTest {
|
|||
private val stakingDeepLinkFactory = mockk<StakingDeepLinkHandler.Factory>(relaxed = true) {
|
||||
every { create(any(), any()) } returns mockk()
|
||||
}
|
||||
private val marketsDeepLinkFactory = mockk<MarketsDeepLinkHandler.Factory>(relaxed = true) {
|
||||
every { create() } returns mockk()
|
||||
}
|
||||
private val marketsTokenDetailDeepLinkFactory = mockk<MarketsTokenDetailDeepLinkHandler.Factory>(relaxed = true) {
|
||||
every { create(any(), any()) } returns mockk()
|
||||
}
|
||||
|
||||
private val mockedUri = mockk<Uri>(relaxed = true)
|
||||
private val isFromOnNewIntent: Boolean = false
|
||||
|
|
@ -65,6 +73,8 @@ class DeepLinkFactoryTest {
|
|||
walletDeepLinkFactory,
|
||||
tokenDetailsDeepLinkFactory,
|
||||
stakingDeepLinkFactory,
|
||||
marketsDeepLinkFactory,
|
||||
marketsTokenDetailDeepLinkFactory,
|
||||
)
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
|
|
@ -220,13 +230,13 @@ class DeepLinkFactoryTest {
|
|||
every { mockedUri.host } returns "staking"
|
||||
deepLinkFactory.handleDeeplink(mockedUri, testScope, isFromOnNewIntent)
|
||||
advanceUntilIdle()
|
||||
verify {
|
||||
tokenDetailsDeepLinkFactory.create(
|
||||
eq(testScope),
|
||||
eq(mapOf("param" to "value")),
|
||||
eq(isFromOnNewIntent),
|
||||
)
|
||||
}
|
||||
verify { stakingDeepLinkFactory.create(eq(testScope), eq(mapOf("param" to "value"))) }
|
||||
|
||||
// Test Market Token Detail
|
||||
every { mockedUri.host } returns "token_chart"
|
||||
deepLinkFactory.handleDeeplink(mockedUri, testScope, isFromOnNewIntent)
|
||||
advanceUntilIdle()
|
||||
verify { marketsTokenDetailDeepLinkFactory.create(eq(testScope), eq(mapOf("param" to "value"))) }
|
||||
|
||||
// Reset params
|
||||
every { mockedUri.queryParameterNames } returns emptySet()
|
||||
|
|
@ -249,6 +259,12 @@ class DeepLinkFactoryTest {
|
|||
deepLinkFactory.handleDeeplink(mockedUri, testScope, isFromOnNewIntent)
|
||||
advanceUntilIdle()
|
||||
verify { walletDeepLinkFactory.create() }
|
||||
|
||||
// Test Markets
|
||||
every { mockedUri.host } returns "markets"
|
||||
deepLinkFactory.handleDeeplink(mockedUri, testScope, isFromOnNewIntent)
|
||||
advanceUntilIdle()
|
||||
verify { marketsDeepLinkFactory.create() }
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
|||
|
|
@ -31,6 +31,14 @@ sealed class DeepLinkRoute {
|
|||
data object Staking : DeepLinkRoute() {
|
||||
override val host: String = "staking"
|
||||
}
|
||||
|
||||
data object Markets : DeepLinkRoute() {
|
||||
override val host: String = "markets"
|
||||
}
|
||||
|
||||
data object MarketTokenDetail : DeepLinkRoute() {
|
||||
override val host: String = "token_chart"
|
||||
}
|
||||
}
|
||||
|
||||
enum class DeepLinkScheme(val scheme: String) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,8 @@
|
|||
package com.tangem.features.markets.deeplink
|
||||
|
||||
interface MarketsDeepLinkHandler {
|
||||
|
||||
interface Factory {
|
||||
fun create(): MarketsDeepLinkHandler
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
package com.tangem.features.markets.deeplink
|
||||
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
|
||||
interface MarketsTokenDetailDeepLinkHandler {
|
||||
|
||||
interface Factory {
|
||||
fun create(coroutineScope: CoroutineScope, params: Map<String, String>): MarketsTokenDetailDeepLinkHandler
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
package com.tangem.features.markets.deeplink
|
||||
|
||||
import com.tangem.common.routing.AppRoute
|
||||
import com.tangem.common.routing.AppRouter
|
||||
import dagger.assisted.AssistedFactory
|
||||
import dagger.assisted.AssistedInject
|
||||
|
||||
internal class DefaultMarketsDeepLinkHandler @AssistedInject constructor(
|
||||
appRouter: AppRouter,
|
||||
) : MarketsDeepLinkHandler {
|
||||
|
||||
init {
|
||||
appRouter.push(AppRoute.Markets)
|
||||
}
|
||||
|
||||
@AssistedFactory
|
||||
interface Factory : MarketsDeepLinkHandler.Factory {
|
||||
override fun create(): DefaultMarketsDeepLinkHandler
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
package com.tangem.features.markets.deeplink
|
||||
|
||||
import arrow.core.getOrElse
|
||||
import com.tangem.common.routing.AppRoute
|
||||
import com.tangem.common.routing.AppRouter
|
||||
import com.tangem.data.common.currency.getTokenIconUrlFromDefaultHost
|
||||
import com.tangem.domain.appcurrency.GetSelectedAppCurrencyUseCase
|
||||
import com.tangem.domain.appcurrency.model.AppCurrency
|
||||
import com.tangem.domain.markets.GetTokenMarketInfoUseCase
|
||||
import com.tangem.domain.markets.TokenMarketParams
|
||||
import com.tangem.domain.models.currency.CryptoCurrency
|
||||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedFactory
|
||||
import dagger.assisted.AssistedInject
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
|
||||
internal class DefaultMarketsTokenDetailDeepLinkHandler @AssistedInject constructor(
|
||||
@Assisted scope: CoroutineScope,
|
||||
@Assisted queryParams: Map<String, String>,
|
||||
appRouter: AppRouter,
|
||||
getSelectedAppCurrencyUseCase: GetSelectedAppCurrencyUseCase,
|
||||
getTokenMarketInfoUseCase: GetTokenMarketInfoUseCase,
|
||||
) : MarketsTokenDetailDeepLinkHandler {
|
||||
|
||||
init {
|
||||
val tokenId = queryParams[TOKEN_ID_KEY]
|
||||
|
||||
val rawTokenId = CryptoCurrency.RawID(tokenId.orEmpty())
|
||||
|
||||
scope.launch {
|
||||
val appCurrency = getSelectedAppCurrencyUseCase.invokeSync().getOrElse {
|
||||
AppCurrency.Default
|
||||
}
|
||||
val tokenInfo = getTokenMarketInfoUseCase(
|
||||
appCurrency = appCurrency,
|
||||
tokenId = rawTokenId,
|
||||
tokenSymbol = TOKEN_SYMBOL_KEY,
|
||||
).getOrElse {
|
||||
Timber.e("Failed to get market token info")
|
||||
return@launch
|
||||
}
|
||||
|
||||
appRouter.push(
|
||||
AppRoute.MarketsTokenDetails(
|
||||
token = TokenMarketParams(
|
||||
id = rawTokenId,
|
||||
name = tokenInfo.name,
|
||||
symbol = tokenInfo.symbol,
|
||||
tokenQuotes = TokenMarketParams.Quotes(
|
||||
currentPrice = tokenInfo.quotes.currentPrice,
|
||||
h24Percent = tokenInfo.quotes.h24ChangePercent,
|
||||
weekPercent = tokenInfo.quotes.weekChangePercent,
|
||||
monthPercent = tokenInfo.quotes.monthChangePercent,
|
||||
),
|
||||
imageUrl = getTokenIconUrlFromDefaultHost(rawTokenId),
|
||||
),
|
||||
appCurrency = appCurrency,
|
||||
showPortfolio = true,
|
||||
analyticsParams = null,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@AssistedFactory
|
||||
interface Factory : MarketsTokenDetailDeepLinkHandler.Factory {
|
||||
override fun create(
|
||||
coroutineScope: CoroutineScope,
|
||||
queryParams: Map<String, String>,
|
||||
): DefaultMarketsTokenDetailDeepLinkHandler
|
||||
}
|
||||
|
||||
private companion object {
|
||||
const val TOKEN_ID_KEY = "token_id"
|
||||
const val TOKEN_SYMBOL_KEY = "token_symbol"
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
package com.tangem.features.markets.deeplink.di
|
||||
|
||||
import com.tangem.features.markets.deeplink.DefaultMarketsDeepLinkHandler
|
||||
import com.tangem.features.markets.deeplink.DefaultMarketsTokenDetailDeepLinkHandler
|
||||
import com.tangem.features.markets.deeplink.MarketsDeepLinkHandler
|
||||
import com.tangem.features.markets.deeplink.MarketsTokenDetailDeepLinkHandler
|
||||
import dagger.Binds
|
||||
import dagger.Module
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Module
|
||||
@InstallIn(SingletonComponent::class)
|
||||
internal interface MarketsDeepLinkModule {
|
||||
|
||||
@Binds
|
||||
@Singleton
|
||||
fun bindMarketsDeepLinkHandlerFactory(impl: DefaultMarketsDeepLinkHandler.Factory): MarketsDeepLinkHandler.Factory
|
||||
|
||||
@Binds
|
||||
@Singleton
|
||||
fun bindMarketsTokenDetailDeepLinkHandlerFactory(
|
||||
impl: DefaultMarketsTokenDetailDeepLinkHandler.Factory,
|
||||
): MarketsTokenDetailDeepLinkHandler.Factory
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue