Skip to content

Commit 90837ca

Browse files
authored
Merge pull request #1831 from IndexCoop/feat/tradingview-advanced-chart
feat: TradingView Advanced Chart
2 parents 74f5c9b + 7483b1d commit 90837ca

14 files changed

+454
-221
lines changed

.gitmodules

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[submodule "public/tradingview-chart"]
2+
path = public/tradingview-chart
3+
url = https://github.com/IndexCoop/tradingview-chart.git

public/tradingview-chart

Submodule tradingview-chart added at 63e2c7f

src/app/leverage/components/leverage-feedback-button.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ export function LeverageFeedbackButton() {
66
return (
77
<PopupButton
88
id='Ns10DhMF'
9-
className='text-ic-black bg-ic-gray-700 hover:bg-ic-gray-500 h-12 w-full rounded-lg py-2.5 font-bold'
9+
className='text-ic-black bg-ic-gray-700 hover:bg-ic-gray-500 hidden h-12 w-full rounded-lg py-2.5 font-bold lg:block'
1010
tracking={surveyTracking}
1111
>
1212
Give us your feedback!
Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,30 @@
1-
import { LeveragePanelDesktop } from '@/app/leverage/components/leverage-panel/leverage-panel-desktop'
2-
import { LeveragePanelMobile } from '@/app/leverage/components/leverage-panel/leverage-panel-mobile'
3-
import { Token } from '@/constants/tokens'
1+
import { Suspense } from 'react'
42

5-
type Props = {
6-
indexToken: Token
7-
}
3+
import { LeverageFeedbackButton } from '@/app/leverage/components/leverage-feedback-button'
4+
import { LeverageWidget } from '@/app/leverage/components/leverage-widget'
5+
import PortfolioWidget from '@/app/leverage/components/portfolio-widget/portfolio-widget'
6+
import { TradingViewChart } from '@/app/leverage/components/trading-view-chart'
87

9-
export function LeveragePanel({ indexToken }: Props) {
8+
export function LeveragePanel() {
109
return (
11-
<>
12-
<LeveragePanelMobile indexToken={indexToken} />
13-
<LeveragePanelDesktop indexToken={indexToken} />
14-
</>
10+
<div className='flex flex-col gap-4 lg:h-[630px] lg:flex-row'>
11+
<div className='xs:h-[442px] aspect-square w-full lg:flex lg:aspect-auto lg:basis-2/3 lg:flex-col lg:gap-4'>
12+
<div className='relative h-full w-full'>
13+
<TradingViewChart />
14+
<div className='hidden lg:block lg:pt-4'>
15+
<PortfolioWidget />
16+
</div>
17+
</div>
18+
</div>
19+
<div className='flex w-full lg:w-auto lg:basis-1/3 lg:flex-col lg:gap-4'>
20+
<Suspense>
21+
<LeverageWidget />
22+
</Suspense>
23+
<LeverageFeedbackButton />
24+
</div>
25+
<div className='w-full lg:hidden'>
26+
<PortfolioWidget />
27+
</div>
28+
</div>
1529
)
1630
}

src/app/leverage/components/leverage-panel/leverage-panel-desktop.tsx

Lines changed: 0 additions & 30 deletions
This file was deleted.

src/app/leverage/components/leverage-panel/leverage-panel-mobile.tsx

Lines changed: 0 additions & 28 deletions
This file was deleted.

src/app/leverage/components/leverage-widget/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ export function LeverageWidget() {
103103

104104
return (
105105
<div
106-
className='leverage-widget flex flex-col gap-4 rounded-lg px-4 pb-5 pt-4'
106+
className='leverage-widget flex w-full flex-col gap-4 rounded-lg px-4 pb-5 pt-4'
107107
id='close-position-scroll'
108108
>
109109
<BuySellSelector isMinting={isMinting} onClick={toggleIsMinting} />
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
import { useEffect, useRef, useState } from 'react'
2+
3+
import { useLeverageToken } from '@/app/leverage/provider'
4+
// eslint-disable-next-line import/order
5+
import datafeed from '@/app/leverage/utils/datafeed'
6+
import {
7+
type ChartingLibraryWidgetOptions,
8+
type IChartingLibraryWidget,
9+
type ResolutionString,
10+
widget,
11+
} from '~/tradingview-chart/charting_library'
12+
13+
const WIDGET_INTERVAL = '1D' as ResolutionString
14+
15+
export const TradingViewChartContainer = () => {
16+
const { market } = useLeverageToken()
17+
const chartContainerRef =
18+
useRef<HTMLDivElement>() as React.MutableRefObject<HTMLInputElement>
19+
const [tvWidget, setTvWidget] = useState<IChartingLibraryWidget | null>(null)
20+
21+
useEffect(() => {
22+
const widgetOptions: ChartingLibraryWidgetOptions = {
23+
datafeed,
24+
debug: false,
25+
symbol: 'ETHUSD',
26+
interval: WIDGET_INTERVAL,
27+
container: chartContainerRef.current,
28+
library_path: '/tradingview-chart/charting_library/',
29+
locale: 'en',
30+
disabled_features: [
31+
'left_toolbar',
32+
'header_saveload',
33+
'header_symbol_search',
34+
],
35+
client_id: 'indexcoop',
36+
fullscreen: false,
37+
autosize: true,
38+
theme: 'dark',
39+
timezone: 'Etc/UTC',
40+
overrides: {
41+
// TODO: background doesn't appear to work
42+
'paneProperties.background': '#0F1717',
43+
'paneProperties.backgroundType': 'solid',
44+
},
45+
}
46+
47+
const tvWidget = new widget(widgetOptions)
48+
tvWidget.onChartReady(() => {
49+
setTvWidget(tvWidget)
50+
})
51+
52+
return () => {
53+
tvWidget.remove()
54+
}
55+
}, [])
56+
57+
useEffect(() => {
58+
if (!tvWidget) return
59+
60+
let symbol = null
61+
switch (market) {
62+
case 'BTC / USD':
63+
symbol = 'BTCUSD'
64+
break
65+
case 'ETH / USD':
66+
symbol = 'ETHUSD'
67+
break
68+
case 'SOL / USD':
69+
symbol = 'SOLUSD'
70+
break
71+
case 'SUI / USD':
72+
symbol = 'SUIUSD'
73+
break
74+
case 'BTC / ETH':
75+
symbol = 'BTCETH'
76+
break
77+
case 'ETH / BTC':
78+
symbol = 'ETHBTC'
79+
break
80+
}
81+
82+
if (symbol && tvWidget) {
83+
tvWidget.setSymbol(symbol, WIDGET_INTERVAL, () => {})
84+
}
85+
}, [market, tvWidget])
86+
87+
return (
88+
<div
89+
ref={chartContainerRef}
90+
className='h-full w-full overflow-hidden rounded-lg'
91+
/>
92+
)
93+
}

src/app/leverage/components/trading-view-chart.tsx

Lines changed: 14 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,26 @@
11
import { Button } from '@headlessui/react'
22
import { useAppKit } from '@reown/appkit/react'
3+
import Script from 'next/script'
4+
import { useState } from 'react'
35

4-
import TradingViewWidget from '@/app/leverage/components/trading-view-widget'
5-
import { Token } from '@/constants/tokens'
6+
import { TradingViewChartContainer } from '@/app/leverage/components/trading-view-chart-container'
67
import { useWallet } from '@/lib/hooks/use-wallet'
78

8-
type Props = {
9-
indexToken: Token
10-
}
11-
12-
export function TradingViewChart({ indexToken }: Props) {
9+
export function TradingViewChart() {
10+
const [isScriptReady, setIsScriptReady] = useState(false)
1311
const { isConnected } = useWallet()
1412
const { open } = useAppKit()
15-
1613
return (
1714
<div className='relative h-full w-full'>
18-
<div className='relative h-full w-full'>
19-
<TradingViewWidget chartSymbol='INDEX:ETHUSD' indexToken={indexToken} />
20-
<TradingViewWidget chartSymbol='INDEX:BTCUSD' indexToken={indexToken} />
21-
<TradingViewWidget
22-
chartSymbol='BINANCE:ETHBTC'
23-
indexToken={indexToken}
24-
/>
25-
<TradingViewWidget
26-
chartSymbol='VANTAGE:BTCETH'
27-
indexToken={indexToken}
28-
/>
29-
<TradingViewWidget
30-
chartSymbol='COINBASE:SOLUSD'
31-
indexToken={indexToken}
32-
/>
33-
<TradingViewWidget
34-
chartSymbol='COINBASE:SUIUSD'
35-
indexToken={indexToken}
36-
/>
37-
</div>
38-
{!isConnected && (
15+
<Script
16+
src='/tradingview-chart/datafeeds/udf/dist/bundle.js'
17+
onLoad={() => {
18+
setIsScriptReady(true)
19+
}}
20+
/>
21+
{isScriptReady && isConnected ? (
22+
<TradingViewChartContainer />
23+
) : (
3924
<div className='bg-ic-black/95 absolute inset-0 z-20 flex items-center justify-center'>
4025
<Button
4126
className='bg-ic-blue-500 dark:bg-ic-blue-300 dark:hover:bg-ic-blue-200 hover:bg-ic-blue-500/90 text-ic-gray-50 dark:text-ic-black block rounded-md px-8 py-1 text-sm font-medium shadow-sm transition-all duration-300 hover:scale-[1.04]'

src/app/leverage/components/trading-view-widget.tsx

Lines changed: 0 additions & 116 deletions
This file was deleted.

0 commit comments

Comments
 (0)