diff --git a/packages/adena-extension/src/components/atoms/option-dropdown/option-dropdown.styles.ts b/packages/adena-extension/src/components/atoms/option-dropdown/option-dropdown.styles.ts index cea69f67f..709547c53 100644 --- a/packages/adena-extension/src/components/atoms/option-dropdown/option-dropdown.styles.ts +++ b/packages/adena-extension/src/components/atoms/option-dropdown/option-dropdown.styles.ts @@ -59,12 +59,24 @@ export const OptionDropdownItemWrapper = styled(Row)` transition: 0.2s; cursor: pointer; - & > svg { - width: 14px; + .item-icon-wrapper { + display: block; + width: 12px; height: 14px; + + & > svg { + width: 12px; + height: 12px; + + &.large { + width: 14px; + height: 14px; + } + } } & > .title { + display: inline-flex; width: 100%; ${fonts.body3Reg} } diff --git a/packages/adena-extension/src/components/atoms/option-dropdown/option-dropdown.tsx b/packages/adena-extension/src/components/atoms/option-dropdown/option-dropdown.tsx index 6b430bb5a..d04252584 100644 --- a/packages/adena-extension/src/components/atoms/option-dropdown/option-dropdown.tsx +++ b/packages/adena-extension/src/components/atoms/option-dropdown/option-dropdown.tsx @@ -78,7 +78,7 @@ interface OptionDropdownItemProps { const OptionDropdownItem: React.FC = ({ icon, text, onClick }) => { return ( - {!!icon && icon} +
{!!icon && icon}
{text}
); diff --git a/packages/adena-extension/src/components/molecules/loading-nft/index.tsx b/packages/adena-extension/src/components/molecules/loading-nft/index.tsx index a6aea7773..378ecd625 100644 --- a/packages/adena-extension/src/components/molecules/loading-nft/index.tsx +++ b/packages/adena-extension/src/components/molecules/loading-nft/index.tsx @@ -15,9 +15,6 @@ const ListBoxWrap = styled.div` ${mixins.flex({ direction: 'row', justify: 'flex-start' })} width: 100%; gap: 16px; - :first-child { - margin-top: 8px; - } `; const SkeletonBox = styled(SkeletonBoxStyle)` @@ -33,8 +30,7 @@ const NftRowBox = (): ReactElement => { {Array.from({ length: 2 }, (v, i) => ( - - + ))} diff --git a/packages/adena-extension/src/components/molecules/transaction-history/transaction-history-list-item/transaction-history-list-item.tsx b/packages/adena-extension/src/components/molecules/transaction-history/transaction-history-list-item/transaction-history-list-item.tsx index 389c4b786..dd3d7fcfe 100644 --- a/packages/adena-extension/src/components/molecules/transaction-history/transaction-history-list-item/transaction-history-list-item.tsx +++ b/packages/adena-extension/src/components/molecules/transaction-history/transaction-history-list-item/transaction-history-list-item.tsx @@ -4,6 +4,7 @@ import ContractIcon from '@assets/contract.svg'; import FailedIcon from '@assets/failed.svg'; import SuccessIcon from '@assets/success.svg'; import { TokenBalance } from '@components/molecules'; +import { UseQueryOptions, UseQueryResult } from '@tanstack/react-query'; import React, { useCallback } from 'react'; import { TransactionHistoryListItemWrapper } from './transaction-history-list-item.styles'; @@ -20,6 +21,11 @@ export interface TransactionHistoryListItemProps { denom: string; }; valueType: 'DEFAULT' | 'ACTIVE' | 'BLUR'; + queryGRC721TokenUri?: ( + packagePath: string, + tokenId: string, + options?: UseQueryOptions, + ) => UseQueryResult; onClickItem: (hash: string) => void; } @@ -33,9 +39,17 @@ const TransactionHistoryListItem: React.FC = ({ description, amount, valueType, + queryGRC721TokenUri, onClickItem, }) => { + const tokenUriQuery = + type === 'TRANSFER_GRC721' && queryGRC721TokenUri ? queryGRC721TokenUri(logo || '', '0') : null; + const getLogoImage = useCallback(() => { + if (type === 'TRANSFER_GRC721' && tokenUriQuery) { + return tokenUriQuery?.data || `${UnknownTokenIcon}`; + } + if (type === 'ADD_PACKAGE') { return `${AddPackageIcon}`; } @@ -49,7 +63,7 @@ const TransactionHistoryListItem: React.FC = ({ return `${UnknownTokenIcon}`; } return `${logo}`; - }, [type, logo]); + }, [type, logo, tokenUriQuery]); const getValueTypeClassName = useCallback(() => { if (valueType === 'ACTIVE') { diff --git a/packages/adena-extension/src/components/molecules/transaction-history/transaction-history-list/transaction-history-list.tsx b/packages/adena-extension/src/components/molecules/transaction-history/transaction-history-list/transaction-history-list.tsx index e49cac270..b23bb728c 100644 --- a/packages/adena-extension/src/components/molecules/transaction-history/transaction-history-list/transaction-history-list.tsx +++ b/packages/adena-extension/src/components/molecules/transaction-history/transaction-history-list/transaction-history-list.tsx @@ -1,17 +1,24 @@ -import React from 'react'; -import { TransactionHistoryListWrapper } from './transaction-history-list.styles'; import TransactionHistoryListItem from '@components/molecules/transaction-history/transaction-history-list-item/transaction-history-list-item'; +import { UseQueryOptions, UseQueryResult } from '@tanstack/react-query'; import { TransactionInfo } from '@types'; +import React from 'react'; +import { TransactionHistoryListWrapper } from './transaction-history-list.styles'; export interface TransactionHistoryListProps { title: string; transactions: TransactionInfo[]; + queryGRC721TokenUri?: ( + packagePath: string, + tokenId: string, + options?: UseQueryOptions, + ) => UseQueryResult; onClickItem: (hash: string) => void; } const TransactionHistoryList: React.FC = ({ title, transactions, + queryGRC721TokenUri, onClickItem, }) => { return ( @@ -19,7 +26,12 @@ const TransactionHistoryList: React.FC = ({ {title}
{transactions.map((transaction, index) => ( - + ))}
diff --git a/packages/adena-extension/src/components/molecules/transaction-history/transaction-history/index.tsx b/packages/adena-extension/src/components/molecules/transaction-history/transaction-history/index.tsx index 3e7c8a35c..2ecd53b69 100644 --- a/packages/adena-extension/src/components/molecules/transaction-history/transaction-history/index.tsx +++ b/packages/adena-extension/src/components/molecules/transaction-history/transaction-history/index.tsx @@ -1,14 +1,15 @@ import React from 'react'; import { useTheme } from 'styled-components'; +import { Text } from '@components/atoms'; +import TransactionHistoryList from '@components/molecules/transaction-history/transaction-history-list/transaction-history-list'; +import { UseQueryOptions, UseQueryResult } from '@tanstack/react-query'; +import { TransactionInfo } from '@types'; +import LoadingHistory from '../loading-history'; import { TransactionHistoryDescriptionWrapper, TransactionHistoryWrapper, } from './transaction-history.styles'; -import TransactionHistoryList from '@components/molecules/transaction-history/transaction-history-list/transaction-history-list'; -import { Text } from '@components/atoms'; -import LoadingHistory from '../loading-history'; -import { TransactionInfo } from '@types'; export interface TransactionHistoryProps { status: 'error' | 'loading' | 'success'; @@ -16,12 +17,18 @@ export interface TransactionHistoryProps { title: string; transactions: TransactionInfo[]; }[]; + queryGRC721TokenUri?: ( + packagePath: string, + tokenId: string, + options?: UseQueryOptions, + ) => UseQueryResult; onClickItem: (hash: string) => void; } export const TransactionHistory: React.FC = ({ status, transactionInfoLists, + queryGRC721TokenUri, onClickItem, }) => { const theme = useTheme(); @@ -41,7 +48,12 @@ export const TransactionHistory: React.FC = ({ return ( {transactionInfoLists.map((transactionInfoList, index) => ( - + ))} ); diff --git a/packages/adena-extension/src/components/pages/nft-asset/nft-asset-header/nft-asset-header.tsx b/packages/adena-extension/src/components/pages/nft-asset/nft-asset-header/nft-asset-header.tsx index 33f715542..7e84dc6cd 100644 --- a/packages/adena-extension/src/components/pages/nft-asset/nft-asset-header/nft-asset-header.tsx +++ b/packages/adena-extension/src/components/pages/nft-asset/nft-asset-header/nft-asset-header.tsx @@ -47,7 +47,7 @@ const NFTAssetHeader: React.FC = ({ }, { text: visible ? 'Hide Collection' : 'Show Collection', - icon: visible ? : , + icon: visible ? : , onClick: visible ? hideCollection : showCollection, }, ], diff --git a/packages/adena-extension/src/components/pages/nft-collection/nft-collection-assets/nft-collection-assets.styles.ts b/packages/adena-extension/src/components/pages/nft-collection/nft-collection-assets/nft-collection-assets.styles.ts index 8e7a5d57a..80632333e 100644 --- a/packages/adena-extension/src/components/pages/nft-collection/nft-collection-assets/nft-collection-assets.styles.ts +++ b/packages/adena-extension/src/components/pages/nft-collection/nft-collection-assets/nft-collection-assets.styles.ts @@ -1,6 +1,8 @@ +import { getTheme } from '@styles/theme'; import styled from 'styled-components'; export const NFTCollectionAssetsWrapper = styled.div` + position: relative; display: grid; width: 100%; min-height: auto; @@ -14,4 +16,13 @@ export const NFTCollectionAssetsWrapper = styled.div` width: 100%; text-align: center; } + + .loading-wrapper { + position: absolute; + width: 100%; + height: auto; + top: 0; + left: 0; + background-color: ${getTheme('neutral', '_8')}; + } `; diff --git a/packages/adena-extension/src/components/pages/nft-collection/nft-collection-assets/nft-collection-assets.tsx b/packages/adena-extension/src/components/pages/nft-collection/nft-collection-assets/nft-collection-assets.tsx index c556094ab..92d3822ec 100644 --- a/packages/adena-extension/src/components/pages/nft-collection/nft-collection-assets/nft-collection-assets.tsx +++ b/packages/adena-extension/src/components/pages/nft-collection/nft-collection-assets/nft-collection-assets.tsx @@ -38,10 +38,6 @@ const NFTCollectionAssets: React.FC = ({ return tokens?.length === 0; }, [tokens]); - if (isLoading) { - return ; - } - if (isEmptyAssets) { return ( @@ -62,6 +58,12 @@ const NFTCollectionAssets: React.FC = ({ moveAssetPage={moveAssetPage} /> ))} + + {isLoading && ( +
+ +
+ )}
); }; diff --git a/packages/adena-extension/src/components/pages/nft/nft-collection-card/nft-collection-card.styles.ts b/packages/adena-extension/src/components/pages/nft/nft-collection-card/nft-collection-card.styles.ts index f744629b7..6aa811e8c 100644 --- a/packages/adena-extension/src/components/pages/nft/nft-collection-card/nft-collection-card.styles.ts +++ b/packages/adena-extension/src/components/pages/nft/nft-collection-card/nft-collection-card.styles.ts @@ -25,6 +25,7 @@ export const NFTCollectionCardWrapper = styled(View)` align-self: center; border-radius: 10px; background-color: ${getTheme('neutral', '_9')}; + cursor: default; .pin-wrapper { ${mixins.flex({ direction: 'column', align: 'center', justify: 'center' })} @@ -51,6 +52,7 @@ export const NFTCollectionCardWrapper = styled(View)` display: inline-block; width: 100%; ${fonts.captionBold} + text-align: center; word-break: break-all; overflow: hidden; white-space: nowrap; diff --git a/packages/adena-extension/src/components/pages/nft/nft-collection-card/nft-collection-card.tsx b/packages/adena-extension/src/components/pages/nft/nft-collection-card/nft-collection-card.tsx index 4180570c7..4f444b97e 100644 --- a/packages/adena-extension/src/components/pages/nft/nft-collection-card/nft-collection-card.tsx +++ b/packages/adena-extension/src/components/pages/nft/nft-collection-card/nft-collection-card.tsx @@ -88,7 +88,13 @@ const NFTCollectionCard: React.FC = ({ -
+
{ + e.preventDefault(); + e.stopPropagation(); + }} + >
diff --git a/packages/adena-extension/src/components/pages/nft/nft-collections/nft-collections.styles.ts b/packages/adena-extension/src/components/pages/nft/nft-collections/nft-collections.styles.ts index 55de1ab84..d0ca29ab0 100644 --- a/packages/adena-extension/src/components/pages/nft/nft-collections/nft-collections.styles.ts +++ b/packages/adena-extension/src/components/pages/nft/nft-collections/nft-collections.styles.ts @@ -1,10 +1,12 @@ +import { getTheme } from '@styles/theme'; import styled from 'styled-components'; export const NFTCollectionsWrapper = styled.div` + position: relative; display: flex; flex-direction: column; width: 100%; - gap: 16px; + gap: 24px; &.non-items { padding-top: 151px; @@ -32,4 +34,13 @@ export const NFTCollectionsWrapper = styled.div` justify-content: center; align-items: center; } + + .loading-wrapper { + position: absolute; + width: 100%; + height: auto; + top: 0; + left: 0; + background-color: ${getTheme('neutral', '_8')}; + } `; diff --git a/packages/adena-extension/src/components/pages/nft/nft-collections/nft-collections.tsx b/packages/adena-extension/src/components/pages/nft/nft-collections/nft-collections.tsx index b45fa3f56..b5cd223be 100644 --- a/packages/adena-extension/src/components/pages/nft/nft-collections/nft-collections.tsx +++ b/packages/adena-extension/src/components/pages/nft/nft-collections/nft-collections.tsx @@ -95,10 +95,6 @@ const NFTCollections: React.FC = ({ moveManageCollectionsPage(); }, [moveManageCollectionsPage]); - if (isLoading) { - return ; - } - if (isEmptyCollections) { return ( @@ -141,6 +137,12 @@ const NFTCollections: React.FC = ({
+ + {isLoading && ( +
+ +
+ )}
); }; diff --git a/packages/adena-extension/src/hooks/nft/use-get-grc721-balance.ts b/packages/adena-extension/src/hooks/nft/use-get-grc721-balance.ts index 06fae563d..d7f3e3311 100644 --- a/packages/adena-extension/src/hooks/nft/use-get-grc721-balance.ts +++ b/packages/adena-extension/src/hooks/nft/use-get-grc721-balance.ts @@ -3,6 +3,8 @@ import { useCurrentAccount } from '@hooks/use-current-account'; import { useNetwork } from '@hooks/use-network'; import { useQuery, UseQueryOptions, UseQueryResult } from '@tanstack/react-query'; +export const GET_GRC721_BALANCE_QUERY_KEY = 'nft/useGetGRC721TokenBalance'; + export const useGetGRC721Balance = ( packagePath: string, options?: UseQueryOptions, @@ -12,7 +14,7 @@ export const useGetGRC721Balance = ( const { currentNetwork } = useNetwork(); return useQuery({ - queryKey: ['nft/useGetGRC721TokenBalance', packagePath, currentAddress, currentNetwork.chainId], + queryKey: [GET_GRC721_BALANCE_QUERY_KEY, packagePath, currentAddress, currentNetwork.chainId], queryFn: () => { if (!currentAddress) { return null; diff --git a/packages/adena-extension/src/hooks/nft/use-get-grc721-collections.ts b/packages/adena-extension/src/hooks/nft/use-get-grc721-collections.ts index a47a27dd7..2fe72eb0a 100644 --- a/packages/adena-extension/src/hooks/nft/use-get-grc721-collections.ts +++ b/packages/adena-extension/src/hooks/nft/use-get-grc721-collections.ts @@ -4,6 +4,8 @@ import { useNetwork } from '@hooks/use-network'; import { useQuery, UseQueryOptions, UseQueryResult } from '@tanstack/react-query'; import { GRC721CollectionModel } from '@types'; +export const GET_GRC721_COLLECTIONS_QUERY_KEY = 'nft/useGetGRC721Collections'; + export const useGetGRC721Collections = ( options?: UseQueryOptions, ): UseQueryResult => { @@ -12,15 +14,17 @@ export const useGetGRC721Collections = ( const { currentNetwork } = useNetwork(); return useQuery({ - queryKey: ['nft/useGetGRC721Collections', currentAccount?.id || '', currentNetwork.chainId], - queryFn: () => { + queryKey: [GET_GRC721_COLLECTIONS_QUERY_KEY, currentAccount?.id || '', currentNetwork.chainId], + queryFn: async () => { if (!currentAccount) { return null; } - return tokenService + const collections = await tokenService .getAccountGRC721Collections(currentAccount.id, currentNetwork.chainId) .catch(() => []); + + return collections.map((collection) => ({ ...collection, tokenId: '0' })); }, staleTime: Infinity, keepPreviousData: true, diff --git a/packages/adena-extension/src/hooks/nft/use-get-grc721-token-uri.ts b/packages/adena-extension/src/hooks/nft/use-get-grc721-token-uri.ts index d084cee5d..cf129160b 100644 --- a/packages/adena-extension/src/hooks/nft/use-get-grc721-token-uri.ts +++ b/packages/adena-extension/src/hooks/nft/use-get-grc721-token-uri.ts @@ -2,6 +2,8 @@ import { useAdenaContext } from '@hooks/use-context'; import { useNetwork } from '@hooks/use-network'; import { useQuery, UseQueryOptions, UseQueryResult } from '@tanstack/react-query'; +export const GET_GRC721_TOKEN_URI_QUERY_KEY = 'nft/useGetGRC721TokenUri'; + export const useGetGRC721TokenUri = ( packagePath: string, tokenId: string, @@ -11,8 +13,9 @@ export const useGetGRC721TokenUri = ( const { currentNetwork } = useNetwork(); return useQuery({ - queryKey: ['nft/useGetGRC721TokenUri', packagePath, tokenId, currentNetwork.chainId], + queryKey: [GET_GRC721_TOKEN_URI_QUERY_KEY, packagePath, tokenId, currentNetwork.chainId], queryFn: () => tokenService.fetchGRC721TokenUri(packagePath, tokenId).catch(() => null), + staleTime: Infinity, ...options, }); }; diff --git a/packages/adena-extension/src/hooks/use-make-transactions-with-time.ts b/packages/adena-extension/src/hooks/use-make-transactions-with-time.ts index 2796e673f..9aae6bf37 100644 --- a/packages/adena-extension/src/hooks/use-make-transactions-with-time.ts +++ b/packages/adena-extension/src/hooks/use-make-transactions-with-time.ts @@ -54,7 +54,7 @@ export const useMakeTransactionsWithTime = ( denom: 'GNOT', }, ), - logo: collection?.image || '', + logo: collection?.packagePath || '', date: time || '', }; } diff --git a/packages/adena-extension/src/pages/popup/wallet/nft-transfer-input/index.tsx b/packages/adena-extension/src/pages/popup/wallet/nft-transfer-input/index.tsx index 75f434bea..899864007 100644 --- a/packages/adena-extension/src/pages/popup/wallet/nft-transfer-input/index.tsx +++ b/packages/adena-extension/src/pages/popup/wallet/nft-transfer-input/index.tsx @@ -14,6 +14,7 @@ import { useGetGRC721TokenUri } from '@hooks/nft/use-get-grc721-token-uri'; import useAppNavigate from '@hooks/use-app-navigate'; import { useNetwork } from '@hooks/use-network'; import { useTransferInfo } from '@hooks/use-transfer-info'; +import BigNumber from 'bignumber.js'; interface HistoryData { grc721Token: GRC721Model; @@ -101,8 +102,10 @@ const NFTTransferInputContainer: React.FC = () => { grc721Token, toAddress: addressBookInput.resultAddress, networkFee: { - value: DEFAULT_NETWORK_FEE.toString(), - denom: GNOT_TOKEN.denom, + value: BigNumber(DEFAULT_NETWORK_FEE) + .shiftedBy(GNOT_TOKEN.decimals * -1) + .toString(), + denom: GNOT_TOKEN.symbol, }, memo, }, diff --git a/packages/adena-extension/src/pages/popup/wallet/nft/collection-asset.tsx b/packages/adena-extension/src/pages/popup/wallet/nft/collection-asset.tsx index e6e71be6a..1c2bc5d44 100644 --- a/packages/adena-extension/src/pages/popup/wallet/nft/collection-asset.tsx +++ b/packages/adena-extension/src/pages/popup/wallet/nft/collection-asset.tsx @@ -22,7 +22,7 @@ const Wrapper = styled.main` height: fit-content; padding-top: 24px; padding-bottom: 96px; - gap: 8px; + gap: 12px; background-color: ${getTheme('neutral', '_8')}; .send-button { diff --git a/packages/adena-extension/src/pages/popup/wallet/transaction-detail/index.tsx b/packages/adena-extension/src/pages/popup/wallet/transaction-detail/index.tsx index cbe5651ee..438a703ea 100644 --- a/packages/adena-extension/src/pages/popup/wallet/transaction-detail/index.tsx +++ b/packages/adena-extension/src/pages/popup/wallet/transaction-detail/index.tsx @@ -1,22 +1,23 @@ -import React, { useCallback } from 'react'; +import { useCallback } from 'react'; import styled from 'styled-components'; -import useLink from '@hooks/use-link'; -import { Text, CopyIconButton, Button } from '@components/atoms'; -import { TokenBalance } from '@components/molecules'; -import { formatHash, getDateTimeText, getStatusStyle } from '@common/utils/client-utils'; -import IconShare from '@assets/icon-share'; -import { useTokenMetainfo } from '@hooks/use-token-metainfo'; -import ContractIcon from '@assets/contract.svg'; import AddPackageIcon from '@assets/addpkg.svg'; -import { useNetwork } from '@hooks/use-network'; -import { fonts, getTheme } from '@styles/theme'; -import mixins from '@styles/mixins'; -import useAppNavigate from '@hooks/use-app-navigate'; -import { RoutePath } from '@types'; import UnknownTokenIcon from '@assets/common-unknown-token.svg'; +import ContractIcon from '@assets/contract.svg'; +import IconShare from '@assets/icon-share'; import { SCANNER_URL } from '@common/constants/resource.constant'; +import { formatHash, getDateTimeText, getStatusStyle } from '@common/utils/client-utils'; import { makeQueryString } from '@common/utils/string-utils'; +import { Button, CopyIconButton, Text } from '@components/atoms'; +import { TokenBalance } from '@components/molecules'; +import { useGetGRC721TokenUri } from '@hooks/nft/use-get-grc721-token-uri'; +import useAppNavigate from '@hooks/use-app-navigate'; +import useLink from '@hooks/use-link'; +import { useNetwork } from '@hooks/use-network'; +import { useTokenMetainfo } from '@hooks/use-token-metainfo'; +import mixins from '@styles/mixins'; +import { fonts, getTheme } from '@styles/theme'; +import { RoutePath } from '@types'; interface DLProps { color?: string; @@ -28,8 +29,16 @@ export const TransactionDetail = (): JSX.Element => { const { currentNetwork, scannerParameters } = useNetwork(); const { goBack, params } = useAppNavigate(); const transactionItem = params.transactionInfo; + const tokenUriQuery = + transactionItem?.type === 'TRANSFER_GRC721' + ? useGetGRC721TokenUri(transactionItem.logo, '0') + : null; const getLogoImage = useCallback(() => { + if (transactionItem?.type === 'TRANSFER_GRC721') { + return tokenUriQuery?.data || `${UnknownTokenIcon}`; + } + if (transactionItem?.type === 'ADD_PACKAGE') { return `${AddPackageIcon}`; }