feat(bag): add check if the user has manually closed the bag (#5074)

* feat(bag): add check if the user has manually closed the bag, and don't reopen on asset add until bag is cleared

* pr feedback
This commit is contained in:
Jordan Frankfurt 2022-11-04 12:19:42 -05:00 committed by GitHub
parent bd0a32b07c
commit 53a6acc199
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 43 additions and 31 deletions

@ -26,7 +26,7 @@ import {
sortUpdatedAssets,
} from 'nft/utils'
import { combineBuyItemsWithTxRoute } from 'nft/utils/txRoute/combineItemsWithTxRoute'
import { useEffect, useMemo, useRef, useState } from 'react'
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
import { useQuery, useQueryClient } from 'react-query'
import { useLocation } from 'react-router-dom'
@ -74,6 +74,7 @@ const Bag = () => {
const toggleBag = useBag((s) => s.toggleBag)
const setTotalEthPrice = useBag((s) => s.setTotalEthPrice)
const setTotalUsdPrice = useBag((s) => s.setTotalUsdPrice)
const setBagExpanded = useBag((state) => state.setBagExpanded)
const { pathname } = useLocation()
const isProfilePage = pathname.startsWith('/profile')
@ -136,11 +137,13 @@ const Bag = () => {
setLocked(false)
setModalIsOpen(false)
setTransactionResponse(purchaseResponse)
bagExpanded && toggleBag()
setBagExpanded({ bagExpanded: false })
reset()
}
}
const handleCloseBag = useCallback(() => setBagExpanded({ bagExpanded: false, manualClose: true }), [setBagExpanded])
const fetchAssets = async () => {
const itemsToBuy = itemsInBag.filter((item) => item.status !== BagItemStatus.UNAVAILABLE).map((item) => item.asset)
const ethSellObject = buildSellObject(
@ -210,7 +213,7 @@ const Bag = () => {
}, [bagIsLocked, isOpen])
useEffect(() => {
bagExpanded && toggleBag()
setBagExpanded({ bagExpanded: false })
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [pathname])
@ -258,7 +261,7 @@ const Bag = () => {
<>
<BagHeader
numberOfAssets={isProfilePage ? sellAssets.length : itemsInBag.length}
toggleBag={toggleBag}
closeBag={handleCloseBag}
resetFlow={isProfilePage ? resetSellAssets : reset}
isProfilePage={isProfilePage}
/>

@ -43,17 +43,17 @@ const IconWrapper = styled.button`
`
interface BagHeaderProps {
numberOfAssets: number
toggleBag: () => void
closeBag: () => void
resetFlow: () => void
isProfilePage: boolean
}
export const BagHeader = ({ numberOfAssets, toggleBag, resetFlow, isProfilePage }: BagHeaderProps) => {
export const BagHeader = ({ numberOfAssets, closeBag, resetFlow, isProfilePage }: BagHeaderProps) => {
return (
<Column gap="4" paddingX="32" marginBottom="20">
<Row className={styles.header}>
<ThemedText.HeadlineSmall>{isProfilePage ? 'Sell NFTs' : 'My bag'}</ThemedText.HeadlineSmall>
<IconWrapper onClick={toggleBag}>
<IconWrapper onClick={closeBag}>
<BagCloseIcon />
</IconWrapper>
</Row>

@ -5,7 +5,7 @@ import { useTrace } from 'analytics/Trace'
import { useBag } from 'nft/hooks'
import { GenieAsset, Markets, UniformHeight } from 'nft/types'
import { formatWeiToDecimal, isAudio, isVideo, rarityProviderLogo } from 'nft/utils'
import { useMemo } from 'react'
import { useCallback, useMemo } from 'react'
import * as Card from './Card'
@ -34,11 +34,12 @@ export const CollectionAsset = ({
setCurrentTokenPlayingMedia,
rarityVerified,
}: CollectionAssetProps) => {
const bagManuallyClosed = useBag((state) => state.bagManuallyClosed)
const addAssetsToBag = useBag((state) => state.addAssetsToBag)
const removeAssetsFromBag = useBag((state) => state.removeAssetsFromBag)
const itemsInBag = useBag((state) => state.itemsInBag)
const bagExpanded = useBag((state) => state.bagExpanded)
const toggleBag = useBag((state) => state.toggleBag)
const setBagExpanded = useBag((state) => state.setBagExpanded)
const trace = useTrace({ page: PageName.NFT_COLLECTION_PAGE })
const { quantity, isSelected } = useMemo(() => {
@ -80,25 +81,29 @@ export const CollectionAsset = ({
}
}, [asset])
const eventProperties = {
collection_address: asset.address,
token_id: asset.tokenId,
token_type: asset.tokenType,
...trace,
}
const handleAddAssetToBag = useCallback(() => {
addAssetsToBag([asset])
if (!bagExpanded && !isMobile && !bagManuallyClosed) {
setBagExpanded({ bagExpanded: true })
}
sendAnalyticsEvent(EventName.NFT_BUY_ADDED, {
collection_address: asset.address,
token_id: asset.tokenId,
token_type: asset.tokenType,
...trace,
})
}, [addAssetsToBag, asset, bagExpanded, bagManuallyClosed, isMobile, setBagExpanded, trace])
const handleRemoveAssetFromBag = useCallback(() => {
removeAssetsFromBag([asset])
}, [asset, removeAssetsFromBag])
return (
<Card.Container
asset={asset}
selected={isSelected}
addAssetToBag={() => {
addAssetsToBag([asset])
!bagExpanded && !isMobile && toggleBag()
sendAnalyticsEvent(EventName.NFT_BUY_ADDED, { ...eventProperties })
}}
removeAssetFromBag={() => {
removeAssetsFromBag([asset])
}}
addAssetToBag={handleAddAssetToBag}
removeAssetFromBag={handleRemoveAssetFromBag}
>
<Card.ImageContainer>
{asset.tokenType === 'ERC1155' && quantity > 0 && <Card.Erc1155Controls quantity={quantity.toString()} />}

@ -6,6 +6,8 @@ import { devtools } from 'zustand/middleware'
interface BagState {
bagStatus: BagStatus
bagManuallyClosed: boolean
setBagExpanded: ({ bagExpanded, manualClose }: { bagExpanded: boolean; manualClose?: boolean }) => void
setBagStatus: (state: BagStatus) => void
itemsInBag: BagItem[]
setItemsInBag: (items: BagItem[]) => void
@ -30,6 +32,8 @@ export const useBag = create<BagState>()(
devtools(
(set, get) => ({
bagStatus: BagStatus.ADDING_TO_BAG,
bagExpanded: false,
bagManuallyClosed: false,
setBagStatus: (newBagStatus) =>
set(() => ({
bagStatus: newBagStatus,
@ -52,11 +56,9 @@ export const useBag = create<BagState>()(
set(() => ({
didOpenUnavailableAssets: didOpen,
})),
bagExpanded: false,
toggleBag: () =>
set(({ bagExpanded }) => ({
bagExpanded: !bagExpanded,
})),
setBagExpanded: ({ bagExpanded, manualClose }) =>
set(({ bagManuallyClosed }) => ({ bagExpanded, bagManuallyClosed: manualClose || bagManuallyClosed })),
toggleBag: () => set(({ bagExpanded }) => ({ bagExpanded: !bagExpanded })),
isLocked: false,
setLocked: (_isLocked) =>
set(() => ({
@ -64,7 +66,8 @@ export const useBag = create<BagState>()(
})),
itemsInBag: [],
setItemsInBag: (items) =>
set(() => ({
set(({ bagManuallyClosed }) => ({
bagManuallyClosed: items.length === 0 ? false : bagManuallyClosed,
itemsInBag: items,
})),
totalEthPrice: BigNumber.from(0),
@ -112,7 +115,7 @@ export const useBag = create<BagState>()(
}
}),
removeAssetsFromBag: (assets) => {
set(({ itemsInBag }) => {
set(({ bagManuallyClosed, itemsInBag }) => {
if (get().isLocked) return { itemsInBag: get().itemsInBag }
if (itemsInBag.length === 0) return { itemsInBag: [] }
const itemsCopy = itemsInBag.filter(
@ -123,7 +126,7 @@ export const useBag = create<BagState>()(
: asset.tokenId === item.asset.tokenId && asset.address === item.asset.address
)
)
return { itemsInBag: itemsCopy }
return { bagManuallyClosed: itemsCopy.length === 0 ? false : bagManuallyClosed, itemsInBag: itemsCopy }
})
},
lockSweepItems: (contractAddress) =>
@ -149,6 +152,7 @@ export const useBag = create<BagState>()(
itemsInBag: [],
didOpenUnavailableAssets: false,
isLocked: false,
bagManuallyClosed: false,
}
else return {}
}),