@@ -7,17 +7,24 @@ import androidx.compose.animation.animateColorAsState
77import androidx.compose.animation.fadeIn
88import androidx.compose.animation.fadeOut
99import androidx.compose.animation.togetherWith
10+ import androidx.compose.foundation.Image
1011import androidx.compose.foundation.background
12+ import androidx.compose.foundation.layout.Arrangement
1113import androidx.compose.foundation.layout.Box
1214import androidx.compose.foundation.layout.Column
1315import androidx.compose.foundation.layout.IntrinsicSize
1416import androidx.compose.foundation.layout.PaddingValues
17+ import androidx.compose.foundation.layout.fillMaxSize
1518import androidx.compose.foundation.layout.fillMaxWidth
1619import androidx.compose.foundation.layout.height
1720import androidx.compose.foundation.layout.padding
1821import androidx.compose.foundation.layout.requiredHeight
22+ import androidx.compose.foundation.layout.size
1923import androidx.compose.material.MaterialTheme
2024import androidx.compose.material.Text
25+ import androidx.compose.material.icons.Icons
26+ import androidx.compose.material.icons.automirrored.filled.ShowChart
27+ import androidx.compose.material.icons.filled.ShowChart
2128import androidx.compose.runtime.Composable
2229import androidx.compose.runtime.derivedStateOf
2330import androidx.compose.runtime.getValue
@@ -27,21 +34,28 @@ import androidx.compose.runtime.setValue
2734import androidx.compose.ui.Alignment
2835import androidx.compose.ui.Modifier
2936import androidx.compose.ui.draw.alpha
37+ import androidx.compose.ui.graphics.ColorFilter
3038import androidx.compose.ui.platform.LocalContext
39+ import androidx.compose.ui.res.painterResource
3140import androidx.compose.ui.res.stringResource
41+ import androidx.compose.ui.tooling.preview.Preview
3242import androidx.compose.ui.unit.dp
3343import com.flipcash.app.core.data.Loadable
44+ import com.flipcash.app.theme.FlipcashPreview
3445import com.flipcash.app.tokens.data.MarketCapPoint
3546import com.flipcash.app.tokens.data.Period
3647import com.flipcash.app.tokens.internal.components.marketcap.MarketCapChart
3748import com.flipcash.features.tokens.R
3849import com.getcode.opencode.model.financial.Fiat
3950import com.getcode.opencode.model.financial.minus
51+ import com.getcode.opencode.model.financial.toFiat
4052import com.getcode.theme.CodeTheme
4153import com.getcode.theme.extraSmall
4254import com.getcode.ui.components.charts.LineTrend
4355import com.getcode.ui.components.charts.TrendType
4456import com.getcode.ui.components.text.AnimatedNumberText
57+ import com.getcode.ui.theme.ButtonState
58+ import com.getcode.ui.theme.CodeButton
4559import com.getcode.ui.theme.CodeCircularProgressIndicator
4660import com.getcode.ui.utils.calculateEndPadding
4761import com.getcode.ui.utils.calculateStartPadding
@@ -67,6 +81,7 @@ internal fun MarketCapSection(
6781 selectedPeriod : Period ,
6882 modifier : Modifier = Modifier ,
6983 contentPadding : PaddingValues = PaddingValues (),
84+ onRetry : () -> Unit ,
7085 onPeriodSelected : (Period ) -> Unit
7186) {
7287 var highlightedCapPoint by remember {
@@ -193,28 +208,67 @@ internal fun MarketCapSection(
193208 onPointHighlighted = { highlightedCapPoint = it },
194209 onPeriodSelected = onPeriodSelected,
195210 placeholder = {
196- when (rawHistoricalData) {
197- is Loadable .Error -> Unit
198- is Loadable .Loaded -> Unit
199- is Loadable .Loading -> {
200- Box (
201- modifier = Modifier
202- .fillMaxWidth()
203- .requiredHeight(240 .dp)
204- ) {
205- CodeCircularProgressIndicator (
206- modifier = Modifier .align(Alignment .Center ),
207- color = CodeTheme .colors.dividerVariant,
208- )
209- }
210- }
211- }
211+ MarketCapChartPlaceholder (rawHistoricalData, onRetry)
212212 }
213213 )
214214 }
215215 }
216216}
217217
218+ @Composable
219+ private fun MarketCapChartPlaceholder (
220+ data : Loadable <List <MarketCapPoint >>,
221+ onRetry : () -> Unit
222+ ) {
223+ when (data) {
224+ is Loadable .Error -> {
225+ Box (
226+ modifier = Modifier
227+ .fillMaxWidth()
228+ .requiredHeight(240 .dp)
229+ ) {
230+ Column (
231+ modifier = Modifier .matchParentSize(),
232+ horizontalAlignment = Alignment .CenterHorizontally ,
233+ verticalArrangement = Arrangement .spacedBy(CodeTheme .dimens.grid.x1, Alignment .CenterVertically ),
234+ ) {
235+ Image (
236+ modifier = Modifier .size(CodeTheme .dimens.grid.x8),
237+ colorFilter = ColorFilter .tint(CodeTheme .colors.textSecondary),
238+ imageVector = Icons .AutoMirrored .Default .ShowChart ,
239+ contentDescription = null
240+ )
241+ Text (
242+ text = stringResource(R .string.error_unableToLoadChartData),
243+ style = CodeTheme .typography.textMedium,
244+ color = CodeTheme .colors.textSecondary,
245+ )
246+ CodeButton (
247+ text = stringResource(R .string.action_retry),
248+ buttonState = ButtonState .Subtle ,
249+ textColor = CodeTheme .colors.textMain,
250+ ) {
251+ onRetry()
252+ }
253+ }
254+ }
255+ }
256+ is Loadable .Loaded -> Unit
257+ is Loadable .Loading -> {
258+ Box (
259+ modifier = Modifier
260+ .fillMaxWidth()
261+ .requiredHeight(240 .dp)
262+ ) {
263+ CodeCircularProgressIndicator (
264+ modifier = Modifier .align(Alignment .Center ),
265+ color = CodeTheme .colors.dividerVariant,
266+ )
267+ }
268+ }
269+ }
270+ }
271+
218272@Composable
219273private fun MarketCapChangeLabel (
220274 change : Fiat ,
@@ -305,3 +359,18 @@ private fun HighlightedPointLabel(
305359 color = CodeTheme .colors.textSecondary,
306360 )
307361}
362+
363+ @Preview
364+ @Composable
365+ private fun Preview_MarketCapSection () {
366+ FlipcashPreview (showBackground = true ) {
367+ MarketCapSection (
368+ 24.44 .toFiat(),
369+ rawHistoricalData = Loadable .Error (" " ),
370+ selectedPeriod = Period .All ,
371+ chartEnabled = true ,
372+ onRetry = {},
373+ onPeriodSelected = {}
374+ )
375+ }
376+ }
0 commit comments