Feedback implementation (#611)

* env: update wallet volnurabilities

* fix: always render TradingChart container

* fix: amounts can be a fraction of MIN_AMOUNT

* feat: added clickaway handler

* tidy: refactor

* fix: size below 0.00001 is possible for BTC and WETH

* fix: fixed tests
This commit is contained in:
Linkie Link 2023-11-03 14:10:19 +01:00 committed by GitHub
parent dd48841504
commit dd29f17a42
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 144 additions and 127 deletions

View File

@ -4,6 +4,12 @@ import AccountDetails from 'components/Account/AccountDetails'
import useCurrentAccount from 'hooks/useCurrentAccount'
import useStore from 'store'
jest.mock('react-router', () => ({
...(jest.requireActual('react-router') as {}),
useLocation: jest.fn().mockImplementation(() => {
return { pathname: '/testroute' }
}),
}))
jest.mock('hooks/useCurrentAccount', () => jest.fn(() => null))
jest.mock('hooks/useHealthComputer', () =>
jest.fn(() => ({

View File

@ -1,6 +1,6 @@
{
"name": "mars-v2-frontend",
"version": "2.0.2",
"version": "2.0.3",
"private": true,
"scripts": {
"build": "yarn validate-env && next build",
@ -23,8 +23,8 @@
},
"dependencies": {
"@cosmjs/cosmwasm-stargate": "^0.31.1",
"@delphi-labs/shuttle-react": "^3.9.1",
"@keplr-wallet/cosmos": "^0.12.35",
"@delphi-labs/shuttle-react": "^3.10.0",
"@keplr-wallet/cosmos": "^0.12.39",
"@sentry/nextjs": "^7.74.0",
"@splinetool/react-spline": "^2.2.6",
"@splinetool/runtime": "^0.9.482",

View File

@ -44,11 +44,11 @@ export default function Size(props: Props) {
)
const formattedAmount = formatAmountToPrecision(size, MAX_AMOUNT_DECIMALS)
const lowAmount = formattedAmount === 0 ? 0 : Math.max(formattedAmount, MIN_AMOUNT)
const lowAmount = formattedAmount === 0 ? MIN_AMOUNT : Math.max(formattedAmount, MIN_AMOUNT)
return (
<FormattedNumber
className={className}
smallerThanThreshold={formattedAmount !== 0 && formattedAmount < MIN_AMOUNT}
smallerThanThreshold={formattedAmount < MIN_AMOUNT}
amount={lowAmount}
options={{
maxDecimals: MAX_AMOUNT_DECIMALS,

View File

@ -29,5 +29,7 @@ export default function Value(props: Props) {
amount: value,
})
return <DisplayCurrency coin={coin} className={classNames('text-xs text-right', color)} />
return (
<DisplayCurrency coin={coin} className={classNames('text-xs text-right', color)} showZero />
)
}

View File

@ -1,5 +1,6 @@
import classNames from 'classnames'
import { useCallback, useMemo } from 'react'
import { useLocation } from 'react-router-dom'
import AccountBalancesTable from 'components/Account/AccountBalancesTable'
import AccountComposition from 'components/Account/AccountComposition'
@ -39,7 +40,6 @@ export default function AccountDetailsController() {
const { data: accountIds } = useAccountIds(address, false)
const accountId = useAccountId()
const account = useCurrentAccount()
const focusComponent = useStore((s) => s.focusComponent)
const isOwnAccount = accountId && accountIds?.includes(accountId)
@ -56,6 +56,7 @@ interface Props {
function AccountDetails(props: Props) {
const { account } = props
const location = useLocation()
const [reduceMotion] = useLocalStorage<boolean>(
LocalStorageKeys.REDUCE_MOTION,
DEFAULT_SETTINGS.reduceMotion,
@ -96,6 +97,7 @@ function AccountDetails(props: Props) {
calculateAccountApr(updatedAccount ?? account, borrowAssetsData, lendingAssetsData, prices),
[account, borrowAssetsData, lendingAssetsData, prices, updatedAccount],
)
const isFullWidth = location.pathname.includes('trade') || location.pathname === '/'
function AccountDetailsHeader() {
const onClose = useCallback(() => useStore.setState({ accountDetailsExpanded: false }), [])
@ -111,86 +113,94 @@ function AccountDetails(props: Props) {
}
return (
<div
data-testid='account-details'
className={classNames(
accountDetailsExpanded ? 'right-4' : '-right-90',
'w-110 flex items-start gap-4 absolute top-6',
!reduceMotion && 'transition-all duration-300',
<>
{!isFullWidth && accountDetailsExpanded && (
<div
className='absolute w-full h-full hover:cursor-pointer z-1'
onClick={() => useStore.setState({ accountDetailsExpanded: false })}
/>
)}
>
<div
data-testid='account-details'
className={classNames(
'flex flex-wrap min-w-16 w-16 group/accountdetail relative',
'border rounded-base border-white/20',
'bg-white/5 backdrop-blur-sticky',
!reduceMotion && 'transition-colors duration-300',
'hover:bg-white/10 hover:cursor-pointer ',
accountDetailsExpanded ? 'right-4' : '-right-90',
'w-110 flex items-start gap-4 absolute top-6',
!reduceMotion && 'transition-all duration-300',
)}
onClick={() => useStore.setState({ accountDetailsExpanded: !accountDetailsExpanded })}
>
<div className='flex flex-wrap justify-center w-full py-4'>
<HealthGauge
health={health}
updatedHealth={updatedHealth}
healthFactor={healthFactor}
updatedHealthFactor={updatedHealthFactor}
/>
<Text size='2xs' className='mb-0.5 mt-1 w-full text-center text-white/50'>
Health
</Text>
</div>
<div className='w-full py-4 border-t border-white/20'>
<Text size='2xs' className='mb-0.5 w-full text-center text-white/50 whitespace-nowrap'>
Net worth
</Text>
<DisplayCurrency coin={coin} className='w-full text-center truncate text-2xs ' />
</div>
<div className='w-full py-4 border-t border-white/20'>
<Text size='2xs' className='mb-0.5 w-full text-center text-white/50'>
Leverage
</Text>
<AccountDetailsLeverage
leverage={leverage.toNumber() || 1}
updatedLeverage={updatedLeverage?.toNumber() || null}
/>
</div>
<div className='w-full py-4 border-t border-white/20'>
<Text size='2xs' className='mb-0.5 w-full text-center text-white/50'>
APR
</Text>
<FormattedNumber
className={'w-full text-center text-2xs'}
amount={apr.toNumber()}
options={{ maxDecimals: 2, minDecimals: 2, suffix: '%' }}
animate
/>
</div>
<div
className={classNames(
'flex justify-center items-center w-full h-6 opacity-50',
!reduceMotion && 'transition-[opacity] duration-300',
'absolute -bottom-6',
'group-hover/accountdetail:opacity-100',
'flex flex-wrap min-w-16 w-16 group/accountdetail relative',
'border rounded-base border-white/20',
'bg-white/5 backdrop-blur-sticky z-2',
!reduceMotion && 'transition-colors duration-300',
'hover:bg-white/10 hover:cursor-pointer ',
)}
onClick={() => useStore.setState({ accountDetailsExpanded: !accountDetailsExpanded })}
>
{!accountDetailsExpanded && <ThreeDots className='h-1' />}
</div>
<div className='flex flex-wrap justify-center w-full py-4'>
<HealthGauge
health={health}
updatedHealth={updatedHealth}
healthFactor={healthFactor}
updatedHealthFactor={updatedHealthFactor}
/>
<Text size='2xs' className='mb-0.5 mt-1 w-full text-center text-white/50'>
Health
</Text>
</div>
<div className='w-full py-4 border-t border-white/20'>
<Text size='2xs' className='mb-0.5 w-full text-center text-white/50 whitespace-nowrap'>
Net worth
</Text>
<DisplayCurrency coin={coin} className='w-full text-center truncate text-2xs ' />
</div>
<div className='w-full py-4 border-t border-white/20'>
<Text size='2xs' className='mb-0.5 w-full text-center text-white/50'>
Leverage
</Text>
<AccountDetailsLeverage
leverage={leverage.toNumber() || 1}
updatedLeverage={updatedLeverage?.toNumber() || null}
/>
</div>
<div className='w-full py-4 border-t border-white/20'>
<Text size='2xs' className='mb-0.5 w-full text-center text-white/50'>
APR
</Text>
<FormattedNumber
className={'w-full text-center text-2xs'}
amount={apr.toNumber()}
options={{ maxDecimals: 2, minDecimals: 2, suffix: '%' }}
animate
/>
</div>
<div
className={classNames(
'flex justify-center items-center w-full h-6 opacity-50',
!reduceMotion && 'transition-[opacity] duration-300',
'absolute -bottom-6',
'group-hover/accountdetail:opacity-100',
)}
>
{!accountDetailsExpanded && <ThreeDots className='h-1' />}
</div>
{glowElement(!reduceMotion)}
{glowElement(!reduceMotion)}
</div>
<div className='flex w-90 backdrop-blur-sticky z-2'>
<Card className='w-90 bg-white/5' title={<AccountDetailsHeader />}>
<AccountComposition account={account} />
<Text className='w-full px-4 py-2 text-white bg-white/10'>Balances</Text>
<AccountBalancesTable
account={account}
borrowingData={borrowAssetsData}
lendingData={lendingAssetsData}
hideCard
/>
</Card>
</div>
</div>
<div className='flex w-90 backdrop-blur-sticky'>
<Card className='w-90 bg-white/5' title={<AccountDetailsHeader />}>
<AccountComposition account={account} />
<Text className='w-full px-4 py-2 text-white bg-white/10'>Balances</Text>
<AccountBalancesTable
account={account}
borrowingData={borrowAssetsData}
lendingData={lendingAssetsData}
hideCard
/>
</Card>
</div>
</div>
</>
)
}

View File

@ -17,6 +17,7 @@ interface Props {
className?: string
isApproximation?: boolean
parentheses?: boolean
showZero?: boolean
}
export default function DisplayCurrency(props: Props) {
@ -49,7 +50,7 @@ export default function DisplayCurrency(props: Props) {
return coinValue.div(displayPrice).toNumber()
}, [displayCurrency, displayCurrencyAsset.decimals, prices, props.coin])
const isLessThanACent = isUSD && amount < 0.01 && amount > 0
const isLessThanACent = (isUSD && amount < 0.01 && amount > 0) || (amount === 0 && props.showZero)
const smallerThanPrefix = isLessThanACent ? '< ' : ''
const prefix = isUSD

View File

@ -10,7 +10,7 @@ export default function OracleResyncButton() {
const { data: pricesData } = usePricesData()
const updateOracle = useStore((s) => s.updateOracle)
const updatePythOracle = useCallback(() => updateOracle(pricesData), [pricesData])
const updatePythOracle = useCallback(() => updateOracle(pricesData), [pricesData, updateOracle])
return (
<Tooltip

View File

@ -28,8 +28,6 @@ export default function TradePage() {
[tradingPair, enabledMarketAssets],
)
if (!tradingPair) return null
return (
<div className='flex flex-col w-full h-full gap-4'>
<MigrationBanner />

View File

@ -1441,21 +1441,21 @@
resolved "https://registry.npmjs.org/@cosmjs/utils/-/utils-0.31.1.tgz"
integrity sha512-n4Se1wu4GnKwztQHNFfJvUeWcpvx3o8cWhSbNs9JQShEuB3nv3R5lqFBtDCgHZF/emFQAP+ZjF8bTfCs9UBGhA==
"@delphi-labs/shuttle-react@^3.9.1":
version "3.9.1"
resolved "https://registry.yarnpkg.com/@delphi-labs/shuttle-react/-/shuttle-react-3.9.1.tgz#6f450a027821c08a6b1c70290078bcf2e45036a9"
integrity sha512-RHhLTAWilrpQDFuwpggkIFVcNyQz3lpaW3tQUW2qsOpAxnD+v8/BYeAaw4jwOjtqD90YgNreDvzFQypZXkxuEw==
"@delphi-labs/shuttle-react@^3.10.0":
version "3.10.0"
resolved "https://registry.yarnpkg.com/@delphi-labs/shuttle-react/-/shuttle-react-3.10.0.tgz#1f4a81cfa4039f2fe548b6671919d0d66893af85"
integrity sha512-cNlUMm9saOVSbngCMgcsWXuvVWPlR6TBXmZdaIgXAAIpc0st/ZOPSlWC4fO2Oga/843GizSJWkIkS0FL5x5rzA==
dependencies:
"@delphi-labs/shuttle" "3.9.1"
"@delphi-labs/shuttle" "3.10.0"
tslib "^2.6.0"
tsup "^7.1.0"
use-local-storage-state "^18.3.3"
zustand "^4.3.8"
"@delphi-labs/shuttle@3.9.1":
version "3.9.1"
resolved "https://registry.yarnpkg.com/@delphi-labs/shuttle/-/shuttle-3.9.1.tgz#19175d4fa6c02e2f2b3706caf14145f5ea7f3660"
integrity sha512-dewZQwV+N1o4QBUp6unKQVHcMxTV6R2ZBnY8xi0+VYcnQcp5+TyScehBXFC/bDcbdFChhdaSU0yoH2yrtu6fpQ==
"@delphi-labs/shuttle@3.10.0":
version "3.10.0"
resolved "https://registry.yarnpkg.com/@delphi-labs/shuttle/-/shuttle-3.10.0.tgz#c5b1c6ad9c6f8e91004bce7d74b83a6256130345"
integrity sha512-7de5UFWYdUPIn5Bz3qA4dVD5I848K6dVPsH5marpFazuiNg2Te3dJpv+owYFHShZ9nZD+xxjEEg4ISPRJGo6Lg==
dependencies:
"@cosmjs/amino" "^0.31.0"
"@cosmjs/cosmwasm-stargate" "^0.31.0"
@ -2450,38 +2450,38 @@
"@jridgewell/resolve-uri" "3.1.0"
"@jridgewell/sourcemap-codec" "1.4.14"
"@keplr-wallet/common@0.12.35":
version "0.12.35"
resolved "https://registry.yarnpkg.com/@keplr-wallet/common/-/common-0.12.35.tgz#85e8f1fa299cda7792776564411aa4e67285f1cc"
integrity sha512-ECwKxeoIJDsSByWzdTK6lvm49g96oh2hNOian4j9Jhxzao0eZL8ip9suQIg7jyHEdJSK7b5oWbXUB9OAnj5ERg==
"@keplr-wallet/common@0.12.39":
version "0.12.39"
resolved "https://registry.yarnpkg.com/@keplr-wallet/common/-/common-0.12.39.tgz#ba50c138e4d02d0a22f6083827a7fc7663ad35db"
integrity sha512-7Xw7mYbi0+YjqS0ZERY7Ncxz0xhed6HEOlwZmrch0d81z0XPn+yBq06bWypf9nNuIl84D9uSgbys1pTuteXUYA==
dependencies:
"@keplr-wallet/crypto" "0.12.35"
"@keplr-wallet/types" "0.12.35"
"@keplr-wallet/crypto" "0.12.39"
"@keplr-wallet/types" "0.12.39"
buffer "^6.0.3"
delay "^4.4.0"
mobx "^6.1.7"
"@keplr-wallet/cosmos@^0.12.35":
version "0.12.35"
resolved "https://registry.yarnpkg.com/@keplr-wallet/cosmos/-/cosmos-0.12.35.tgz#e0bb20e0daf7b9c2a6416fd4d1c97facec71f228"
integrity sha512-qgjKh6doSZs4W42uPbwOPuh1vsEI7ljypj72NtLn54NinYYETajmrUA5bmLu9JSxAjaYocJVOFGyrpjsFi93vw==
"@keplr-wallet/cosmos@^0.12.39":
version "0.12.39"
resolved "https://registry.yarnpkg.com/@keplr-wallet/cosmos/-/cosmos-0.12.39.tgz#d4a633de619f8828eb3bfd4dc216b210c8f0ef69"
integrity sha512-ag8IfaJQF84zDdqt2Ljvf/LGrlcKiG67aB8SKPERMT0daHRvobtII4dlofAp+UW34fgohmPbWi40mWveA+GNeQ==
dependencies:
"@ethersproject/address" "^5.6.0"
"@keplr-wallet/common" "0.12.35"
"@keplr-wallet/crypto" "0.12.35"
"@keplr-wallet/proto-types" "0.12.35"
"@keplr-wallet/simple-fetch" "0.12.35"
"@keplr-wallet/types" "0.12.35"
"@keplr-wallet/unit" "0.12.35"
"@keplr-wallet/common" "0.12.39"
"@keplr-wallet/crypto" "0.12.39"
"@keplr-wallet/proto-types" "0.12.39"
"@keplr-wallet/simple-fetch" "0.12.39"
"@keplr-wallet/types" "0.12.39"
"@keplr-wallet/unit" "0.12.39"
bech32 "^1.1.4"
buffer "^6.0.3"
long "^4.0.0"
protobufjs "^6.11.2"
"@keplr-wallet/crypto@0.12.35":
version "0.12.35"
resolved "https://registry.yarnpkg.com/@keplr-wallet/crypto/-/crypto-0.12.35.tgz#5a36acd970ed94fda2fc9f94c82ffb001dc4daa1"
integrity sha512-8dlVIWntta9NJbN9cYT8ntephEuMzWI0azmCaF4L1sBv68m8Cjy98JAAeUQVEn6Vs324y2gh3knGjfTKbuAeFQ==
"@keplr-wallet/crypto@0.12.39":
version "0.12.39"
resolved "https://registry.yarnpkg.com/@keplr-wallet/crypto/-/crypto-0.12.39.tgz#30d065ccc7a1c15f48340932a64ccb33e65a1482"
integrity sha512-7tkXiLAe04whpiMvVV0s3yDjv9to3nVFKR9rArfWTzs/x0VFEyIaVFL9+AmyjqSKQlnAKzPoK4ysmyGeBqEk6Q==
dependencies:
"@ethersproject/keccak256" "^5.5.0"
bip32 "^2.0.6"
@ -2492,32 +2492,32 @@
elliptic "^6.5.3"
sha.js "^2.4.11"
"@keplr-wallet/proto-types@0.12.35":
version "0.12.35"
resolved "https://registry.yarnpkg.com/@keplr-wallet/proto-types/-/proto-types-0.12.35.tgz#c75e95c2d099c134a6427efa13247c3dbd059135"
integrity sha512-Cl7nXdga38VbcVVNTOi1y5YrrrQatGmhxx2ywo3FZRyKxP0/UZM95y3kDUM6dRHy47UHdfpXJ9+B9SxbEDSE0Q==
"@keplr-wallet/proto-types@0.12.39":
version "0.12.39"
resolved "https://registry.yarnpkg.com/@keplr-wallet/proto-types/-/proto-types-0.12.39.tgz#6d65d1863c7d0db57729ee27539ad1492a18177d"
integrity sha512-jY0Gbz/2orBi31buSx6V1EXC/Nfv98iN85wedovAtcbHn/lJa/b7KV1fuFMyXpANq9Bj/cYd5rw+NLi8IGyMWg==
dependencies:
long "^4.0.0"
protobufjs "^6.11.2"
"@keplr-wallet/simple-fetch@0.12.35":
version "0.12.35"
resolved "https://registry.yarnpkg.com/@keplr-wallet/simple-fetch/-/simple-fetch-0.12.35.tgz#4f04f075d7a15768513fcfaaa8c2949ea117f9f1"
integrity sha512-qds/ous9bnJo/rNShjryxaqKPoOzHeGWvIZ35ux4ed4qmRfOIWYVtAST8DbDfHM+n8n9dVDwbcP11fjVIcVAWw==
"@keplr-wallet/simple-fetch@0.12.39":
version "0.12.39"
resolved "https://registry.yarnpkg.com/@keplr-wallet/simple-fetch/-/simple-fetch-0.12.39.tgz#3dbba58ac1171f0ce62dea0da1f5f6bb71a91192"
integrity sha512-QXS3iwggmUVEX1uHpiZK/JeT6EzsUr5g7b50hgziXl5pit002z0/L8s2Imh+2FtVmWROUHcAreS+n6Aptpbd6g==
"@keplr-wallet/types@0.12.35":
version "0.12.35"
resolved "https://registry.yarnpkg.com/@keplr-wallet/types/-/types-0.12.35.tgz#d7a8def781e6450929b52afd62735852f74f1af7"
integrity sha512-BHPXzIcRazT+udogesaXzdhf708A619QAuiAFpKE+zsmfAZLcDtbzoFPyQmqX3DhDCsmxbAj+GK2RXsnWoS3fQ==
"@keplr-wallet/types@0.12.39":
version "0.12.39"
resolved "https://registry.yarnpkg.com/@keplr-wallet/types/-/types-0.12.39.tgz#31c86e994b1b223a13a877385f7c46760bb7c794"
integrity sha512-eAgXrAl/56n2F27SV9WARpAdFGBZguSof0MX4yi5QtPlIQO8ksTA7E+raOZu1opD6/ZOiG+uYaKbrdYGMDL9Ng==
dependencies:
long "^4.0.0"
"@keplr-wallet/unit@0.12.35":
version "0.12.35"
resolved "https://registry.yarnpkg.com/@keplr-wallet/unit/-/unit-0.12.35.tgz#81b2ac092b512252c5bb1fa250c9f6354ae0f719"
integrity sha512-6uBJ0dIIZ1MuPYsHATgU032hcJUVdOw0Um9vIrtDXGio/7/jibHFMmW0ii+t16fIsP5Saam8BsdJjsk3Wlz88A==
"@keplr-wallet/unit@0.12.39":
version "0.12.39"
resolved "https://registry.yarnpkg.com/@keplr-wallet/unit/-/unit-0.12.39.tgz#58d8f75488bf721eda2eac830f60805a22c2f707"
integrity sha512-O7ERBm9OhfZ7hh6qkq+wZ5K41RdGOjzHT5I3RYHcKm/2giArjnFQDyL4o59YcZd0Ku0u30UhjZ6keHpZqGo9UA==
dependencies:
"@keplr-wallet/types" "0.12.35"
"@keplr-wallet/types" "0.12.39"
big-integer "^1.6.48"
utility-types "^3.10.0"