diff --git a/apps/flipcash/app/src/main/kotlin/com/flipcash/app/internal/ui/navigation/AppContent.kt b/apps/flipcash/app/src/main/kotlin/com/flipcash/app/internal/ui/navigation/AppContent.kt index 760ab37a94..629ee3e2c6 100644 --- a/apps/flipcash/app/src/main/kotlin/com/flipcash/app/internal/ui/navigation/AppContent.kt +++ b/apps/flipcash/app/src/main/kotlin/com/flipcash/app/internal/ui/navigation/AppContent.kt @@ -35,6 +35,8 @@ import com.flipcash.app.core.navigation.TabBarVisibilityController import com.flipcash.app.core.navigation.asNavBarTab import com.flipcash.app.core.navigation.destinationRoute import com.flipcash.app.core.ui.transitions.CardExpandTransition +import com.flipcash.app.core.tokens.TokenInfoEntry +import com.flipcash.app.core.tokens.TokenInfoPresentation import com.flipcash.app.internal.ui.AppNavigationBar import com.flipcash.app.internal.ui.navigation.decorators.rememberNavBillOverlayEntryDecorator import com.flipcash.app.internal.ui.navigation.decorators.rememberNavBlockingOverlayEntryDecorator @@ -57,11 +59,17 @@ import dev.theolm.rinku.DeepLink private fun isTokenInfoKey(key: Any?): Boolean { val s = key?.toString() ?: return false // The bespoke fade-in-place card-expand transition is only for the wallet/balance presentation. - // A drill-in push (asPush=true, e.g. from token discovery) is an ordinary stack push, so let it fall - // through to the default horizontal slide (and slide-back on pop / predictive-pop). - return s.startsWith("Info(") && s.contains("mint=") && !s.contains("asPush=true") + // A drill-in push (TokenInfoPresentation.Push, e.g. from token discovery) is an ordinary stack push, + // so let it fall through to the default horizontal slide (and slide-back on pop / predictive-pop). + return s.startsWith("Info(") && s.contains("mint=") && pushedTokenInfoEntries.none { s.contains(it) } } +/** The `entry=…` fragments of an [AppRoute.Token.Info] key whose entry is presented as a push. */ +private val pushedTokenInfoEntries: List = + TokenInfoEntry.all + .filter { it.presentation == TokenInfoPresentation.Push } + .map { "entry=$it" } + /** * True when a scene key belongs to [AppRoute.Sheets.Give] (the give/cash screen, which is pushed * rather than presented as a sheet). Same stringified-key match as [isTokenInfoKey]. diff --git a/apps/flipcash/app/src/main/kotlin/com/flipcash/app/internal/ui/navigation/AppScreenContent.kt b/apps/flipcash/app/src/main/kotlin/com/flipcash/app/internal/ui/navigation/AppScreenContent.kt index 41a7429817..f3e67ebf0b 100644 --- a/apps/flipcash/app/src/main/kotlin/com/flipcash/app/internal/ui/navigation/AppScreenContent.kt +++ b/apps/flipcash/app/src/main/kotlin/com/flipcash/app/internal/ui/navigation/AppScreenContent.kt @@ -126,7 +126,7 @@ fun appEntryProvider( // Tokens annotatedEntry(testTag = "token_info_screen") { key -> - TokenInfoScreen(key.mint, key.shortfall, key.fromDeeplink, key.asPush, key.returnAfterBuy) + TokenInfoScreen(key.mint, key.entry) } annotatedEntry(testTag = "transaction_history_screen") { key -> TransactionHistoryScreen(key.mint) diff --git a/apps/flipcash/app/src/test/kotlin/com/flipcash/app/internal/ui/navigation/BuildNavGraphForLaunchTest.kt b/apps/flipcash/app/src/test/kotlin/com/flipcash/app/internal/ui/navigation/BuildNavGraphForLaunchTest.kt index 873fe5e601..3027814154 100644 --- a/apps/flipcash/app/src/test/kotlin/com/flipcash/app/internal/ui/navigation/BuildNavGraphForLaunchTest.kt +++ b/apps/flipcash/app/src/test/kotlin/com/flipcash/app/internal/ui/navigation/BuildNavGraphForLaunchTest.kt @@ -8,6 +8,7 @@ import com.flipcash.services.models.chat.ChatId import com.getcode.solana.keys.Mint import com.flipcash.app.core.navigation.DeeplinkAction import com.flipcash.app.core.navigation.DeeplinkType +import com.flipcash.app.core.tokens.TokenInfoEntry import com.flipcash.app.router.Router import com.flipcash.services.user.AuthState import dev.theolm.rinku.DeepLink @@ -194,7 +195,7 @@ class BuildNavGraphForLaunchTest { fun `token deeplink pushes token info onto the Wallet tab without a sheet`() { val result = buildReady( DeeplinkAction.Navigate( - listOf(AppRoute.Sheets.Wallet, AppRoute.Token.Info(mint, fromDeeplink = true)) + listOf(AppRoute.Sheets.Wallet, AppRoute.Token.Info(mint, TokenInfoEntry.Deeplink)) ) ) diff --git a/apps/flipcash/core/src/main/kotlin/com/flipcash/app/core/AppRoute.kt b/apps/flipcash/core/src/main/kotlin/com/flipcash/app/core/AppRoute.kt index 4cbeca5a4c..91894db4e8 100644 --- a/apps/flipcash/core/src/main/kotlin/com/flipcash/app/core/AppRoute.kt +++ b/apps/flipcash/core/src/main/kotlin/com/flipcash/app/core/AppRoute.kt @@ -16,6 +16,7 @@ import com.flipcash.app.core.tokens.FundingSource import com.flipcash.app.core.tokens.SwapPurpose import com.flipcash.app.core.tokens.SwapResult import com.flipcash.app.core.tokens.SwapStep +import com.flipcash.app.core.tokens.TokenInfoEntry import com.flipcash.app.core.tokens.TokenPurpose import com.flipcash.app.core.navigation.SteppedFlowRoute import com.flipcash.app.core.userprofile.UpdateProfileResult @@ -210,16 +211,7 @@ sealed interface AppRoute : NavKey, Parcelable { @Serializable data class Info( val mint: Mint, - val shortfall: Fiat? = null, - val fromDeeplink: Boolean = false, - // A normal stack PUSH (slide in, back arrow) rather than the wallet card-expand presentation - // (fade-in-place, ✕ dismiss). Set when the screen is reached by drilling in from a list — e.g. - // token discovery — where a back arrow that slides back is the expected navigation. - val asPush: Boolean = false, - // Pop back to whatever opened this screen once a buy of [mint] succeeds, rather than - // staying here. Set by a chat's gate: the reader came to buy their way into the group, - // so the purchase finishing is the moment to put them back in front of Join. - val returnAfterBuy: Boolean = false, + val entry: TokenInfoEntry = TokenInfoEntry.Wallet, ) : Token @Serializable diff --git a/apps/flipcash/core/src/main/kotlin/com/flipcash/app/core/tokens/TokenInfoEntry.kt b/apps/flipcash/core/src/main/kotlin/com/flipcash/app/core/tokens/TokenInfoEntry.kt new file mode 100644 index 0000000000..3fcc0b9cde --- /dev/null +++ b/apps/flipcash/core/src/main/kotlin/com/flipcash/app/core/tokens/TokenInfoEntry.kt @@ -0,0 +1,104 @@ +package com.flipcash.app.core.tokens + +import android.os.Parcelable +import com.getcode.solana.keys.Mint +import kotlinx.parcelize.Parcelize +import kotlinx.serialization.Serializable + +/** + * Where a currency-info screen was opened from. Each origin states how the screen is presented + * and what it does once a buy of its currency succeeds; [afterSwap] turns that into the step the + * screen takes when a swap it launched returns. + */ +@Serializable +@Parcelize +sealed interface TokenInfoEntry : Parcelable { + val presentation: TokenInfoPresentation + val afterBuy: AfterBuy + + /** The wallet, or any route that lands on a currency without a more specific origin. */ + @Serializable + data object Wallet : TokenInfoEntry { + override val presentation get() = TokenInfoPresentation.CardExpand + override val afterBuy get() = AfterBuy.Stay + } + + /** A token deeplink, opened or scanned. */ + @Serializable + data object Deeplink : TokenInfoEntry { + override val presentation get() = TokenInfoPresentation.CardExpand + override val afterBuy get() = AfterBuy.Stay + } + + /** Token discovery's list. */ + @Serializable + data object Discovery : TokenInfoEntry { + override val presentation get() = TokenInfoPresentation.Push + override val afterBuy get() = AfterBuy.Stay + } + + /** A currency mentioned in a chat transcript. */ + @Serializable + data object Chat : TokenInfoEntry { + override val presentation get() = TokenInfoPresentation.Push + override val afterBuy get() = AfterBuy.Stay + } + + /** + * A group chat's buy-in gate. The reader came to buy their way into the group, so the + * purchase finishing is the moment to put them back in front of Join. + */ + @Serializable + data object ChatGate : TokenInfoEntry { + override val presentation get() = TokenInfoPresentation.Push + override val afterBuy get() = AfterBuy.ReturnToOpener + } + + companion object { + /** Every origin. Covered by a test against the serializer's subclass list. */ + val all: List = listOf(Wallet, Deeplink, Discovery, Chat, ChatGate) + } +} + +enum class TokenInfoPresentation { + /** The wallet card grows into the screen in place; the screen leads with ✕. */ + CardExpand, + + /** An ordinary stack push: slides in, leads with a back arrow. */ + Push, +} + +enum class AfterBuy { + /** Stay on the currency's info screen. */ + Stay, + + /** Pop back to whatever opened the screen. */ + ReturnToOpener, +} + +/** The step a currency-info screen takes when a swap it launched returns. */ +enum class TokenInfoSwapOutcome { + Stay, + Pop, + OpenDeposit, +} + +/** + * The step to take when a swap launched from the info screen for [mint] returns [result]. + * + * [afterBuy] applies only to a buy of [mint] itself. Add Money from this screen also ends in a + * successful buy, but of USDF to fund this one, and the reader still has this purchase to make. + */ +fun TokenInfoEntry.afterSwap(mint: Mint, purpose: SwapPurpose, result: SwapResult): TokenInfoSwapOutcome = + when (result) { + SwapResult.OpenDeposit -> TokenInfoSwapOutcome.OpenDeposit + SwapResult.Canceled -> TokenInfoSwapOutcome.Stay + is SwapResult.Success -> { + val boughtThisCurrency = purpose is SwapPurpose.Buy && purpose.mint == mint + when { + !boughtThisCurrency -> TokenInfoSwapOutcome.Stay + afterBuy == AfterBuy.ReturnToOpener -> TokenInfoSwapOutcome.Pop + else -> TokenInfoSwapOutcome.Stay + } + } + } diff --git a/apps/flipcash/core/src/test/kotlin/com/flipcash/app/core/tokens/TokenInfoEntryTest.kt b/apps/flipcash/core/src/test/kotlin/com/flipcash/app/core/tokens/TokenInfoEntryTest.kt new file mode 100644 index 0000000000..7eb2c4ba57 --- /dev/null +++ b/apps/flipcash/core/src/test/kotlin/com/flipcash/app/core/tokens/TokenInfoEntryTest.kt @@ -0,0 +1,80 @@ +package com.flipcash.app.core.tokens + +import com.getcode.solana.keys.Mint +import kotlinx.serialization.descriptors.elementNames +import kotlin.test.Test +import kotlin.test.assertEquals + +class TokenInfoEntryTest { + + private val mint = Mint("EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v") + private val buyThis = SwapPurpose.Buy(mint) + private val success = SwapResult.Success() + + @Test + fun `all lists every origin`() { + // AppContent picks the transition from TokenInfoEntry.all, so an origin missing from it + // would silently get the card-expand transition. + val subclasses = TokenInfoEntry.serializer().descriptor.getElementDescriptor(1).elementNames.toSet() + assertEquals(subclasses, TokenInfoEntry.all.map { it::class.qualifiedName }.toSet()) + } + + @Test + fun `wallet and deeplink expand the card, list and chat origins push`() { + assertEquals( + mapOf( + TokenInfoEntry.Wallet to TokenInfoPresentation.CardExpand, + TokenInfoEntry.Deeplink to TokenInfoPresentation.CardExpand, + TokenInfoEntry.Discovery to TokenInfoPresentation.Push, + TokenInfoEntry.Chat to TokenInfoPresentation.Push, + TokenInfoEntry.ChatGate to TokenInfoPresentation.Push, + ), + TokenInfoEntry.all.associateWith { it.presentation }, + ) + } + + @Test + fun `buying this currency returns to the opener only from a chat gate`() { + assertEquals( + mapOf( + TokenInfoEntry.Wallet to TokenInfoSwapOutcome.Stay, + TokenInfoEntry.Deeplink to TokenInfoSwapOutcome.Stay, + TokenInfoEntry.Discovery to TokenInfoSwapOutcome.Stay, + TokenInfoEntry.Chat to TokenInfoSwapOutcome.Stay, + TokenInfoEntry.ChatGate to TokenInfoSwapOutcome.Pop, + ), + TokenInfoEntry.all.associateWith { it.afterSwap(mint, buyThis, success) }, + ) + } + + @Test + fun `adding money from a chat gate stays, since this currency is still unbought`() { + assertEquals( + TokenInfoSwapOutcome.Stay, + TokenInfoEntry.ChatGate.afterSwap(mint, SwapPurpose.Buy(Mint.usdf), success), + ) + } + + @Test + fun `selling or converting from a chat gate stays`() { + assertEquals(TokenInfoSwapOutcome.Stay, TokenInfoEntry.ChatGate.afterSwap(mint, SwapPurpose.Sell(mint), success)) + assertEquals( + TokenInfoSwapOutcome.Stay, + TokenInfoEntry.ChatGate.afterSwap(mint, SwapPurpose.Convert(mint, Mint.usdf), success), + ) + } + + @Test + fun `a canceled buy stays`() { + TokenInfoEntry.all.forEach { + assertEquals(TokenInfoSwapOutcome.Stay, it.afterSwap(mint, buyThis, SwapResult.Canceled)) + } + } + + @Test + fun `open deposit opens deposit from every origin`() { + TokenInfoEntry.all.forEach { + assertEquals(TokenInfoSwapOutcome.OpenDeposit, it.afterSwap(mint, buyThis, SwapResult.OpenDeposit)) + } + } +} diff --git a/apps/flipcash/features/discovery/src/main/kotlin/com/flipcash/app/discovery/TokenDiscoveryScreen.kt b/apps/flipcash/features/discovery/src/main/kotlin/com/flipcash/app/discovery/TokenDiscoveryScreen.kt index 93128ae817..3dbd5156f0 100644 --- a/apps/flipcash/features/discovery/src/main/kotlin/com/flipcash/app/discovery/TokenDiscoveryScreen.kt +++ b/apps/flipcash/features/discovery/src/main/kotlin/com/flipcash/app/discovery/TokenDiscoveryScreen.kt @@ -9,6 +9,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel import com.flipcash.app.core.AppRoute +import com.flipcash.app.core.tokens.TokenInfoEntry import com.flipcash.app.discovery.internal.TokenDiscoveryScreen import com.flipcash.app.discovery.internal.TokenDiscoveryViewModel import com.flipcash.core.R @@ -54,7 +55,7 @@ private fun TokenDiscoveryEventHandler(viewModel: TokenDiscoveryViewModel, navig viewModel.eventFlow .filterIsInstance() .map { it.mint } - .onEach { navigator.navigate(AppRoute.Token.Info(it, asPush = true)) } + .onEach { navigator.navigate(AppRoute.Token.Info(it, TokenInfoEntry.Discovery)) } .launchIn(this) } diff --git a/apps/flipcash/features/messenger/src/main/kotlin/com/flipcash/app/messenger/internal/screens/MessengerScreen.kt b/apps/flipcash/features/messenger/src/main/kotlin/com/flipcash/app/messenger/internal/screens/MessengerScreen.kt index 45fa0c2baf..f7dd700cc1 100644 --- a/apps/flipcash/features/messenger/src/main/kotlin/com/flipcash/app/messenger/internal/screens/MessengerScreen.kt +++ b/apps/flipcash/features/messenger/src/main/kotlin/com/flipcash/app/messenger/internal/screens/MessengerScreen.kt @@ -16,6 +16,7 @@ import androidx.paging.compose.collectAsLazyPagingItems import com.flipcash.app.core.AppRoute import com.flipcash.app.core.chat.ChatIdentifier import com.flipcash.app.core.chat.ChatStep +import com.flipcash.app.core.tokens.TokenInfoEntry import com.flipcash.app.messenger.internal.ChatSubject import com.flipcash.app.messenger.internal.ChatViewModel import com.flipcash.app.messenger.internal.screens.components.ChatTopBar @@ -75,8 +76,7 @@ internal fun MessengerScreen(viewModel: ChatViewModel) { // is no card here for it to grow from. AppRoute.Token.Info( action.mint, - asPush = true, - returnAfterBuy = action.returnAfterBuy, + if (action.returnAfterBuy) TokenInfoEntry.ChatGate else TokenInfoEntry.Chat, ) ) ) diff --git a/apps/flipcash/features/scanner/src/main/kotlin/com/flipcash/app/scanner/internal/Scanner.kt b/apps/flipcash/features/scanner/src/main/kotlin/com/flipcash/app/scanner/internal/Scanner.kt index c4e94487e1..d48645eb35 100644 --- a/apps/flipcash/features/scanner/src/main/kotlin/com/flipcash/app/scanner/internal/Scanner.kt +++ b/apps/flipcash/features/scanner/src/main/kotlin/com/flipcash/app/scanner/internal/Scanner.kt @@ -28,6 +28,7 @@ import com.flipcash.app.core.AppRoute.Token.* import com.flipcash.app.core.extensions.navigateAll import com.flipcash.app.core.navigation.DeeplinkType import com.flipcash.app.core.tipping.TipCardOwner +import com.flipcash.app.core.tokens.TokenInfoEntry import com.flipcash.app.router.LocalRouter import com.flipcash.app.scanner.internal.bills.ScannableContainer import com.flipcash.app.session.CodeScanEvent @@ -110,7 +111,7 @@ internal fun Scanner() { val routes: List = when (deeplink) { is DeeplinkType.TokenInfo -> listOf( AppRoute.Sheets.Wallet, - Info(deeplink.mint, fromDeeplink = true) + Info(deeplink.mint, TokenInfoEntry.Deeplink) ) // Scanned tip-DM code — same destination as the // /tip/chat/{id} deeplink. diff --git a/apps/flipcash/features/tokens/src/main/kotlin/com/flipcash/app/tokens/TokenInfoScreen.kt b/apps/flipcash/features/tokens/src/main/kotlin/com/flipcash/app/tokens/TokenInfoScreen.kt index 44734d4fc2..b3beef5b68 100644 --- a/apps/flipcash/features/tokens/src/main/kotlin/com/flipcash/app/tokens/TokenInfoScreen.kt +++ b/apps/flipcash/features/tokens/src/main/kotlin/com/flipcash/app/tokens/TokenInfoScreen.kt @@ -35,8 +35,11 @@ import com.flipcash.app.analytics.Analytics import com.flipcash.app.analytics.Button import com.flipcash.app.analytics.rememberAnalytics import com.flipcash.app.core.AppRoute -import com.flipcash.app.core.tokens.SwapPurpose import com.flipcash.app.core.tokens.SwapResult +import com.flipcash.app.core.tokens.TokenInfoEntry +import com.flipcash.app.core.tokens.TokenInfoPresentation +import com.flipcash.app.core.tokens.TokenInfoSwapOutcome +import com.flipcash.app.core.tokens.afterSwap import com.flipcash.app.tokens.internal.TokenInfoScreen import com.flipcash.app.tokens.internal.components.info.CurrencyInfoTitlePill import com.flipcash.app.tokens.ui.TokenInfoViewModel @@ -45,7 +48,6 @@ import com.flipcash.services.internal.model.thirdparty.OnRampProvider import com.getcode.navigation.core.LocalCodeNavigator import com.getcode.navigation.results.NavResultOrCanceled import com.getcode.navigation.results.navigateForResult -import com.getcode.opencode.model.financial.Fiat import com.getcode.solana.keys.Mint import com.getcode.theme.CodeTheme import com.getcode.ui.components.AppBarDefaults @@ -64,10 +66,7 @@ import kotlinx.coroutines.flow.onEach @Composable fun TokenInfoScreen( mint: Mint, - shortFall: Fiat?, - fromDeeplink: Boolean, - asPush: Boolean = false, - returnAfterBuy: Boolean = false, + entry: TokenInfoEntry, ) { val navigator = LocalCodeNavigator.current val analytics = rememberAnalytics() @@ -109,7 +108,7 @@ fun TokenInfoScreen( // Currency-info is a modal dismiss, not a true back nav — lead with a close (✕). But when // it was PUSHED onto the stack (e.g. drilled into from token discovery) it IS a back nav, so // lead with a back arrow instead. - leadingDismiss = !asPush, + leadingDismiss = entry.presentation == TokenInfoPresentation.CardExpand, hazeState = haze, endContent = { state.token.dataOrNull?.let { @@ -162,7 +161,7 @@ fun TokenInfoScreen( ) { topPadding -> TokenInfoScreen( viewModel = viewModel, - shortfall = shortFall, + shortfall = null, listState = listState, contentPadding = PaddingValues( top = topPadding, @@ -173,16 +172,18 @@ fun TokenInfoScreen( } LaunchedEffect(Unit) { - val source = when { - shortFall != null -> Analytics.TokenInfoSource.Give - fromDeeplink -> Analytics.TokenInfoSource.Deeplink - else -> Analytics.TokenInfoSource.Wallet + val source = when (entry) { + TokenInfoEntry.Deeplink -> Analytics.TokenInfoSource.Deeplink + TokenInfoEntry.Wallet, + TokenInfoEntry.Discovery, + TokenInfoEntry.Chat, + TokenInfoEntry.ChatGate -> Analytics.TokenInfoSource.Wallet } analytics.openTokenInfo(source = source, mint = mint) } LaunchedEffect(Unit) { - viewModel.dispatchEvent(TokenInfoViewModel.Event.OnMintProvided(mint, shortFall)) + viewModel.dispatchEvent(TokenInfoViewModel.Event.OnMintProvided(mint, null)) } LaunchedEffect(viewModel) { @@ -201,17 +202,11 @@ fun TokenInfoScreen( is AppRoute.Token.Swap -> { navigator.navigateForResult(screen) { result -> if (result !is NavResultOrCanceled.ReturnValue) return@navigateForResult - when (result.value) { - is SwapResult.OpenDeposit -> + when (entry.afterSwap(mint, screen.purpose, result.value)) { + TokenInfoSwapOutcome.OpenDeposit -> navigator.push(AppRoute.Transfers.Deposit(showOtherOptions = false)) - // Only a buy of this currency. Add Money from here also ends in a - // successful Buy, but of USDF to fund this one, and the reader - // still has this purchase to make. - is SwapResult.Success -> { - val bought = (screen.purpose as? SwapPurpose.Buy)?.mint - if (returnAfterBuy && bought == mint) navigator.pop() - } - else -> Unit + TokenInfoSwapOutcome.Pop -> navigator.pop() + TokenInfoSwapOutcome.Stay -> Unit } } } diff --git a/apps/flipcash/shared/router/src/main/kotlin/com/flipcash/app/router/internal/AppRouter.kt b/apps/flipcash/shared/router/src/main/kotlin/com/flipcash/app/router/internal/AppRouter.kt index 6379135b91..9411ffd1bc 100644 --- a/apps/flipcash/shared/router/src/main/kotlin/com/flipcash/app/router/internal/AppRouter.kt +++ b/apps/flipcash/shared/router/src/main/kotlin/com/flipcash/app/router/internal/AppRouter.kt @@ -13,6 +13,7 @@ import com.flipcash.app.core.navigation.fragments import com.flipcash.app.core.tokens.SwapPurpose import com.flipcash.app.core.verification.email.EmailDeeplinkOrigin import com.flipcash.app.core.tipping.TipCardOwner +import com.flipcash.app.core.tokens.TokenInfoEntry import com.flipcash.app.router.Router import com.flipcash.app.router.internal.AppRouter.Companion.cashLink import com.flipcash.app.router.internal.AppRouter.Companion.chat @@ -119,7 +120,7 @@ internal class AppRouter( mint = type.mint, routes = listOf( AppRoute.Sheets.Wallet, - AppRoute.Token.Info(type.mint, fromDeeplink = true), + AppRoute.Token.Info(type.mint, TokenInfoEntry.Deeplink), ), ) diff --git a/apps/flipcash/shared/router/src/test/kotlin/com/flipcash/app/router/internal/AppRouterTest.kt b/apps/flipcash/shared/router/src/test/kotlin/com/flipcash/app/router/internal/AppRouterTest.kt index 2c0887f17d..6914edec2e 100644 --- a/apps/flipcash/shared/router/src/test/kotlin/com/flipcash/app/router/internal/AppRouterTest.kt +++ b/apps/flipcash/shared/router/src/test/kotlin/com/flipcash/app/router/internal/AppRouterTest.kt @@ -7,6 +7,7 @@ import com.flipcash.app.core.navigation.DeeplinkAction import com.flipcash.app.core.navigation.DeeplinkType import com.flipcash.app.core.util.Linkify import com.flipcash.app.core.tipping.TipCardOwner +import com.flipcash.app.core.tokens.TokenInfoEntry import com.flipcash.services.models.chat.ChatId import com.flipcash.services.user.AuthState import com.getcode.opencode.model.core.ID @@ -341,7 +342,7 @@ class AppRouterTest { val tokenInfo = action.routes[1] assertIs(tokenInfo) assertEquals(Mint(mint), tokenInfo.mint) - assertTrue(tokenInfo.fromDeeplink) + assertEquals(TokenInfoEntry.Deeplink, tokenInfo.entry) } // endregion diff --git a/apps/flipcash/shared/router/src/test/kotlin/com/flipcash/app/router/internal/NavigateToTest.kt b/apps/flipcash/shared/router/src/test/kotlin/com/flipcash/app/router/internal/NavigateToTest.kt index e847c5c577..9ae91d888b 100644 --- a/apps/flipcash/shared/router/src/test/kotlin/com/flipcash/app/router/internal/NavigateToTest.kt +++ b/apps/flipcash/shared/router/src/test/kotlin/com/flipcash/app/router/internal/NavigateToTest.kt @@ -6,6 +6,7 @@ import com.flipcash.app.core.AppRoute import com.flipcash.app.core.extensions.navigateAll import com.flipcash.app.core.extensions.openAsSheet import com.flipcash.app.core.extensions.resolveRoutes +import com.flipcash.app.core.tokens.TokenInfoEntry import com.getcode.navigation.core.CodeNavigator import com.getcode.navigation.core.EmptyCodeNavigator import com.getcode.navigation.core.NavOptions @@ -167,12 +168,12 @@ class NavigateToTest { AppRoute.Main.Scanner, AppRoute.Main.Sheet( AppRoute.Sheets.ActivityHistory, - listOf(AppRoute.Token.Info(mint, fromDeeplink = true)), + listOf(AppRoute.Token.Info(mint, TokenInfoEntry.Deeplink)), ), ) navigator.navigateAll( - listOf(AppRoute.Sheets.ActivityHistory, AppRoute.Token.Info(mint, fromDeeplink = true)), + listOf(AppRoute.Sheets.ActivityHistory, AppRoute.Token.Info(mint, TokenInfoEntry.Deeplink)), options = quietOptions, ) diff --git a/apps/flipcash/shared/router/src/test/kotlin/com/flipcash/app/router/internal/ResolveRoutesTest.kt b/apps/flipcash/shared/router/src/test/kotlin/com/flipcash/app/router/internal/ResolveRoutesTest.kt index d236289719..93e7cfd542 100644 --- a/apps/flipcash/shared/router/src/test/kotlin/com/flipcash/app/router/internal/ResolveRoutesTest.kt +++ b/apps/flipcash/shared/router/src/test/kotlin/com/flipcash/app/router/internal/ResolveRoutesTest.kt @@ -6,6 +6,7 @@ import com.flipcash.app.core.extensions.resolveBackStack import com.flipcash.app.core.extensions.resolveRoutes import com.flipcash.app.core.chat.ChatIdentifier import com.flipcash.app.core.tokens.SwapPurpose +import com.flipcash.app.core.tokens.TokenInfoEntry import com.flipcash.services.models.chat.ChatId import com.getcode.solana.keys.Mint import org.junit.runner.RunWith @@ -53,7 +54,7 @@ class ResolveRoutesTest { fun `sheet with inner routes bundles into Main Sheet`() { val routes = listOf( AppRoute.Sheets.ActivityHistory, - AppRoute.Token.Info(mint, fromDeeplink = true), + AppRoute.Token.Info(mint, TokenInfoEntry.Deeplink), ) val resolved = resolveRoutes(routes) @@ -113,7 +114,7 @@ class ResolveRoutesTest { fun `resolved routes are structurally equal when inputs match`() { val routes = listOf( AppRoute.Sheets.ActivityHistory, - AppRoute.Token.Info(mint, fromDeeplink = true), + AppRoute.Token.Info(mint, TokenInfoEntry.Deeplink), ) val resolved1 = resolveRoutes(routes) @@ -141,7 +142,7 @@ class ResolveRoutesTest { fun `wallet tab stays flat and token info pushes on top`() { val routes = listOf( AppRoute.Sheets.Wallet, - AppRoute.Token.Info(mint, fromDeeplink = true), + AppRoute.Token.Info(mint, TokenInfoEntry.Deeplink), ) val resolved = resolveRoutes(routes) @@ -215,7 +216,7 @@ class ResolveRoutesTest { @Test fun `a token deeplink lands on the wallet tab exactly once`() { val base = listOf(AppRoute.Sheets.Wallet) - val deeplink = listOf(AppRoute.Sheets.Wallet, AppRoute.Token.Info(mint, fromDeeplink = true)) + val deeplink = listOf(AppRoute.Sheets.Wallet, AppRoute.Token.Info(mint, TokenInfoEntry.Deeplink)) val stack = resolveBackStack(base, deeplink) assertEquals(2, stack.size)