Skip to content

Commit fdaabd9

Browse files
authored
Merge pull request #1644 from mars-protocol/develop
v2.11.5
2 parents f3d203f + 3661948 commit fdaabd9

File tree

20 files changed

+496
-123
lines changed

20 files changed

+496
-123
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "mars-v2-frontend",
3-
"version": "2.11.4",
3+
"version": "2.11.5",
44
"homepage": "./",
55
"private": false,
66
"license": "SEE LICENSE IN LICENSE FILE",

src/chains/neutron/neutron-1.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,7 +187,7 @@ const Neutron1: ChainConfig = {
187187
evmAssetSupport: true,
188188
slinky: true,
189189
managedVaults: true,
190-
swapFee: 0.005,
190+
swapFee: 0.0005,
191191
}
192192

193193
export default Neutron1

src/chains/neutron/pion-1.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ const Pion1: ChainConfig = {
7070
evmAssetSupport: true,
7171
slinky: true,
7272
managedVaults: true,
73-
swapFee: 0.005,
73+
swapFee: 0.0005,
7474
}
7575

7676
export default Pion1

src/components/common/AmountAndValue.tsx

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -38,10 +38,14 @@ export default function AmountAndValue(props: Props) {
3838
: 'flex-row items-center gap-1.5 [&>div]:before:content-["|"] [&>div]:before:mx-0.5 [&>div]:before:text-white/10',
3939
)}
4040
>
41-
<FormattedNumber
42-
amount={isZero ? 0 : displayAmount}
43-
smallerThanThreshold={!isZero && isBelowMinAmount}
44-
options={{ abbreviated: abbreviated ?? true, maxDecimals: MAX_AMOUNT_DECIMALS }}
41+
<DisplayCurrency
42+
className=''
43+
coin={BNCoin.fromDenomAndBigNumber(
44+
priceOverride ? 'usd' : asset.denom,
45+
priceOverride ? amount.times(priceOverride).shiftedBy(-asset.decimals) : amount,
46+
)}
47+
isApproximation={isApproximation}
48+
options={{ abbreviated: abbreviated ?? true }}
4549
/>
4650
<div className={classNames('flex', layout === 'horizontal' && 'items-center gap-2')}>
4751
{changePercentage && (
@@ -59,14 +63,11 @@ export default function AmountAndValue(props: Props) {
5963
}}
6064
/>
6165
)}
62-
<DisplayCurrency
66+
<FormattedNumber
6367
className='justify-end text-xs text-white/50'
64-
coin={BNCoin.fromDenomAndBigNumber(
65-
priceOverride ? 'usd' : asset.denom,
66-
priceOverride ? amount.times(priceOverride).shiftedBy(-asset.decimals) : amount,
67-
)}
68-
isApproximation={isApproximation}
69-
options={{ abbreviated: abbreviated ?? true }}
68+
amount={isZero ? 0 : displayAmount}
69+
smallerThanThreshold={!isZero && isBelowMinAmount}
70+
options={{ abbreviated: abbreviated ?? true, maxDecimals: MAX_AMOUNT_DECIMALS }}
7071
/>
7172
</div>
7273
</div>
Lines changed: 157 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,169 @@
1-
import classNames from 'classnames'
2-
31
import DisplayCurrency from 'components/common/DisplayCurrency'
4-
import { FormattedNumber } from 'components/common/FormattedNumber'
5-
import TitleAndSubCell from 'components/common/TitleAndSubCell'
2+
import { Tooltip } from 'components/common/Tooltip'
3+
import AnimatedCircularProgressBar from 'components/common/ProgressBars/AnimatedCircularProgressBar'
4+
import Text from 'components/common/Text'
65
import { BNCoin } from 'types/classes/BNCoin'
6+
import useAssets from 'hooks/assets/useAssets'
7+
import useDisplayCurrency from 'hooks/localStorage/useDisplayCurrency'
8+
import useDisplayCurrencyAssets from 'hooks/assets/useDisplayCurrencyAssets'
9+
import { getCoinValueWithoutFallback } from 'utils/formatters'
10+
import { BN } from 'utils/helpers'
11+
import { FormattedNumber } from './FormattedNumber'
12+
import classNames from 'classnames'
713

814
interface Props {
915
depositCap: DepositCap
1016
}
1117

