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

prototype network feedback based on asset network checks

This commit is contained in:
Matthias Kretschmann 2021-05-27 13:58:52 +02:00
parent fa682dad1e
commit 9d7486d626
Signed by: m
GPG Key ID: 606EEEF3C479A91F
14 changed files with 66 additions and 30 deletions

View File

@ -24,5 +24,5 @@
.network svg { .network svg {
vertical-align: baseline; vertical-align: baseline;
margin-bottom: -0.1em; margin-bottom: -0.15em;
} }

View File

@ -33,7 +33,6 @@
} }
.datatoken { .datatoken {
margin-top: calc(var(--spacer) / 8);
margin-bottom: 0; margin-bottom: 0;
color: var(--color-secondary); color: var(--color-secondary);
} }

View File

@ -3,7 +3,6 @@ import { File as FileMetadata } from '@oceanprotocol/lib/dist/node/ddo/interface
import Markdown from '../atoms/Markdown' import Markdown from '../atoms/Markdown'
import Tags from '../atoms/Tags' import Tags from '../atoms/Tags'
import MetaItem from '../organisms/AssetContent/MetaItem' import MetaItem from '../organisms/AssetContent/MetaItem'
import styles from './MetadataPreview.module.css'
import File from '../atoms/File' import File from '../atoms/File'
import { import {
MetadataPublishFormDataset, MetadataPublishFormDataset,
@ -11,6 +10,9 @@ import {
} from '../../@types/MetaData' } from '../../@types/MetaData'
import Button from '../atoms/Button' import Button from '../atoms/Button'
import { transformTags } from '../../utils/metadata' import { transformTags } from '../../utils/metadata'
import NetworkName from '../atoms/NetworkName'
import { useWeb3 } from '../../providers/Web3'
import styles from './MetadataPreview.module.css'
function Description({ description }: { description: string }) { function Description({ description }: { description: string }) {
const [fullDescription, setFullDescription] = useState<boolean>(false) const [fullDescription, setFullDescription] = useState<boolean>(false)
@ -92,10 +94,13 @@ export function MetadataPreview({
}: { }: {
values: Partial<MetadataPublishFormDataset> values: Partial<MetadataPublishFormDataset>
}): ReactElement { }): ReactElement {
const { networkId } = useWeb3()
return ( return (
<div className={styles.preview}> <div className={styles.preview}>
<h2 className={styles.previewTitle}>Preview</h2> <h2 className={styles.previewTitle}>Preview</h2>
<header> <header>
{networkId && <NetworkName networkId={networkId} />}
{values.name && <h3 className={styles.title}>{values.name}</h3>} {values.name && <h3 className={styles.title}>{values.name}</h3>}
{values.dataTokenOptions?.name && ( {values.dataTokenOptions?.name && (
<p <p
@ -130,10 +135,13 @@ export function MetadataAlgorithmPreview({
}: { }: {
values: Partial<MetadataPublishFormAlgorithm> values: Partial<MetadataPublishFormAlgorithm>
}): ReactElement { }): ReactElement {
const { networkId } = useWeb3()
return ( return (
<div className={styles.preview}> <div className={styles.preview}>
<h2 className={styles.previewTitle}>Preview</h2> <h2 className={styles.previewTitle}>Preview</h2>
<header> <header>
{networkId && <NetworkName networkId={networkId} />}
{values.name && <h3 className={styles.title}>{values.name}</h3>} {values.name && <h3 className={styles.title}>{values.name}</h3>}
{values.dataTokenOptions?.name && ( {values.dataTokenOptions?.name && (
<p <p

View File

@ -7,7 +7,7 @@ import AddToken from '../../atoms/AddToken'
import Conversion from '../../atoms/Price/Conversion' import Conversion from '../../atoms/Price/Conversion'
import { useWeb3 } from '../../../providers/Web3' import { useWeb3 } from '../../../providers/Web3'
import Web3Feedback from './Feedback' import Web3Feedback from '../Web3Feedback'
import styles from './Details.module.css' import styles from './Details.module.css'
export default function Details(): ReactElement { export default function Details(): ReactElement {

View File

@ -1,5 +1,5 @@
import React from 'react' import React from 'react'
import Web3Feedback from './Feedback' import Web3Feedback from '../Web3Feedback'
import web3Mock from '../../../../tests/unit/__mocks__/web3' import web3Mock from '../../../../tests/unit/__mocks__/web3'
import { Center } from '../../../../.storybook/helpers' import { Center } from '../../../../.storybook/helpers'

View File

@ -2,8 +2,7 @@
font-size: var(--font-size-small); font-size: var(--font-size-small);
padding-left: var(--spacer); padding-left: var(--spacer);
padding-top: calc(var(--spacer) / 1.5); padding-top: calc(var(--spacer) / 1.5);
margin-top: var(--spacer); margin-top: calc(var(--spacer) / 2);
border-top: 1px solid var(--border-color);
position: relative; position: relative;
width: 100%; width: 100%;
} }

View File

@ -1,7 +1,7 @@
import React, { ReactElement } from 'react' import React, { ReactElement } from 'react'
import { useOcean } from '../../../providers/Ocean' import { useOcean } from '../../providers/Ocean'
import Status from '../../atoms/Status' import Status from '../atoms/Status'
import styles from './Feedback.module.css' import styles from './Web3Feedback.module.css'
export declare type Web3Error = { export declare type Web3Error = {
status: 'error' | 'warning' | 'success' status: 'error' | 'warning' | 'success'
@ -10,16 +10,22 @@ export declare type Web3Error = {
} }
export default function Web3Feedback({ export default function Web3Feedback({
isBalanceSufficient isBalanceSufficient,
isAssetNetwork
}: { }: {
isBalanceSufficient?: boolean isBalanceSufficient?: boolean
isAssetNetwork?: boolean
}): ReactElement { }): ReactElement {
const { account, ocean } = useOcean() const { account, ocean } = useOcean()
const showFeedback = !account || !ocean || isBalanceSufficient === false const showFeedback =
!account ||
!ocean ||
isBalanceSufficient === false ||
isAssetNetwork === false
const state = !account const state = !account
? 'error' ? 'error'
: account && isBalanceSufficient : account && isBalanceSufficient && isAssetNetwork
? 'success' ? 'success'
: 'warning' : 'warning'
@ -27,6 +33,8 @@ export default function Web3Feedback({
? 'No account connected' ? 'No account connected'
: !ocean : !ocean
? 'Error connecting to Ocean' ? 'Error connecting to Ocean'
: account && isAssetNetwork === false
? 'Wrong network'
: account : account
? isBalanceSufficient === false ? isBalanceSufficient === false
? 'Insufficient balance' ? 'Insufficient balance'
@ -39,6 +47,8 @@ export default function Web3Feedback({
? 'Please try again.' ? 'Please try again.'
: isBalanceSufficient === false : isBalanceSufficient === false
? 'You do not have enough OCEAN in your wallet to purchase this asset.' ? 'You do not have enough OCEAN in your wallet to purchase this asset.'
: isAssetNetwork === false
? 'Connect to the asset network.'
: 'Something went wrong.' : 'Something went wrong.'
return showFeedback ? ( return showFeedback ? (

View File

@ -84,7 +84,7 @@ export default function FormStartCompute({
const { isValid, values }: FormikContextType<{ algorithm: string }> = const { isValid, values }: FormikContextType<{ algorithm: string }> =
useFormikContext() useFormikContext()
const { price, ddo } = useAsset() const { price, ddo, isAssetNetwork } = useAsset()
const [totalPrice, setTotalPrice] = useState(price?.value) const [totalPrice, setTotalPrice] = useState(price?.value)
function getAlgorithmAsset(algorithmId: string): DDO { function getAlgorithmAsset(algorithmId: string): DDO {
@ -149,7 +149,7 @@ export default function FormStartCompute({
<ButtonBuy <ButtonBuy
action="compute" action="compute"
disabled={isComputeButtonDisabled || !isValid} disabled={isComputeButtonDisabled || !isValid || !isAssetNetwork}
hasPreviousOrder={hasPreviousOrder} hasPreviousOrder={hasPreviousOrder}
hasDatatoken={hasDatatoken} hasDatatoken={hasDatatoken}
dtSymbol={ddo.dataTokenInfo.symbol} dtSymbol={ddo.dataTokenInfo.symbol}

View File

@ -10,7 +10,6 @@ import { toast } from 'react-toastify'
import Price from '../../../atoms/Price' import Price from '../../../atoms/Price'
import File from '../../../atoms/File' import File from '../../../atoms/File'
import Alert from '../../../atoms/Alert' import Alert from '../../../atoms/Alert'
import Web3Feedback from '../../../molecules/Wallet/Feedback'
import { useSiteMetadata } from '../../../../hooks/useSiteMetadata' import { useSiteMetadata } from '../../../../hooks/useSiteMetadata'
import { useOcean } from '../../../../providers/Ocean' import { useOcean } from '../../../../providers/Ocean'
import { useWeb3 } from '../../../../providers/Web3' import { useWeb3 } from '../../../../providers/Web3'
@ -57,7 +56,7 @@ export default function Compute({
const { appConfig } = useSiteMetadata() const { appConfig } = useSiteMetadata()
const { accountId } = useWeb3() const { accountId } = useWeb3()
const { ocean, account, config } = useOcean() const { ocean, account, config } = useOcean()
const { price, type, ddo } = useAsset() const { price, type, ddo, isAssetNetwork } = useAsset()
const { buyDT, pricingError, pricingStepText } = usePricing() const { buyDT, pricingError, pricingStepText } = usePricing()
const [isJobStarting, setIsJobStarting] = useState(false) const [isJobStarting, setIsJobStarting] = useState(false)
const [error, setError] = useState<string>() const [error, setError] = useState<string>()
@ -418,9 +417,6 @@ export default function Compute({
action={<SuccessAction />} action={<SuccessAction />}
/> />
)} )}
{type !== 'algorithm' && (
<Web3Feedback isBalanceSufficient={isBalanceSufficient} />
)}
</footer> </footer>
</> </>
) )

View File

@ -3,7 +3,6 @@ import { toast } from 'react-toastify'
import { File as FileMetadata, DDO } from '@oceanprotocol/lib' import { File as FileMetadata, DDO } from '@oceanprotocol/lib'
import File from '../../atoms/File' import File from '../../atoms/File'
import Price from '../../atoms/Price' import Price from '../../atoms/Price'
import Web3Feedback from '../../molecules/Wallet/Feedback'
import styles from './Consume.module.css' import styles from './Consume.module.css'
import { useSiteMetadata } from '../../../hooks/useSiteMetadata' import { useSiteMetadata } from '../../../hooks/useSiteMetadata'
import { useAsset } from '../../../providers/Asset' import { useAsset } from '../../../providers/Asset'
@ -47,7 +46,7 @@ export default function Consume({
const { appConfig } = useSiteMetadata() const { appConfig } = useSiteMetadata()
const [hasPreviousOrder, setHasPreviousOrder] = useState(false) const [hasPreviousOrder, setHasPreviousOrder] = useState(false)
const [previousOrderId, setPreviousOrderId] = useState<string>() const [previousOrderId, setPreviousOrderId] = useState<string>()
const { isInPurgatory, price, type } = useAsset() const { isInPurgatory, price, type, isAssetNetwork } = useAsset()
const { buyDT, pricingStepText, pricingError, pricingIsLoading } = const { buyDT, pricingStepText, pricingError, pricingIsLoading } =
usePricing() usePricing()
const { consumeStepText, consume, consumeError } = useConsume() const { consumeStepText, consume, consumeError } = useConsume()
@ -105,6 +104,7 @@ export default function Consume({
setIsDisabled( setIsDisabled(
(!ocean || (!ocean ||
!isBalanceSufficient || !isBalanceSufficient ||
!isAssetNetwork ||
typeof consumeStepText !== 'undefined' || typeof consumeStepText !== 'undefined' ||
pricingIsLoading || pricingIsLoading ||
!isConsumable) && !isConsumable) &&
@ -115,6 +115,7 @@ export default function Consume({
ocean, ocean,
hasPreviousOrder, hasPreviousOrder,
isBalanceSufficient, isBalanceSufficient,
isAssetNetwork,
consumeStepText, consumeStepText,
pricingIsLoading, pricingIsLoading,
isConsumable, isConsumable,
@ -166,9 +167,6 @@ export default function Consume({
{!isInPurgatory && <PurchaseButton />} {!isInPurgatory && <PurchaseButton />}
</div> </div>
</div> </div>
<footer className={styles.feedback}>
<Web3Feedback isBalanceSufficient={isBalanceSufficient} />
</footer>
</aside> </aside>
) )
} }

View File

@ -9,7 +9,7 @@ import { useAsset } from '../../../../providers/Asset'
import { useUserPreferences } from '../../../../providers/UserPreferences' import { useUserPreferences } from '../../../../providers/UserPreferences'
import { MetadataPreview } from '../../../molecules/MetadataPreview' import { MetadataPreview } from '../../../molecules/MetadataPreview'
import Debug from './DebugEditMetadata' import Debug from './DebugEditMetadata'
import Web3Feedback from '../../../molecules/Wallet/Feedback' import Web3Feedback from '../../../molecules/Web3Feedback'
import FormEditMetadata from './FormEditMetadata' import FormEditMetadata from './FormEditMetadata'
import { mapTimeoutStringToSeconds } from '../../../../utils/metadata' import { mapTimeoutStringToSeconds } from '../../../../utils/metadata'
import styles from './index.module.css' import styles from './index.module.css'

View File

@ -10,11 +10,12 @@ import Trade from './Trade'
import { useAsset } from '../../../providers/Asset' import { useAsset } from '../../../providers/Asset'
import { useOcean } from '../../../providers/Ocean' import { useOcean } from '../../../providers/Ocean'
import { useWeb3 } from '../../../providers/Web3' import { useWeb3 } from '../../../providers/Web3'
import Web3Feedback from '../../molecules/Web3Feedback'
export default function AssetActions(): ReactElement { export default function AssetActions(): ReactElement {
const { accountId } = useWeb3() const { accountId } = useWeb3()
const { ocean, balance, account } = useOcean() const { ocean, balance, account } = useOcean()
const { price, ddo, metadata } = useAsset() const { price, ddo, metadata, type, isAssetNetwork } = useAsset()
const [isBalanceSufficient, setIsBalanceSufficient] = useState<boolean>() const [isBalanceSufficient, setIsBalanceSufficient] = useState<boolean>()
const [dtBalance, setDtBalance] = useState<string>() const [dtBalance, setDtBalance] = useState<string>()
@ -85,5 +86,15 @@ export default function AssetActions(): ReactElement {
} }
) )
return <Tabs items={tabs} className={styles.actions} /> return (
<>
<Tabs items={tabs} className={styles.actions} />
{type !== 'algorithm' && (
<Web3Feedback
isBalanceSufficient={isBalanceSufficient}
isAssetNetwork={isAssetNetwork}
/>
)}
</>
)
} }

View File

@ -4,7 +4,7 @@ import { usePublish } from '../../../hooks/usePublish'
import styles from './index.module.css' import styles from './index.module.css'
import FormPublish from './FormPublish' import FormPublish from './FormPublish'
import FormAlgoPublish from './FormAlgoPublish' import FormAlgoPublish from './FormAlgoPublish'
import Web3Feedback from '../../molecules/Wallet/Feedback' import Web3Feedback from '../../molecules/Web3Feedback'
import Tabs from '../../atoms/Tabs' import Tabs from '../../atoms/Tabs'
import { initialValues, validationSchema } from '../../../models/FormPublish' import { initialValues, validationSchema } from '../../../models/FormPublish'
import { import {

View File

@ -15,6 +15,7 @@ import { retrieveDDO } from '../utils/aquarius'
import { getPrice } from '../utils/subgraph' import { getPrice } from '../utils/subgraph'
import { MetadataMarket } from '../@types/MetaData' import { MetadataMarket } from '../@types/MetaData'
import { useOcean } from './Ocean' import { useOcean } from './Ocean'
import { useWeb3 } from './Web3'
interface AssetProviderValue { interface AssetProviderValue {
isInPurgatory: boolean isInPurgatory: boolean
@ -28,6 +29,7 @@ interface AssetProviderValue {
type: MetadataMain['type'] | undefined type: MetadataMain['type'] | undefined
error?: string error?: string
refreshInterval: number refreshInterval: number
isAssetNetwork: boolean
refreshDdo: (token?: CancelToken) => Promise<void> refreshDdo: (token?: CancelToken) => Promise<void>
} }
@ -42,6 +44,7 @@ function AssetProvider({
asset: string | DDO asset: string | DDO
children: ReactNode children: ReactNode
}): ReactElement { }): ReactElement {
const { networkId } = useWeb3()
const { config } = useOcean() const { config } = useOcean()
const [isInPurgatory, setIsInPurgatory] = useState(false) const [isInPurgatory, setIsInPurgatory] = useState(false)
const [purgatoryData, setPurgatoryData] = useState<PurgatoryData>() const [purgatoryData, setPurgatoryData] = useState<PurgatoryData>()
@ -53,6 +56,7 @@ function AssetProvider({
const [owner, setOwner] = useState<string>() const [owner, setOwner] = useState<string>()
const [error, setError] = useState<string>() const [error, setError] = useState<string>()
const [type, setType] = useState<MetadataMain['type']>() const [type, setType] = useState<MetadataMain['type']>()
const [isAssetNetwork, setIsAssetNetwork] = useState<boolean>()
const fetchDdo = async (token?: CancelToken) => { const fetchDdo = async (token?: CancelToken) => {
Logger.log('[asset] Init asset, get DDO') Logger.log('[asset] Init asset, get DDO')
@ -137,6 +141,16 @@ function AssetProvider({
initMetadata(ddo) initMetadata(ddo)
}, [ddo, initMetadata]) }, [ddo, initMetadata])
// Check user network against asset network
useEffect(() => {
if (!networkId || !ddo) return
// TODO: replace with actual check against multinetwork DDO
// const isAssetNetwork = networkId === ddo.networkId
const isAssetNetwork = true
setIsAssetNetwork(isAssetNetwork)
}, [networkId, ddo])
return ( return (
<AssetContext.Provider <AssetContext.Provider
value={ value={
@ -152,7 +166,8 @@ function AssetProvider({
isInPurgatory, isInPurgatory,
purgatoryData, purgatoryData,
refreshInterval, refreshInterval,
refreshDdo refreshDdo,
isAssetNetwork
} as AssetProviderValue } as AssetProviderValue
} }
> >