Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
f4ad670
fix(services): keep chat holdings summary in mint quarks
bmc08gt Oct 27, 2026
19dbc45
feat(tokens): load top community chats and add More sheet to token info
bmc08gt Oct 27, 2026
66ebf91
feat(share): add Share <name> to chats sheet for currency links
bmc08gt Oct 27, 2026
fe7b9dc
feat(cash): give a preset amount straight to the bill
bmc08gt Oct 27, 2026
a03aa9f
feat(messenger): send a currency to a DM recipient from Currency Info
bmc08gt Oct 27, 2026
b26634c
feat(tokens): Send, Transactions and More tiles, top community chats …
bmc08gt Oct 27, 2026
59d9585
fix(messenger): drop handle line from send recipient rows, avoid doub…
bmc08gt Oct 27, 2026
15ed514
fix(tokens): show community chat holdings as fiat, keep member count …
bmc08gt Oct 27, 2026
d980f70
fix(messenger): let the send confirmation sheet be dismissed, drop mo…
bmc08gt Oct 27, 2026
e31a8d9
fix(tokens): 24dp action tile icons, drop sub-cent fraction in commun…
bmc08gt Oct 27, 2026
3a44682
fix(messenger): hide the send sheet before leaving Currency Info
bmc08gt Oct 27, 2026
a6c69a9
feat(tokens): show About above the market cap chart
bmc08gt Oct 27, 2026
37db641
fix(messenger): match Select Recipient row sizing to the design
bmc08gt Oct 27, 2026
dfee166
feat(messenger): scroll Select Recipient under a haze button with pro…
bmc08gt Oct 27, 2026
9f6d649
feat(tokens): card rows for View All chats; share completion shared b…
bmc08gt Oct 27, 2026
198c287
feat(tokens): per-token Deposit from More; Dollars Deposit opens the …
bmc08gt Oct 27, 2026
03c429f
test(messenger): cover sheet hide before navigating back
bmc08gt Oct 27, 2026
fcccd6b
feat(tokens): Dollars Deposit opens the add-money options
bmc08gt Oct 27, 2026
50511d1
refactor(payments): hold payment success for one second, matching iOS
bmc08gt Oct 27, 2026
512ce2c
refactor(payments): add holdPaymentSuccess and use it on send and pay…
bmc08gt Oct 28, 2026
a986836
fix(currency-send): push Select Recipient over the amount instead of …
bmc08gt Oct 28, 2026
3d82eb7
feat(currency-send): present the bill over the recipient list; use hi…
bmc08gt Oct 28, 2026
3dd816f
fix(currency-info): card rows for community chats and design-matched …
bmc08gt Oct 28, 2026
d053d95
refactor(currency-info): use grid tokens for spacing and sizes
bmc08gt Oct 28, 2026
637d330
refactor(currency-info): spacing and heights on grid, images on stati…
bmc08gt Oct 28, 2026
f87d65e
fix(currency-info): match Figma sizes, weights and colours on the sen…
bmc08gt Oct 28, 2026
8db00d1
fix(currency-send): progressive blur under Give As Cash, Figma search…
bmc08gt Oct 28, 2026
e0deba8
feat(currency-info): progressive blur at the bottom edge
bmc08gt Oct 28, 2026
952d445
fix(currency-info): use theme text styles instead of Figma Regular
bmc08gt Oct 28, 2026
9a6889c
fix(currency-info): small text for About and footer
bmc08gt Oct 28, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,13 @@ import com.flipcash.app.currency.RegionSelectionScreen
import com.flipcash.app.deposit.DepositFlowScreen
import com.flipcash.app.invite.InviteContactScreen
import com.flipcash.app.messenger.ChatFlowScreen
import com.flipcash.app.tokens.internal.CommunityChatsScreen
import com.flipcash.app.messenger.CurrencySendScreen
import com.flipcash.app.messenger.E2eeLearnMoreScreen
import com.flipcash.app.messenger.MuteChatScreen
import com.flipcash.app.messenger.ProfileScreen
import com.flipcash.app.messenger.SharePickerScreen
import com.flipcash.app.messenger.ShareCurrencyToChatsScreen
import com.flipcash.app.messenger.ShareProfileToChatsScreen
import com.flipcash.app.messenger.ReportFlowScreen
import com.flipcash.app.discovery.TokenDiscoveryScreen
Expand Down Expand Up @@ -124,7 +127,8 @@ internal fun appEntryProvider(

// Sheets (inner content — wrapped in Main.Sheet by navigateTo())
// Route type is `Give` but the screen is the Cash/Give screen the flows call cash_screen.
annotatedEntry<AppRoute.Sheets.Give>(testTag = "cash_screen") { key -> CashScreen(key.mint, key.fromTokenInfo) }
annotatedEntry<AppRoute.Sheets.CurrencySend>(testTag = "currency_send_screen") { key -> CurrencySendScreen(key.mint, resultStateRegistry) }
annotatedEntry<AppRoute.Sheets.Give>(testTag = "cash_screen") { key -> CashScreen(key.mint, key.fromTokenInfo, key.amount) }
annotatedEntry<AppRoute.Sheets.TokenSelection> { key -> TokenSelectScreen(key.purpose) }
annotatedEntry<AppRoute.Sheets.ShareApp> { ShareAppScreen() }
annotatedEntry<AppRoute.Sheets.ActivityHistory> { ActivityHistoryScreen() }
Expand Down Expand Up @@ -169,6 +173,7 @@ internal fun appEntryProvider(
}
annotatedEntry<AppRoute.Messaging.SharePicker> { SharePickerScreen() }
annotatedEntry<AppRoute.Messaging.ShareProfileToChats> { key -> ShareProfileToChatsScreen(key) }
annotatedEntry<AppRoute.Messaging.ShareCurrencyToChats> { key -> ShareCurrencyToChatsScreen(key) }
annotatedEntry<AppRoute.Messaging.MuteChat> { key -> MuteChatScreen(key.chatId, key.chatType) }
annotatedEntry<AppRoute.Messaging.E2eeDmInfo> { E2eeLearnMoreScreen(forGroup = false) }
annotatedEntry<AppRoute.Messaging.E2eeGroupInfo> { E2eeLearnMoreScreen(forGroup = true) }
Expand All @@ -183,6 +188,7 @@ internal fun appEntryProvider(
annotatedEntry<AppRoute.Token.Transactions>(testTag = "transaction_history_screen") { key ->
TransactionHistoryScreen(key.mint)
}
annotatedEntry<AppRoute.Token.CommunityChats>(testTag = "community_chats_screen") { key -> CommunityChatsScreen(key.mint) }
annotatedEntry<AppRoute.Token.MarketCapExplainer>(testTag = "market_cap_explainer_screen") { key ->
MarketCapExplainerScreen(key.mint)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ fun TokenSelectionPill(
),
textStyle: TextStyle = CodeTheme.typography.screenTitle,
imageSize: Dp = CodeTheme.dimens.staticGrid.x5,
// False draws the currency alone, with no dropdown mark and nothing to tap, for a flow that is
// locked to one currency.
showsPicker: Boolean = true,
onClick: () -> Unit
) {
// [contentPadding] only applies when a background is supplied, so call sites without one
Expand All @@ -45,7 +48,7 @@ fun TokenSelectionPill(
modifier = modifier
.clip(CircleShape)
.background(color = background, shape = CircleShape)
.clickable { onClick() }
.clickable(enabled = showsPicker) { onClick() }
.then(if (hasBackground) Modifier.padding(contentPadding) else Modifier),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(
Expand All @@ -61,12 +64,14 @@ fun TokenSelectionPill(
textStyle = textStyle,
)

Image(
modifier = Modifier
.size(CodeTheme.dimens.grid.x4),
painter = painterResource(R.drawable.ic_dropdown),
contentDescription = ""
)
if (showsPicker) {
Image(
modifier = Modifier
.size(CodeTheme.dimens.grid.x4),
painter = painterResource(R.drawable.ic_dropdown),
contentDescription = ""
)
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,22 @@ sealed interface AppRoute : NavKey, Parcelable {
@Serializable
data class TokenSelection(val purpose: TokenPurpose) : Sheets
@Serializable
data class Give(val mint: Mint? = null, val fromTokenInfo: Boolean = false) : Sheets
data class Give(
val mint: Mint? = null,
val fromTokenInfo: Boolean = false,
/**
* An amount in the viewer's preferred currency to give as-is. When set, the screen
* skips its own amount entry and goes straight to the bill.
*/
val amount: Double? = null,
) : Sheets

/**
* Send from Currency Info: an amount of [mint], then a recipient from the viewer's DMs.
* Dismisses back to Currency Info after the send.
*/
@Serializable
data class CurrencySend(val mint: Mint) : Sheets

/** Full unified paged activity history — the "dive in" from the wallet's recent-activity preview. */
@Serializable
Expand Down Expand Up @@ -230,6 +245,9 @@ sealed interface AppRoute : NavKey, Parcelable {
data class Transactions(val mint: Mint) : Token
@Serializable
data class MarketCapExplainer(val mint: Mint) : Token
/** "Top Community Chats": View All from Currency Info. */
@Serializable
data class CommunityChats(val mint: Mint) : Token
@Serializable
data class Swap(
val purpose: SwapPurpose,
Expand Down Expand Up @@ -284,9 +302,14 @@ sealed interface AppRoute : NavKey, Parcelable {
@Parcelize
sealed interface Transfers : AppRoute {
@Serializable
data class Deposit(val showOtherOptions: Boolean = true): Transfers, FlowRouteWithResult<DepositResult> {
data class Deposit(
val showOtherOptions: Boolean = true,
/** When set, opens straight on that currency's deposit address instead of the USDC intro. */
val mint: Mint? = null,
): Transfers, FlowRouteWithResult<DepositResult> {
override val initialStack: List<NavKey>
get() = listOf(DepositStep.UsdcInformational(showOtherOptions))
get() = mint?.let { listOf(DepositStep.Destination(it)) }
?: listOf(DepositStep.UsdcInformational(showOtherOptions))
}

/**
Expand Down Expand Up @@ -549,6 +572,14 @@ sealed interface AppRoute : NavKey, Parcelable {
val directChatId: ChatId?,
) : Messaging, com.getcode.navigation.Sheet, com.getcode.navigation.FullscreenSheet

/** "Share <name>" from Currency Info: the page link shared, copied, or sent into recent chats. */
@Serializable
@Parcelize
data class ShareCurrencyToChats(
val mint: Mint,
val name: String,
) : Messaging, com.getcode.navigation.Sheet, com.getcode.navigation.FullscreenSheet

/**
* What end-to-end encryption covers in a DM, opened from the DM profile's footer. A
* [com.getcode.navigation.WrapContentSheet], for the reason [MuteChat] is one.
Expand Down
12 changes: 12 additions & 0 deletions apps/flipcash/core/src/main/res/drawable/ic_currency_buy.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M9,8V6C9,5.20435 9.31607,4.44129 9.87868,3.87868C10.4413,3.31607 11.2044,3 12,3C12.7956,3 13.5587,3.31607 14.1213,3.87868C14.6839,4.44129 15,5.20435 15,6V8M6,7H18L19,20H5L6,7Z"
android:strokeColor="#FFFFFF"
android:strokeWidth="1.6"
android:strokeLineCap="round"
android:strokeLineJoin="round" />
</vector>
18 changes: 18 additions & 0 deletions apps/flipcash/core/src/main/res/drawable/ic_currency_send.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:pathData="M21,3L14,21L10,14L3,10L21,3Z"
android:strokeColor="#FFFFFF"
android:strokeWidth="1.6"
android:strokeLineCap="round"
android:strokeLineJoin="round" />
<path
android:pathData="M10,14L21,3"
android:strokeColor="#FFFFFF"
android:strokeWidth="1.6"
android:strokeLineCap="round"
android:strokeLineJoin="round" />
</vector>
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<!-- Material Symbols "history" (Apache 2.0). -->
<path
android:pathData="M13,3c-4.97,0 -9,4.03 -9,9L1,12l3.89,3.89 0.07,0.14L9,12L6,12c0,-3.87 3.13,-7 7,-7s7,3.13 7,7 -3.13,7 -7,7c-1.93,0 -3.68,-0.79 -4.94,-2.06l-1.42,1.42C8.27,19.99 10.51,21 13,21c4.97,0 9,-4.03 9,-9s-4.03,-9 -9,-9zM12,8v5l4.28,2.54 0.72,-1.21 -3.5,-2.08L13.5,8L12,8z"
android:fillColor="#FFFFFF" />
</vector>
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="28dp"
android:height="28dp"
android:viewportWidth="28"
android:viewportHeight="28">
<path
android:fillColor="#FFFFFF"
android:pathData="M5.25,12.25a1.75,1.75 0,1 0,0 3.5a1.75,1.75 0,1 0,0 -3.5ZM14,12.25a1.75,1.75 0,1 0,0 3.5a1.75,1.75 0,1 0,0 -3.5ZM22.75,12.25a1.75,1.75 0,1 0,0 3.5a1.75,1.75 0,1 0,0 -3.5Z" />
</vector>
10 changes: 10 additions & 0 deletions apps/flipcash/core/src/main/res/drawable/ic_transactions.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="28dp"
android:height="28dp"
android:viewportWidth="28"
android:viewportHeight="28">
<path
android:fillColor="#FFFFFF"
android:fillType="evenOdd"
android:pathData="M5.25,7a0.875,0.875 0,0 1,0.875 -0.875h15.75a0.875,0.875 0,0 1,0 1.75H6.125A0.875,0.875 0,0 1,5.25 7ZM5.25,14a0.875,0.875 0,0 1,0.875 -0.875h15.75a0.875,0.875 0,0 1,0 1.75H6.125A0.875,0.875 0,0 1,5.25 14ZM5.25,21a0.875,0.875 0,0 1,0.875 -0.875h15.75a0.875,0.875 0,0 1,0 1.75H6.125A0.875,0.875 0,0 1,5.25 21Z" />
</vector>
24 changes: 24 additions & 0 deletions apps/flipcash/core/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
<string name="subtitle_giveCashHintLimitExceeded">You can only give up to %1$s</string>

<string name="subtitle_sendHint">Enter up to %1$s</string>
<string name="subtitle_currencySendAvailable">%1$s available</string>
<string name="subtitle_sendHintLimitExceeded">You can only send up to %1$s</string>

<string name="error_title_sendLimitReached">Transaction Limit Reached</string>
Expand Down Expand Up @@ -1858,4 +1859,27 @@
<item quantity="other">%1$s and %2$d others reacted</item>
</plurals>
<string name="alert_someone">Someone</string>
<string name="action_more">More</string>
<string name="action_transactions">Transactions</string>
<string name="action_orGiveAsCash">Or Give As Cash</string>
<string name="subtitle_moreConvert">Convert %1$s to another community currency on Flipcash</string>
<string name="subtitle_moreWithdraw">Withdraw %1$s to a different Solana crypto wallet</string>
<string name="subtitle_moreDeposit">Deposit %1$s from a different Solana crypto wallet</string>
<string name="title_topCommunityChats">Top Community Chats</string>
<string name="action_viewAll">View All</string>
<string name="title_howChatsAreRanked">How Chats Are Ranked</string>
<string name="description_howChatsAreRanked">Chats are ranked by the total amount of %1$s held by their members. Chats with higher combined holdings appear higher</string>
<string name="action_ok">OK</string>
<plurals name="subtitle_communityChatHoldings">
<item quantity="one">%1$s of %2$s held by %3$d member</item>
<item quantity="other">%1$s of %2$s held by %3$d members</item>
</plurals>
<plurals name="subtitle_communityChatMembers">
<item quantity="one">%1$d member</item>
<item quantity="other">%1$d members</item>
</plurals>
<string name="error_description_currencySendStaleRates">Couldn\'t get a fresh rate. Please try again</string>
<string name="title_selectRecipient">Select Recipient</string>
<string name="title_shareCurrency">Share %1$s</string>
<string name="title_recentChats">Recent Chats</string>
</resources>
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.flipcash.app.cash

import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
Expand All @@ -22,6 +23,7 @@ import com.getcode.solana.keys.Mint
import com.getcode.ui.components.AppBarDefaults
import com.getcode.ui.components.AppBarWithTitle
import kotlinx.coroutines.flow.filterIsInstance
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.onEach
Expand All @@ -30,6 +32,8 @@ import kotlinx.coroutines.flow.onEach
fun CashScreen(
selectedMint: Mint?,
fromTokenInfo: Boolean,
// Set when another screen already collected the amount: the bill is made for it, with no entry.
presetAmount: Double? = null,
) {
val navigator = LocalCodeNavigator.current
val session = LocalSessionController.current!!
Expand All @@ -53,7 +57,18 @@ fun CashScreen(
.launchIn(this)
}

Column(
if (presetAmount != null) {
// The entry is never shown: once the token and currency have loaded, type the amount into
// the delegate and give, the same path the Next button takes.
LaunchedEffect(viewModel, presetAmount) {
viewModel.stateFlow
.first { it.token != null && it.currencyModel.selected != null }
viewModel.amountDelegate.state.first { it.currency.selected != null }
viewModel.amountDelegate.prefill(presetAmount)
viewModel.dispatchEvent(CashScreenViewModel.Event.OnGive)
}
Box(modifier = Modifier.fillMaxSize())
} else Column(
modifier = Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -541,7 +541,6 @@ private fun FlowShareMessageSheet(messageId: Long) {
inviteUrl = link,
subject = ShareToChatsSubject.Message,
state = inviteState,
onShare = {},
onCopy = { viewModel.dispatchEvent(ChatViewModel.Event.CopyMessageLink(messageId)) },
onToggle = inviteViewModel::toggle,
onMessageChanged = inviteViewModel::onMessageChanged,
Expand Down
Loading
Loading