1218
export default function DepositCapCell(props: Props) {
13-
const percent = props.depositCap.used.dividedBy(props.depositCap.max).multipliedBy(100)
14-
const depositCapUsed = Math.min(percent.toNumber(), 100)
19+
const { data: assets } = useAssets()
20+
const displayCurrencies = useDisplayCurrencyAssets()
21+
const [displayCurrency] = useDisplayCurrency()
22+
23+
const displayCurrencyAsset = displayCurrencies.find((asset) => asset.denom === displayCurrency)
24+
25+
const depositedCoin = BNCoin.fromDenomAndBigNumber(props.depositCap.denom, props.depositCap.used)
26+
const depositCapCoin = BNCoin.fromDenomAndBigNumber(props.depositCap.denom, props.depositCap.max)
27+
28+
const percent = props.depositCap.max.isZero()
29+
? BN(0)
30+
: props.depositCap.used.dividedBy(props.depositCap.max).multipliedBy(100)
31+
32+
const capUsedPercent = percent.toNumber()
33+
const depositCapUsed = Number.isFinite(capUsedPercent) ? Math.min(capUsedPercent, 100) : 0
34+
const textBase = 'text-xs font-semibold whitespace-nowrap text-right'
35+
const valueClassName = `${textBase} text-white`
36+
37+
const depositedValue = getCoinValueWithoutFallback(depositedCoin, assets)
38+
const depositCapValue = getCoinValueWithoutFallback(depositCapCoin, assets)
39+
40+
// Get asset info for proper formatting
41+
const asset = assets?.find((a) => a.denom === props.depositCap.denom)
42+
const decimals = displayCurrencyAsset?.decimals ?? 2
43+
const gaugeMax = depositCapValue?.shiftedBy(-decimals).toNumber() ?? 0
44+
const gaugeValue = depositedValue?.shiftedBy(-decimals).toNumber() ?? 0
45+
46+
// Determine colors based on usage
47+
let gaugePrimaryColor = '#FFFFFF'
48+
if (depositCapUsed >= 100) {
49+
gaugePrimaryColor = '#F87171'
50+
} else if (depositCapUsed > 90) {
51+
gaugePrimaryColor = '#F59E0B'
52+
}
53+
54+
let displayCurrencyColorClass = 'text-white/40'
55+
if (depositCapUsed >= 100) {
56+
displayCurrencyColorClass = 'text-loss/40'
57+
} else if (depositCapUsed > 90) {
58+
displayCurrencyColorClass = 'text-warning/40'
59+
}
60+
61+
const tooltipContent = (
62+
<div className='flex flex-col gap-3 p-1'>
63+
<div className='flex flex-col gap-2'>
64+
<div className='flex items-start justify-between gap-6 whitespace-nowrap'>
65+
<Text size='2xs' className='text-white/60'>
66+
Deposits
67+
</Text>
68+
<div className='flex flex-col items-end gap-0.5 text-right'>
69+
<DisplayCurrency coin={depositedCoin} className={valueClassName} />
70+
<span className='text-[10px] text-white/40'>
71+
{asset && (
72+
<FormattedNumber
73+
amount={depositedCoin.amount.toNumber()}
74+
className='text-xs text-white/60 whitespace-nowrap'
75+
options={{
76+
abbreviated: true,
77+
decimals: asset?.decimals,
78+
suffix: ` ${asset?.symbol}`,
79+
minDecimals: 0,
80+
maxDecimals: Math.min(asset?.decimals, 6),
81+
}}
82+
/>
83+
)}
84+
</span>
85+
</div>
86+
</div>
87+
<div className='flex items-start justify-between gap-6 whitespace-nowrap'>
88+
<Text size='2xs' className='text-white/60'>
89+
Deposit Cap
90+
</Text>
91+
<div className='flex flex-col items-end gap-0.5 text-right'>
92+
<DisplayCurrency coin={depositCapCoin} className={valueClassName} />
93+
<span className='text-[10px] text-white/40'>
94+
{asset && (
95+
<FormattedNumber
96+
amount={depositCapCoin.amount.toNumber()}
97+
className='text-xs text-white/60 whitespace-nowrap'
98+
options={{
99+
abbreviated: true,
100+
decimals: asset?.decimals,
101+
suffix: ` ${asset?.symbol}`,
102+
minDecimals: 0,
103+
maxDecimals: Math.min(asset?.decimals, 6),
104+
}}
105+
/>
106+
)}
107+
</span>
108+
</div>
109+
</div>
110+
<div className='flex items-start justify-between gap-6 whitespace-nowrap'>
111+
<Text size='2xs' className='text-white/60'>
112+
Remaining
113+
</Text>
114+
<div className='flex flex-col items-end gap-0.5 text-right'>
115+
<DisplayCurrency
116+
coin={BNCoin.fromDenomAndBigNumber(
117+
props.depositCap.denom,
118+
props.depositCap.max.minus(props.depositCap.used),
119+
)}
120+
className={valueClassName}
121+
/>
122+
<span className='text-[10px] text-white/40'>
123+
{asset && (
124+
<FormattedNumber
125+
amount={props.depositCap.max.minus(props.depositCap.used).toNumber()}
126+
className='text-xs text-white/60 whitespace-nowrap'
127+
options={{
128+
abbreviated: true,
129+
decimals: asset?.decimals,
130+
suffix: ` ${asset?.symbol}`,
131+
minDecimals: 0,
132+
maxDecimals: Math.min(asset?.decimals, 6),
133+
}}
134+
/>
135+
)}
136+
</span>
137+
</div>
138+
</div>
139+
</div>
140+
<AnimatedCircularProgressBar
141+
value={gaugeValue}
142+
max={gaugeMax}
143+
min={0}
144+
gaugePrimaryColor={gaugePrimaryColor}
145+
gaugeSecondaryColor='rgba(255, 255, 255, 0.1)'
146+
className='mx-auto h-24 w-24 text-sm'
147+
/>
148+
</div>
149+
)
15150

16151
return (
17-
<TitleAndSubCell
18-
title={
19-
<DisplayCurrency
20-
coin={BNCoin.fromDenomAndBigNumber(props.depositCap.denom, props.depositCap.max)}
21-
className='text-xs'
22-
/>
23-
}
24-
sub={
25-
<FormattedNumber
26-
amount={depositCapUsed}
27-
options={{ minDecimals: 2, maxDecimals: 2, suffix: '% Filled' }}
28-
className={classNames(
29-
'text-xs',
30-
depositCapUsed >= 100 ? 'text-loss/60' : depositCapUsed > 90 ? 'text-info/60' : '',
31-
)}
32-
/>
33-
}
34-
/>
152+
<Tooltip type='info' content={tooltipContent}>
153+
<div className='flex items-center justify-end w-full gap-3'>
154+
{/* Deposits and Cap Info */}
155+
<div className='flex flex-col gap-0.5'>
156+
<div className='flex items-center justify-end'>
157+
<DisplayCurrency coin={depositedCoin} className={valueClassName} />
158+
</div>
159+
<div className='flex items-center justify-end'>
160+
<DisplayCurrency
161+
coin={depositCapCoin}
162+
className={classNames(valueClassName, displayCurrencyColorClass)}
163+
/>
164+
</div>
165+
</div>
166+
</div>
167+
</Tooltip>
35168
)
36169
}

