Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions apps/evm/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
"i18next": "^25.0.0",
"i18next-browser-languagedetector": "^8.2.0",
"immer": "^10.1.1",
"klinecharts": "^10.0.0-beta1",
"lodash": "^4.17.21",
"lodash.merge": "^4.6.2",
"motion": "^12.0.3",
Expand Down
142 changes: 142 additions & 0 deletions apps/evm/src/components/KLineChart/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
import { cn } from '@venusprotocol/ui';
import { type KLineData, type PeriodType, dispose, init } from 'klinecharts';
import { useEffect, useRef } from 'react';
import { rgb } from './rgb';

export interface KLineChartProps {
title: string;
data: KLineData[];
period?: PeriodType;
className?: string;
}

export const KLineChart: React.FC<KLineChartProps> = ({
className,
data,
period = 'day',
title,
}) => {
const containerRef = useRef<HTMLDivElement | null>(null);
const chartRef = useRef<ReturnType<typeof init> | null>(null);
const latestDataRef = useRef<KLineData[]>(data);

useEffect(() => {
if (!containerRef.current) {
return undefined;
}

const chart = init(containerRef.current);

if (!chart) {
return undefined;
}

chartRef.current = chart;

const darkBlueHover = rgb('--color-dark-blue-hover-rgb');
const darkBlueActive = rgb('--color-dark-blue-active-rgb');
const grey = rgb('--color-grey-rgb');
const white = rgb('--color-white-rgb');
const green = rgb('--color-green-rgb');
const red = rgb('--color-red-rgb');

chart.setStyles({
grid: {
horizontal: { color: darkBlueHover, dashedValue: [3, 3] },
vertical: { color: darkBlueHover, dashedValue: [3, 3] },
},
candle: {
bar: {
upColor: green,
downColor: red,
upBorderColor: green,
downBorderColor: red,
upWickColor: green,
downWickColor: red,
noChangeColor: grey,
noChangeBorderColor: grey,
noChangeWickColor: grey,
},
tooltip: {
rect: {
color: darkBlueHover,
borderColor: darkBlueActive,
},
title: { color: white },
legend: { color: grey },
},
},
xAxis: {
axisLine: { color: darkBlueActive },
tickLine: { color: darkBlueActive },
tickText: { color: grey },
},
yAxis: {
axisLine: { color: darkBlueActive },
tickLine: { color: darkBlueActive },
tickText: { color: grey },
},
crosshair: {
horizontal: {
line: { color: grey },
text: {
color: white,
borderColor: darkBlueActive,
backgroundColor: darkBlueHover,
},
},
vertical: {
line: { color: grey },
text: {
color: white,
borderColor: darkBlueActive,
backgroundColor: darkBlueHover,
},
},
},
separator: {
color: darkBlueActive,
activeBackgroundColor: darkBlueHover,
},
});

chart.setDataLoader({
getBars: ({ callback }) => {
callback(latestDataRef.current);
},
});

// Re-render chart when browser window is resized
const resizeObserver = new ResizeObserver(() => {
chart.resize();
});

resizeObserver.observe(containerRef.current);

return () => {
chartRef.current = null;
resizeObserver?.disconnect();
dispose(chart);
};
}, []);

useEffect(() => {
chartRef.current?.setSymbol({ ticker: title });
}, [title]);

useEffect(() => {
chartRef.current?.setPeriod({ span: 1, type: period });
}, [period]);

useEffect(() => {
latestDataRef.current = data;

chartRef.current?.setDataLoader({
getBars: ({ callback }) => {
callback(data);
},
});
}, [data]);

return <div ref={containerRef} className={cn('w-full h-full bg-dark-blue', className)} />;
};
8 changes: 8 additions & 0 deletions apps/evm/src/components/KLineChart/rgb/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export const rgb = (cssVariableName: string) => {
const computedValue =
typeof window === 'undefined'
? ''
: getComputedStyle(document.documentElement).getPropertyValue(cssVariableName).trim();

return `rgb(${computedValue})`;
};
1 change: 1 addition & 0 deletions apps/evm/src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,4 @@ export * from './TokenIcon';
export * from './BalanceUpdates';
export * from './TokenListWrapper';
export * from './Wrapper';
export * from './KLineChart';
10 changes: 8 additions & 2 deletions apps/evm/src/pages/YieldPlus/Banner/index.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { cn } from '@venusprotocol/ui';

import { Card, Icon } from 'components';
import { Link } from 'containers/Link';
import { useTranslation } from 'libs/translations';
Expand All @@ -6,13 +8,17 @@ import { store } from './store';

const LEARN_MORE_URL = ''; // TODO: add

