From 53a6acc19906d3d68cb8e767ec9db5c929b8e89d Mon Sep 17 00:00:00 2001 From: Jordan Frankfurt Date: Fri, 4 Nov 2022 12:19:42 -0500 Subject: [PATCH] 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 --- src/nft/components/bag/Bag.tsx | 11 ++++-- src/nft/components/bag/BagHeader.tsx | 6 +-- .../components/collection/CollectionAsset.tsx | 37 +++++++++++-------- src/nft/hooks/useBag.ts | 20 ++++++---- 4 files changed, 43 insertions(+), 31 deletions(-) diff --git a/src/nft/components/bag/Bag.tsx b/src/nft/components/bag/Bag.tsx index dbafe20e4f..37225db86e 100644 --- a/src/nft/components/bag/Bag.tsx +++ b/src/nft/components/bag/Bag.tsx @@ -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 = () => { <> diff --git a/src/nft/components/bag/BagHeader.tsx b/src/nft/components/bag/BagHeader.tsx index 6ff348364f..efc2e35698 100644 --- a/src/nft/components/bag/BagHeader.tsx +++ b/src/nft/components/bag/BagHeader.tsx @@ -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 ( {isProfilePage ? 'Sell NFTs' : 'My bag'} - + diff --git a/src/nft/components/collection/CollectionAsset.tsx b/src/nft/components/collection/CollectionAsset.tsx index 7f46937569..e3ece3c305 100644 --- a/src/nft/components/collection/CollectionAsset.tsx +++ b/src/nft/components/collection/CollectionAsset.tsx @@ -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 ( { - addAssetsToBag([asset]) - !bagExpanded && !isMobile && toggleBag() - sendAnalyticsEvent(EventName.NFT_BUY_ADDED, { ...eventProperties }) - }} - removeAssetFromBag={() => { - removeAssetsFromBag([asset]) - }} + addAssetToBag={handleAddAssetToBag} + removeAssetFromBag={handleRemoveAssetFromBag} > {asset.tokenType === 'ERC1155' && quantity > 0 && } diff --git a/src/nft/hooks/useBag.ts b/src/nft/hooks/useBag.ts index d359e673a4..b756906d70 100644 --- a/src/nft/hooks/useBag.ts +++ b/src/nft/hooks/useBag.ts @@ -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()( 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()( 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()( })), 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()( } }), 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()( : 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()( itemsInBag: [], didOpenUnavailableAssets: false, isLocked: false, + bagManuallyClosed: false, } else return {} }),