src/components/common/DisplayCurrency.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ export default function DisplayCurrency(props: Props) {
116116
options={{
117117
minDecimals: isUSD ? 2 : 0,
118118
maxDecimals: isLessThanACent && showDetailedPrice ? 6 : 2,
119-
abbreviated: true,
119+
abbreviated: (absoluteAmount ?? 0) >= 10000,
120120
suffix,
121121
...options,
122122
prefix,
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
import classNames from 'classnames'
2+
3+
export interface AnimatedCircularProgressBarProps {
4+
max: number
5+
value: number
6+
min?: number
7+
gaugePrimaryColor: string
8+
gaugeSecondaryColor: string
9+
className?: string
10+
usedLabel?: string | null
11+
}
12+
13+
export default function AnimatedCircularProgressBar(props: AnimatedCircularProgressBarProps) {
14+
const {
15+
max = 100,
16+
min = 0,
17+
value = 0,
18+
gaugePrimaryColor,
19+
gaugeSecondaryColor,
20+
className,
21+
usedLabel = 'Used',
22+
} = props
23+
24+
const clampValue = (val: number) => {
25+
if (Number.isNaN(val) || !Number.isFinite(val)) return 0
26+
if (val < min) return min
27+
if (val > max) return max
28+
return val
29+
}
30+
31+
const safeMax = max <= min ? min + 1 : max
32+
const boundedValue = clampValue(value)
33+
const circumference = 2 * Math.PI * 45
34+
const percentPx = circumference / 100
35+
const currentPercent = ((boundedValue - min) / (safeMax - min)) * 100
36+
const percentValue = Number.isFinite(currentPercent)
37+
? Math.max(0, Math.min(100, currentPercent))
38+
: 0
39+
40+
return (
41+
<div
42+
className={classNames('relative size-40 text-sm font-semibold', className)}
43+
style={
44+
{
45+
'--circle-size': '100px',
46+
'--circumference': circumference,
47+
'--percent-to-px': `${percentPx}px`,
48+
'--gap-percent': '5',
49+
'--offset-factor': '0',
50+
'--transition-length': '1s',
51+
'--transition-step': '200ms',
52+
'--delay': '0s',
53+
'--percent-to-deg': '3.6deg',
54+
transform: 'translateZ(0)',
55+
} as React.CSSProperties
56+
}
57+
>
58+
<svg fill='none' className='size-full' strokeWidth='2' viewBox='0 0 100 100'>
59+
{percentValue <= 90 && percentValue >= 0 && (
60+
<circle
61+
cx='50'
62+
cy='50'
63+
r='45'
64+
strokeWidth='10'
65+
strokeDashoffset='0'
66+
strokeLinecap='round'
67+
strokeLinejoin='round'
68+
className='opacity-100'
69+
style={
70+
{
71+
stroke: gaugeSecondaryColor,
72+
'--stroke-percent': 90 - percentValue,
73+
'--offset-factor-secondary': 'calc(1 - var(--offset-factor))',
74+
strokeDasharray:
75+
'calc(var(--stroke-percent) * var(--percent-to-px)) var(--circumference)',
76+
transform:
77+
'rotate(calc(1turn - 90deg - (var(--gap-percent) * var(--percent-to-deg) * var(--offset-factor-secondary)))) scaleY(-1)',
78+
transition: 'all var(--transition-length) ease var(--delay)',
79+
transformOrigin: 'calc(var(--circle-size) / 2) calc(var(--circle-size) / 2)',
80+
} as React.CSSProperties
81+
}
82+
/>
83+
)}
84+
<circle
85+
cx='50'
86+
cy='50'
87+
r='45'
88+
strokeWidth='10'
89+
strokeDashoffset='0'
90+
strokeLinecap='round'
91+
strokeLinejoin='round'
92+
className='opacity-100'
93+
style={
94+
{
95+
stroke: gaugePrimaryColor,
96+
'--stroke-percent': percentValue,
97+
strokeDasharray:
98+
'calc(var(--stroke-percent) * var(--percent-to-px)) var(--circumference)',
99+
transition:
100+
'var(--transition-length) ease var(--delay),stroke var(--transition-length) ease var(--delay)',
101+
transitionProperty: 'stroke-dasharray,transform',
102+
transform:
103+
'rotate(calc(-90deg + var(--gap-percent) * var(--offset-factor) * var(--percent-to-deg)))',
104+
transformOrigin: 'calc(var(--circle-size) / 2) calc(var(--circle-size) / 2)',
105+
} as React.CSSProperties
106+
}
107+
/>
108+
</svg>
109+
<div className='absolute inset-0 flex flex-col items-center justify-center text-center'>
110+
<span className='text-sm text-white'>{percentValue.toPrecision(4)}%</span>
111+
{usedLabel && <span className='text-xs text-white/60'>{usedLabel}</span>}
112+
</div>
113+
</div>
114+
)
115+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { default } from 'components/common/ProgressBars/AnimatedCircularProgressBar'

src/components/common/RouteInfo.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ export interface SwapAssets {
2828
}
2929

3030
export function RouteInfo(props: Props) {
31-
const [showSummary, setShowSummary] = useToggle()
31+
const [showSummary, setShowSummary] = useToggle(true)
3232
const chainConfig = useChainConfig()
3333

3434
return (

0 commit comments

Comments
 (0)