From dc8946c17d0a22d9e3f8b2c5360867b0a294fbe6 Mon Sep 17 00:00:00 2001 From: Imamah-Zafar <88320460+Imamah-Zafar@users.noreply.github.com> Date: Wed, 9 Nov 2022 18:59:23 +0500 Subject: [PATCH 01/10] Add Nft detail screen --- src/app/hooks/useNftDataSelector.ts | 14 + src/app/hooks/useNftReducer.ts | 21 ++ src/app/routes/index.tsx | 5 + src/app/screens/nftDashboard/index.tsx | 125 +++---- src/app/screens/nftDashboard/nft.tsx | 27 +- src/app/screens/nftDashboard/nftImage.tsx | 27 +- src/app/screens/nftDetail/descriptionTile.tsx | 36 ++ src/app/screens/nftDetail/index.tsx | 339 ++++++++++++++++++ src/app/screens/nftDetail/nftAttribute.tsx | 38 ++ src/app/stores/index.ts | 3 + .../stores/nftData/actions/actionCreator.ts | 10 + src/app/stores/nftData/actions/types.ts | 14 + src/app/stores/nftData/reducer.ts | 23 ++ src/locales/en.json | 19 + 14 files changed, 609 insertions(+), 92 deletions(-) create mode 100644 src/app/hooks/useNftDataSelector.ts create mode 100644 src/app/hooks/useNftReducer.ts create mode 100644 src/app/screens/nftDetail/descriptionTile.tsx create mode 100644 src/app/screens/nftDetail/index.tsx create mode 100644 src/app/screens/nftDetail/nftAttribute.tsx create mode 100644 src/app/stores/nftData/actions/actionCreator.ts create mode 100644 src/app/stores/nftData/actions/types.ts create mode 100644 src/app/stores/nftData/reducer.ts diff --git a/src/app/hooks/useNftDataSelector.ts b/src/app/hooks/useNftDataSelector.ts new file mode 100644 index 000000000..a9a4309ed --- /dev/null +++ b/src/app/hooks/useNftDataSelector.ts @@ -0,0 +1,14 @@ +import { StoreState } from '@stores/index'; +import { useSelector } from 'react-redux'; + +const useNftDataSelector = () => { + const nftDataState = useSelector((state: StoreState) => ({ + ...state.nftDataState, + })); + + return { + ...nftDataState, + }; +}; + +export default useNftDataSelector; diff --git a/src/app/hooks/useNftReducer.ts b/src/app/hooks/useNftReducer.ts new file mode 100644 index 000000000..dee6e9f3c --- /dev/null +++ b/src/app/hooks/useNftReducer.ts @@ -0,0 +1,21 @@ +import { NftDetailResponse } from '@secretkeylabs/xverse-core/types'; +import { setNftDataAction } from '@stores/nftData/actions/actionCreator'; +import { useDispatch } from 'react-redux'; +import useNftDataSelector from './useNftDataSelector'; + +const useNftDataReducer = () => { + const { nftData } = useNftDataSelector(); + const dispatch = useDispatch(); + const storeNftData = (data:NftDetailResponse) => { + if (data && !nftData.includes(data.data)) { + const modifiedNftList = [...nftData]; + modifiedNftList.push(data.data); + dispatch(setNftDataAction(modifiedNftList)); + } + }; + return { + storeNftData, + }; +}; + +export default useNftDataReducer; diff --git a/src/app/routes/index.tsx b/src/app/routes/index.tsx index 6ee439eb1..f9c057e73 100644 --- a/src/app/routes/index.tsx +++ b/src/app/routes/index.tsx @@ -21,6 +21,7 @@ import RestoreWallet from '@screens/restoreWallet'; import ForgotPassword from '@screens/forgotPassword'; import BackupWalletSteps from '@screens/backupWalletSteps'; import NftDashboard from '@screens/nftDashboard'; +import NftDetailScreen from '@screens/nftDetail'; const router = createHashRouter([ { @@ -111,6 +112,10 @@ const router = createHashRouter([ path: 'nft-dashboard', element: , }, + { + path: 'nft-dashboard/nft-detail/:id', + element: , + }, ], }, ]); diff --git a/src/app/screens/nftDashboard/index.tsx b/src/app/screens/nftDashboard/index.tsx index bc3528694..238f17032 100644 --- a/src/app/screens/nftDashboard/index.tsx +++ b/src/app/screens/nftDashboard/index.tsx @@ -20,16 +20,16 @@ import ShareDialog from '@components/shareNft'; import Nft from './nft'; const Container = styled.div` -display: flex; -flex-direction: column; -flex: 1; -margin-left: 5%; -margin-right: 5%; -margin-bottom: 5%; -overflow-y: auto; -&::-webkit-scrollbar { - display: none; -} + display: flex; + flex-direction: column; + flex: 1; + margin-left: 5%; + margin-right: 5%; + margin-bottom: 5%; + overflow-y: auto; + &::-webkit-scrollbar { + display: none; + } `; const GridContainer = styled.div((props) => ({ @@ -89,8 +89,8 @@ const NoCollectiblesText = styled.h1((props) => ({ })); const BarLoaderContainer = styled.div((props) => ({ - display: 'flex', marginTop: props.theme.spacing(5), + maxWidth: 300, })); function NftDashboard() { @@ -103,11 +103,9 @@ function NftDashboard() { const [nftTotal, setNftTotal] = useState(0); const [showShareNftOptions, setShowNftOptions] = useState(false); - const { - isLoading, data, - } = useQuery( + const { isLoading, data } = useQuery( ['nft-meta-data', { stxAddress, network, offset: offset.current }], - async () => getNftsData(stxAddress, network, offset.current), + async () => getNftsData('SP2VC4CXTWYRZEV7MSGXPNHE739N14ECQWX8JP2BF', network, offset.current), ); useEffect(() => { @@ -120,39 +118,20 @@ function NftDashboard() { navigate('/account-list'); }; - const loader = ( - - - - ); - const openInGalleryView = async () => { await chrome.tabs.create({ url: chrome.runtime.getURL('options.html#/nft-dashboard'), }); }; - const collectiblesCard = ( - - {t('COLLECTIBLES')} - {isLoading ? loader - : {`${nftTotal} ${t('ITEMS')}`}} - - - ); - - const nftListView = ( - nftTotal === 0 ? ( - - {t('NO_COLLECTIBLES')} - - ) : ( - - { nftList.map((nft) => ( - - ))} - - ) + const nftListView = nftTotal === 0 ? ( + {t('NO_COLLECTIBLES')} + ) : ( + + {nftList.map((nft) => ( + + ))} + ); const onSharePress = () => { @@ -167,27 +146,6 @@ function NftDashboard() { navigate('/receive/STX'); }; - const buttons = ( - - - - {showShareNftOptions && } - - ); - - const showLoader = ( - - - - ); - return ( <> @@ -195,9 +153,44 @@ function NftDashboard() { - {collectiblesCard} - {buttons} - {isLoading ? showLoader : nftListView} + + {t('COLLECTIBLES')} + {isLoading ? ( + + + + ) : ( + {`${nftTotal} ${t('ITEMS')}`} + )} + + + + + + {showShareNftOptions && ( + + )} + + {isLoading ? ( + + + + ) : ( + nftListView + )} diff --git a/src/app/screens/nftDashboard/nft.tsx b/src/app/screens/nftDashboard/nft.tsx index 587e389f9..e46357577 100644 --- a/src/app/screens/nftDashboard/nft.tsx +++ b/src/app/screens/nftDashboard/nft.tsx @@ -5,6 +5,7 @@ import { NonFungibleToken, getBnsNftName } from '@secretkeylabs/xverse-core/type import { BNS_CONTRACT } from '@utils/constants'; import NftUser from '@assets/img/nftDashboard/nft_user.svg'; import { useNavigate } from 'react-router-dom'; +import useNftDataReducer from '@hooks/useNftReducer'; import NftImage from './nftImage'; interface Props { @@ -42,6 +43,8 @@ const GridItemContainer = styled.button((props) => ({ function Nft({ asset }: Props) { const navigate = useNavigate(); + const { storeNftData } = useNftDataReducer(); + const url = `${asset.asset_identifier}::${asset.value.repr}`; const { data } = useQuery( ['nft-meta-data', asset.asset_identifier], async () => { @@ -63,30 +66,26 @@ function Nft({ asset }: Props) { } } - const nftName = ( - {getName()} - ); - - const bnsPlaceholder = ( - - user - - ); - const handleOnClick = () => { - + storeNftData(data); + if (asset.asset_identifier !== BNS_CONTRACT) { + navigate(`nft-detail/${url}`); + } }; return ( - {asset.asset_identifier === BNS_CONTRACT ? bnsPlaceholder : ( + {asset.asset_identifier === BNS_CONTRACT ? ( + + user + + ) : ( )} - {nftName} + {getName()} - ); } export default Nft; diff --git a/src/app/screens/nftDashboard/nftImage.tsx b/src/app/screens/nftDashboard/nftImage.tsx index a20444b5d..c6080b124 100644 --- a/src/app/screens/nftDashboard/nftImage.tsx +++ b/src/app/screens/nftDashboard/nftImage.tsx @@ -1,10 +1,10 @@ import { Suspense } from 'react'; import styled from 'styled-components'; import { Ring } from 'react-spinners-css'; +import Img from 'react-image'; import { TokenMetaData } from '@secretkeylabs/xverse-core/types/api/stacks/assets'; import { getFetchableUrl } from '@utils/helper'; import NftPlaceholderImage from '@assets/img/nftDashboard/ic_nft_diamond.svg'; -import Img from 'react-image'; const ImageContainer = styled.div((props) => ({ padding: props.theme.spacing(10), @@ -22,12 +22,6 @@ interface Props { metadata: TokenMetaData; } -const showloader = ( - - - -); - const showNftImagePlaceholder = ( nft @@ -38,21 +32,30 @@ function NftImage({ metadata }: Props) { if (metadata?.image_protocol) { return ( - + + + + )} + unloader={showNftImagePlaceholder} + /> ); } if (metadata?.asset_protocol) { return ( - - +