Skip to content

Commit 643ee06

Browse files
committed
feat(discovery): replace bottom bar CTA with inline currency creator upsell card
Move the "Create Your Own Currency" action from a floating bottom bar button into an inline upsell card at the top of the token leaderboard. Adds a new shared CurrencyCreatorUpsellCard component with bill preview imagery and updates the balance screen button styling. Signed-off-by: Brandon McAnsh <git@bmcreations.dev>
1 parent 087d48d commit 643ee06

6 files changed

Lines changed: 130 additions & 35 deletions

File tree

29.4 KB
Loading

apps/flipcash/core/src/main/res/values/strings.xml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -494,7 +494,7 @@
494494
<string name="action_retry">Retry</string>
495495
<string name="error_unableToLoadChartData">Unable To Load</string>
496496

497-
<string name="title_discoverCurrencies">Currencies</string>
497+
<string name="title_discoverCurrencies">Discover Currencies</string>
498498
<string name="action_discoverCurrencies">Discover Currencies</string>
499499
<string name="title_discoverPopular">Popular</string>
500500
<string name="title_discoverNew">New</string>
@@ -508,6 +508,7 @@
508508
<string name="subtitle_discoverEmptyNew">No currencies have been created in the last week</string>
509509
<string name="subtitle_discoverEmptyPopular">No popular currencies right now</string>
510510
<string name="action_createYourOwnCurrency">Create Your Own Currency</string>
511+
<string name="subtitle_createYourOwnCurrency">Create a currency in minutes and immediately use it as cash</string>
511512
<string name="prompt_title_notYetAvailable">Not Yet Available</string>
512513
<string name="prompt_message_currencyCreateNotYetAvailable">Check back soon</string>
513514

