From f7684e3b8627ab7cc3a4783f1d65bb80e5c98f9e Mon Sep 17 00:00:00 2001 From: Matthew Russell Date: Thu, 7 Dec 2023 21:15:24 -0800 Subject: [PATCH] feat: persist selected indicators --- .../chart-container/chart-container.tsx | 6 +++++ .../chart-container/use-chart-settings.ts | 10 ++++++++ .../src/lib/trading-view-container.tsx | 8 +++++- libs/trading-view/src/lib/trading-view.tsx | 25 ++++++++++++++----- 4 files changed, 42 insertions(+), 7 deletions(-) diff --git a/apps/trading/components/chart-container/chart-container.tsx b/apps/trading/components/chart-container/chart-container.tsx index 2b27ac35b..535f8e2b6 100644 --- a/apps/trading/components/chart-container/chart-container.tsx +++ b/apps/trading/components/chart-container/chart-container.tsx @@ -25,10 +25,12 @@ export const ChartContainer = ({ marketId }: { marketId: string }) => { overlays, studies, studySizes, + tradingViewStudies, setInterval, setStudies, setStudySizes, setOverlays, + setTradingViewStudies, } = useChartSettings(); const pennantChart = ( @@ -62,9 +64,13 @@ export const ChartContainer = ({ marketId }: { marketId: string }) => { libraryHash={CHARTING_LIBRARY_HASH} marketId={marketId} interval={toTradingViewResolution(interval)} + studies={tradingViewStudies} onIntervalChange={(newInterval) => { setInterval(fromTradingViewResolution(newInterval)); }} + onAutoSaveNeeded={(data: { studies: string[] }) => { + setTradingViewStudies(data.studies); + }} /> ); } diff --git a/apps/trading/components/chart-container/use-chart-settings.ts b/apps/trading/components/chart-container/use-chart-settings.ts index f2819679f..fb33b3297 100644 --- a/apps/trading/components/chart-container/use-chart-settings.ts +++ b/apps/trading/components/chart-container/use-chart-settings.ts @@ -17,6 +17,7 @@ interface StoredSettings { overlays: Overlay[]; studies: Study[]; studySizes: StudySizes; + tradingViewStudies: string[]; } export const STUDY_SIZE = 90; @@ -35,6 +36,7 @@ export const DEFAULT_CHART_SETTINGS = { overlays: [Overlay.MOVING_AVERAGE], studies: [Study.MACD, Study.VOLUME], studySizes: {}, + tradingViewStudies: ['Volume'], }; export const useChartSettingsStore = create< @@ -45,6 +47,7 @@ export const useChartSettingsStore = create< setStudies: (studies?: Study[]) => void; setStudySizes: (sizes: number[]) => void; setChartlib: (lib: Chartlib) => void; + setTradingViewStudies: (studies: string[]) => void; } >()( persist( @@ -92,6 +95,11 @@ export const useChartSettingsStore = create< state.chartlib = lib; }); }, + setTradingViewStudies: (studies: string[]) => { + set((state) => { + state.tradingViewStudies = studies; + }); + }, })), { name: 'vega_candles_chart_store', @@ -139,11 +147,13 @@ export const useChartSettings = () => { overlays, studies, studySizes, + tradingViewStudies: settings.tradingViewStudies, setInterval: settings.setInterval, setType: settings.setType, setStudies: settings.setStudies, setOverlays: settings.setOverlays, setStudySizes: settings.setStudySizes, setChartlib: settings.setChartlib, + setTradingViewStudies: settings.setTradingViewStudies, }; }; diff --git a/libs/trading-view/src/lib/trading-view-container.tsx b/libs/trading-view/src/lib/trading-view-container.tsx index 44743ff4b..9cb02906e 100644 --- a/libs/trading-view/src/lib/trading-view-container.tsx +++ b/libs/trading-view/src/lib/trading-view-container.tsx @@ -1,7 +1,7 @@ import { useScript } from '@vegaprotocol/react-helpers'; import { Splash } from '@vegaprotocol/ui-toolkit'; import { useT } from './use-t'; -import { TradingView } from './trading-view'; +import { TradingView, type OnAutoSaveNeededCallback } from './trading-view'; import { CHARTING_LIBRARY_FILE, type ResolutionString } from './constants'; export const TradingViewContainer = ({ @@ -9,13 +9,17 @@ export const TradingViewContainer = ({ libraryHash, marketId, interval, + studies, onIntervalChange, + onAutoSaveNeeded, }: { libraryPath: string; libraryHash: string; marketId: string; interval: ResolutionString; + studies: string[]; onIntervalChange: (interval: string) => void; + onAutoSaveNeeded: OnAutoSaveNeededCallback; }) => { const t = useT(); const scriptState = useScript( @@ -44,7 +48,9 @@ export const TradingViewContainer = ({ libraryPath={libraryPath} marketId={marketId} interval={interval} + studies={studies} onIntervalChange={onIntervalChange} + onAutoSaveNeeded={onAutoSaveNeeded} /> ); }; diff --git a/libs/trading-view/src/lib/trading-view.tsx b/libs/trading-view/src/lib/trading-view.tsx index d7541646d..f839c1f79 100644 --- a/libs/trading-view/src/lib/trading-view.tsx +++ b/libs/trading-view/src/lib/trading-view.tsx @@ -7,16 +7,22 @@ import { useLanguage } from './use-t'; import { useDatafeed } from './use-datafeed'; import { type ResolutionString } from './constants'; +export type OnAutoSaveNeededCallback = (data: { studies: string[] }) => void; + export const TradingView = ({ marketId, libraryPath, interval, + studies, onIntervalChange, + onAutoSaveNeeded, }: { marketId: string; libraryPath: string; interval: ResolutionString; + studies: string[]; onIntervalChange: (interval: string) => void; + onAutoSaveNeeded: OnAutoSaveNeededCallback; }) => { const { isMobile } = useScreenDimensions(); const { theme } = useThemeSwitcher(); @@ -69,17 +75,24 @@ export const TradingView = ({ widgetRef.current.onChartReady(() => { widgetRef.current.applyOverrides(getOverrides(theme)); + widgetRef.current.subscribe('onAutoSaveNeeded', () => { + const studies = widgetRef.current + .activeChart() + .getAllStudies() + .map((s: { id: string; name: string }) => s.name); + onAutoSaveNeeded({ studies }); + }); + const activeChart = widgetRef.current.activeChart(); // Show volume study by default, second bool arg adds it as a overlay on top of the chart - activeChart.createStudy('volume', true); + studies.forEach((study) => { + const asOverlay = study === 'Volume'; + activeChart.createStudy(study, asOverlay); + }); // Subscribe to interval changes so it can be persisted in chart settings - activeChart - .onIntervalChanged() - .subscribe(null, (resolution: string) => { - onIntervalChange(resolution); - }); + activeChart.onIntervalChanged().subscribe(null, onIntervalChange); }); return () => {