export const Banner: React.FC = () => {
export interface BannerProps {
className?: string;
}

export const Banner: React.FC<BannerProps> = ({ className }) => {
const { t } = useTranslation();

const hideBanner = store.use.hideBanner();

return (
<Card className="h-21 relative bg-dark-blue-active items-center flex">
<Card className={cn('h-21 relative bg-dark-blue-active items-center flex', className)}>
<img
src={illustrationSrc}
className="h-18 absolute bottom-0 right-2 sm:h-22 sm:right-12 md:h-24 md:right-14 lg:h-19 lg:right-3 2xl:right-6"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ export const TokenSelect: React.FC<TokenSelectProps> = ({
>
<div
className={cn(
'h-full flex w-12 shrink-0 items-center justify-center py-3',
'h-full flex w-12 shrink-0 items-center justify-center py-3 rounded-r-lg',
type === 'long' ? 'bg-green' : 'bg-red',
)}
>
Expand Down
33 changes: 21 additions & 12 deletions apps/evm/src/pages/YieldPlus/PairInfo/index.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
import BigNumber from 'bignumber.js';
import { useSearchParams } from 'react-router';

import { useGetPool } from 'clients/api';
import { Apy, CellGroup, type CellProps, TokenIcon } from 'components';
import PLACEHOLDER_KEY from 'constants/placeholderKey';
import { useChain } from 'hooks/useChain';
import { useGetTokens } from 'libs/tokens';
import { useTranslation } from 'libs/translations';
import type { Asset, Token } from 'types';
import {
Expand All @@ -22,7 +20,6 @@ export const PairInfo: React.FC = () => {
const { corePoolComptrollerContractAddress } = useChain();
const { shortToken, longToken } = useTokenPair();
const [_, setSearchParams] = useSearchParams();
const tokens = useGetTokens();

const setLongToken = (newLongToken: Token) => {
setSearchParams(currentSearchParams => ({
Expand All @@ -37,16 +34,16 @@ export const PairInfo: React.FC = () => {
[SHORT_TOKEN_ADDRESS_PARAM_KEY]: newShortToken.address,
}));

const priceLongTokens = new BigNumber('0.02341'); // TODO: fetch
const changePercentage = 3.32; // TODO: fetch

const corePool = useGetPool({
const { data: getPoolData } = useGetPool({
poolComptrollerAddress: corePoolComptrollerContractAddress,
});

const { shortAsset, longAsset } = (corePool.data?.pool.assets || []).reduce<{
const { shortAsset, longAsset, tokens } = (getPoolData?.pool.assets || []).reduce<{
shortAsset: Asset | undefined;
longAsset: Asset | undefined;
tokens: Token[];
}>(
(acc, asset) => {
if (areTokensEqual(asset.vToken.underlyingToken, shortToken)) {
Expand All @@ -57,28 +54,40 @@ export const PairInfo: React.FC = () => {
acc.longAsset = asset;
}

// Filter out paused assets
if (asset.disabledTokenActions.length > 0) {
acc.tokens.push(asset.vToken.underlyingToken);
}

return acc;
},
{
shortAsset: undefined,
longAsset: undefined,
tokens: [],
},
);

const readablePriceLongTokens = priceLongTokens.dp(6).toFixed();
const priceLongTokens =
longAsset && shortAsset ? longAsset.tokenPriceCents.div(shortAsset.tokenPriceCents) : undefined;

const readablePriceLongTokens = priceLongTokens
? priceLongTokens.dp(6).toFixed()
: PLACEHOLDER_KEY;

const readableChangePercentage = formatPercentageToReadableValue(changePercentage);

const cells: CellProps[] = [
{
label: t('yieldPlus.longLiquidity'),
value: formatCentsToReadableValue({
value: shortAsset?.liquidityCents,
value: longAsset?.liquidityCents,
}),
},
{
label: t('yieldPlus.shortLiquidity'),
value: formatCentsToReadableValue({
value: longAsset?.liquidityCents,
value: shortAsset?.liquidityCents,
}),
},
{
Expand Down Expand Up @@ -116,14 +125,14 @@ export const PairInfo: React.FC = () => {
<div className="flex min-w-0 flex-col gap-6 md:flex-row md:justify-between md:items-start lg:flex lg:flex-col">
<div className="flex items-center gap-x-3">
<div className="flex items-center -space-x-2">
<TokenIcon token={shortToken} className="size-8" />

<TokenIcon token={longToken} className="size-8" />

<TokenIcon token={shortToken} className="size-8" />
</div>

<div className="flex flex-col">
<p className="text-b1s">
{shortToken.symbol}/{longToken.symbol}
{longToken.symbol}/{shortToken.symbol}
</p>

<div className="flex items-center gap-x-1">
Expand Down
Loading
Loading