Skip to content

Commit

Permalink
chore(suite): fiat rates loading visualization
Browse files Browse the repository at this point in the history
  • Loading branch information
AdamSchinzel authored and tomasklim committed Apr 29, 2024
1 parent dfb1169 commit f904439
Show file tree
Hide file tree
Showing 12 changed files with 165 additions and 230 deletions.
18 changes: 17 additions & 1 deletion packages/suite/src/components/suite/FiatValue.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import {
useFiatFromCryptoValueParams,
} from 'src/hooks/suite/useFiatFromCryptoValue';
import { HiddenPlaceholderProps } from './HiddenPlaceholder';
import { useLoadingSkeleton } from 'src/hooks/suite';
import { SkeletonRectangle } from '@trezor/components';

const StyledHiddenPlaceholder = styled((props: HiddenPlaceholderProps) => (
<HiddenPlaceholder {...props} />
Expand All @@ -32,7 +34,9 @@ type FiatValueProps = useFiatFromCryptoValueParams & {
disableHiddenPlaceholder?: boolean;
fiatAmountFormatterOptions?: FormatNumberOptions;
shouldConvert?: boolean;
showLoadingSkeleton?: boolean;
className?: string;
isLoading?: boolean;
};

/**
Expand Down Expand Up @@ -60,7 +64,10 @@ export const FiatValue = ({
disableHiddenPlaceholder,
fiatAmountFormatterOptions,
shouldConvert = true,
showLoadingSkeleton,
isLoading,
}: FiatValueProps) => {
const { shouldAnimate } = useLoadingSkeleton();
const { targetCurrency, fiatAmount, ratesSource, currentRate } = useFiatFromCryptoValue({
amount,
symbol,
Expand All @@ -74,6 +81,16 @@ export const FiatValue = ({
const value = shouldConvert ? fiatAmount : amount;

const WrapperComponent = disableHiddenPlaceholder ? SameWidthNums : StyledHiddenPlaceholder;

const fiatRateValue = ratesSource?.[targetCurrency] ?? null;

if (
(!fiatRateValue || !value || !currentRate?.lastTickerTimestamp || isLoading) &&
showLoadingSkeleton
) {
return <SkeletonRectangle animate={shouldAnimate} />;
}

if (value) {
const fiatValueComponent = (
<WrapperComponent className={className}>
Expand All @@ -86,7 +103,6 @@ export const FiatValue = ({
</WrapperComponent>
);

const fiatRateValue = ratesSource?.[targetCurrency] ?? null;
const fiatRateComponent = fiatRateValue ? (
<SameWidthNums>
<FiatAmountFormatter currency={targetCurrency} value={fiatRateValue} />
Expand Down
44 changes: 44 additions & 0 deletions packages/suite/src/components/suite/Ticker/LastUpdateTooltip.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import { Translation } from 'src/components/suite';
import styled from 'styled-components';
import { Tooltip } from '@trezor/components';
import { FormattedRelativeTime } from 'react-intl';
import { ReactNode } from 'react';
import { differenceInMinutes } from 'date-fns';

const LastUpdate = styled.div`
text-transform: none;
`;

interface LastUpdateTooltipProps {
timestamp: number;
children: ReactNode;
}

export const LastUpdateTooltip = ({ timestamp, children }: LastUpdateTooltipProps) => {
const rateAge = (timestamp: number) => differenceInMinutes(new Date(timestamp), new Date());

return (
<Tooltip
maxWidth={285}
placement="top"
content={
<LastUpdate>
<Translation
id="TR_LAST_UPDATE"
values={{
value: (
<FormattedRelativeTime
value={rateAge(timestamp) * 60}
numeric="auto"
updateIntervalInSeconds={10}
/>
),
}}
/>
</LastUpdate>
}
>
{children}
</Tooltip>
);
};
40 changes: 20 additions & 20 deletions packages/suite/src/components/suite/Ticker/NoRatesTooltip.tsx
Original file line number Diff line number Diff line change
@@ -1,34 +1,34 @@
import { Translation, TooltipSymbol } from 'src/components/suite';
import styled from 'styled-components';
import { Tooltip, variables } from '@trezor/components';
import styled, { useTheme } from 'styled-components';
import { TranslationKey } from '../Translation';
import { typography } from '@trezor/theme';

const NoRatesMessage = styled.div`
${typography.label};
display: flex;
align-items: center;
color: ${({ theme }) => theme.TYPE_LIGHT_GREY};
font-size: ${variables.FONT_SIZE.TINY};
font-weight: ${variables.FONT_WEIGHT.REGULAR};
color: ${({ theme }) => theme.textSubdued};
text-transform: none;
`;

interface NoRatesTooltipProps extends Partial<typeof Tooltip> {
interface NoRatesTooltipProps {
customText?: TranslationKey;
customTooltip?: TranslationKey;
iconOnly?: boolean;
className?: string;
}

export const NoRatesTooltip = ({
customText,
iconOnly,
customTooltip,
className,
}: NoRatesTooltipProps) => (
<NoRatesMessage className={className}>
{!iconOnly && <Translation id={customText || 'TR_FIAT_RATES_NOT_AVAILABLE'} />}
<TooltipSymbol
content={<Translation id={customTooltip || 'TR_FIAT_RATES_NOT_AVAILABLE_TOOLTIP'} />}
/>
</NoRatesMessage>
);
export const NoRatesTooltip = ({ customText, customTooltip, className }: NoRatesTooltipProps) => {
const theme = useTheme();

return (
<NoRatesMessage className={className}>
<Translation id={customText || 'TR_FIAT_RATES_NOT_AVAILABLE'} />
<TooltipSymbol
content={
<Translation id={customTooltip || 'TR_FIAT_RATES_NOT_AVAILABLE_TOOLTIP'} />
}
iconColor={theme.iconSubdued}
/>
</NoRatesMessage>
);
};
63 changes: 16 additions & 47 deletions packages/suite/src/components/suite/Ticker/PriceTicker.tsx
Original file line number Diff line number Diff line change
@@ -1,61 +1,30 @@
import styled from 'styled-components';
import { differenceInMinutes } from 'date-fns';
import { FormattedRelativeTime } from 'react-intl';

import { Tooltip } from '@trezor/components';
import { FiatValue, Translation } from 'src/components/suite';
import { FiatValue } from 'src/components/suite';
import { NoRatesTooltip } from './NoRatesTooltip';
import { typography } from '@trezor/theme';
import { LastUpdateTooltip } from './LastUpdateTooltip';

const FiatRateWrapper = styled.span`
${typography.hint}
display: flex;
align-items: center;
color: ${({ theme }) => theme.TYPE_DARK_GREY};
${typography.hint}
`;

const LastUpdate = styled.div`
text-transform: none;
`;

interface PriceTickerProps {
symbol: string;
tooltipPos?: 'top' | 'bottom';
compact?: boolean;
}
export const PriceTicker = ({ symbol, tooltipPos = 'top', compact = false }: PriceTickerProps) => {
const rateAge = (timestamp: number) => differenceInMinutes(new Date(timestamp), new Date());

return (
<FiatValue amount="1" symbol={symbol}>
{({ rate, timestamp }) =>
rate && timestamp ? (
<Tooltip
maxWidth={285}
placement={tooltipPos}
content={
<LastUpdate>
<Translation
id="TR_LAST_UPDATE"
values={{
value: (
<FormattedRelativeTime
value={rateAge(timestamp) * 60}
numeric="auto"
updateIntervalInSeconds={10}
/>
),
}}
/>
</LastUpdate>
}
>
<FiatRateWrapper>{rate}</FiatRateWrapper>
</Tooltip>
) : (
<NoRatesTooltip iconOnly={compact} />
)
}
</FiatValue>
);
};
export const PriceTicker = ({ symbol }: PriceTickerProps) => (
<FiatValue amount="1" symbol={symbol} showLoadingSkeleton>
{({ rate, timestamp }) =>
rate && timestamp ? (
<LastUpdateTooltip timestamp={timestamp}>
<FiatRateWrapper>{rate}</FiatRateWrapper>
</LastUpdateTooltip>
) : (
<NoRatesTooltip />
)
}
</FiatValue>
);
87 changes: 0 additions & 87 deletions packages/suite/src/components/suite/Ticker/Ticker.tsx

This file was deleted.

7 changes: 3 additions & 4 deletions packages/suite/src/components/suite/Ticker/TrendTicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,8 @@ const calculatePercentageDifference = (a: number, b: number) => (a - b) / b;

interface TickerProps {
symbol: NetworkSymbol;
compact?: boolean;
}
export const TrendTicker = ({ symbol, compact = false }: TickerProps) => {
export const TrendTicker = ({ symbol }: TickerProps) => {
const locale = useSelector(state => state.suite.settings.language);
const localCurrency = useSelector(selectLocalCurrency);
const fiatRateKey = getFiatRateKey(symbol, localCurrency);
Expand All @@ -45,7 +44,7 @@ export const TrendTicker = ({ symbol, compact = false }: TickerProps) => {
: 0;

return (
<FiatValue amount="1" symbol={symbol}>
<FiatValue amount="1" symbol={symbol} showLoadingSkeleton isLoading={!percentageChange}>
{({ rate, timestamp }) =>
rate && timestamp && percentageChange ? (
<PercentageWrapper $isRateGoingUp={isRateGoingUp}>
Expand All @@ -57,7 +56,7 @@ export const TrendTicker = ({ symbol, compact = false }: TickerProps) => {
{localizePercentage({ valueInFraction: percentageChange, locale })}
</PercentageWrapper>
) : (
<NoRatesTooltip iconOnly={compact} />
<NoRatesTooltip />
)
}
</FiatValue>
Expand Down
10 changes: 8 additions & 2 deletions packages/suite/src/components/suite/TooltipSymbol.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,18 @@ const InlineTooltip = styled(Tooltip)`
type TooltipSymbolProps = {
content: ReactNode;
icon?: IconType;
iconColor?: string;
className?: string;
};

const TooltipSymbol = ({ content, icon = 'QUESTION', className }: TooltipSymbolProps) => (
const TooltipSymbol = ({
content,
icon = 'QUESTION',
iconColor,
className,
}: TooltipSymbolProps) => (
<InlineTooltip content={content} maxWidth={250} className={className}>
<Icon icon={icon} size={16} />
<Icon icon={icon} size={16} color={iconColor} />
</InlineTooltip>
);

Expand Down
2 changes: 0 additions & 2 deletions packages/suite/src/components/suite/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import { WebUsbButton } from './WebUsbButton';
import { HiddenPlaceholder } from './HiddenPlaceholder';
import { QuestionTooltip } from './QuestionTooltip';
import { DeviceInvalidModeLayout } from './DeviceInvalidModeLayout';
import { Ticker } from './Ticker/Ticker';
import { TrendTicker } from './Ticker/TrendTicker';
import { PriceTicker } from './Ticker/PriceTicker';
import { Translation } from './Translation';
Expand Down Expand Up @@ -80,7 +79,6 @@ export {
QuestionTooltip,
FormattedCryptoAmount,
FormattedNftAmount,
Ticker,
TrendTicker,
PriceTicker,
Sign,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -190,10 +190,10 @@ export const AssetRow = memo(
</FailedCol>
)}
<ExchangeRateWrapper $isLastRow={isLastRow}>
{!isTestnet(symbol) && <PriceTicker symbol={symbol} compact />}
{!isTestnet(symbol) && <PriceTicker symbol={symbol} />}
</ExchangeRateWrapper>
<ExchangeRateWrapper7Days $isLastRow={isLastRow}>
{!isTestnet(symbol) && <TrendTicker symbol={symbol} compact />}
{!isTestnet(symbol) && <TrendTicker symbol={symbol} />}
</ExchangeRateWrapper7Days>
<BuyButtonWrapper $isLastRow={isLastRow}>
{!isTestnet(symbol) && (
Expand Down
Loading

0 comments on commit f904439

Please sign in to comment.