1
0
mirror of https://github.com/oceanprotocol/market.git synced 2024-12-02 05:57:29 +01:00

special veOCEAN number treatment (#1782)

* special veOCEAN number treatment

* path fix

* fix duplicate AllLocked declarations

* so many duplicate declarations

* bold numbers on asset teasers

* update test

* unify number formatting in more generic `formatNumber()` method
This commit is contained in:
Matthias Kretschmann 2022-11-09 14:14:57 +00:00 committed by GitHub
parent b99634a3b3
commit 4b4a926f89
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 80 additions and 46 deletions

View File

@ -1,5 +1,20 @@
import { formatCurrency } from '@coingecko/cryptoformat'
import { Decimal } from 'decimal.js' import { Decimal } from 'decimal.js'
export function formatNumber(
price: number,
locale: string,
decimals?: string
): string {
return formatCurrency(price, '', locale, false, {
// Not exactly clear what `significant figures` are for this library,
// but setting this seems to give us the formatting we want.
// See https://github.com/oceanprotocol/market/issues/70
significantFigures: 4,
...(decimals && { decimalPlaces: Number(decimals) })
})
}
// Run decimal.js comparison // Run decimal.js comparison
// http://mikemcl.github.io/decimal.js/#cmp // http://mikemcl.github.io/decimal.js/#cmp
export function compareAsBN(balance: string, price: string): boolean { export function compareAsBN(balance: string, price: string): boolean {

View File

@ -1,7 +1,7 @@
import { AllLocked } from 'src/@types/subgraph/AllLocked' import { AllLockedQuery } from 'src/@types/subgraph/AllLockedQuery'
import { OwnAllocations } from 'src/@types/subgraph/OwnAllocations' import { OwnAllocationsQuery } from 'src/@types/subgraph/OwnAllocationsQuery'
import { NftOwnAllocation } from 'src/@types/subgraph/NftOwnAllocation' import { NftOwnAllocationQuery } from 'src/@types/subgraph/NftOwnAllocationQuery'
import { OceanLocked } from 'src/@types/subgraph/OceanLocked' import { OceanLockedQuery } from 'src/@types/subgraph/OceanLockedQuery'
import { gql, OperationResult } from 'urql' import { gql, OperationResult } from 'urql'
import { fetchData, getQueryContext } from './subgraph' import { fetchData, getQueryContext } from './subgraph'
import axios from 'axios' import axios from 'axios'
@ -12,11 +12,11 @@ import {
NetworkType NetworkType
} from '@hooks/useNetworkMetadata' } from '@hooks/useNetworkMetadata'
import { getAssetsFromNftList } from './aquarius' import { getAssetsFromNftList } from './aquarius'
import { chainIdsSupported } from 'app.config' import { chainIdsSupported } from '../../app.config'
import { Asset } from '@oceanprotocol/lib' import { Asset } from '@oceanprotocol/lib'
const AllLocked = gql` const AllLocked = gql`
query AllLocked { query AllLockedQuery {
veOCEANs(first: 1000) { veOCEANs(first: 1000) {
lockedAmount lockedAmount
} }
@ -24,7 +24,7 @@ const AllLocked = gql`
` `
const OwnAllocations = gql` const OwnAllocations = gql`
query OwnAllocations($address: String) { query OwnAllocationsQuery($address: String) {
veAllocations(where: { allocationUser: $address }) { veAllocations(where: { allocationUser: $address }) {
id id
nftAddress nftAddress
@ -33,7 +33,7 @@ const OwnAllocations = gql`
} }
` `
const NftOwnAllocation = gql` const NftOwnAllocation = gql`
query NftOwnAllocation($address: String, $nftAddress: String) { query NftOwnAllocationQuery($address: String, $nftAddress: String) {
veAllocations( veAllocations(
where: { allocationUser: $address, nftAddress: $nftAddress } where: { allocationUser: $address, nftAddress: $nftAddress }
) { ) {
@ -42,7 +42,7 @@ const NftOwnAllocation = gql`
} }
` `
const OceanLocked = gql` const OceanLocked = gql`
query OceanLocked($address: ID!) { query OceanLockedQuery($address: ID!) {
veOCEAN(id: $address) { veOCEAN(id: $address) {
id id
lockedAmount lockedAmount
@ -87,7 +87,7 @@ export async function getNftOwnAllocation(
): Promise<number> { ): Promise<number> {
const veNetworkId = getVeChainNetworkId(networkId) const veNetworkId = getVeChainNetworkId(networkId)
const queryContext = getQueryContext(veNetworkId) const queryContext = getQueryContext(veNetworkId)
const fetchedAllocation: OperationResult<NftOwnAllocation, any> = const fetchedAllocation: OperationResult<NftOwnAllocationQuery, any> =
await fetchData( await fetchData(
NftOwnAllocation, NftOwnAllocation,
{ {
@ -115,7 +115,7 @@ export async function getTotalAllocatedAndLocked(): Promise<TotalVe> {
0 0
) )
const fetchedLocked: OperationResult<AllLocked, any> = await fetchData( const fetchedLocked: OperationResult<AllLockedQuery, any> = await fetchData(
AllLocked, AllLocked,
null, null,
queryContext queryContext
@ -136,11 +136,12 @@ export async function getLocked(
const veNetworkIds = getVeChainNetworkIds(networkIds) const veNetworkIds = getVeChainNetworkIds(networkIds)
for (let i = 0; i < veNetworkIds.length; i++) { for (let i = 0; i < veNetworkIds.length; i++) {
const queryContext = getQueryContext(veNetworkIds[i]) const queryContext = getQueryContext(veNetworkIds[i])
const fetchedLocked: OperationResult<OceanLocked, any> = await fetchData( const fetchedLocked: OperationResult<OceanLockedQuery, any> =
OceanLocked, await fetchData(
{ address: userAddress.toLowerCase() }, OceanLocked,
queryContext { address: userAddress.toLowerCase() },
) queryContext
)
fetchedLocked.data?.veOCEAN?.lockedAmount && fetchedLocked.data?.veOCEAN?.lockedAmount &&
(total += Number(fetchedLocked.data?.veOCEAN?.lockedAmount)) (total += Number(fetchedLocked.data?.veOCEAN?.lockedAmount))
@ -157,7 +158,7 @@ export async function getOwnAllocations(
const veNetworkIds = getVeChainNetworkIds(networkIds) const veNetworkIds = getVeChainNetworkIds(networkIds)
for (let i = 0; i < veNetworkIds.length; i++) { for (let i = 0; i < veNetworkIds.length; i++) {
const queryContext = getQueryContext(veNetworkIds[i]) const queryContext = getQueryContext(veNetworkIds[i])
const fetchedAllocations: OperationResult<OwnAllocations, any> = const fetchedAllocations: OperationResult<OwnAllocationsQuery, any> =
await fetchData( await fetchData(
OwnAllocations, OwnAllocations,
{ address: userAddress.toLowerCase() }, { address: userAddress.toLowerCase() },

View File

@ -48,7 +48,7 @@
} }
.footer { .footer {
margin-top: calc(var(--spacer) / 12); margin-top: calc(var(--spacer) / 24);
} }
.typeLabel { .typeLabel {

View File

@ -8,8 +8,8 @@ import AssetType from '@shared/AssetType'
import NetworkName from '@shared/NetworkName' import NetworkName from '@shared/NetworkName'
import styles from './index.module.css' import styles from './index.module.css'
import { getServiceByName } from '@utils/ddo' import { getServiceByName } from '@utils/ddo'
import { formatPrice } from '@shared/Price/PriceUnit'
import { useUserPreferences } from '@context/UserPreferences' import { useUserPreferences } from '@context/UserPreferences'
import { formatNumber } from '@utils/numbers'
export declare type AssetTeaserProps = { export declare type AssetTeaserProps = {
asset: AssetExtended asset: AssetExtended
@ -77,23 +77,37 @@ export default function AssetTeaser({
<footer className={styles.footer}> <footer className={styles.footer}>
{allocated && allocated > 0 ? ( {allocated && allocated > 0 ? (
<span className={styles.typeLabel}> <span className={styles.typeLabel}>
{allocated < 0 {allocated < 0 ? (
? '' ''
: `${formatPrice(allocated, locale)} veOCEAN`} ) : (
<>
<strong>{formatNumber(allocated, locale, '0')}</strong>{' '}
veOCEAN
</>
)}
</span> </span>
) : null} ) : null}
{orders && orders > 0 ? ( {orders && orders > 0 ? (
<span className={styles.typeLabel}> <span className={styles.typeLabel}>
{orders < 0 {orders < 0 ? (
? 'N/A' 'N/A'
: `${orders} ${orders === 1 ? 'sale' : 'sales'}`} ) : (
<>
<strong>{orders}</strong> {orders === 1 ? 'sale' : 'sales'}
</>
)}
</span> </span>
) : null} ) : null}
{asset.views && asset.views > 0 ? ( {asset.views && asset.views > 0 ? (
<span className={styles.typeLabel}> <span className={styles.typeLabel}>
{asset.views < 0 {asset.views < 0 ? (
? 'N/A' 'N/A'
: `${asset.views} ${asset.views === 1 ? 'view' : 'views'}`} ) : (
<>
<strong>{asset.views}</strong>{' '}
{asset.views === 1 ? 'view' : 'views'}
</>
)}
</span> </span>
) : null} ) : null}
</footer> </footer>

View File

@ -1,17 +1,8 @@
import React, { ReactElement } from 'react' import React, { ReactElement } from 'react'
import { formatCurrency } from '@coingecko/cryptoformat'
import Conversion from './Conversion' import Conversion from './Conversion'
import styles from './PriceUnit.module.css' import styles from './PriceUnit.module.css'
import { useUserPreferences } from '@context/UserPreferences' import { useUserPreferences } from '@context/UserPreferences'
import { formatNumber } from '@utils/numbers'
export function formatPrice(price: number, locale: string): string {
return formatCurrency(price, '', locale, false, {
// Not exactly clear what `significant figures` are for this library,
// but setting this seems to give us the formatting we want.
// See https://github.com/oceanprotocol/market/issues/70
significantFigures: 4
})
}
export default function PriceUnit({ export default function PriceUnit({
price, price,
@ -19,7 +10,8 @@ export default function PriceUnit({
size = 'small', size = 'small',
conversion, conversion,
symbol, symbol,
type type,
decimals
}: { }: {
price: number price: number
type?: string type?: string
@ -27,6 +19,7 @@ export default function PriceUnit({
size?: 'small' | 'mini' | 'large' size?: 'small' | 'mini' | 'large'
conversion?: boolean conversion?: boolean
symbol?: string symbol?: string
decimals?: string
}): ReactElement { }): ReactElement {
const { locale } = useUserPreferences() const { locale } = useUserPreferences()
@ -37,7 +30,7 @@ export default function PriceUnit({
) : ( ) : (
<> <>
<div> <div>
{Number.isNaN(price) ? '-' : formatPrice(price, locale)}{' '} {Number.isNaN(price) ? '-' : formatNumber(price, locale, decimals)}{' '}
<span className={styles.symbol}>{symbol}</span> <span className={styles.symbol}>{symbol}</span>
</div> </div>
{conversion && <Conversion price={price} symbol={symbol} />} {conversion && <Conversion price={price} symbol={symbol} />}

View File

@ -2,7 +2,7 @@ import { useAsset } from '@context/Asset'
import { useUserPreferences } from '@context/UserPreferences' import { useUserPreferences } from '@context/UserPreferences'
import { useWeb3 } from '@context/Web3' import { useWeb3 } from '@context/Web3'
import Tooltip from '@shared/atoms/Tooltip' import Tooltip from '@shared/atoms/Tooltip'
import { formatPrice } from '@shared/Price/PriceUnit' import { formatNumber } from '@utils/numbers'
import { getNftOwnAllocation } from '@utils/veAllocation' import { getNftOwnAllocation } from '@utils/veAllocation'
import React, { useEffect, useState } from 'react' import React, { useEffect, useState } from 'react'
import styles from './index.module.css' import styles from './index.module.css'
@ -33,8 +33,8 @@ export default function AssetStats() {
{asset?.stats?.allocated && asset?.stats?.allocated > 0 ? ( {asset?.stats?.allocated && asset?.stats?.allocated > 0 ? (
<span className={styles.stat}> <span className={styles.stat}>
<span className={styles.number}> <span className={styles.number}>
{formatPrice(asset.stats.allocated, locale)} {formatNumber(asset.stats.allocated, locale, '0')}
</span> </span>{' '}
veOCEAN veOCEAN
</span> </span>
) : null} ) : null}

View File

@ -124,8 +124,19 @@ export default function MarketStats(): ReactElement {
/> />
</div> </div>
<div> <div>
<PriceUnit price={total.veLocked} symbol="OCEAN" size="small" /> locked.{' '} <PriceUnit
<PriceUnit price={total.veAllocated} symbol="veOCEAN" size="small" />{' '} decimals="0"
price={total.veLocked}
symbol="OCEAN"
size="small"
/>{' '}
locked.{' '}
<PriceUnit
decimals="0"
price={total.veAllocated}
symbol="veOCEAN"
size="small"
/>{' '}
allocated. allocated.
</div> </div>
</div> </div>

View File

@ -32,7 +32,7 @@ describe('components/Home/MostViews', () => {
) )
queryMetadataMock.mockResolvedValue(queryMetadataBaseReturn) queryMetadataMock.mockResolvedValue(queryMetadataBaseReturn)
render(<MostViews />) render(<MostViews />)
await screen.findByText('666 views') await screen.findByText('666')
}) })
it('catches errors', async () => { it('catches errors', async () => {