Skip to content

Commit

Permalink
bugfix: empty state account + Check when adding new address
Browse files Browse the repository at this point in the history
test: ✅ Add tests for new Hooks

Check when adding new address

✅ Add tests for new Hooks
  • Loading branch information
mcayuelas-ledger committed Oct 29, 2024
1 parent c2cd1a8 commit a96bcd1
Show file tree
Hide file tree
Showing 37 changed files with 445 additions and 259 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,39 +2,27 @@ import { useSelector } from "react-redux";
import { useHistory, useParams } from "react-router-dom";
import { State } from "~/renderer/reducers";
import { accountSelector } from "~/renderer/reducers/accounts";
import { nftsByCollections } from "@ledgerhq/live-nft";
import { useCallback, useMemo } from "react";
import { ProtoNFT } from "@ledgerhq/types-live";
import { DropDownItemType } from "~/renderer/components/DropDownSelector";
import { setTrackingSource } from "~/renderer/analytics/TrackPage";
import { useFeature } from "@ledgerhq/live-common/featureFlags/index";
import { isThresholdValid, useNftGalleryFilter } from "@ledgerhq/live-nft-react";
import { useNftCollections } from "~/renderer/hooks/nfts/useNftCollections";

const useBreadCrumbModel = () => {
const history = useHistory();
const { id, collectionAddress } = useParams<{ id?: string; collectionAddress?: string }>();
const nftsFromSimplehashFeature = useFeature("nftsFromSimplehash");
const thresold = nftsFromSimplehashFeature?.params?.threshold;

const account = useSelector((state: State) =>
id ? accountSelector(state, { accountId: id }) : null,
id ? accountSelector(state, { accountId: id }) : undefined,
);

const { nfts } = useNftGalleryFilter({
nftsOwned: account?.nfts || [],
addresses: String(account?.freshAddress),
chains: [String(account?.currency.id)],
threshold: isThresholdValid(thresold) ? Number(thresold) : 75,
const { collections } = useNftCollections({
account,
});

const collections = useMemo(
() => nftsByCollections(nftsFromSimplehashFeature?.enabled ? nfts : account?.nfts),
[account?.nfts, nfts, nftsFromSimplehashFeature],
);

const items: DropDownItemType<ProtoNFT>[] = useMemo(
() =>
Object.entries(collections).map(([contract, nfts]: [string, ProtoNFT[]]) => ({
collections.map(([contract, nfts]: [string, ProtoNFT[]]) => ({
key: contract,
label: contract,
content: nfts[0],
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,10 @@
import { useCallback, useEffect, useMemo, useState } from "react";
import { Account, ProtoNFT } from "@ledgerhq/types-live";
import { useDispatch, useSelector } from "react-redux";
import { useDispatch } from "react-redux";
import { useHistory } from "react-router-dom";
import { openModal } from "~/renderer/actions/modals";
import { hiddenNftCollectionsSelector } from "~/renderer/reducers/settings";
import { nftsByCollections } from "@ledgerhq/live-nft/index";
import { useFeature } from "@ledgerhq/live-common/featureFlags/index";
import { isThresholdValid, useNftGalleryFilter } from "@ledgerhq/live-nft-react";
import {
filterHiddenCollections,
mapCollectionsToStructure,
} from "LLD/features/Collectibles/utils/collectionUtils";
import { mapCollectionsToStructure } from "LLD/features/Collectibles/utils/collectionUtils";
import { useNftCollections } from "~/renderer/hooks/nfts/useNftCollections";

type NftsInTheCollections = {
contract: string;
Expand All @@ -27,9 +21,6 @@ const INCREMENT = 5;
export const useNftCollectionsModel = ({ account }: Props) => {
const history = useHistory();
const dispatch = useDispatch();
const nftsFromSimplehashFeature = useFeature("nftsFromSimplehash");
const thresold = nftsFromSimplehashFeature?.params?.threshold;
const hiddenNftCollections = useSelector(hiddenNftCollectionsSelector);
const [numberOfVisibleCollections, setNumberOfVisibleCollections] = useState(INCREMENT);
const [displayShowMore, setDisplayShowMore] = useState(false);

Expand All @@ -53,42 +44,26 @@ export const useNftCollectionsModel = ({ account }: Props) => {
history.push(`/account/${account.id}/nft-collection`);
}, [account.id, history]);

const { nfts, fetchNextPage, hasNextPage } = useNftGalleryFilter({
nftsOwned: account.nfts || [],
addresses: account.freshAddress,
chains: [account.currency.id],
threshold: isThresholdValid(thresold) ? Number(thresold) : 75,
const { fetchNextPage, hasNextPage, collections, collectionsLength } = useNftCollections({
account,
});

const collections = useMemo(
() => nftsByCollections(nftsFromSimplehashFeature?.enabled ? nfts : account.nfts),
[account.nfts, nfts, nftsFromSimplehashFeature],
);

const collectionsLength = Object.keys(collections).length;

const onShowMore = useCallback(() => {
setNumberOfVisibleCollections(numberOfVisibleCollections =>
Math.min(numberOfVisibleCollections + INCREMENT, collectionsLength),
);
if (hasNextPage) fetchNextPage();
}, [collectionsLength, fetchNextPage, hasNextPage]);

const filteredCollections = useMemo(
() => filterHiddenCollections(collections, hiddenNftCollections, account.id),
[account.id, collections, hiddenNftCollections],
);

const nftsInTheCollection: NftsInTheCollections[] = useMemo(
() =>
mapCollectionsToStructure(filteredCollections, numberOfVisibleCollections, onOpenCollection),
[filteredCollections, numberOfVisibleCollections, onOpenCollection],
() => mapCollectionsToStructure(collections, numberOfVisibleCollections, onOpenCollection),
[collections, numberOfVisibleCollections, onOpenCollection],
);

useEffect(() => {
const moreToShow = numberOfVisibleCollections < filteredCollections.length;
const moreToShow = numberOfVisibleCollections < collections.length;
setDisplayShowMore(moreToShow);
}, [numberOfVisibleCollections, filteredCollections.length]);
}, [numberOfVisibleCollections, collections.length]);

return {
nftsInTheCollection,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,10 @@ import { useHistory, useParams } from "react-router-dom";
import { useDispatch, useSelector } from "react-redux";
import { State } from "~/renderer/reducers";
import { accountSelector } from "~/renderer/reducers/accounts";
import { hiddenNftCollectionsSelector } from "~/renderer/reducers/settings";
import { useNftGalleryFilter, isThresholdValid } from "@ledgerhq/live-nft-react";
import { nftsByCollections } from "@ledgerhq/live-nft";
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import { useCallback, useEffect, useRef, useState } from "react";
import { openModal } from "~/renderer/actions/modals";
import { useOnScreen } from "LLD/hooks/useOnScreen";
import useFeature from "@ledgerhq/live-common/featureFlags/useFeature";
import { BlockchainEVM } from "@ledgerhq/live-nft/supported";
import { useNftCollections } from "~/renderer/hooks/nfts/useNftCollections";

const defaultNumberOfVisibleNfts = 10;

Expand All @@ -18,31 +14,17 @@ const useNftGalleryModel = () => {
const history = useHistory();
const { id } = useParams<{ id: string }>();

const nftsFromSimplehashFeature = useFeature("nftsFromSimplehash");
const threshold = nftsFromSimplehashFeature?.params?.threshold;

const listFooterRef = useRef<HTMLDivElement>(null);
const [maxVisibleNFTs, setMaxVisibleNFTs] = useState(defaultNumberOfVisibleNfts);

const { account, hiddenNftCollections } = useSelector((state: State) => ({
const { account } = useSelector((state: State) => ({
account: accountSelector(state, { accountId: id }),
hiddenNftCollections: hiddenNftCollectionsSelector(state),
}));

const { nfts, fetchNextPage, hasNextPage } = useNftGalleryFilter({
nftsOwned: account?.nfts || [],
addresses: account?.freshAddress || "",
chains: [account?.currency.id ?? BlockchainEVM.Ethereum],
threshold: isThresholdValid(threshold) ? Number(threshold) : 75,
const { fetchNextPage, hasNextPage, collections, allNfts } = useNftCollections({
account,
});

const collections = useMemo(() => {
const allNfts = nftsFromSimplehashFeature?.enabled ? nfts : account?.nfts;
return Object.entries(nftsByCollections(allNfts)).filter(
([contract]) => !hiddenNftCollections.includes(`${account?.id}|${contract}`),
);
}, [account?.id, account?.nfts, hiddenNftCollections, nfts, nftsFromSimplehashFeature?.enabled]);

useEffect(() => {
if (collections.length < 1) {
history.push(`/account/${account?.id}/`);
Expand Down Expand Up @@ -70,13 +52,13 @@ const useNftGalleryModel = () => {
}, [hasNextPage, fetchNextPage]);

useOnScreen({
enabled: maxVisibleNFTs < nfts?.length,
enabled: maxVisibleNFTs < allNfts?.length,
onIntersect: updateMaxVisibleNtfs,
target: listFooterRef,
threshold: 0.5,
});

const nftsByCollection = nfts.reduce(
const nftsByCollection = allNfts.reduce(
(acc, nft) => {
const collectionKey = nft.contract || "-";
if (!acc[collectionKey]) {
Expand All @@ -85,12 +67,11 @@ const useNftGalleryModel = () => {
acc[collectionKey].push(nft);
return acc;
},
{} as Record<string, typeof nfts>,
{} as Record<string, typeof allNfts>,
);

return {
account,
hiddenNftCollections,
nftsByCollection,
listFooterRef,
collections,
Expand Down
2 changes: 1 addition & 1 deletion apps/ledger-live-desktop/src/renderer/Default.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ import { isLocked as isLockedSelector } from "~/renderer/reducers/application";
import { useAutoDismissPostOnboardingEntryPoint } from "@ledgerhq/live-common/postOnboarding/hooks/index";
import { setShareAnalytics, setSharePersonalizedRecommendations } from "./actions/settings";
import useEnv from "@ledgerhq/live-common/hooks/useEnv";
import { useSyncNFTsWithAccounts } from "./hooks/useSyncNFTsWithAccounts";
import { useSyncNFTsWithAccounts } from "./hooks/nfts/useSyncNFTsWithAccounts";

const PlatformCatalog = lazy(() => import("~/renderer/screens/platform"));
const Dashboard = lazy(() => import("~/renderer/screens/dashboard"));
Expand Down
10 changes: 10 additions & 0 deletions apps/ledger-live-desktop/src/renderer/actions/settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,12 @@ export const hideNftCollection = (collectionId: string) => ({
type: "HIDE_NFT_COLLECTION",
payload: collectionId,
});

export const whitelistNftCollection = (collectionId: string) => ({
type: "WHITELIST_NFT_COLLECTION",
payload: collectionId,
});

export const hideOrdinalsAsset = (inscriptionId: string) => ({
type: "HIDE_ORDINALS_ASSET",
payload: inscriptionId,
Expand Down Expand Up @@ -252,6 +258,10 @@ export const unhideNftCollection = (collectionId: string) => ({
type: "UNHIDE_NFT_COLLECTION",
payload: collectionId,
});
export const unwhitelistNftCollection = (collectionId: string) => ({
type: "UNWHITELIST_NFT_COLLECTION",
payload: collectionId,
});
export const unhideOrdinalsAsset = (inscriptionId: string) => ({
type: "UNHIDE_ORDINALS_ASSET",
payload: inscriptionId,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import React, { useCallback, useMemo, memo } from "react";
import { useHistory, useParams } from "react-router-dom";
import { useSelector } from "react-redux";
import { nftsByCollections } from "@ledgerhq/live-nft";
import { accountSelector } from "~/renderer/reducers/accounts";
import DropDownSelector, { DropDownItemType } from "~/renderer/components/DropDownSelector";
import Button from "~/renderer/components/Button";
Expand All @@ -14,8 +13,7 @@ import { setTrackingSource } from "~/renderer/analytics/TrackPage";
import CollectionName from "~/renderer/components/Nft/CollectionName";
import { ProtoNFT } from "@ledgerhq/types-live";
import { State } from "~/renderer/reducers";
import { useFeature } from "@ledgerhq/live-common/featureFlags/index";
import { isThresholdValid, useNftGalleryFilter } from "@ledgerhq/live-nft-react";
import { useNftCollections } from "~/renderer/hooks/nfts/useNftCollections";

const LabelWithMeta = ({
item,
Expand All @@ -38,38 +36,29 @@ const LabelWithMeta = ({

const NFTCrumb = () => {
const history = useHistory();
const nftsFromSimplehashFeature = useFeature("nftsFromSimplehash");
const thresold = nftsFromSimplehashFeature?.params?.threshold;
const { id, collectionAddress } = useParams<{ id?: string; collectionAddress?: string }>();
const account = useSelector((state: State) =>
id
? accountSelector(state, {
accountId: id,
})
: null,
: undefined,
);

const { nfts } = useNftGalleryFilter({
nftsOwned: account?.nfts || [],
addresses: String(account?.freshAddress),
chains: [String(account?.currency.id)],
threshold: isThresholdValid(thresold) ? Number(thresold) : 75,
const { collections } = useNftCollections({
account,
});

const collections = useMemo(
() => nftsByCollections(nftsFromSimplehashFeature?.enabled ? nfts : account?.nfts),
[account?.nfts, nfts, nftsFromSimplehashFeature],
);

const items: DropDownItemType<ProtoNFT>[] = useMemo(
() =>
Object.entries(collections).map(([contract, nfts]: [string, ProtoNFT[]]) => ({
collections.map(([contract, nfts]: [string, ProtoNFT[]]) => ({
key: contract,
label: contract,
content: nfts[0],
})),
[collections],
);

const activeItem: DropDownItemType<ProtoNFT> | undefined | null = useMemo(
() => items.find(item => item.key === collectionAddress) || items[0],
[collectionAddress, items],
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { memo } from "react";
import ContextMenuItem from "./ContextMenuItem";
import { Account, ProtoNFT, NFTMetadata } from "@ledgerhq/types-live";
import useNftLinks from "~/renderer/hooks/useNftLinks";
import useNftLinks from "~/renderer/hooks/nfts/useNftLinks";

type Props = {
account: Account;
Expand Down
Loading

0 comments on commit a96bcd1

Please sign in to comment.