feat: [ListV2] Connect modal styling to functionality (#5905)
* dynamic styles based on listing status * connect collection approval to v2 modal * import cleanup * add comments * connect sign listing logic * correct pending styles * correct pending status for collection approval * correct pending status for os listings * use check from react-feather --------- Co-authored-by: Charles Bachmeier <charlie@genie.xyz>
This commit is contained in:
parent
35a03e2681
commit
48833f27e3
@ -1,4 +1,3 @@
|
||||
import { addressesByNetwork, SupportedChainId } from '@looksrare/sdk'
|
||||
import { sendAnalyticsEvent, Trace, useTrace } from '@uniswap/analytics'
|
||||
import { InterfaceModalName, NFTEventName } from '@uniswap/analytics-events'
|
||||
import { useWeb3React } from '@web3-react/core'
|
||||
@ -109,7 +108,6 @@ const ListingModal = () => {
|
||||
if (!signer) return
|
||||
sendAnalyticsEvent(NFTEventName.NFT_SELL_START_LISTING, { ...startListingEventProperties })
|
||||
setListingStatus(ListingStatus.SIGNING)
|
||||
const addresses = addressesByNetwork[SupportedChainId.MAINNET]
|
||||
const signerAddress = await signer.getAddress()
|
||||
const nonce = await looksRareNonceFetcher(signerAddress)
|
||||
setLooksRareNonce(nonce ?? 0)
|
||||
@ -118,7 +116,6 @@ const ListingModal = () => {
|
||||
setListingStatus(ListingStatus.SIGNING)
|
||||
setOpenIndex(1)
|
||||
}
|
||||
const looksRareAddress = addresses.TRANSFER_MANAGER_ERC721
|
||||
// for all unique collection, marketplace combos -> approve collections
|
||||
for (const collectionRow of collectionsRequiringApproval) {
|
||||
verifyStatus(collectionRow.status) &&
|
||||
@ -128,7 +125,6 @@ const ListingModal = () => {
|
||||
collectionsRequiringApproval,
|
||||
setCollectionsRequiringApproval,
|
||||
signer,
|
||||
looksRareAddress,
|
||||
pauseAllRows
|
||||
)
|
||||
: approveCollectionRow(
|
||||
@ -136,7 +132,6 @@ const ListingModal = () => {
|
||||
collectionsRequiringApproval,
|
||||
setCollectionsRequiringApproval,
|
||||
signer,
|
||||
looksRareAddress,
|
||||
pauseAllRows
|
||||
))
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
import type { JsonRpcSigner, Web3Provider } from '@ethersproject/providers'
|
||||
import { addressesByNetwork, SupportedChainId } from '@looksrare/sdk'
|
||||
import { LOOKSRARE_MARKETPLACE_CONTRACT, X2Y2_TRANSFER_CONTRACT } from 'nft/queries'
|
||||
import { OPENSEA_CROSS_CHAIN_CONDUIT } from 'nft/queries/openSea'
|
||||
import { AssetRow, CollectionRow, ListingMarket, ListingRow, ListingStatus, WalletAsset } from 'nft/types'
|
||||
@ -31,8 +32,7 @@ export async function approveCollectionRow(
|
||||
collectionsRequiringApproval: CollectionRow[],
|
||||
setCollectionsRequiringApproval: Dispatch<CollectionRow[]>,
|
||||
signer: JsonRpcSigner,
|
||||
looksRareAddress: string,
|
||||
pauseAllRows: () => void
|
||||
pauseAllRows?: () => void
|
||||
) {
|
||||
updateStatus({
|
||||
listing: collectionRow,
|
||||
@ -45,11 +45,11 @@ export async function approveCollectionRow(
|
||||
collectionsRequiringApproval,
|
||||
setCollectionsRequiringApproval,
|
||||
signer,
|
||||
looksRareAddress,
|
||||
pauseAllRows
|
||||
),
|
||||
})
|
||||
const { marketplace, collectionAddress } = collectionRow
|
||||
const addresses = addressesByNetwork[SupportedChainId.MAINNET]
|
||||
const spender =
|
||||
marketplace.name === 'OpenSea'
|
||||
? OPENSEA_CROSS_CHAIN_CONDUIT
|
||||
@ -57,7 +57,7 @@ export async function approveCollectionRow(
|
||||
? LOOKSRARE_MARKETPLACE_CONTRACT
|
||||
: marketplace.name === 'X2Y2'
|
||||
? X2Y2_TRANSFER_CONTRACT
|
||||
: looksRareAddress
|
||||
: addresses.TRANSFER_MANAGER_ERC721
|
||||
!!collectionAddress &&
|
||||
(await approveCollection(spender, collectionAddress, signer, (newStatus: ListingStatus) =>
|
||||
updateStatus({
|
||||
@ -67,7 +67,11 @@ export async function approveCollectionRow(
|
||||
setRows: setCollectionsRequiringApproval as Dispatch<AssetRow[]>,
|
||||
})
|
||||
))
|
||||
if (collectionRow.status === ListingStatus.REJECTED || collectionRow.status === ListingStatus.FAILED) pauseAllRows()
|
||||
if (
|
||||
(collectionRow.status === ListingStatus.REJECTED || collectionRow.status === ListingStatus.FAILED) &&
|
||||
pauseAllRows
|
||||
)
|
||||
pauseAllRows()
|
||||
}
|
||||
|
||||
export async function signListingRow(
|
||||
@ -78,7 +82,7 @@ export async function signListingRow(
|
||||
provider: Web3Provider,
|
||||
getLooksRareNonce: () => number,
|
||||
setLooksRareNonce: (nonce: number) => void,
|
||||
pauseAllRows: () => void
|
||||
pauseAllRows?: () => void
|
||||
) {
|
||||
const looksRareNonce = getLooksRareNonce()
|
||||
updateStatus({
|
||||
@ -108,7 +112,7 @@ export async function signListingRow(
|
||||
setRows: setListings as Dispatch<AssetRow[]>,
|
||||
})
|
||||
)
|
||||
if (listing.status === ListingStatus.REJECTED) pauseAllRows()
|
||||
if (listing.status === ListingStatus.REJECTED && pauseAllRows) pauseAllRows()
|
||||
else {
|
||||
res && listing.marketplace.name === 'LooksRare' && setLooksRareNonce(looksRareNonce + 1)
|
||||
const newStatus = res ? ListingStatus.APPROVED : ListingStatus.FAILED
|
||||
|
@ -760,8 +760,8 @@ export const CancelListingIcon = (props: SVGProps) => (
|
||||
|
||||
export const ListingModalWindowActive = (props: SVGProps) => (
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" {...props}>
|
||||
<circle cx="8" cy="8" r="8" fill={themeVars.colors.accentAction} fillOpacity="0.24" />
|
||||
<circle cx="8" cy="8" r="5" fill={themeVars.colors.accentAction} />
|
||||
<circle cx="8" cy="8" r="8" fill={props.fill ? props.fill : themeVars.colors.accentAction} fillOpacity="0.24" />
|
||||
<circle cx="8" cy="8" r="5" fill={props.fill ? props.fill : themeVars.colors.accentAction} />
|
||||
</svg>
|
||||
)
|
||||
|
||||
|
@ -1,15 +1,19 @@
|
||||
import { t, Trans } from '@lingui/macro'
|
||||
import { sendAnalyticsEvent, useTrace } from '@uniswap/analytics'
|
||||
import { InterfaceModalName, NFTEventName } from '@uniswap/analytics-events'
|
||||
import { useWeb3React } from '@web3-react/core'
|
||||
import Column from 'components/Column'
|
||||
import Row from 'components/Row'
|
||||
import { SMALL_MEDIA_BREAKPOINT } from 'components/Tokens/constants'
|
||||
import { NftListV2Variant, useNftListV2Flag } from 'featureFlags/flags/nftListV2'
|
||||
import { ListingButton } from 'nft/components/bag/profile/ListingButton'
|
||||
import { getListingState, getTotalEthValue } from 'nft/components/bag/profile/utils'
|
||||
import { approveCollectionRow, getListingState, getTotalEthValue, verifyStatus } from 'nft/components/bag/profile/utils'
|
||||
import { BackArrowIcon } from 'nft/components/icons'
|
||||
import { headlineLarge, headlineSmall } from 'nft/css/common.css'
|
||||
import { themeVars } from 'nft/css/sprinkles.css'
|
||||
import { useBag, useIsMobile, useNFTList, useProfilePageState, useSellAsset } from 'nft/hooks'
|
||||
import { LIST_PAGE_MARGIN, LIST_PAGE_MARGIN_MOBILE } from 'nft/pages/profile/shared'
|
||||
import { looksRareNonceFetcher } from 'nft/queries'
|
||||
import { ListingStatus, ProfilePageStateType } from 'nft/types'
|
||||
import { fetchPrice, formatEth, formatUsdPrice } from 'nft/utils'
|
||||
import { ListingMarkets } from 'nft/utils/listNfts'
|
||||
@ -17,6 +21,7 @@ import { useEffect, useMemo, useReducer, useState } from 'react'
|
||||
import styled, { css } from 'styled-components/macro'
|
||||
import { BREAKPOINTS, ThemedText } from 'theme'
|
||||
import { Z_INDEX } from 'theme/zIndex'
|
||||
import shallow from 'zustand/shallow'
|
||||
|
||||
import { ListModal } from './Modal/ListModal'
|
||||
import { NFTListingsGrid } from './NFTListingsGrid'
|
||||
@ -150,21 +155,50 @@ const ListingButtonWrapper = styled.div`
|
||||
|
||||
export const ListPage = () => {
|
||||
const { setProfilePageState: setSellPageState } = useProfilePageState()
|
||||
const setGlobalMarketplaces = useSellAsset((state) => state.setGlobalMarketplaces)
|
||||
const [selectedMarkets, setSelectedMarkets] = useState([ListingMarkets[0]]) // default marketplace: x2y2
|
||||
const { provider } = useWeb3React()
|
||||
const toggleBag = useBag((s) => s.toggleBag)
|
||||
const listings = useNFTList((state) => state.listings)
|
||||
const collectionsRequiringApproval = useNFTList((state) => state.collectionsRequiringApproval)
|
||||
const listingStatus = useNFTList((state) => state.listingStatus)
|
||||
const setListingStatus = useNFTList((state) => state.setListingStatus)
|
||||
const sellAssets = useSellAsset((state) => state.sellAssets)
|
||||
const isMobile = useIsMobile()
|
||||
const isNftListV2 = useNftListV2Flag() === NftListV2Variant.Enabled
|
||||
const trace = useTrace({ modal: InterfaceModalName.NFT_LISTING })
|
||||
const { setGlobalMarketplaces, sellAssets } = useSellAsset(
|
||||
({ setGlobalMarketplaces, sellAssets }) => ({
|
||||
setGlobalMarketplaces,
|
||||
sellAssets,
|
||||
}),
|
||||
shallow
|
||||
)
|
||||
const {
|
||||
listings,
|
||||
collectionsRequiringApproval,
|
||||
listingStatus,
|
||||
setListingStatus,
|
||||
setLooksRareNonce,
|
||||
setCollectionsRequiringApproval,
|
||||
} = useNFTList(
|
||||
({
|
||||
listings,
|
||||
collectionsRequiringApproval,
|
||||
listingStatus,
|
||||
setListingStatus,
|
||||
setLooksRareNonce,
|
||||
setCollectionsRequiringApproval,
|
||||
}) => ({
|
||||
listings,
|
||||
collectionsRequiringApproval,
|
||||
listingStatus,
|
||||
setListingStatus,
|
||||
setLooksRareNonce,
|
||||
setCollectionsRequiringApproval,
|
||||
}),
|
||||
shallow
|
||||
)
|
||||
|
||||
const totalEthListingValue = useMemo(() => getTotalEthValue(sellAssets), [sellAssets])
|
||||
const anyListingsMissingPrice = useMemo(() => !!listings.find((listing) => !listing.price), [listings])
|
||||
const [ethPriceInUSD, setEthPriceInUSD] = useState(0)
|
||||
const [showListModal, toggleShowListModal] = useReducer((s) => !s, false)
|
||||
const [selectedMarkets, setSelectedMarkets] = useState([ListingMarkets[0]]) // default marketplace: x2y2
|
||||
const [ethPriceInUSD, setEthPriceInUSD] = useState(0)
|
||||
const signer = provider?.getSigner()
|
||||
|
||||
useEffect(() => {
|
||||
fetchPrice().then((price) => {
|
||||
@ -172,6 +206,7 @@ export const ListPage = () => {
|
||||
})
|
||||
}, [])
|
||||
|
||||
// TODO with removal of list v1 see if this logic can be removed
|
||||
useEffect(() => {
|
||||
const state = getListingState(collectionsRequiringApproval, listings)
|
||||
|
||||
@ -188,8 +223,43 @@ export const ListPage = () => {
|
||||
|
||||
useEffect(() => {
|
||||
setGlobalMarketplaces(selectedMarkets)
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [selectedMarkets])
|
||||
}, [selectedMarkets, setGlobalMarketplaces])
|
||||
|
||||
const startListingEventProperties = {
|
||||
collection_addresses: sellAssets.map((asset) => asset.asset_contract.address),
|
||||
token_ids: sellAssets.map((asset) => asset.tokenId),
|
||||
marketplaces: Array.from(new Set(listings.map((asset) => asset.marketplace.name))),
|
||||
list_quantity: listings.length,
|
||||
usd_value: ethPriceInUSD * totalEthListingValue,
|
||||
...trace,
|
||||
}
|
||||
|
||||
const startListingFlow = async () => {
|
||||
if (!signer) return
|
||||
sendAnalyticsEvent(NFTEventName.NFT_SELL_START_LISTING, { ...startListingEventProperties })
|
||||
setListingStatus(ListingStatus.SIGNING)
|
||||
const signerAddress = await signer.getAddress()
|
||||
const nonce = await looksRareNonceFetcher(signerAddress)
|
||||
setLooksRareNonce(nonce ?? 0)
|
||||
|
||||
// for all unique collection, marketplace combos -> approve collections
|
||||
for (const collectionRow of collectionsRequiringApproval) {
|
||||
verifyStatus(collectionRow.status) &&
|
||||
(isMobile
|
||||
? await approveCollectionRow(
|
||||
collectionRow,
|
||||
collectionsRequiringApproval,
|
||||
setCollectionsRequiringApproval,
|
||||
signer
|
||||
)
|
||||
: approveCollectionRow(collectionRow, collectionsRequiringApproval, setCollectionsRequiringApproval, signer))
|
||||
}
|
||||
}
|
||||
|
||||
const handleV2Click = () => {
|
||||
toggleShowListModal()
|
||||
startListingFlow()
|
||||
}
|
||||
|
||||
const BannerText = isMobile ? (
|
||||
<ThemedText.SubHeader lineHeight="24px">
|
||||
@ -241,7 +311,7 @@ export const ListPage = () => {
|
||||
</ProceedsWrapper>
|
||||
<ListingButtonWrapper>
|
||||
<ListingButton
|
||||
onClick={isNftListV2 ? toggleShowListModal : toggleBag}
|
||||
onClick={handleV2Click}
|
||||
buttonText={anyListingsMissingPrice && !isMobile ? t`Set prices to continue` : t`Start listing`}
|
||||
/>
|
||||
</ListingButtonWrapper>
|
||||
|
@ -1,11 +1,15 @@
|
||||
import { Trans } from '@lingui/macro'
|
||||
import { Trace } from '@uniswap/analytics'
|
||||
import { InterfaceModalName } from '@uniswap/analytics-events'
|
||||
import { sendAnalyticsEvent, Trace, useTrace } from '@uniswap/analytics'
|
||||
import { InterfaceModalName, NFTEventName } from '@uniswap/analytics-events'
|
||||
import { useWeb3React } from '@web3-react/core'
|
||||
import Row from 'components/Row'
|
||||
import { getTotalEthValue, signListingRow } from 'nft/components/bag/profile/utils'
|
||||
import { Portal } from 'nft/components/common/Portal'
|
||||
import { Overlay } from 'nft/components/modals/Overlay'
|
||||
import { useNFTList } from 'nft/hooks'
|
||||
import { useReducer } from 'react'
|
||||
import { useNFTList, useSellAsset } from 'nft/hooks'
|
||||
import { ListingStatus } from 'nft/types'
|
||||
import { fetchPrice } from 'nft/utils'
|
||||
import { useEffect, useMemo, useReducer, useState } from 'react'
|
||||
import { X } from 'react-feather'
|
||||
import styled from 'styled-components/macro'
|
||||
import { BREAKPOINTS, ThemedText } from 'theme'
|
||||
@ -41,34 +45,85 @@ const TitleRow = styled(Row)`
|
||||
`
|
||||
|
||||
export const ListModal = ({ overlayClick }: { overlayClick: () => void }) => {
|
||||
const { provider } = useWeb3React()
|
||||
const signer = provider?.getSigner()
|
||||
const trace = useTrace({ modal: InterfaceModalName.NFT_LISTING })
|
||||
const sellAssets = useSellAsset((state) => state.sellAssets)
|
||||
const listings = useNFTList((state) => state.listings)
|
||||
const collectionsRequiringApproval = useNFTList((state) => state.collectionsRequiringApproval)
|
||||
const listingStatus = useNFTList((state) => state.listingStatus)
|
||||
const setListings = useNFTList((state) => state.setListings)
|
||||
const setLooksRareNonce = useNFTList((state) => state.setLooksRareNonce)
|
||||
const getLooksRareNonce = useNFTList((state) => state.getLooksRareNonce)
|
||||
|
||||
const totalEthListingValue = useMemo(() => getTotalEthValue(sellAssets), [sellAssets])
|
||||
const [openSection, toggleOpenSection] = useReducer(
|
||||
(s) => (s === Section.APPROVE ? Section.SIGN : Section.APPROVE),
|
||||
Section.APPROVE
|
||||
)
|
||||
const [ethPriceInUSD, setEthPriceInUSD] = useState(0)
|
||||
|
||||
useEffect(() => {
|
||||
fetchPrice().then((price) => {
|
||||
setEthPriceInUSD(price || 0)
|
||||
})
|
||||
}, [])
|
||||
|
||||
const allCollectionsApproved = useMemo(
|
||||
() => collectionsRequiringApproval.every((collection) => collection.status === ListingStatus.APPROVED),
|
||||
[collectionsRequiringApproval]
|
||||
)
|
||||
|
||||
const signListings = async () => {
|
||||
if (!signer || !provider) return
|
||||
// sign listings
|
||||
for (const listing of listings) {
|
||||
await signListingRow(listing, listings, setListings, signer, provider, getLooksRareNonce, setLooksRareNonce)
|
||||
}
|
||||
sendAnalyticsEvent(NFTEventName.NFT_LISTING_COMPLETED, {
|
||||
signatures_approved: listings.filter((asset) => asset.status === ListingStatus.APPROVED),
|
||||
list_quantity: listings.length,
|
||||
usd_value: ethPriceInUSD * totalEthListingValue,
|
||||
...trace,
|
||||
})
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (allCollectionsApproved) {
|
||||
signListings()
|
||||
openSection === Section.APPROVE && toggleOpenSection()
|
||||
}
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [allCollectionsApproved])
|
||||
|
||||
return (
|
||||
<Portal>
|
||||
<Trace modal={InterfaceModalName.NFT_LISTING}>
|
||||
<ListModalWrapper>
|
||||
<TitleRow>
|
||||
<ThemedText.HeadlineSmall lineHeight="28px">
|
||||
<Trans>List NFTs</Trans>
|
||||
</ThemedText.HeadlineSmall>
|
||||
<X size={24} cursor="pointer" onClick={overlayClick} />
|
||||
</TitleRow>
|
||||
<ListModalSection
|
||||
sectionType={Section.APPROVE}
|
||||
active={openSection === Section.APPROVE}
|
||||
content={collectionsRequiringApproval}
|
||||
toggleSection={toggleOpenSection}
|
||||
/>
|
||||
<ListModalSection
|
||||
sectionType={Section.SIGN}
|
||||
active={openSection === Section.SIGN}
|
||||
content={listings}
|
||||
toggleSection={toggleOpenSection}
|
||||
/>
|
||||
{listingStatus === ListingStatus.APPROVED ? (
|
||||
<>TODO Success Screen</>
|
||||
) : (
|
||||
<>
|
||||
<TitleRow>
|
||||
<ThemedText.HeadlineSmall lineHeight="28px">
|
||||
<Trans>List NFTs</Trans>
|
||||
</ThemedText.HeadlineSmall>
|
||||
<X size={24} cursor="pointer" onClick={overlayClick} />
|
||||
</TitleRow>
|
||||
<ListModalSection
|
||||
sectionType={Section.APPROVE}
|
||||
active={openSection === Section.APPROVE}
|
||||
content={collectionsRequiringApproval}
|
||||
toggleSection={toggleOpenSection}
|
||||
/>
|
||||
<ListModalSection
|
||||
sectionType={Section.SIGN}
|
||||
active={openSection === Section.SIGN}
|
||||
content={listings}
|
||||
toggleSection={toggleOpenSection}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</ListModalWrapper>
|
||||
</Trace>
|
||||
<Overlay onClick={overlayClick} />
|
||||
|
@ -10,8 +10,9 @@ import {
|
||||
LoadingIcon,
|
||||
VerifiedIcon,
|
||||
} from 'nft/components/icons'
|
||||
import { AssetRow, CollectionRow } from 'nft/types'
|
||||
import { Info } from 'react-feather'
|
||||
import { AssetRow, CollectionRow, ListingStatus } from 'nft/types'
|
||||
import { useMemo } from 'react'
|
||||
import { Check, Info } from 'react-feather'
|
||||
import styled, { useTheme } from 'styled-components/macro'
|
||||
import { ThemedText } from 'theme'
|
||||
import { colors } from 'theme/colors'
|
||||
@ -21,9 +22,10 @@ const SectionHeader = styled(Row)`
|
||||
justify-content: space-between;
|
||||
`
|
||||
|
||||
const SectionTitle = styled(ThemedText.SubHeader)<{ active: boolean }>`
|
||||
const SectionTitle = styled(ThemedText.SubHeader)<{ active: boolean; approved: boolean }>`
|
||||
line-height: 24px;
|
||||
color: ${({ theme, active }) => (active ? theme.textPrimary : theme.textSecondary)};
|
||||
color: ${({ theme, active, approved }) =>
|
||||
approved ? theme.accentSuccess : active ? theme.textPrimary : theme.textSecondary};
|
||||
`
|
||||
|
||||
const SectionArrow = styled(ChevronUpIcon)<{ active: boolean }>`
|
||||
@ -56,11 +58,11 @@ const ContentRowContainer = styled(Column)`
|
||||
gap: 8px;
|
||||
`
|
||||
|
||||
const ContentRow = styled(Row)`
|
||||
const ContentRow = styled(Row)<{ active: boolean }>`
|
||||
padding: 16px;
|
||||
border: 1px solid ${({ theme }) => theme.backgroundOutline};
|
||||
border-radius: 12px;
|
||||
opacity: 0.6;
|
||||
opacity: ${({ active }) => (active ? '1' : '0.6')};
|
||||
`
|
||||
|
||||
const CollectionIcon = styled.img`
|
||||
@ -94,16 +96,20 @@ const ContentName = styled(ThemedText.SubHeaderSmall)`
|
||||
max-width: 50%;
|
||||
`
|
||||
|
||||
const ProceedText = styled.span`
|
||||
font-weight: 600;
|
||||
font-size: 12px;
|
||||
line-height: 16px;
|
||||
color: ${({ theme }) => theme.textSecondary};
|
||||
`
|
||||
|
||||
const StyledVerifiedIcon = styled(VerifiedIcon)`
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
margin-left: 4px;
|
||||
`
|
||||
|
||||
const StyledLoadingIconBackground = styled(LoadingIcon)`
|
||||
height: 14px;
|
||||
width: 14px;
|
||||
stroke: ${({ theme }) => theme.textTertiary};
|
||||
const IconWrapper = styled.div`
|
||||
margin-left: auto;
|
||||
margin-right: 0px;
|
||||
`
|
||||
@ -122,13 +128,18 @@ interface ListModalSectionProps {
|
||||
|
||||
export const ListModalSection = ({ sectionType, active, content, toggleSection }: ListModalSectionProps) => {
|
||||
const theme = useTheme()
|
||||
const allContentApproved = useMemo(() => !content.some((row) => row.status !== ListingStatus.APPROVED), [content])
|
||||
const isCollectionApprovalSection = sectionType === Section.APPROVE
|
||||
return (
|
||||
<Column>
|
||||
<SectionHeader>
|
||||
<Row>
|
||||
{active ? <ListingModalWindowActive /> : <ListingModalWindowClosed />}
|
||||
<SectionTitle active={active} marginLeft="12px">
|
||||
{active || allContentApproved ? (
|
||||
<ListingModalWindowActive fill={allContentApproved ? theme.accentSuccess : theme.accentAction} />
|
||||
) : (
|
||||
<ListingModalWindowClosed />
|
||||
)}
|
||||
<SectionTitle active={active} marginLeft="12px" approved={allContentApproved}>
|
||||
{isCollectionApprovalSection ? (
|
||||
<>
|
||||
<Trans>Approve</Trans> {content.length}
|
||||
@ -165,7 +176,10 @@ export const ListModalSection = ({ sectionType, active, content, toggleSection }
|
||||
<ContentRowContainer>
|
||||
{content.map((row) => {
|
||||
return (
|
||||
<ContentRow key={row.name}>
|
||||
<ContentRow
|
||||
key={row.name}
|
||||
active={row.status === ListingStatus.SIGNING || row.status === ListingStatus.APPROVED}
|
||||
>
|
||||
{isCollectionApprovalSection ? (
|
||||
<CollectionIcon src={row.images[0]} />
|
||||
) : (
|
||||
@ -174,7 +188,23 @@ export const ListModalSection = ({ sectionType, active, content, toggleSection }
|
||||
<MarketplaceIcon src={row.images[1]} />
|
||||
<ContentName>{row.name}</ContentName>
|
||||
{isCollectionApprovalSection && (row as CollectionRow).isVerified && <StyledVerifiedIcon />}
|
||||
<StyledLoadingIconBackground />
|
||||
<IconWrapper>
|
||||
{row.status === ListingStatus.DEFINED || row.status === ListingStatus.PENDING ? (
|
||||
<LoadingIcon
|
||||
height="14px"
|
||||
width="14px"
|
||||
stroke={row.status === ListingStatus.PENDING ? theme.accentAction : theme.textTertiary}
|
||||
/>
|
||||
) : row.status === ListingStatus.SIGNING ? (
|
||||
<ProceedText>
|
||||
<Trans>Proceed in wallet</Trans>
|
||||
</ProceedText>
|
||||
) : (
|
||||
row.status === ListingStatus.APPROVED && (
|
||||
<Check height="20" width="20" stroke={theme.accentSuccess} />
|
||||
)
|
||||
)}
|
||||
</IconWrapper>
|
||||
</ContentRow>
|
||||
)
|
||||
})}
|
||||
|
@ -12,6 +12,7 @@ interface SellAssetState {
|
||||
setAssetListPrice: (asset: WalletAsset, price?: number, marketplace?: ListingMarket) => void
|
||||
setGlobalMarketplaces: (marketplaces: ListingMarket[]) => void
|
||||
removeAssetMarketplace: (asset: WalletAsset, marketplace: ListingMarket) => void
|
||||
// TODO: After merging v2, see if this marketplace logic can be removed
|
||||
addMarketplaceWarning: (asset: WalletAsset, warning: ListingWarning) => void
|
||||
removeMarketplaceWarning: (asset: WalletAsset, warning: ListingWarning, setGlobalOverride?: boolean) => void
|
||||
removeAllMarketplaceWarnings: () => void
|
||||
|
@ -118,8 +118,3 @@ export enum ProfilePageStateType {
|
||||
VIEWING,
|
||||
LISTING,
|
||||
}
|
||||
|
||||
export enum ListingResponse {
|
||||
TRY_AGAIN,
|
||||
SUCCESS,
|
||||
}
|
||||
|
@ -92,7 +92,7 @@ export async function approveCollection(
|
||||
// setApprovalForAll() method
|
||||
const ERC721Contract = new Contract(collectionAddress, ERC721, signer)
|
||||
const signerAddress = await signer.getAddress()
|
||||
setStatus(ListingStatus.PENDING)
|
||||
|
||||
try {
|
||||
const approved = await ERC721Contract.isApprovedForAll(signerAddress, operator)
|
||||
if (approved) {
|
||||
@ -160,6 +160,7 @@ export async function signListing(
|
||||
)
|
||||
|
||||
const order = await executeAllActions()
|
||||
setStatus(ListingStatus.PENDING)
|
||||
const res = await PostOpenSeaSellOrder(order)
|
||||
if (res) setStatus(ListingStatus.APPROVED)
|
||||
return res
|
||||
|
Loading…
Reference in New Issue
Block a user