Skip to content

Commit

Permalink
NFT - split list by owned token
Browse files Browse the repository at this point in the history
  • Loading branch information
Ivan-Mahda committed Dec 16, 2024
1 parent 579baf5 commit 0b85f72
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 20 deletions.
16 changes: 16 additions & 0 deletions packages/browser-wallet/src/popup/popupX/pages/Nft/Nft.scss
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@
.label__main {
color: $color-white;
}

&:not(:first-child) {
margin-top: rem(32px);
}

&:has(+ .nft-x__list:empty) {
display: none;
}
}

&__list {
Expand Down Expand Up @@ -39,6 +47,14 @@
text-align: left;
}
}

&:empty {
margin-top: unset;

& + .owner {
margin-top: unset;
}
}
}
}

Expand Down
77 changes: 57 additions & 20 deletions packages/browser-wallet/src/popup/popupX/pages/Nft/Nft.tsx
Original file line number Diff line number Diff line change
@@ -1,43 +1,75 @@
import React from 'react';
import { useTranslation } from 'react-i18next';
import { useAtomValue } from 'jotai';
import Page from '@popup/popupX/shared/Page';
import Text from '@popup/popupX/shared/Text';
import Button from '@popup/popupX/shared/Button';
import { displayNameAndSplitAddress, useSelectedCredential } from '@popup/shared/utils/account-helpers';
import Img from '@popup/shared/Img';
import { WalletCredential } from '@shared/storage/types';
import { useFlattenedAccountTokens } from '@popup/pages/Account/Tokens/utils';
import { AccountTokenDetails, useFlattenedAccountTokens } from '@popup/pages/Account/Tokens/utils';
import { getMetadataUnique } from '@shared/utils/token-helpers';
import { useNavigate } from 'react-router-dom';
import { relativeRoutes } from '@popup/popupX/constants/routes';
import { contractBalancesFamily } from '@popup/store/token';

function useFilteredTokens(account: WalletCredential, unique: boolean) {
function useFilteredTokens(account: WalletCredential | undefined, unique: boolean) {
const tokens = useFlattenedAccountTokens(account);
return tokens.filter((t) => getMetadataUnique(t.metadata) === unique);
}

function NftList({ account }: { account: WalletCredential }) {
const tokens = useFilteredTokens(account, true);
function TokenDisplay({
accountAddress,
token,
owned,
}: {
accountAddress: string;
token: AccountTokenDetails;
owned?: boolean;
}) {
const { contractIndex, id, metadata } = token;
const nav = useNavigate();
const navToDetails = (contractIndex: string, id: string) =>
const navToDetails = () =>
nav(relativeRoutes.settings.nft.details.path.replace(':contractIndex', contractIndex).replace(':id', id));
const { [id]: balance } = useAtomValue(contractBalancesFamily(accountAddress, contractIndex));

// Hide not owned tokens
if (owned && balance === 0n) return null;

// Hide owned tokens
if (!owned && balance !== 0n) return null;

return (
<Button.Base key={`${contractIndex}.${id}`} onClick={() => navToDetails()} className="nft-x__list_item">
<Img
className="nft-x__list_item-img"
src={metadata.thumbnail?.url ?? metadata.display?.url}
alt={metadata.name}
withDefaults
/>
<Text.MainRegular>{metadata.name}</Text.MainRegular>
</Button.Base>
);
}

function NftList({
account,
tokens,
owned,
}: {
account: WalletCredential;
tokens: AccountTokenDetails[];
owned?: boolean;
}) {
return (
<div className="nft-x__list">
{tokens.map(({ contractIndex, id, metadata }) => (
<Button.Base
key={`${contractIndex}.${id}`}
onClick={() => navToDetails(contractIndex, id)}
className="nft-x__list_item"
>
<Img
className="nft-x__list_item-img"
src={metadata.thumbnail?.url ?? metadata.display?.url}
alt={metadata.name}
withDefaults
/>
<Text.MainRegular>{metadata.name}</Text.MainRegular>
</Button.Base>
{tokens.map((token) => (
<TokenDisplay
accountAddress={account.address}
key={`${token.contractIndex}.${token.id}`}
token={token}
owned={owned}
/>
))}
</div>
);
Expand All @@ -46,6 +78,7 @@ function NftList({ account }: { account: WalletCredential }) {
export default function Nft() {
const { t } = useTranslation('x', { keyPrefix: 'nft' });
const account = useSelectedCredential();
const tokens = useFilteredTokens(account, true);

if (account === undefined) {
return null;
Expand All @@ -59,7 +92,11 @@ export default function Nft() {
<Text.Label>{t('owned')}</Text.Label>
<Text.Capture>{t('on', { value: displayNameAndSplitAddress(account) })}</Text.Capture>
</span>
<NftList account={account} />
<NftList account={account} tokens={tokens} owned />
<span className="owner">
<Text.Label>{t('unownedUnique')}</Text.Label>
</span>
<NftList account={account} tokens={tokens} />
</Page.Main>
</Page>
);
Expand Down

0 comments on commit 0b85f72

Please sign in to comment.