Commit 1411a921 authored by Jordan Frankfurt's avatar Jordan Frankfurt Committed by GitHub

feat(sell-bag): closing link sell bag open/close state with sell mode activation (#5128)

* stash resolve

* toggling bag open/close also toggles sell mode
parent d016bdd8
......@@ -2,14 +2,33 @@ import { NavIcon } from 'components/NavBar/NavIcon'
import * as styles from 'components/NavBar/ShoppingBag.css'
import { Box } from 'nft/components/Box'
import { BagIcon, HundredsOverflowIcon } from 'nft/components/icons'
import { useBag } from 'nft/hooks'
import { useEffect, useState } from 'react'
import { useBag, useSellAsset } from 'nft/hooks'
import { useCallback, useEffect, useState } from 'react'
import shallow from 'zustand/shallow'
export const ShoppingBag = () => {
const itemsInBag = useBag((state) => state.itemsInBag)
const [bagQuantity, setBagQuantity] = useState(0)
const toggleBag = useBag((s) => s.toggleBag)
const { bagExpanded, setBagExpanded } = useBag(
({ bagExpanded, setBagExpanded }) => ({ bagExpanded, setBagExpanded }),
shallow
)
const { isSellMode, resetSellAssets, setIsSellMode } = useSellAsset(
({ isSellMode, reset, setIsSellMode }) => ({
isSellMode,
resetSellAssets: reset,
setIsSellMode,
}),
shallow
)
const handleIconClick = useCallback(() => {
if (isSellMode && bagExpanded) {
resetSellAssets()
setIsSellMode(false)
}
setBagExpanded({ bagExpanded: !bagExpanded })
}, [bagExpanded, isSellMode, resetSellAssets, setBagExpanded, setIsSellMode])
useEffect(() => {
setBagQuantity(itemsInBag.length)
......@@ -18,7 +37,7 @@ export const ShoppingBag = () => {
const bagHasItems = bagQuantity > 0
return (
<NavIcon onClick={toggleBag}>
<NavIcon onClick={handleIconClick}>
<BagIcon viewBox="0 0 20 20" width={24} height={24} />
{bagHasItems && (
<Box className={styles.bagQuantity}>{bagQuantity > 99 ? <HundredsOverflowIcon /> : bagQuantity}</Box>
......
......@@ -30,6 +30,7 @@ import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
import { useQuery, useQueryClient } from 'react-query'
import { useLocation } from 'react-router-dom'
import styled from 'styled-components/macro'
import shallow from 'zustand/shallow'
import * as styles from './Bag.css'
import { BagContent } from './BagContent'
......@@ -67,24 +68,37 @@ const ScrollingIndicator = ({ top, show }: SeparatorProps) => (
const Bag = () => {
const { account, provider } = useWeb3React()
const bagStatus = useBag((s) => s.bagStatus)
const setBagStatus = useBag((s) => s.setBagStatus)
const didOpenUnavailableAssets = useBag((s) => s.didOpenUnavailableAssets)
const setDidOpenUnavailableAssets = useBag((s) => s.setDidOpenUnavailableAssets)
const bagIsLocked = useBag((s) => s.isLocked)
const setLocked = useBag((s) => s.setLocked)
const reset = useBag((s) => s.reset)
const resetSellAssets = useSellAsset((state) => state.reset)
const sellAssets = useSellAsset((state) => state.sellAssets)
const setProfilePageState = useProfilePageState((state) => state.setProfilePageState)
const profilePageState = useProfilePageState((state) => state.state)
const uncheckedItemsInBag = useBag((s) => s.itemsInBag)
const setItemsInBag = useBag((s) => s.setItemsInBag)
const bagExpanded = useBag((s) => s.bagExpanded)
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 { resetSellAssets, sellAssets, setIsSellMode } = useSellAsset(
({ isSellMode, reset, sellAssets, setIsSellMode }) => ({
isSellMode,
resetSellAssets: reset,
sellAssets,
setIsSellMode,
}),
shallow
)
const { profilePageState, setProfilePageState } = useProfilePageState(
({ setProfilePageState, state }) => ({ profilePageState: state, setProfilePageState }),
shallow
)
const {
bagStatus,
setBagStatus,
didOpenUnavailableAssets,
setDidOpenUnavailableAssets,
bagIsLocked,
setLocked,
reset,
setItemsInBag,
bagExpanded,
toggleBag,
setTotalEthPrice,
setTotalUsdPrice,
setBagExpanded,
} = useBag((state) => ({ ...state, bagIsLocked: state.isLocked, uncheckedItemsInBag: state.itemsInBag }), shallow)
const { uncheckedItemsInBag } = useBag(({ itemsInBag }) => ({ uncheckedItemsInBag: itemsInBag }))
const { pathname } = useLocation()
const isProfilePage = pathname.startsWith('/nfts/profile')
......@@ -101,9 +115,7 @@ const Bag = () => {
const queryClient = useQueryClient()
const itemsInBag = useMemo(() => {
return recalculateBagUsingPooledAssets(uncheckedItemsInBag)
}, [uncheckedItemsInBag])
const itemsInBag = useMemo(() => recalculateBagUsingPooledAssets(uncheckedItemsInBag), [uncheckedItemsInBag])
const [isOpen, setModalIsOpen] = useState(false)
const [userCanScroll, setUserCanScroll] = useState(false)
......@@ -153,7 +165,10 @@ const Bag = () => {
}
}
const handleCloseBag = useCallback(() => setBagExpanded({ bagExpanded: false, manualClose: true }), [setBagExpanded])
const handleCloseBag = useCallback(() => {
setIsSellMode(false)
setBagExpanded({ bagExpanded: false, manualClose: true })
}, [setBagExpanded, setIsSellMode])
const fetchAssets = async () => {
const itemsToBuy = itemsInBag.filter((item) => item.status !== BagItemStatus.UNAVAILABLE).map((item) => item.asset)
......@@ -258,6 +273,14 @@ const Bag = () => {
(!isProfilePage && !isBuyingAssets && bagStatus === BagStatus.ADDING_TO_BAG) || (isProfilePage && !isSellingAssets)
)
const eventProperties = useMemo(
() => ({
usd_value: totalUsdPrice,
...formatAssetEventProperties(itemsInBag.map((item) => item.asset)),
}),
[itemsInBag, totalUsdPrice]
)
return (
<>
{bagExpanded && isNFTPage ? (
......@@ -283,10 +306,7 @@ const Bag = () => {
totalUsdPrice={totalUsdPrice}
bagStatus={bagStatus}
fetchAssets={fetchAssets}
eventProperties={{
usd_value: totalUsdPrice,
...formatAssetEventProperties(itemsInBag.map((item) => item.asset)),
}}
eventProperties={eventProperties}
/>
)}
{isSellingAssets && isProfilePage && (
......
......@@ -9,6 +9,7 @@ import { CrossIcon, TagIcon } from 'nft/components/icons'
import { FilterSidebar } from 'nft/components/profile/view/FilterSidebar'
import { buttonTextMedium, subhead } from 'nft/css/common.css'
import {
useBag,
useFiltersExpanded,
useIsMobile,
useProfilePageState,
......@@ -19,11 +20,12 @@ import {
import { ScreenBreakpointsPaddings } from 'nft/pages/collection/index.css'
import { fetchWalletAssets, OSCollectionsFetcher } from 'nft/queries'
import { ProfilePageStateType, WalletAsset, WalletCollection } from 'nft/types'
import { Dispatch, SetStateAction, useEffect, useMemo, useReducer, useState } from 'react'
import { Dispatch, SetStateAction, useCallback, useEffect, useMemo, useState } from 'react'
import InfiniteScroll from 'react-infinite-scroll-component'
import { useInfiniteQuery, useQuery } from 'react-query'
import { useSpring } from 'react-spring'
import styled from 'styled-components/macro'
import shallow from 'zustand/shallow'
import { EmptyWalletContent } from './EmptyWalletContent'
import { ProfileAccountDetails } from './ProfileAccountDetails'
......@@ -69,19 +71,27 @@ export const ProfilePage = () => {
const walletCollections = useWalletCollections((state) => state.walletCollections)
const setWalletCollections = useWalletCollections((state) => state.setWalletCollections)
const listFilter = useWalletCollections((state) => state.listFilter)
const { isSellMode, resetSellAssets, setIsSellMode } = useSellAsset(
({ isSellMode, reset, setIsSellMode }) => ({
isSellMode,
resetSellAssets: reset,
setIsSellMode,
}),
shallow
)
const sellAssets = useSellAsset((state) => state.sellAssets)
const reset = useSellAsset((state) => state.reset)
const resetSellAssets = useSellAsset((state) => state.reset)
const { setBagExpanded } = useBag(({ setBagExpanded }) => ({ setBagExpanded }), shallow)
const setSellPageState = useProfilePageState((state) => state.setProfilePageState)
const [isFiltersExpanded, setFiltersExpanded] = useFiltersExpanded()
const isMobile = useIsMobile()
const isNftGraphQl = useNftGraphQlFlag() === NftGraphQlVariant.Enabled
const [isSellMode, toggleSellMode] = useReducer((s) => !s, false)
const handleSellModeClick = () => {
const handleSellModeClick = useCallback(() => {
resetSellAssets()
toggleSellMode()
}
setIsSellMode(!isSellMode)
setBagExpanded({ bagExpanded: !isSellMode })
}, [isSellMode, resetSellAssets, setBagExpanded, setIsSellMode])
const { data: ownerCollections, isLoading: collectionsAreLoading } = useQuery(
['ownerCollections', address],
......@@ -234,7 +244,7 @@ export const ProfilePage = () => {
color="genieBlue"
marginRight="20"
marginLeft="auto"
onClick={reset}
onClick={resetSellAssets}
lineHeight="16"
>
Clear
......
......@@ -4,6 +4,7 @@ import { devtools } from 'zustand/middleware'
import { ListingMarket, ListingWarning, WalletAsset } from '../types'
interface SellAssetState {
isSellMode: boolean
sellAssets: WalletAsset[]
selectSellAsset: (asset: WalletAsset) => void
removeSellAsset: (asset: WalletAsset) => void
......@@ -11,6 +12,7 @@ interface SellAssetState {
setGlobalExpiration: (expirationTime: number) => void
setAssetListPrice: (asset: WalletAsset, price?: number, marketplace?: ListingMarket) => void
setGlobalMarketplaces: (marketplaces: ListingMarket[]) => void
setIsSellMode: (b: boolean) => void
removeAssetMarketplace: (asset: WalletAsset, marketplace: ListingMarket) => void
addMarketplaceWarning: (asset: WalletAsset, warning: ListingWarning) => void
removeMarketplaceWarning: (asset: WalletAsset, warning: ListingWarning, setGlobalOverride?: boolean) => void
......@@ -20,6 +22,7 @@ interface SellAssetState {
export const useSellAsset = create<SellAssetState>()(
devtools(
(set) => ({
isSellMode: false,
sellAssets: [],
selectSellAsset: (asset) =>
set(({ sellAssets }) => {
......@@ -95,6 +98,7 @@ export const useSellAsset = create<SellAssetState>()(
return { sellAssets: assetsCopy }
})
},
setIsSellMode: (isSellMode) => set(() => ({ isSellMode })),
removeAssetMarketplace: (asset, marketplace) => {
set(({ sellAssets }) => {
const assetsCopy = [...sellAssets]
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment