11package com.flipcash.app.balance.internal
22
3+ import androidx.compose.foundation.background
4+ import androidx.compose.foundation.layout.Arrangement
5+ import androidx.compose.foundation.layout.Box
36import androidx.compose.foundation.layout.Column
47import androidx.compose.foundation.layout.Spacer
58import androidx.compose.foundation.layout.WindowInsets
69import androidx.compose.foundation.layout.fillMaxWidth
710import androidx.compose.foundation.layout.navigationBars
11+ import androidx.compose.foundation.layout.padding
812import androidx.compose.foundation.layout.windowInsetsPadding
913import androidx.compose.foundation.lazy.LazyColumn
1014import androidx.compose.foundation.lazy.itemsIndexed
1115import androidx.compose.foundation.lazy.rememberLazyListState
1216import androidx.compose.material.Divider
17+ import androidx.compose.material.Text
1318import androidx.compose.runtime.Composable
19+ import androidx.compose.runtime.CompositionLocalProvider
1420import androidx.compose.runtime.collectAsState
1521import androidx.compose.runtime.getValue
22+ import androidx.compose.ui.Alignment
1623import androidx.compose.ui.Modifier
24+ import androidx.compose.ui.platform.LocalContext
25+ import androidx.compose.ui.text.style.TextAlign
26+ import androidx.compose.ui.tooling.preview.Preview
27+ import androidx.paging.LoadState
28+ import androidx.paging.PagingData
29+ import androidx.paging.compose.LazyPagingItems
1730import androidx.paging.compose.collectAsLazyPagingItems
1831import androidx.paging.compose.itemKey
1932import cafe.adriel.voyager.core.registry.ScreenRegistry
2033import com.flipcash.app.balance.internal.components.BalanceHeader
2134import com.flipcash.app.balance.internal.components.FeedItem
2235import com.flipcash.app.core.NavScreenProvider
36+ import com.flipcash.app.core.feed.ActivityFeedMessage
2337import com.flipcash.app.core.money.CurrencySelectionKind
38+ import com.flipcash.app.core.transfers.TransferDirection
39+ import com.flipcash.app.theme.FlipcashDesignSystem
2440import com.getcode.navigation.core.LocalCodeNavigator
41+ import com.getcode.opencode.compose.ExchangeStub
42+ import com.getcode.opencode.compose.LocalExchange
43+ import com.getcode.opencode.model.financial.CurrencyCode
44+ import com.getcode.opencode.model.financial.LocalFiat
45+ import com.getcode.opencode.model.financial.Rate
46+ import com.getcode.opencode.model.financial.toFiat
2547import com.getcode.theme.CodeTheme
2648import com.getcode.ui.core.verticalScrollStateGradient
49+ import com.getcode.ui.theme.ButtonState
50+ import com.getcode.ui.theme.CodeButton
51+ import kotlinx.coroutines.flow.flowOf
52+ import kotlin.collections.emptyList
2753
2854@Composable
29- internal fun BalanceScreenContent (viewModel : BalanceViewModel ) {
55+ internal fun BalanceScreen (viewModel : BalanceViewModel ) {
3056 val state by viewModel.stateFlow.collectAsState()
31- val navigator = LocalCodeNavigator .current
32-
3357 val feed = viewModel.feed.collectAsLazyPagingItems()
3458
59+ BalanceScreenContent (
60+ state = state,
61+ feed = feed,
62+ dispatchEvent = viewModel::dispatchEvent
63+ )
64+ }
65+
66+ @Composable
67+ private fun BalanceScreenContent (
68+ state : BalanceViewModel .State ,
69+ feed : LazyPagingItems <ActivityFeedMessage >,
70+ dispatchEvent : (BalanceViewModel .Event ) -> Unit
71+ ) {
3572 Column {
3673 BalanceHeader (
3774 modifier = Modifier
3875 .fillMaxWidth(),
3976 balance = state.balance
4077 ) {
41- navigator.push( ScreenRegistry .get( NavScreenProvider . HomeScreen . CurrencySelection ( CurrencySelectionKind . Balance )) )
78+ dispatchEvent( BalanceViewModel . Event . OpenCurrencySelection )
4279 }
4380
44- val listState = rememberLazyListState()
45- LazyColumn (
46- modifier = Modifier
47- .weight(1f )
48- .verticalScrollStateGradient(
49- scrollState = listState,
50- color = CodeTheme .colors.background,
51- showAtEnd = true
52- ),
53- state = listState
54- ) {
81+ FeedList (
82+ modifier = Modifier .weight(1f ),
83+ state = state,
84+ feed = feed,
85+ dispatchEvent = dispatchEvent
86+ )
87+ }
88+ }
89+
90+ @Composable
91+ private fun FeedList (
92+ modifier : Modifier = Modifier ,
93+ state : BalanceViewModel .State ,
94+ feed : LazyPagingItems <ActivityFeedMessage >,
95+ dispatchEvent : (BalanceViewModel .Event ) -> Unit
96+ ) {
97+ val listState = rememberLazyListState()
98+ LazyColumn (
99+ modifier = modifier
100+ .verticalScrollStateGradient(
101+ scrollState = listState,
102+ color = CodeTheme .colors.background,
103+ showAtEnd = true
104+ ),
105+ state = listState
106+ ) {
107+ if (feed.itemCount == 0 && feed.loadState.append is LoadState .NotLoading ) {
108+ item {
109+ Box (
110+ modifier = Modifier .fillParentMaxSize().padding(bottom = CodeTheme .dimens.inset),
111+ contentAlignment = Alignment .Center
112+ ) {
113+ Column (
114+ modifier = Modifier .fillMaxWidth().padding(horizontal = CodeTheme .dimens.inset),
115+ verticalArrangement = Arrangement .spacedBy(CodeTheme .dimens.grid.x6)
116+ ) {
117+ Text (
118+ modifier = Modifier .fillMaxWidth(),
119+ text = " Ask a friend to give you some Flipcash, or deposit USDC from your crypto exchange or other crypto wallet" ,
120+ style = CodeTheme .typography.textMedium,
121+ color = CodeTheme .colors.textMain,
122+ textAlign = TextAlign .Center ,
123+ )
124+
125+ CodeButton (
126+ modifier = Modifier .fillMaxWidth(),
127+ text = " Deposit USDC" ,
128+ buttonState = ButtonState .Filled
129+ ) {
130+ dispatchEvent(BalanceViewModel .Event .OpenDeposit )
131+ }
132+ }
133+ }
134+ }
135+ } else {
55136 items(feed.itemCount, key = feed.itemKey { item -> item.id }) { index ->
56137 val message = feed[index] ? : return @items
57138 FeedItem (
@@ -61,7 +142,7 @@ internal fun BalanceScreenContent(viewModel: BalanceViewModel) {
61142 message = message,
62143 canViewDetails = state.canViewDetails,
63144 isExpanded = state.expandedItem == message.id,
64- dispatch = viewModel:: dispatchEvent
145+ dispatch = dispatchEvent
65146 )
66147
67148 if (index < feed.itemCount - 1 ) {
@@ -74,4 +155,48 @@ internal fun BalanceScreenContent(viewModel: BalanceViewModel) {
74155 }
75156 }
76157 }
158+ }
159+
160+ private val cadUsdRate = Rate (fx = 1.371881 , currency = CurrencyCode .CAD )
161+ private val usdCadRate = Rate (fx = 1.0 / 1.371881 , currency = CurrencyCode .CAD )
162+
163+ @Preview
164+ @Composable
165+ private fun Preview_BalanceScreen_Empty () {
166+ FlipcashDesignSystem {
167+ CompositionLocalProvider (
168+ LocalExchange provides ExchangeStub (
169+ providedRates = mapOf (
170+ CurrencyCode .CAD to cadUsdRate,
171+ CurrencyCode .USD to usdCadRate
172+ ),
173+ context = LocalContext .current
174+ ),
175+ ) {
176+ Box (modifier = Modifier .background(CodeTheme .colors.background)) {
177+ BalanceScreenContent (
178+ state = BalanceViewModel .State (
179+ balance = LocalFiat (0 .toFiat())
180+ ),
181+ feed = flowOf(PagingData .empty<ActivityFeedMessage >()).collectAsLazyPagingItems(),
182+ dispatchEvent = {}
183+ )
184+ }
185+ }
186+ }
187+ }
188+
189+ @Preview
190+ @Composable
191+ private fun Preview_FeedList_Empty () {
192+ FlipcashDesignSystem {
193+ Box (modifier = Modifier .background(CodeTheme .colors.background)) {
194+ FeedList (
195+ state = BalanceViewModel .State (
196+ balance = LocalFiat (0 .toFiat())
197+ ),
198+ feed = flowOf(PagingData .empty<ActivityFeedMessage >()).collectAsLazyPagingItems()
199+ ) { }
200+ }
201+ }
77202}
0 commit comments