Skip to content

Commit

Permalink
Initial charts cleanup (#6387)
Browse files Browse the repository at this point in the history
  • Loading branch information
christianbaroni authored Jan 10, 2025
1 parent ede2624 commit c768946
Show file tree
Hide file tree
Showing 25 changed files with 497 additions and 494 deletions.
26 changes: 9 additions & 17 deletions src/components/expanded-state/asset/ChartExpandedState.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,11 @@ import { useBackendNetworksStore } from '@/state/backendNetworks/backendNetworks
import { ChainId } from '@/state/backendNetworks/types';
import { useTimeoutEffect } from '@/hooks/useTimeout';
import { analyticsV2 } from '@/analytics';
import { IS_ANDROID, IS_IOS } from '@/env';

const defaultCarouselHeight = 60;
const baseHeight = 386 + (android && 20 - getSoftMenuBarHeight()) - defaultCarouselHeight;
const heightWithoutChart = baseHeight + (android && 30);
const baseHeight = 386 + (IS_ANDROID && 20 - getSoftMenuBarHeight()) - defaultCarouselHeight;
const heightWithoutChart = baseHeight + (IS_ANDROID && 30);
const heightWithChart = baseHeight + 292;

const Carousel = styled.ScrollView.attrs({
Expand Down Expand Up @@ -187,24 +188,15 @@ export default function ChartExpandedState({ asset }) {

const delayedDescriptions = useDelayedValueWithLayoutAnimation(data?.description?.replace(/\s+/g, ''));

const scrollableContentHeight = true;
const { chart, chartType, color, fetchingCharts, updateChartType, initialChartDataLabels, showChart, throttledData } =
useChartThrottledPoints({
asset: assetWithPrice,
heightWithChart: Math.min(
carouselHeight +
heightWithChart -
(!hasBalance && 68) +
additionalContentHeight +
(additionalContentHeight === 0 ? 0 : scrollableContentHeight),
carouselHeight + heightWithChart - (!hasBalance && 68) + additionalContentHeight + (additionalContentHeight === 0 ? 0 : true),
screenHeight
),
heightWithoutChart: Math.min(
carouselHeight +
heightWithoutChart -
(!hasBalance && 68) +
additionalContentHeight +
(additionalContentHeight === 0 ? 0 : scrollableContentHeight),
carouselHeight + heightWithoutChart - (!hasBalance && 68) + additionalContentHeight + (additionalContentHeight === 0 ? 0 : true),
screenHeight
),
shortHeightWithChart: Math.min(carouselHeight + heightWithChart - (!hasBalance && 68), screenHeight),
Expand All @@ -219,9 +211,9 @@ export default function ChartExpandedState({ asset }) {
duration.current = 300;
}

let ChartExpandedStateSheetHeight = ios || showChart ? heightWithChart : heightWithoutChart;
let ChartExpandedStateSheetHeight = IS_IOS || showChart ? heightWithChart : heightWithoutChart;

if (android && !hasBalance) {
if (IS_ANDROID && !hasBalance) {
ChartExpandedStateSheetHeight -= 60;
}

Expand Down Expand Up @@ -271,10 +263,10 @@ export default function ChartExpandedState({ asset }) {

return (
<SlackSheet
additionalTopPadding={android}
additionalTopPadding={IS_ANDROID}
contentHeight={ChartExpandedStateSheetHeight}
scrollEnabled
{...(ios ? { height: '100%' } : { additionalTopPadding: true, contentHeight: screenHeight - 80 })}
{...(IS_IOS ? { height: '100%' } : { additionalTopPadding: true, contentHeight: screenHeight - 80 })}
>
<ChartPathProvider data={throttledData}>
<Chart
Expand Down
114 changes: 53 additions & 61 deletions src/components/expanded-state/chart/ChartExpandedStateHeader.js
Original file line number Diff line number Diff line change
@@ -1,46 +1,31 @@
import lang from 'i18n-js';
import React, { useMemo } from 'react';
import { runOnJS, useAnimatedReaction } from 'react-native-reanimated';
import { Column, ColumnWithMargins, Row, RowWithMargins } from '../../layout';
import ChartContextButton from './ChartContextButton';
import { ChartDateLabel, ChartHeaderSubtitle, ChartPercentChangeLabel, ChartPriceLabel } from './chart-data-labels';
import { useChartData } from '@/react-native-animated-charts/src';
import { View } from 'react-native';
import Animated, { FadeIn, useAnimatedStyle, withTiming } from 'react-native-reanimated';
import { TIMING_CONFIGS } from '@/components/animations/animationConfigs';
import RainbowCoinIcon from '@/components/coin-icon/RainbowCoinIcon';
import { Column, Columns, Text } from '@/design-system';
import ChartTypes from '@/helpers/chartTypes';
import { convertAmountToNativeDisplay } from '@/helpers/utilities';
import { useAccountSettings, useBooleanState } from '@/hooks';
import { useAccountSettings } from '@/hooks';
import { useChartData } from '@/react-native-animated-charts/src';
import styled from '@/styled-thing';
import { padding } from '@/styles';
import RainbowCoinIcon from '@/components/coin-icon/RainbowCoinIcon';
import { ColumnWithMargins, Row } from '../../layout';
import ChartContextButton from './ChartContextButton';
import { ChartDateLabel, ChartPercentChangeLabel, ChartPriceLabel } from './chart-data-labels';

const noPriceData = lang.t('expanded_state.chart.no_price_data');

const Container = styled(ColumnWithMargins).attrs({
margin: 12,
marginTop: android ? -10 : 0,
margin: 20,
})(({ showChart }) => ({
...padding.object(0, 19, showChart ? (android ? 15 : 30) : 0),
...padding.object(0, 19, showChart ? 36 : 0),
}));

function useTabularNumsWhileScrubbing() {
const [tabularNums, enable, disable] = useBooleanState();
// Only enable tabularNums on the price label when the user is scrubbing
// because we are obnoxiously into details
const { isActive } = useChartData();

useAnimatedReaction(
() => isActive.value,
useTabularNums => {
runOnJS(useTabularNums ? enable : disable)();
}
);

return tabularNums;
}

export default function ChartExpandedStateHeader({
asset,
color: givenColors,
dateRef,
isPool,
latestChange,
latestPrice = noPriceData,
Expand All @@ -52,7 +37,6 @@ export default function ChartExpandedStateHeader({
const theme = useTheme();
const color = givenColors || theme.colors.dark;
const { nativeCurrency } = useAccountSettings();
const tabularNums = useTabularNumsWhileScrubbing();

const isNoPriceData = latestPrice === noPriceData;

Expand All @@ -64,8 +48,6 @@ export default function ChartExpandedStateHeader({

const titleOrNoPriceData = isNoPriceData ? noPriceData : title;

const showPriceChange = !isNoPriceData && showChart && !isNaN(latestChange);

const invertedChartTypes = Object.entries(ChartTypes).reduce((acc, [key, value]) => {
acc[value] = key;
return acc;
Expand Down Expand Up @@ -101,9 +83,17 @@ export default function ChartExpandedStateHeader({
const firstValue = data?.points?.[0]?.y;
const lastValue = data?.points?.[data.points.length - 1]?.y;

return firstValue === Number(firstValue) ? lastValue / firstValue : 1;
return firstValue === Number(firstValue) ? lastValue / firstValue : undefined;
}, [data]);

const showPriceChangeStyle = useAnimatedStyle(() => {
const showPriceChange = !isNoPriceData && showChart && !isNaN(latestChange.value);
return {
display: showPriceChange ? 'flex' : 'none',
opacity: withTiming(showPriceChange ? 1 : 0, TIMING_CONFIGS.slowFadeConfig),
};
});

return (
<Container showChart={showChart}>
<Row align="center" justify="space-between" testID={testID ? `${testID}-expanded-state-header` : 'expanded-state-header'}>
Expand All @@ -115,38 +105,40 @@ export default function ChartExpandedStateHeader({
theme={theme}
colors={asset?.colors}
/>

<ChartContextButton asset={asset} color={color} />
</Row>
<Column>
<RowWithMargins height={30} justify="space-between" marginHorizontal={1}>
<ChartPriceLabel
defaultValue={title}
isNoPriceData={isNoPriceData}
isPool={isPool}
priceRef={priceRef}
priceValue={price}
tabularNums={tabularNums}
/>
{showPriceChange && <ChartPercentChangeLabel latestChange={latestChange} ratio={ratio} />}
</RowWithMargins>

<RowWithMargins
height={30}
justify="space-between"
marginHorizontal={android ? (isNoPriceData ? -7 : 0) : 1}
marginVertical={android ? 4 : 1}
>
<ChartHeaderSubtitle
color={isNoPriceData ? theme.colors.alpha(theme.colors.blueGreyDark, 0.8) : color}
testID={`chart-header-${titleOrNoPriceData}`}
weight={isNoPriceData ? 'semibold' : 'bold'}
>
{titleOrNoPriceData}
</ChartHeaderSubtitle>
{showPriceChange && <ChartDateLabel chartTimeDefaultValue={defaultTimeValue} dateRef={dateRef} ratio={ratio} />}
</RowWithMargins>
</Column>

<View style={{ justifyContent: 'space-between', gap: 12, height: 42 }}>
<Columns alignHorizontal="justify" alignVertical="center" space="10px">
<Column>
<ChartPriceLabel defaultValue={title} isNoPriceData={isNoPriceData} isPool={isPool} priceRef={priceRef} priceValue={price} />
</Column>
<Column>
<Animated.View entering={FadeIn.duration(140)} style={showPriceChangeStyle}>
<ChartPercentChangeLabel latestChange={latestChange} ratio={ratio} />
</Animated.View>
</Column>
</Columns>

<Columns alignHorizontal="justify" alignVertical="center" space="10px">
<Column>
<Text
color={{ custom: isNoPriceData ? theme.colors.alpha(theme.colors.blueGreyDark, 0.8) : color }}
numberOfLines={1}
size="20pt"
testID={`chart-header-${titleOrNoPriceData}`}
weight={isNoPriceData ? 'semibold' : 'bold'}
>
{titleOrNoPriceData}
</Text>
</Column>
<Column width="content">
<Animated.View entering={FadeIn.duration(140)} style={showPriceChangeStyle}>
<ChartDateLabel chartTimeDefaultValue={defaultTimeValue} ratio={ratio} showPriceChangeStyle={showPriceChangeStyle} />
</Animated.View>
</Column>
</Columns>
</View>
</Container>
);
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
import MaskedView from '@react-native-masked-view/masked-view';
import React from 'react';
import Animated, { useAnimatedStyle } from 'react-native-reanimated';
import { Icon } from '../../../icons';
import Animated, { DerivedValue, useAnimatedStyle } from 'react-native-reanimated';
import { useChartData } from '@/react-native-animated-charts/src';
import styled from '@/styled-thing';
import { Icon } from '../../../icons';
import { useTheme } from '@/theme';

const AnimatedMaskedView = Animated.createAnimatedComponent(MaskedView);

const ArrowIcon = styled(Icon).attrs({
direction: 'right',
name: 'fatArrow',
})({});
const ArrowIcon = () => <Icon direction="right" name="fatArrow" />;

export default function ChartChangeDirectionArrow({ ratio, sharedRatio }) {
export default function ChartChangeDirectionArrow({ ratio, sharedRatio }: { ratio: number; sharedRatio: DerivedValue<number> }) {
const { colors } = useTheme();
const { isActive } = useChartData();

Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,9 @@
import lang from 'i18n-js';
import React from 'react';
import { View } from 'react-native';
import { useAnimatedStyle } from 'react-native-reanimated';
import React, { useCallback } from 'react';
import Animated, { AnimatedStyle, FadeIn, useAnimatedStyle } from 'react-native-reanimated';
import { useRatio } from './useRatio';
import { ChartXLabel, useChartData } from '@/react-native-animated-charts/src';
import styled from '@/styled-thing';
import { fonts, fontWithWidth } from '@/styles';

const Label = styled(ChartXLabel)({
...fontWithWidth(fonts.weight.semibold),
fontSize: fonts.size.larger,
fontVariant: ['tabular-nums'],
letterSpacing: fonts.letterSpacing.roundedMedium,
textAlign: 'right',
...(android ? { marginVertical: -20 } : {}),
});
import { useTheme } from '@/theme';

const MONTHS = [
lang.t('expanded_state.chart.date.months.month_00'),
Expand All @@ -31,7 +20,7 @@ const MONTHS = [
lang.t('expanded_state.chart.date.months.month_11'),
];

function formatDatetime(value, chartTimeDefaultValue) {
function formatDatetime(value: string, chartTimeDefaultValue: string) {
'worklet';
// we have to do it manually due to limitations of reanimated
if (value === '') {
Expand Down Expand Up @@ -82,27 +71,37 @@ function formatDatetime(value, chartTimeDefaultValue) {
return res;
}

export default function ChartDateLabel({ chartTimeDefaultValue, ratio }) {
export default function ChartDateLabel({
chartTimeDefaultValue,
ratio,
showPriceChangeStyle,
}: {
chartTimeDefaultValue: string;
ratio: number | undefined;
showPriceChangeStyle: AnimatedStyle;
}) {
const { isActive } = useChartData();
const sharedRatio = useRatio('ChartDataLabel');
const sharedRatio = useRatio();
const { colors } = useTheme();

const textStyle = useAnimatedStyle(() => {
const realRatio = isActive.value ? sharedRatio.value : ratio;
return {
color: realRatio === 1 ? colors.blueGreyDark : realRatio < 1 ? colors.red : colors.green,
color: realRatio !== undefined ? (realRatio === 1 ? colors.blueGreyDark : realRatio < 1 ? colors.red : colors.green) : 'transparent',
};
}, [ratio]);
});

const formatWorklet = useCallback(
(value: string) => {
'worklet';
return formatDatetime(value, chartTimeDefaultValue);
},
[chartTimeDefaultValue]
);

return (
<View style={{ overflow: 'hidden' }}>
<Label
format={value => {
'worklet';
return formatDatetime(value, chartTimeDefaultValue);
}}
style={textStyle}
/>
</View>
<Animated.View entering={FadeIn.duration(140)} style={showPriceChangeStyle}>
<ChartXLabel align="right" formatWorklet={formatWorklet} size="20pt" style={textStyle} tabularNumbers weight="semibold" />
</Animated.View>
);
}

This file was deleted.

Loading

0 comments on commit c768946

Please sign in to comment.