apps/flipcash/features/balance/src/main/kotlin/com/flipcash/app/balance/internal/BalanceScreenContent.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,6 @@ private fun BalanceScreenContent(
119119
contentPadding = PaddingValues(),
120120
text = stringResource(R.string.action_discoverCurrencies),
121121
shape = CircleShape,
122-
buttonState = ButtonState.Filled
123122
)
124123
}
125124
}
@@ -144,6 +143,7 @@ private fun BalanceScreenContent(
144143
.padding(bottom = CodeTheme.dimens.grid.x3)
145144
.navigationBarsPadding(),
146145
text = stringResource(R.string.action_discoverCurrencies),
146+
buttonState = ButtonState.Filled10,
147147
onClick = {
148148
dispatchEvent(
149149
BalanceViewModel.Event.OpenScreen(AppRoute.Token.Discovery)

apps/flipcash/features/discovery/src/main/kotlin/com/flipcash/app/discovery/internal/TokenDiscoveryScreenContent.kt

Lines changed: 1 addition & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -60,39 +60,7 @@ private fun TokenDiscoveryScreenContent(
6060
dispatch: (TokenDiscoveryViewModel.Event) -> Unit
6161
) {
6262
val listState = rememberLazyListState()
63-
CodeScaffold(
64-
bottomBar = {
65-
if (state.createEnabled) {
66-
Box {
67-
var buttonHeight by remember { mutableStateOf(0.dp) }
68-
Box(
69-
modifier = Modifier
70-
.fillMaxWidth()
71-
.height(buttonHeight)
72-
.drawWithGradient(
73-
color = CodeTheme.colors.background,
74-
startY = { 0f },
75-
endY = { size.height * 0.38f }
76-
)
77-
)
78-
CodeButton(
79-
modifier = Modifier
80-
.fillMaxWidth()
81-
.measured { buttonHeight = it.height }
82-
.navigationBarsPadding()
83-
.padding(horizontal = CodeTheme.dimens.inset)
84-
.padding(
85-
top = CodeTheme.dimens.grid.x9,
86-
bottom = CodeTheme.dimens.grid.x3
87-
),
88-
text = stringResource(R.string.action_createYourOwnCurrency),
89-
) {
90-
dispatch(TokenDiscoveryViewModel.Event.CreateCurrency)
91-
}
92-
}
93-
}
94-
},
95-
) { padding ->
63+
CodeScaffold { padding ->
9664
AnimatedContent(
9765
targetState = state.tokens,
9866
transitionSpec = { fadeIn(tween()) togetherWith fadeOut(tween()) },

apps/flipcash/features/discovery/src/main/kotlin/com/flipcash/app/discovery/internal/components/TokenLeaderboard.kt

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import androidx.compose.ui.unit.dp
2222
import com.flipcash.app.core.data.Loadable
2323
import com.flipcash.app.core.data.isLoaded
2424
import com.flipcash.app.discovery.internal.TokenDiscoveryViewModel
25+
import com.flipcash.app.tokens.ui.CurrencyCreatorUpsellCard
2526
import com.flipcash.features.discovery.R
2627
import com.getcode.opencode.model.financial.Token
2728
import com.getcode.opencode.model.ui.DiscoverCategory
@@ -103,6 +104,13 @@ internal fun TokenLeaderboard(
103104

104105
is Loadable.Loaded -> {
105106
val results = tokens.data
107+
// currency creator upsell card
108+
item {
109+
CurrencyCreatorUpsellCard(modifier = Modifier.fillParentMaxWidth()) {
110+
dispatch(TokenDiscoveryViewModel.Event.CreateCurrency)
111+
}
112+
}
113+
106114
if (results.isEmpty()) {
107115
item {
108116
Box(
@@ -135,6 +143,19 @@ internal fun TokenLeaderboard(
135143
}
136144
}
137145
} else {
146+
// leaderboard header
147+
item {
148+
Text(
149+
modifier = Modifier.padding(
150+
top = CodeTheme.dimens.inset,
151+
bottom = CodeTheme.dimens.grid.x1,
152+
),
153+
text = "Leaderboard",
154+
style = CodeTheme.typography.textLarge,
155+
color = CodeTheme.colors.textMain,
156+
)
157+
}
158+
138159
itemsIndexed(
139160
items = tokens.data,
140161
key = { _, t -> t.address.base58() },
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
package com.flipcash.app.tokens.ui
2+
3+
import androidx.compose.foundation.Image
4+
import androidx.compose.foundation.layout.Arrangement
5+
import androidx.compose.foundation.layout.Box
6+
import androidx.compose.foundation.layout.Column
7+
import androidx.compose.foundation.layout.Row
8+
import androidx.compose.foundation.layout.fillMaxWidth
9+
import androidx.compose.foundation.layout.padding
10+
import androidx.compose.foundation.layout.requiredSize
11+
import androidx.compose.material.icons.Icons
12+
import androidx.compose.material.icons.automirrored.filled.ArrowForward
13+
import androidx.compose.material3.Icon
14+
import androidx.compose.material3.Surface
15+
import androidx.compose.material3.Text
16+
import androidx.compose.runtime.Composable
17+
import androidx.compose.runtime.getValue
18+
import androidx.compose.runtime.mutableStateOf
19+
import androidx.compose.runtime.remember
20+
import androidx.compose.runtime.setValue
21+
import androidx.compose.ui.Alignment
22+
import androidx.compose.ui.Modifier
23+
import androidx.compose.ui.layout.onSizeChanged
24+
import androidx.compose.ui.platform.LocalDensity
25+
import androidx.compose.ui.res.painterResource
26+
import androidx.compose.ui.res.stringResource
27+
import androidx.compose.ui.tooling.preview.Preview
28+
import androidx.compose.ui.tooling.preview.PreviewWrapper
29+
import androidx.compose.ui.unit.dp
30+
import com.flipcash.app.theme.FlipcashThemeWrapper
31+
import com.flipcash.shared.tokens.R
32+
import com.getcode.theme.CodeTheme
33+
34+
@Composable
35+
fun CurrencyCreatorUpsellCard(
36+
modifier: Modifier = Modifier,
37+
onClick: () -> Unit,
38+
) {
39+
Surface(
40+
modifier = modifier,
41+
color = CodeTheme.colors.surfaceVariant,
42+
contentColor = CodeTheme.colors.textMain,
43+
shape = CodeTheme.shapes.medium,
44+
tonalElevation = 0.dp,
45+
shadowElevation = 0.dp,
46+
onClick = onClick
47+
) {
48+
Box(modifier = Modifier.fillMaxWidth()) {
49+
val density = LocalDensity.current
50+
var imageWidth by remember { mutableStateOf(0.dp) }
51+
52+
Column(
53+
modifier = Modifier
54+
.fillMaxWidth()
55+
.padding(
56+
start = CodeTheme.dimens.grid.x3,
57+
top = CodeTheme.dimens.grid.x3,
58+
),
59+
verticalArrangement = Arrangement.spacedBy(CodeTheme.dimens.grid.x1),
60+
) {
61+
Row(
62+
modifier = Modifier.fillMaxWidth(),
63+
verticalAlignment = Alignment.CenterVertically,
64+
horizontalArrangement = Arrangement.spacedBy(CodeTheme.dimens.grid.x2)
65+
) {
66+
Text(
67+
text = stringResource(R.string.action_createYourOwnCurrency),
68+
style = CodeTheme.typography.screenTitle,
69+
color = CodeTheme.colors.textMain,
70+
)
71+
Icon(
72+
modifier = Modifier.requiredSize(CodeTheme.dimens.staticGrid.x4),
73+
imageVector = Icons.AutoMirrored.Default.ArrowForward,
74+
contentDescription = null,
75+
tint = CodeTheme.colors.textMain,
76+
)
77+
}
78+
79+
Text(
80+
modifier = Modifier.padding(end = imageWidth),
81+
text = stringResource(R.string.subtitle_createYourOwnCurrency),
82+
style = CodeTheme.typography.textSmall,
83+
color = CodeTheme.colors.textSecondary,
84+
)
85+
}
86+
87+
Image(
88+
modifier = Modifier
89+
.align(Alignment.BottomEnd)
90+
.onSizeChanged { size ->
91+
imageWidth = with(density) { size.width.toDp() }
92+
},
93+
painter = painterResource(R.drawable.ic_bill_previews),
94+
contentDescription = null,
95+
)
96+
}
97+
}
98+
}
99+
100+
@Preview
101+
@PreviewWrapper(FlipcashThemeWrapper::class)
102+
@Composable
103+
private fun Preview_CurrencyCreatorUpsellCard() {
104+
CurrencyCreatorUpsellCard() { }
105+
}

0 commit comments

Comments
 (0)