@@ -2,13 +2,8 @@ package com.flipcash.app.tokens.internal.components.info
22
33import android.text.format.DateFormat
44import androidx.compose.animation.AnimatedContent
5- import androidx.compose.animation.AnimatedVisibility
6- import androidx.compose.animation.Crossfade
75import androidx.compose.animation.SizeTransform
86import androidx.compose.animation.animateColorAsState
9- import androidx.compose.animation.animateContentSize
10- import androidx.compose.animation.core.animateFloatAsState
11- import androidx.compose.animation.core.snap
127import androidx.compose.animation.core.tween
138import androidx.compose.animation.fadeIn
149import androidx.compose.animation.fadeOut
@@ -18,19 +13,15 @@ import androidx.compose.foundation.layout.Box
1813import androidx.compose.foundation.layout.Column
1914import androidx.compose.foundation.layout.IntrinsicSize
2015import androidx.compose.foundation.layout.PaddingValues
21- import androidx.compose.foundation.layout.Spacer
22- import androidx.compose.foundation.layout.fillMaxSize
2316import androidx.compose.foundation.layout.fillMaxWidth
2417import androidx.compose.foundation.layout.height
2518import androidx.compose.foundation.layout.padding
2619import androidx.compose.foundation.layout.requiredHeight
27- import androidx.compose.foundation.layout.size
2820import androidx.compose.material.MaterialTheme
2921import androidx.compose.material.Text
3022import androidx.compose.runtime.Composable
3123import androidx.compose.runtime.derivedStateOf
3224import androidx.compose.runtime.getValue
33- import androidx.compose.runtime.key
3425import androidx.compose.runtime.mutableStateOf
3526import androidx.compose.runtime.remember
3627import androidx.compose.runtime.setValue
@@ -43,9 +34,7 @@ import androidx.compose.ui.unit.dp
4334import com.flipcash.app.core.data.Loadable
4435import com.flipcash.app.tokens.data.MarketCapPoint
4536import com.flipcash.app.tokens.data.Period
46- import com.flipcash.app.tokens.data.collapse
4737import com.flipcash.app.tokens.internal.components.marketcap.MarketCapChart
48- import com.flipcash.app.tokens.internal.components.marketcap.TARGET_POINTS
4938import com.flipcash.features.tokens.R
5039import com.getcode.opencode.model.financial.Fiat
5140import com.getcode.opencode.model.financial.minus
@@ -64,6 +53,12 @@ import java.util.Locale
6453import kotlin.time.Clock
6554import kotlin.time.Instant
6655
56+ private sealed interface MarketCapLabelState {
57+ data object Hidden : MarketCapLabelState
58+ data class Change (val change : Fiat , val period : Period ) : MarketCapLabelState
59+ data class Highlighted (val point : MarketCapPoint , val period : Period ) : MarketCapLabelState
60+ }
61+
6762@Composable
6863internal fun MarketCapSection (
6964 marketCap : Fiat ,
@@ -105,6 +100,28 @@ internal fun MarketCapSection(
105100 }
106101 }
107102
103+ var lastChange by remember { mutableStateOf<MarketCapLabelState .Change ?>(null ) }
104+
105+ val labelState by remember(marketCapDiff, highlightedCapPoint, selectedPeriod) {
106+ derivedStateOf {
107+ val highlightedPoint = highlightedCapPoint
108+ val diff = marketCapDiff
109+ when {
110+ highlightedPoint != null -> MarketCapLabelState .Highlighted (highlightedPoint, selectedPeriod)
111+ diff != null && selectedPeriod != Period .All -> {
112+ MarketCapLabelState .Change (diff, selectedPeriod).also { lastChange = it }
113+ }
114+ else ->
115+ if (selectedPeriod == Period .All ) {
116+ lastChange = null
117+ MarketCapLabelState .Hidden
118+ } else {
119+ lastChange ? : MarketCapLabelState .Hidden
120+ }
121+ }
122+ }
123+ }
124+
108125 Column (
109126 modifier = modifier,
110127 ) {
@@ -123,30 +140,46 @@ internal fun MarketCapSection(
123140 )
124141
125142 if (chartEnabled) {
126- Box (
143+ AnimatedContent (
127144 modifier = Modifier
128145 .padding(
129146 start = contentPadding.calculateStartPadding(),
130147 top = CodeTheme .dimens.grid.x1,
131- ).height(IntrinsicSize .Min ),
132- ) {
133- Crossfade (marketCapDiff) { diff ->
134- if (diff != null ) {
148+ )
149+ .height(IntrinsicSize .Max ),
150+ targetState = labelState,
151+ label = " MarketCapLabel" ,
152+ transitionSpec = {
153+ fadeIn().togetherWith(fadeOut()).using(SizeTransform (clip = false ))
154+ },
155+ contentKey = { state ->
156+ when (state) {
157+ is MarketCapLabelState .Change -> " change"
158+ is MarketCapLabelState .Highlighted -> " highlighted"
159+ MarketCapLabelState .Hidden -> " hidden"
160+ }
161+ }
162+ ) { state ->
163+ when (state) {
164+ is MarketCapLabelState .Change -> MarketCapChangeLabel (
165+ change = state.change,
166+ period = state.period,
167+ )
168+
169+ is MarketCapLabelState .Highlighted -> HighlightedPointLabel (
170+ modifier = Modifier .padding(bottom = 4 .dp),
171+ point = state.point,
172+ period = state.period,
173+ )
174+
175+ MarketCapLabelState .Hidden -> {
135176 MarketCapChangeLabel (
136- change = diff ,
137- isVisible = highlightedCapPoint == null ,
177+ modifier = Modifier .alpha( 0f ) ,
178+ change = Fiat . Zero ,
138179 period = selectedPeriod,
139180 )
140- } else {
141- Spacer (Modifier .size(CodeTheme .dimens.grid.x3))
142181 }
143182 }
144-
145- HighlightedPointLabel (
146- point = highlightedCapPoint,
147- isVisible = highlightedCapPoint != null ,
148- period = selectedPeriod,
149- )
150183 }
151184
152185 MarketCapChart (
@@ -169,9 +202,10 @@ internal fun MarketCapSection(
169202 is Loadable .Error -> Unit
170203 is Loadable .Loaded -> Unit
171204 is Loadable .Loading -> {
172- Box (modifier = Modifier
173- .fillMaxWidth()
174- .requiredHeight(240 .dp)
205+ Box (
206+ modifier = Modifier
207+ .fillMaxWidth()
208+ .requiredHeight(240 .dp)
175209 ) {
176210 CodeCircularProgressIndicator (
177211 modifier = Modifier .align(Alignment .Center ),
@@ -189,21 +223,17 @@ internal fun MarketCapSection(
189223@Composable
190224private fun MarketCapChangeLabel (
191225 change : Fiat ,
192- isVisible : Boolean ,
193226 period : Period ,
227+ modifier : Modifier = Modifier ,
194228) {
195229 val isPositiveChange = change.decimalValue >= 0
196230 val changeColor by animateColorAsState(
197- if (isPositiveChange) LineTrend .Up .color else LineTrend .Down .color
198- )
199-
200- val alpha by animateFloatAsState(
201- if (isVisible) 1f else 0f
231+ if (isPositiveChange) LineTrend .Up .color else LineTrend .Down .color,
232+ label = " change color"
202233 )
203234
204235 Text (
205- modifier = Modifier
206- .alpha(alpha)
236+ modifier = modifier
207237 .background(
208238 color = changeColor.copy(0.20f ),
209239 shape = MaterialTheme .shapes.extraSmall,
@@ -229,18 +259,14 @@ private fun MarketCapChangeLabel(
229259
230260@Composable
231261private fun HighlightedPointLabel (
232- point : MarketCapPoint ? ,
262+ point : MarketCapPoint ,
233263 period : Period ,
234- isVisible : Boolean ,
264+ modifier : Modifier = Modifier ,
235265) {
236- val alpha by animateFloatAsState(
237- if (isVisible) 1f else 0f
238- )
239-
240266 val context = LocalContext .current
241267
242268 val timeLabel = remember(point, period) {
243- val epoch = point?.x ? : return @remember null
269+ val epoch = point.x
244270 val instant = Instant .fromEpochMilliseconds(epoch)
245271 val now = Clock .System .now()
246272 val isCurrentYear = instant.toLocalDateTime(TimeZone .currentSystemDefault()).year ==
@@ -285,13 +311,10 @@ private fun HighlightedPointLabel(
285311 }
286312 }
287313
288- if (timeLabel != null ) {
289- Text (
290- modifier = Modifier
291- .alpha(alpha),
292- text = timeLabel,
293- style = CodeTheme .typography.textSmall,
294- color = CodeTheme .colors.textSecondary,
295- )
296- }
297- }
314+ Text (
315+ modifier = modifier,
316+ text = timeLabel,
317+ style = CodeTheme .typography.textSmall,
318+ color = CodeTheme .colors.textSecondary,
319+ )
320+ }
0 commit comments