@@ -21,13 +21,15 @@ import androidx.compose.ui.platform.LocalContext
2121import androidx.compose.ui.res.stringResource
2222import androidx.compose.ui.text.style.TextAlign
2323import androidx.compose.ui.tooling.preview.Preview
24+ import androidx.compose.ui.tooling.preview.PreviewWrapper
2425import androidx.lifecycle.compose.collectAsStateWithLifecycle
2526import com.flipcash.app.balance.internal.components.BalanceHeader
2627import com.flipcash.app.core.AppRoute
2728import com.flipcash.app.core.tokens.TokenPurpose
2829import com.flipcash.app.theme.FlipcashPreview
2930import com.flipcash.app.tokens.ui.SelectTokenViewModel
3031import com.flipcash.app.core.ui.rememberTokenBalanceRowStyling
32+ import com.flipcash.app.theme.FlipcashThemeWrapper
3133import com.flipcash.app.tokens.ui.TokenList
3234import com.flipcash.features.balance.R
3335import com.getcode.opencode.compose.ExchangeStub
@@ -60,32 +62,39 @@ private fun BalanceScreenContent(
6062) {
6163 Column {
6264 val tokens = remember(tokenState.tokens) { tokenState.tokens }
65+ val isEmpty = tokens.orEmpty().isEmpty()
66+
67+ val headerContent: @Composable () -> Unit = {
68+ BalanceHeader (
69+ modifier = Modifier
70+ .fillMaxWidth(),
71+ balance = tokenState.totalBalance,
72+ appreciation = tokenState.aggregateAppreciation,
73+ ) {
74+ dispatchEvent(BalanceViewModel .Event .OpenCurrencySelection )
75+ }
76+
77+ Spacer (modifier = Modifier .padding(CodeTheme .dimens.grid.x2))
78+ }
6379
6480 TokenList (
6581 modifier = Modifier .weight(1f ),
6682 itemModifier = { Modifier .animateItem(fadeInSpec = null ) },
6783 styling = rememberTokenBalanceRowStyling(),
68- header = {
69- BalanceHeader (
70- modifier = Modifier
71- .fillMaxWidth(),
72- balance = tokenState.totalBalance,
73- appreciation = tokenState.aggregateAppreciation,
74- ) {
75- dispatchEvent(BalanceViewModel .Event .OpenCurrencySelection )
76- }
77-
78- Spacer (modifier = Modifier .padding(CodeTheme .dimens.grid.x2))
79- },
84+ // When empty, the header is rendered inside the empty state (pinned
85+ // to the top) so the prompt can be centered against the full
86+ // viewport. As a separate leading list item it would offset the
87+ // empty state down by the header's height.
88+ header = if (isEmpty) null else headerContent,
8089 emptyState = {
81- Box (
82- modifier = Modifier
83- .fillParentMaxSize()
84- .padding(bottom = CodeTheme .dimens.grid.x20),
85- contentAlignment = Alignment .Center
86- ) {
90+ Box (modifier = Modifier .fillParentMaxSize()) {
91+ Column (modifier = Modifier .align(Alignment .TopCenter )) {
92+ headerContent()
93+ }
94+
8795 Column (
8896 modifier = Modifier
97+ .align(Alignment .Center )
8998 .fillMaxWidth()
9099 .padding(horizontal = CodeTheme .dimens.inset),
91100 verticalArrangement = Arrangement .spacedBy(CodeTheme .dimens.grid.x2),
@@ -129,20 +138,30 @@ private fun BalanceScreenContent(
129138 }
130139 },
131140 pinFooter = true ,
132- footer = if (tokenState.discoveryEnabled ) {
141+ footer = if (tokenState.totalBalance?.nativeAmount?.hasDisplayableValue == true ) {
133142 {
134143 CodeButton (
135144 modifier = Modifier
136145 .fillMaxWidth()
137146 .padding(horizontal = CodeTheme .dimens.inset)
138147 .padding(bottom = CodeTheme .dimens.grid.x3)
139148 .navigationBarsPadding(),
140- text = stringResource(R .string.action_discoverCurrencies),
149+ text = if (addMoneyUx) {
150+ stringResource(R .string.action_addMoney)
151+ } else {
152+ stringResource(R .string.action_discoverCurrencies)
153+ },
141154 buttonState = ButtonState .Filled10 ,
142155 onClick = {
143- dispatchEvent(
144- BalanceViewModel .Event .OpenScreen (AppRoute .Token .Discovery )
145- )
156+ if (addMoneyUx) {
157+ dispatchEvent(
158+ BalanceViewModel .Event .PresentDepositOptions
159+ )
160+ } else {
161+ dispatchEvent(
162+ BalanceViewModel .Event .OpenScreen (AppRoute .Token .Discovery )
163+ )
164+ }
146165 }
147166 )
148167 }
@@ -163,27 +182,27 @@ private val cadUsdRate = Rate(fx = 1.371881, currency = CurrencyCode.CAD)
163182private val usdCadRate = Rate (fx = 1.0 / 1.371881 , currency = CurrencyCode .CAD )
164183
165184@Preview
185+ @PreviewWrapper(FlipcashThemeWrapper ::class )
166186@Composable
167187private fun Preview_BalanceScreen_Empty () {
168- FlipcashPreview {
169- CompositionLocalProvider (
170- LocalExchange provides ExchangeStub (
171- providedRates = mapOf (
172- CurrencyCode .CAD to cadUsdRate,
173- CurrencyCode .USD to usdCadRate
174- ),
175- context = LocalContext .current
188+ CompositionLocalProvider (
189+ LocalExchange provides ExchangeStub (
190+ providedRates = mapOf (
191+ CurrencyCode .CAD to cadUsdRate,
192+ CurrencyCode .USD to usdCadRate
176193 ),
177- ) {
178- Box (modifier = Modifier .background(CodeTheme .colors.background)) {
179- BalanceScreenContent (
180- tokenState = SelectTokenViewModel .State (
181- purpose = TokenPurpose .Balance ,
182- tokens = emptyList()
183- ),
184- dispatchEvent = {}
185- )
186- }
194+ context = LocalContext .current
195+ ),
196+ ) {
197+ Box (modifier = Modifier .background(CodeTheme .colors.background)) {
198+ BalanceScreenContent (
199+ addMoneyUx = true ,
200+ tokenState = SelectTokenViewModel .State (
201+ purpose = TokenPurpose .Balance ,
202+ tokens = emptyList()
203+ ),
204+ dispatchEvent = {}
205+ )
187206 }
188207 }
189208}
0 commit comments