import { FunctionComponent, useEffect, useMemo, createRef, useState, } from 'react' import { MarketConfig } from '@blockworks-foundation/mango-client' import useMangoStore from '../stores/useMangoStore' import Modal from './Modal' import { useScreenshot } from '../hooks/useScreenshot' import * as MonoIcons from './icons' import { TwitterIcon } from './icons' import QRCode from 'react-qr-code' import { useTranslation } from 'next-i18next' import useMangoAccount from '../hooks/useMangoAccount' import { mangoCacheSelector, mangoGroupConfigSelector, mangoGroupSelector, } from '../stores/selectors' import { getMarketIndexBySymbol, ReferrerIdRecord, } from '@blockworks-foundation/mango-client' import Button from './Button' import Switch from './Switch' import { roundPerpSize } from 'utils' const calculatePositionPercentage = (position) => { if (position.basePosition > 0) { const returnsPercentage = (position.indexPrice / position.avgEntryPrice - 1) * 100 return returnsPercentage } else { const returnsPercentage = (position.indexPrice / position.avgEntryPrice - 1) * -100 return returnsPercentage } } async function copyToClipboard(image) { try { image.toBlob((blob) => { navigator.clipboard.write([new ClipboardItem({ 'image/png': blob })]) }, 'image/png') } catch (error) { console.error(error) } } interface ShareModalProps { onClose: () => void isOpen: boolean position: { indexPrice: number avgEntryPrice: number basePosition: number marketConfig: MarketConfig notionalSize: number } } const ShareModal: FunctionComponent = ({ isOpen, onClose, position, }) => { const { t } = useTranslation(['common', 'share-modal']) const ref = createRef() const [copied, setCopied] = useState(false) const [showButton, setShowButton] = useState(true) const [image, takeScreenshot] = useScreenshot() const { mangoAccount } = useMangoAccount() const mangoCache = useMangoStore(mangoCacheSelector) const groupConfig = useMangoStore(mangoGroupConfigSelector) const client = useMangoStore.getState().connection.client const mangoGroup = useMangoStore(mangoGroupSelector) const [customRefLinks, setCustomRefLinks] = useState([]) const [showSize, setShowSize] = useState(true) const mngoIndex = getMarketIndexBySymbol(groupConfig, 'MNGO') const hasRequiredMngo = useMemo(() => { return mangoGroup && mangoAccount && mangoCache ? mangoAccount .getUiDeposit( mangoCache.rootBankCache[mngoIndex], mangoGroup, mngoIndex ) .toNumber() >= 10000 : false }, [mangoAccount, mangoGroup]) const [showReferral, setShowReferral] = useState( hasRequiredMngo ? true : false ) const marketConfig = position.marketConfig // const maxLeverage = useMemo(() => { // if (!mangoGroup) return 1 // const ws = getWeights(mangoGroup, marketConfig.marketIndex, 'Init') // return Math.round((100 * -1) / (ws.perpAssetWeight.toNumber() - 1)) / 100 // }, [mangoGroup, marketConfig]) const positionPercentage = calculatePositionPercentage(position) const side = position.basePosition > 0 ? 'long' : 'short' useEffect(() => { if (image) { copyToClipboard(image) setCopied(true) setShowButton(true) } }, [image]) useEffect(() => { // if the button is hidden we are taking a screenshot if (!showButton) { takeScreenshot(ref.current as HTMLElement) } }, [showButton]) const handleCopyToClipboard = () => { setShowButton(false) } useEffect(() => { const fetchCustomReferralLinks = async (mangoAccount) => { const referrerIds = await client.getReferrerIdsForMangoAccount( mangoAccount ) setCustomRefLinks(referrerIds) } if (mangoAccount && customRefLinks?.length === 0) { fetchCustomReferralLinks(mangoAccount) } }, [mangoAccount]) const isProfit = positionPercentage > 0 const iconName = `${marketConfig.baseSymbol.slice( 0, 1 )}${marketConfig.baseSymbol.slice(1, 4).toLowerCase()}MonoIcon` const SymbolIcon = MonoIcons[iconName] return (
{hasRequiredMngo && showReferral ? (
0 ? `https://trade.mango.markets?ref=${customRefLinks[0].referrerId}` : `https://trade.mango.markets?ref=${mangoAccount?.publicKey.toString()}` } />
) : null}
{position.marketConfig.name} 0 ? 'border-th-green text-th-green' : 'border-th-red text-th-red' }`} > {t(side).toLocaleUpperCase()}
{positionPercentage > 0 ? '+' : null} {positionPercentage.toFixed(2)}%
{showSize ? (
{t('size')} {roundPerpSize( position.basePosition, position.marketConfig.baseSymbol )}
) : null}
{t('average-entry')} $ {position.avgEntryPrice.toLocaleString(undefined, { maximumFractionDigits: 2, minimumFractionDigits: 2, })}
{t('share-modal:mark-price')} $ {position.indexPrice.toLocaleString(undefined, { maximumFractionDigits: 2, minimumFractionDigits: 2, })}
{/*
{t('share-modal:max-leverage')} {maxLeverage}x
*/}
{!copied ? (
setShowSize(checked)} />
{hasRequiredMngo ? (
setShowReferral(checked)} />
) : null}
) : null} {copied ? (
{t('share-modal:tweet-position')}
) : (
)}
) } export default ShareModal