setup introjs tour
This commit is contained in:
parent
1e0c38799f
commit
b8d34934d9
|
@ -5,6 +5,7 @@ import Button from './Button'
|
|||
import useLocalStorageState from '../hooks/useLocalStorageState'
|
||||
import { useTranslation } from 'next-i18next'
|
||||
import Checkbox from './Checkbox'
|
||||
import { SHOW_TOUR_KEY } from './IntroTips'
|
||||
|
||||
export const ALPHA_MODAL_KEY = 'mangoAlphaAccepted-3.06'
|
||||
|
||||
|
@ -18,11 +19,17 @@ const AlphaModal = ({
|
|||
const { t } = useTranslation('common')
|
||||
const [acceptRisks, setAcceptRisks] = useState(false)
|
||||
const [, setAlphaAccepted] = useLocalStorageState(ALPHA_MODAL_KEY, false)
|
||||
const [, setShowTips] = useLocalStorageState(SHOW_TOUR_KEY, false)
|
||||
|
||||
const handleAccept = () => {
|
||||
const handleGetStarted = () => {
|
||||
setAlphaAccepted(true)
|
||||
}
|
||||
|
||||
const handleTakeTour = () => {
|
||||
setAlphaAccepted(true)
|
||||
setShowTips(true)
|
||||
}
|
||||
|
||||
return (
|
||||
<Modal isOpen={isOpen} onClose={onClose} hideClose>
|
||||
<Modal.Header>
|
||||
|
@ -71,9 +78,20 @@ const AlphaModal = ({
|
|||
I understand and accept the risks
|
||||
</Checkbox>
|
||||
</div>
|
||||
<div className={`mt-6 flex justify-center`}>
|
||||
<Button disabled={!acceptRisks} onClick={handleAccept}>
|
||||
Let's Go
|
||||
<div className={`mt-6 flex justify-center space-x-4`}>
|
||||
<Button
|
||||
className="w-40"
|
||||
disabled={!acceptRisks}
|
||||
onClick={handleGetStarted}
|
||||
>
|
||||
Get Started
|
||||
</Button>
|
||||
<Button
|
||||
className="w-40"
|
||||
disabled={!acceptRisks}
|
||||
onClick={handleTakeTour}
|
||||
>
|
||||
Take a Tour
|
||||
</Button>
|
||||
</div>
|
||||
</Modal>
|
||||
|
|
|
@ -54,7 +54,7 @@ const ConnectWalletButton = () => {
|
|||
<>
|
||||
{connected && wallet?.publicKey ? (
|
||||
<Menu>
|
||||
<div className="relative">
|
||||
<div className="relative" id="intro-step-1">
|
||||
<Menu.Button className="bg-th-bkg-4 flex items-center justify-center rounded-full w-10 h-10 text-white focus:outline-none hover:bg-th-bkg-4 hover:text-th-fgd-3">
|
||||
<ProfileIcon className="h-6 w-6" />
|
||||
</Menu.Button>
|
||||
|
@ -104,7 +104,10 @@ const ConnectWalletButton = () => {
|
|||
</div>
|
||||
</Menu>
|
||||
) : (
|
||||
<div className="bg-th-bkg-1 h-14 flex divide-x divide-th-bkg-3 justify-between">
|
||||
<div
|
||||
className="bg-th-bkg-1 h-14 flex divide-x divide-th-bkg-3 justify-between"
|
||||
id="intro-step-0"
|
||||
>
|
||||
<button
|
||||
onClick={handleWalletConect}
|
||||
disabled={!wallet}
|
||||
|
|
|
@ -0,0 +1,165 @@
|
|||
import React, { Component } from 'react'
|
||||
import { Steps } from 'intro.js-react'
|
||||
|
||||
export const SHOW_TOUR_KEY = 'showTour'
|
||||
|
||||
interface Props {
|
||||
showTour: boolean
|
||||
connected: boolean
|
||||
}
|
||||
|
||||
interface State {
|
||||
steps: any
|
||||
stepsEnabled: boolean
|
||||
initialStep: number
|
||||
}
|
||||
|
||||
class IntroTips extends Component<Props, State> {
|
||||
steps: any
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.state = {
|
||||
stepsEnabled: true,
|
||||
initialStep: 0,
|
||||
steps: [
|
||||
{
|
||||
element: '#intro-step-0',
|
||||
intro: (
|
||||
<div>
|
||||
<h4>Connect your wallet</h4>
|
||||
<p>We'll show you around...</p>
|
||||
</div>
|
||||
),
|
||||
tooltipClass: 'intro-tooltip',
|
||||
highlightClass: 'intro-highlight',
|
||||
},
|
||||
{
|
||||
element: '#intro-step-1',
|
||||
intro: (
|
||||
<div>
|
||||
<h4>Profile Menu</h4>
|
||||
<p>
|
||||
Access your Mango Accounts, copy your wallet address and
|
||||
disconnect here.
|
||||
</p>
|
||||
</div>
|
||||
),
|
||||
tooltipClass: 'intro-tooltip',
|
||||
highlightClass: 'intro-highlight',
|
||||
disableInteraction: true,
|
||||
},
|
||||
{
|
||||
element: '#intro-step-2',
|
||||
intro: (
|
||||
<div>
|
||||
<h4>Pick a theme</h4>
|
||||
<p>Mango, Dark or Light (if you're that way inclined).</p>
|
||||
</div>
|
||||
),
|
||||
tooltipClass: 'intro-tooltip',
|
||||
highlightClass: 'intro-highlight',
|
||||
disableInteraction: true,
|
||||
},
|
||||
{
|
||||
element: '#intro-step-3',
|
||||
intro: (
|
||||
<div>
|
||||
<h4>English not your preferred language?</h4>
|
||||
<p>No problem, change it here. More languages coming soon...</p>
|
||||
</div>
|
||||
),
|
||||
tooltipClass: 'intro-tooltip',
|
||||
highlightClass: 'intro-highlight',
|
||||
disableInteraction: true,
|
||||
},
|
||||
{
|
||||
element: '#intro-step-4',
|
||||
intro: (
|
||||
<div>
|
||||
<h4>Refresh your account data</h4>
|
||||
<p>
|
||||
Data is refreshed automatically but you can manually refresh
|
||||
here.
|
||||
</p>
|
||||
</div>
|
||||
),
|
||||
tooltipClass: 'intro-tooltip',
|
||||
highlightClass: 'intro-highlight',
|
||||
disableInteraction: true,
|
||||
},
|
||||
{
|
||||
element: '#intro-step-5',
|
||||
intro: (
|
||||
<div>
|
||||
<h4>Customize the layout</h4>
|
||||
<p>
|
||||
Unlock to re-arrange and re-size the trading panels to your
|
||||
liking.
|
||||
</p>
|
||||
</div>
|
||||
),
|
||||
tooltipClass: 'intro-tooltip',
|
||||
highlightClass: 'intro-highlight',
|
||||
disableInteraction: true,
|
||||
},
|
||||
{
|
||||
element: '#intro-step-6',
|
||||
intro: (
|
||||
<div>
|
||||
<h4>Perp position details</h4>
|
||||
<p>
|
||||
When you open a perp position, you'll see the details here.
|
||||
If you're unfamiliar with how settling PnL works, we'd
|
||||
recommend reading up on it before you get started.
|
||||
</p>
|
||||
</div>
|
||||
),
|
||||
tooltipClass: 'intro-tooltip',
|
||||
highlightClass: 'intro-highlight',
|
||||
disableInteraction: true,
|
||||
},
|
||||
],
|
||||
}
|
||||
}
|
||||
|
||||
handleEndTour = () => {
|
||||
localStorage.setItem('showTour', 'false')
|
||||
this.setState({ stepsEnabled: false })
|
||||
}
|
||||
|
||||
onBeforeChange = (nextStepIndex) => {
|
||||
if (nextStepIndex === 1) {
|
||||
this.steps.updateStepElement(nextStepIndex)
|
||||
document.querySelector<HTMLElement>(
|
||||
'.introjs-tooltipbuttons'
|
||||
).style.display = 'block'
|
||||
}
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
if (this.props.connected !== prevProps.connected) {
|
||||
this.steps.introJs.nextStep()
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
const { initialStep, stepsEnabled, steps } = this.state
|
||||
const { showTour } = this.props
|
||||
|
||||
return showTour ? (
|
||||
<Steps
|
||||
enabled={stepsEnabled}
|
||||
steps={steps}
|
||||
initialStep={initialStep}
|
||||
onBeforeChange={this.onBeforeChange}
|
||||
onExit={() => this.handleEndTour()}
|
||||
options={{
|
||||
skipLabel: 'Skip Tour',
|
||||
exitOnOverlayClick: false,
|
||||
}}
|
||||
ref={(steps) => (this.steps = steps)}
|
||||
/>
|
||||
) : null
|
||||
}
|
||||
}
|
||||
export default IntroTips
|
|
@ -36,20 +36,24 @@ const LanguageSwitch = () => {
|
|||
setSavedLanguage(e)
|
||||
}
|
||||
|
||||
return mounted ? (
|
||||
<DropMenu
|
||||
button={
|
||||
<div className="bg-th-bkg-4 flex items-center justify-center rounded-full w-8 h-8 text-th-fgd-1 focus:outline-none hover:text-th-primary">
|
||||
<TranslateIcon className="h-4 w-4" />
|
||||
</div>
|
||||
}
|
||||
value={savedLanguage}
|
||||
onChange={(lang) => handleLangChange(lang)}
|
||||
options={LANGS}
|
||||
toolTipContent={t('change-language')}
|
||||
/>
|
||||
) : (
|
||||
<div className="bg-th-bkg-3 rounded-full w-8 h-8" />
|
||||
return (
|
||||
<div id="intro-step-3">
|
||||
{mounted ? (
|
||||
<DropMenu
|
||||
button={
|
||||
<div className="bg-th-bkg-4 flex items-center justify-center rounded-full w-8 h-8 text-th-fgd-1 focus:outline-none hover:text-th-primary">
|
||||
<TranslateIcon className="h-4 w-4" />
|
||||
</div>
|
||||
}
|
||||
value={savedLanguage}
|
||||
onChange={(lang) => handleLangChange(lang)}
|
||||
options={LANGS}
|
||||
toolTipContent={t('change-language')}
|
||||
/>
|
||||
) : (
|
||||
<div className="bg-th-bkg-3 rounded-full w-8 h-8" />
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -254,10 +254,14 @@ const MarketDetails = () => {
|
|||
</div>
|
||||
</div>
|
||||
<div className="absolute right-4 bottom-0 sm:bottom-auto lg:right-6 flex items-center justify-end">
|
||||
{!isMobile ? <UiLock /> : null}
|
||||
{!isMobile && connected && mangoAccount ? (
|
||||
<ManualRefresh className="pl-2" />
|
||||
{!isMobile ? (
|
||||
<div id="intro-step-5">
|
||||
<UiLock />
|
||||
</div>
|
||||
) : null}
|
||||
<div className="ml-2" id="intro-step-4">
|
||||
{!isMobile && connected && mangoAccount ? <ManualRefresh /> : null}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
|
|
@ -152,7 +152,10 @@ export default function MarketPosition() {
|
|||
|
||||
return (
|
||||
<>
|
||||
<div className={!connected && !isMobile ? 'filter blur-sm' : null}>
|
||||
<div
|
||||
className={!connected && !isMobile ? 'filter blur-sm' : null}
|
||||
id="intro-step-6"
|
||||
>
|
||||
{!isMobile ? (
|
||||
<ElementTitle>
|
||||
{marketConfig.name} {t('position')}
|
||||
|
|
|
@ -19,20 +19,24 @@ const ThemeSwitch = () => {
|
|||
// When mounted on client, now we can show the UI
|
||||
useEffect(() => setMounted(true), [])
|
||||
|
||||
return mounted ? (
|
||||
<DropMenu
|
||||
button={
|
||||
<div className="bg-th-bkg-4 flex items-center justify-center rounded-full w-8 h-8 text-th-fgd-1 focus:outline-none hover:text-th-primary">
|
||||
{THEMES.find((t) => t.name === theme).icon}
|
||||
</div>
|
||||
}
|
||||
value={theme}
|
||||
onChange={(theme) => setTheme(theme)}
|
||||
options={THEMES}
|
||||
toolTipContent={t('change-theme')}
|
||||
/>
|
||||
) : (
|
||||
<div className="bg-th-bkg-3 rounded-full w-8 h-8" />
|
||||
return (
|
||||
<div id="intro-step-2">
|
||||
{mounted ? (
|
||||
<DropMenu
|
||||
button={
|
||||
<div className="bg-th-bkg-4 flex items-center justify-center rounded-full w-8 h-8 text-th-fgd-1 focus:outline-none hover:text-th-primary">
|
||||
{THEMES.find((t) => t.name === theme).icon}
|
||||
</div>
|
||||
}
|
||||
value={theme}
|
||||
onChange={(theme) => setTheme(theme)}
|
||||
options={THEMES}
|
||||
toolTipContent={t('change-theme')}
|
||||
/>
|
||||
) : (
|
||||
<div className="bg-th-bkg-3 rounded-full w-8 h-8" />
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -47,7 +47,7 @@ const TVChartContainer = () => {
|
|||
|
||||
const selectedMarketName = selectedMarketConfig.name
|
||||
const openOrders = useOpenOrders()
|
||||
const actions = useMangoStore((s) => s.actions )
|
||||
const actions = useMangoStore((s) => s.actions)
|
||||
const connected = useMangoStore((s) => s.wallet.connected)
|
||||
const selectedMarginAccount =
|
||||
useMangoStore.getState().selectedMangoAccount.current
|
||||
|
@ -149,7 +149,6 @@ const TVChartContainer = () => {
|
|||
//eslint-disable-next-line
|
||||
}, [selectedMarketConfig, theme, isMobile])
|
||||
|
||||
|
||||
const handleCancelOrder = async (
|
||||
order: Order | PerpOrder | PerpTriggerOrder,
|
||||
market: Market | PerpMarket
|
||||
|
@ -204,11 +203,10 @@ const TVChartContainer = () => {
|
|||
actions.reloadMangoAccount()
|
||||
actions.reloadOrders()
|
||||
toggleOrderInProgress(false)
|
||||
toggleMoveInProgress(false)
|
||||
toggleMoveInProgress(false)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const handleModifyOrder = async (
|
||||
order: Order | PerpOrder,
|
||||
market: Market | PerpMarket,
|
||||
|
@ -283,7 +281,6 @@ const TVChartContainer = () => {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
function getLine(order, market) {
|
||||
return tvWidgetRef.current
|
||||
.chart()
|
||||
|
@ -321,13 +318,9 @@ const TVChartContainer = () => {
|
|||
tvWidgetRef.current.showConfirmDialog({
|
||||
title: 'Modify Your Order?',
|
||||
body: `Would you like to change your order from a
|
||||
${order.size} ${market.config.baseSymbol} ${
|
||||
order.side
|
||||
} at $${currentOrderPrice}
|
||||
${order.size} ${market.config.baseSymbol} ${order.side} at $${currentOrderPrice}
|
||||
to a
|
||||
${order.size} ${market.config.baseSymbol} LIMIT ${
|
||||
order.side
|
||||
} at $${updatedOrderPrice}?
|
||||
${order.size} ${market.config.baseSymbol} LIMIT ${order.side} at $${updatedOrderPrice}?
|
||||
`,
|
||||
callback: (res) => {
|
||||
if (res) {
|
||||
|
@ -340,11 +333,10 @@ const TVChartContainer = () => {
|
|||
},
|
||||
})
|
||||
}
|
||||
} else {
|
||||
} else {
|
||||
tvWidgetRef.current.showNoticeDialog({
|
||||
title: 'Advanced Order Type',
|
||||
body:
|
||||
'Advanced order types in the chart window may only be cancelled. If new conditions are required, please cancel this order and use the Advanced Trade Form.',
|
||||
body: 'Advanced order types in the chart window may only be cancelled. If new conditions are required, please cancel this order and use the Advanced Trade Form.',
|
||||
callback: () => {
|
||||
this.setPrice(currentOrderPrice)
|
||||
toggleMoveInProgress(false)
|
||||
|
@ -358,9 +350,7 @@ const TVChartContainer = () => {
|
|||
tvWidgetRef.current.showConfirmDialog({
|
||||
title: 'Cancel Your Order?',
|
||||
body: `Would you like to cancel your order for
|
||||
${order.size} ${market.config.baseSymbol} ${
|
||||
order.side
|
||||
} at $${order.price}
|
||||
${order.size} ${market.config.baseSymbol} ${order.side} at $${order.price}
|
||||
`,
|
||||
callback: (res) => {
|
||||
if (res) {
|
||||
|
@ -374,39 +364,94 @@ const TVChartContainer = () => {
|
|||
.setPrice(order.price)
|
||||
.setQuantity(order.size)
|
||||
.setText(getLineText(order, market))
|
||||
.setTooltip(order.perpTrigger?.clientOrderId ? `${order.orderType} Order #: ${order.orderId}` : `Order #: ${order.orderId}`)
|
||||
.setBodyTextColor(theme === 'Dark' ? '#F2C94C' : theme === 'Light' ? '#FF9C24' : '#F2C94C')
|
||||
.setQuantityTextColor(theme === 'Dark' ? '#F2C94C' : theme === 'Light' ? '#FF9C24' : '#F2C94C')
|
||||
.setCancelButtonIconColor(theme === 'Dark' ? '#F2C94C' : theme === 'Light' ? '#FF9C24' : '#F2C94C')
|
||||
.setBodyBorderColor(order.perpTrigger?.clientOrderId ? '#FF9C24' : order.side == 'buy' ? '#4BA53B' : '#AA2222')
|
||||
.setQuantityBorderColor(order.perpTrigger?.clientOrderId ? '#FF9C24' : order.side == 'buy' ? '#4BA53B' : '#AA2222')
|
||||
.setCancelButtonBorderColor(order.perpTrigger?.clientOrderId ? '#FF9C24' : order.side == 'buy' ? '#4BA53B' : '#AA2222')
|
||||
.setBodyBackgroundColor(theme === 'Dark' ? '#1B1B1F' : theme === 'Light' ? '#fff' : '#1D1832')
|
||||
.setQuantityBackgroundColor(theme === 'Dark' ? '#1B1B1F' : theme === 'Light' ? '#fff' : '#1D1832')
|
||||
.setCancelButtonBackgroundColor(theme === 'Dark' ? '#1B1B1F' : theme === 'Light' ? '#fff' : '#1D1832')
|
||||
.setTooltip(
|
||||
order.perpTrigger?.clientOrderId
|
||||
? `${order.orderType} Order #: ${order.orderId}`
|
||||
: `Order #: ${order.orderId}`
|
||||
)
|
||||
.setBodyTextColor(
|
||||
theme === 'Dark' ? '#F2C94C' : theme === 'Light' ? '#FF9C24' : '#F2C94C'
|
||||
)
|
||||
.setQuantityTextColor(
|
||||
theme === 'Dark' ? '#F2C94C' : theme === 'Light' ? '#FF9C24' : '#F2C94C'
|
||||
)
|
||||
.setCancelButtonIconColor(
|
||||
theme === 'Dark' ? '#F2C94C' : theme === 'Light' ? '#FF9C24' : '#F2C94C'
|
||||
)
|
||||
.setBodyBorderColor(
|
||||
order.perpTrigger?.clientOrderId
|
||||
? '#FF9C24'
|
||||
: order.side == 'buy'
|
||||
? '#4BA53B'
|
||||
: '#AA2222'
|
||||
)
|
||||
.setQuantityBorderColor(
|
||||
order.perpTrigger?.clientOrderId
|
||||
? '#FF9C24'
|
||||
: order.side == 'buy'
|
||||
? '#4BA53B'
|
||||
: '#AA2222'
|
||||
)
|
||||
.setCancelButtonBorderColor(
|
||||
order.perpTrigger?.clientOrderId
|
||||
? '#FF9C24'
|
||||
: order.side == 'buy'
|
||||
? '#4BA53B'
|
||||
: '#AA2222'
|
||||
)
|
||||
.setBodyBackgroundColor(
|
||||
theme === 'Dark' ? '#1B1B1F' : theme === 'Light' ? '#fff' : '#1D1832'
|
||||
)
|
||||
.setQuantityBackgroundColor(
|
||||
theme === 'Dark' ? '#1B1B1F' : theme === 'Light' ? '#fff' : '#1D1832'
|
||||
)
|
||||
.setCancelButtonBackgroundColor(
|
||||
theme === 'Dark' ? '#1B1B1F' : theme === 'Light' ? '#fff' : '#1D1832'
|
||||
)
|
||||
.setBodyFont('Lato, sans-serif')
|
||||
.setQuantityFont('Lato, sans-serif')
|
||||
.setLineColor(order.perpTrigger?.clientOrderId ? '#FF9C24' : order.side == 'buy' ? '#4BA53B' : '#AA2222')
|
||||
.setLineColor(
|
||||
order.perpTrigger?.clientOrderId
|
||||
? '#FF9C24'
|
||||
: order.side == 'buy'
|
||||
? '#4BA53B'
|
||||
: '#AA2222'
|
||||
)
|
||||
.setLineLength(3)
|
||||
.setLineWidth(2)
|
||||
.setLineStyle(1)
|
||||
}
|
||||
|
||||
|
||||
function getLineText(order, market) {
|
||||
if (order.perpTrigger?.clientOrderId) {
|
||||
const triggerPrice = order.perpTrigger.triggerPrice * Math.pow(10, market.config.baseDecimals - market.config.quoteDecimals)
|
||||
const triggerPrice =
|
||||
order.perpTrigger.triggerPrice *
|
||||
Math.pow(10, market.config.baseDecimals - market.config.quoteDecimals)
|
||||
if (order.side === 'buy') {
|
||||
if (order.perpTrigger.triggerCondition === 'above') {
|
||||
return (order.orderType === 'market' ? `Stop Loss ` : `Stop Limit `) + `(${order.orderType} ${order.side}) if price is ${order.perpTrigger.triggerCondition} ${usdFormatter(triggerPrice)}`
|
||||
return (
|
||||
(order.orderType === 'market' ? `Stop Loss ` : `Stop Limit `) +
|
||||
`(${order.orderType} ${order.side}) if price is ${
|
||||
order.perpTrigger.triggerCondition
|
||||
} ${usdFormatter(triggerPrice)}`
|
||||
)
|
||||
} else {
|
||||
return `Take Profit (${order.orderType} ${order.side}) if price is ${order.perpTrigger.triggerCondition} ${usdFormatter(triggerPrice)}`
|
||||
return `Take Profit (${order.orderType} ${order.side}) if price is ${
|
||||
order.perpTrigger.triggerCondition
|
||||
} ${usdFormatter(triggerPrice)}`
|
||||
}
|
||||
} else {
|
||||
if (order.perpTrigger.triggerCondition === 'below') {
|
||||
return (order.orderType === 'market' ? `Stop Loss ` : `Stop Limit `) + `(${order.orderType} ${order.side}) if price is ${order.perpTrigger.triggerCondition} ${usdFormatter(triggerPrice)}`
|
||||
return (
|
||||
(order.orderType === 'market' ? `Stop Loss ` : `Stop Limit `) +
|
||||
`(${order.orderType} ${order.side}) if price is ${
|
||||
order.perpTrigger.triggerCondition
|
||||
} ${usdFormatter(triggerPrice)}`
|
||||
)
|
||||
} else {
|
||||
return `Take Profit (${order.orderType} ${order.side}) if price is ${order.perpTrigger.triggerCondition} ${usdFormatter(triggerPrice)}`
|
||||
return `Take Profit (${order.orderType} ${order.side}) if price is ${
|
||||
order.perpTrigger.triggerCondition
|
||||
} ${usdFormatter(triggerPrice)}`
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -414,7 +459,6 @@ const TVChartContainer = () => {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
function deleteLines() {
|
||||
tvWidgetRef.current.onChartReady(() => {
|
||||
if (lines?.size > 0) {
|
||||
|
@ -426,7 +470,6 @@ const TVChartContainer = () => {
|
|||
return new Map()
|
||||
}
|
||||
|
||||
|
||||
function drawLines() {
|
||||
const tempLines = new Map()
|
||||
tvWidgetRef.current.onChartReady(() => {
|
||||
|
@ -439,10 +482,14 @@ const TVChartContainer = () => {
|
|||
return tempLines
|
||||
}
|
||||
|
||||
|
||||
useInterval(() => {
|
||||
if (selectedMarginAccount && connected && !moveInProgress && !orderInProgress && openOrders?.length > 0) {
|
||||
|
||||
if (
|
||||
selectedMarginAccount &&
|
||||
connected &&
|
||||
!moveInProgress &&
|
||||
!orderInProgress &&
|
||||
openOrders?.length > 0
|
||||
) {
|
||||
let matches = 0
|
||||
let openOrdersInSelectedMarket = 0
|
||||
lines?.forEach((value, key) => {
|
||||
|
@ -460,23 +507,23 @@ const TVChartContainer = () => {
|
|||
})
|
||||
|
||||
if (
|
||||
lines?.size != openOrdersInSelectedMarket
|
||||
|| matches != openOrdersInSelectedMarket
|
||||
|| lines?.size > 0 && lines?.size != matches
|
||||
|| lines?.size > 0 && !selectedMarginAccount
|
||||
|| priceReset
|
||||
lines?.size != openOrdersInSelectedMarket ||
|
||||
matches != openOrdersInSelectedMarket ||
|
||||
(lines?.size > 0 && lines?.size != matches) ||
|
||||
(lines?.size > 0 && !selectedMarginAccount) ||
|
||||
priceReset
|
||||
) {
|
||||
if (priceReset) { togglePriceReset(false) }
|
||||
if (priceReset) {
|
||||
togglePriceReset(false)
|
||||
}
|
||||
setLines(deleteLines())
|
||||
setLines(drawLines())
|
||||
}
|
||||
|
||||
} else if (lines?.size > 0 && !moveInProgress && !orderInProgress) {
|
||||
setLines(deleteLines())
|
||||
}
|
||||
}, [100])
|
||||
|
||||
|
||||
return <div id={defaultProps.containerId} className="tradingview-chart" />
|
||||
}
|
||||
|
||||
|
|
|
@ -62,4 +62,4 @@ const TradeType = ({
|
|||
)
|
||||
}
|
||||
|
||||
export default TradeType
|
||||
export default TradeType
|
||||
|
|
|
@ -48,6 +48,8 @@
|
|||
"dayjs": "^1.10.4",
|
||||
"immer": "^9.0.1",
|
||||
"immutable-tuple": "^0.4.10",
|
||||
"intro.js": "^4.2.2",
|
||||
"intro.js-react": "^0.5.0",
|
||||
"lodash-es": "^4.17.21",
|
||||
"next": "^11.1.0",
|
||||
"next-i18next": "^8.9.0",
|
||||
|
|
|
@ -2,6 +2,7 @@ import Head from 'next/head'
|
|||
import { ThemeProvider } from 'next-themes'
|
||||
import '../node_modules/react-grid-layout/css/styles.css'
|
||||
import '../node_modules/react-resizable/css/styles.css'
|
||||
import 'intro.js/introjs.css'
|
||||
import '../styles/index.css'
|
||||
import useWallet from '../hooks/useWallet'
|
||||
import useHydrateStore from '../hooks/useHydrateStore'
|
||||
|
|
|
@ -13,6 +13,7 @@ import useLocalStorageState from '../../hooks/useLocalStorageState'
|
|||
import AlphaModal, { ALPHA_MODAL_KEY } from '../../components/AlphaModal'
|
||||
import { PageBodyWrapper } from '../../components/styles'
|
||||
import { serverSideTranslations } from 'next-i18next/serverSideTranslations'
|
||||
import IntroTips, { SHOW_TOUR_KEY } from '../../components/IntroTips'
|
||||
|
||||
export async function getServerSideProps({ locale }) {
|
||||
return {
|
||||
|
@ -25,8 +26,10 @@ export async function getServerSideProps({ locale }) {
|
|||
|
||||
const PerpMarket = () => {
|
||||
const [alphaAccepted] = useLocalStorageState(ALPHA_MODAL_KEY, false)
|
||||
const [showTour] = useLocalStorageState(SHOW_TOUR_KEY, false)
|
||||
const groupConfig = useMangoGroupConfig()
|
||||
const setMangoStore = useMangoStore((s) => s.set)
|
||||
const connected = useMangoStore((s) => s.wallet.connected)
|
||||
const mangoGroup = useMangoStore((s) => s.selectedMangoGroup.current)
|
||||
const mangoCache = useMangoStore((s) => s.selectedMangoGroup.cache)
|
||||
const marketConfig = useMangoStore((s) => s.selectedMarket.config)
|
||||
|
@ -61,6 +64,7 @@ const PerpMarket = () => {
|
|||
|
||||
return (
|
||||
<div className={`bg-th-bkg-1 text-th-fgd-1 transition-all `}>
|
||||
<IntroTips connected={connected} showTour={showTour} />
|
||||
<TopBar />
|
||||
<MarketSelect />
|
||||
<PageBodyWrapper className="p-1 sm:px-2 sm:py-1 md:px-2 md:py-1">
|
||||
|
|
|
@ -321,3 +321,79 @@ input[type='number'] {
|
|||
.react-swipeable-view-container > div[aria-hidden='true'] {
|
||||
height: 0;
|
||||
}
|
||||
|
||||
/* Intro Tour */
|
||||
|
||||
.introjs-tooltip {
|
||||
@apply bg-transparent;
|
||||
}
|
||||
|
||||
.introjs-arrow {
|
||||
@apply border-0;
|
||||
}
|
||||
|
||||
.intro-tooltip * {
|
||||
@apply bg-th-bkg-1 font-body text-th-fgd-1;
|
||||
}
|
||||
|
||||
.introjs-skipbutton {
|
||||
@apply text-sm text-th-fgd-3;
|
||||
}
|
||||
|
||||
.introjs-tooltip-header {
|
||||
@apply rounded-t-md;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.introjs-tooltipbuttons {
|
||||
@apply border-th-bkg-4 hidden font-bold rounded-b-md focus:outline-none;
|
||||
}
|
||||
|
||||
.introjs-nextbutton {
|
||||
@apply bg-th-bkg-4 border-th-bkg-4 flex h-4 items-center rounded-full text-sm text-th-fgd-1;
|
||||
text-shadow: none;
|
||||
}
|
||||
|
||||
.introjs-prevbutton {
|
||||
@apply hidden;
|
||||
}
|
||||
|
||||
.introjs-button:hover {
|
||||
@apply bg-th-bkg-4 border-th-bkg-4 brightness-[1.15] text-th-fgd-1;
|
||||
}
|
||||
|
||||
.introjs-button:focus {
|
||||
@apply bg-th-bkg-4 border-th-bkg-4 shadow-none text-th-fgd-1;
|
||||
}
|
||||
|
||||
.introjs-hidden {
|
||||
@apply hidden;
|
||||
}
|
||||
|
||||
.introjs-progressbar {
|
||||
@apply bg-th-primary;
|
||||
}
|
||||
|
||||
.intro-tooltip h4 {
|
||||
@apply font-body font-bold mb-1 text-lg;
|
||||
}
|
||||
|
||||
.intro-tooltip p {
|
||||
@apply font-body text-sm text-th-fgd-3;
|
||||
}
|
||||
|
||||
.introjs-bullets ul li a {
|
||||
@apply bg-th-bkg-4;
|
||||
}
|
||||
|
||||
.introjs-bullets ul li a:hover {
|
||||
@apply bg-th-fgd-4;
|
||||
}
|
||||
|
||||
.introjs-bullets ul li a.active {
|
||||
@apply bg-th-primary;
|
||||
}
|
||||
|
||||
.intro-highlight {
|
||||
@apply border-0;
|
||||
}
|
||||
|
|
|
@ -108,7 +108,7 @@ export function calculateTradePrice(
|
|||
if (tradeType === 'Market') {
|
||||
return calculateMarketPrice(orderBook, baseSize, side)
|
||||
} else if (TRIGGER_ORDER_TYPES.includes(tradeType)) {
|
||||
if( tradeType === 'Take Profit Limit' || tradeType === 'Stop Limit' ) {
|
||||
if (tradeType === 'Take Profit Limit' || tradeType === 'Stop Limit') {
|
||||
return Number(price)
|
||||
} else {
|
||||
return Number(triggerPrice)
|
||||
|
|
10
yarn.lock
10
yarn.lock
|
@ -4802,6 +4802,16 @@ internmap@^1.0.0:
|
|||
resolved "https://registry.yarnpkg.com/internmap/-/internmap-1.0.1.tgz#0017cc8a3b99605f0302f2b198d272e015e5df95"
|
||||
integrity sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw==
|
||||
|
||||
intro.js-react@^0.5.0:
|
||||
version "0.5.0"
|
||||
resolved "https://registry.yarnpkg.com/intro.js-react/-/intro.js-react-0.5.0.tgz#d4e67a4f6e4726bee803222ff09d6deacb4598c8"
|
||||
integrity sha512-tr9uhoy/aRgcdZxpqYC/TPSVlJ/Gt9Kx4mpI7clCdFa7c3SG8reJugIa1U5XnWlDLRNMc+e8egb8Jf186yvc1A==
|
||||
|
||||
intro.js@^4.2.2:
|
||||
version "4.2.2"
|
||||
resolved "https://registry.yarnpkg.com/intro.js/-/intro.js-4.2.2.tgz#9077549cc6ef697e78d18d1c05003b7471281e1a"
|
||||
integrity sha512-Zgz2e8syCuttJ2vJlDOWCSWPUJBr7AOJkU5Ti3zcvXho+y//q0ixwoT+PkPLJWI7AX35IdgRcxAEWUrOAJYiNQ==
|
||||
|
||||
is-accessor-descriptor@^0.1.6:
|
||||
version "0.1.6"
|
||||
resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6"
|
||||
|
|
Loading…
Reference in New Issue