From cb38fabaac951c74233fd397e8168aa96afd1cf6 Mon Sep 17 00:00:00 2001 From: Martin CAYUELAS <112866305+mcayuelas-ledger@users.noreply.github.com> Date: Tue, 30 Jan 2024 14:20:03 +0100 Subject: [PATCH] [FEAT]: use simpleHash for LLD Gallery (#6042) --- apps/ledger-live-desktop/package.json | 1 + apps/ledger-live-desktop/src/renderer/App.tsx | 8 +++++- .../screens/nft/Collections/Collections.tsx | 22 ++++++++++++++-- .../renderer/screens/nft/Gallery/Gallery.tsx | 26 +++++++++++++++---- pnpm-lock.yaml | 3 +++ 5 files changed, 52 insertions(+), 8 deletions(-) diff --git a/apps/ledger-live-desktop/package.json b/apps/ledger-live-desktop/package.json index 5a8ba0a4ea7d..93b8e4f02920 100644 --- a/apps/ledger-live-desktop/package.json +++ b/apps/ledger-live-desktop/package.json @@ -75,6 +75,7 @@ "@sentry/electron": "^4.15.1", "@sentry/node": "7.84.0", "@sentry/tracing": "7.84.0", + "@tanstack/react-query": "^5.17.19", "@tippyjs/react": "^4.2.6", "@trust/keyto": "^1.0.1", "@types/qrcode": "^1.5.0", diff --git a/apps/ledger-live-desktop/src/renderer/App.tsx b/apps/ledger-live-desktop/src/renderer/App.tsx index 37dabd6461b3..5764b86f18a1 100644 --- a/apps/ledger-live-desktop/src/renderer/App.tsx +++ b/apps/ledger-live-desktop/src/renderer/App.tsx @@ -29,6 +29,8 @@ import PostOnboardingProviderWrapped from "~/renderer/components/PostOnboardingH import { useBraze } from "./hooks/useBraze"; import { StorylyProvider } from "~/storyly/StorylyProvider"; import { CounterValuesStateRaw } from "@ledgerhq/live-countervalues/types"; +import { QueryClientProvider, QueryClient } from "@tanstack/react-query"; + const reloadApp = (event: KeyboardEvent) => { if ((event.ctrlKey || event.metaKey) && event.key === "r") { window.api?.reloadRenderer(); @@ -40,6 +42,8 @@ type Props = { initialCountervalues: CounterValuesStateRaw; }; +const queryClient = new QueryClient(); + const InnerApp = ({ initialCountervalues }: { initialCountervalues: CounterValuesStateRaw }) => { const [reloadEnabled, setReloadEnabled] = useState(true); @@ -80,7 +84,9 @@ const InnerApp = ({ initialCountervalues }: { initialCountervalues: CounterValue - + + + diff --git a/apps/ledger-live-desktop/src/renderer/screens/nft/Collections/Collections.tsx b/apps/ledger-live-desktop/src/renderer/screens/nft/Collections/Collections.tsx index 62678f3538f6..b95815b796cd 100644 --- a/apps/ledger-live-desktop/src/renderer/screens/nft/Collections/Collections.tsx +++ b/apps/ledger-live-desktop/src/renderer/screens/nft/Collections/Collections.tsx @@ -19,6 +19,9 @@ import Text from "~/renderer/components/Text"; import { openURL } from "~/renderer/linking"; import Box from "~/renderer/components/Box"; import Row from "./Row"; +import { useNftGalleryFilter } from "@ledgerhq/live-nft-react"; +import { useFeature } from "@ledgerhq/live-common/featureFlags/index"; + const INCREMENT = 5; const EmptyState = styled.div` padding: 15px 20px; @@ -42,6 +45,8 @@ type Props = { account: Account; }; const Collections = ({ account }: Props) => { + const nftsFromSimplehashFeature = useFeature("nftsFromSimplehash"); + const dispatch = useDispatch(); const { t } = useTranslation(); const history = useHistory(); @@ -64,13 +69,25 @@ const Collections = ({ account }: Props) => { history.push(`/account/${account.id}/nft-collection/${collectionAddress}`), [account.id, history], ); - const collections = useMemo(() => nftsByCollections(account.nfts), [account.nfts]); + + const { nfts, fetchNextPage, hasNextPage } = useNftGalleryFilter({ + nftsOwned: account.nfts || [], + addresses: account.freshAddress, + chains: [account.currency.id], + }); + 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), ); - }, [collectionsLength]); + if (hasNextPage) { + fetchNextPage(); + } + }, [collectionsLength, fetchNextPage, hasNextPage]); const hiddenNftCollections = useSelector(hiddenNftCollectionsSelector); const filteredCollections = useMemo( () => @@ -94,6 +111,7 @@ const Collections = ({ account }: Props) => { )), [account, filteredCollections, numberOfVisibleCollections, onOpenCollection], ); + useEffect(() => { track("View NFT Collections (Account Page)"); }, []); diff --git a/apps/ledger-live-desktop/src/renderer/screens/nft/Gallery/Gallery.tsx b/apps/ledger-live-desktop/src/renderer/screens/nft/Gallery/Gallery.tsx index 9ebb602a6312..ddbc06ece8e4 100644 --- a/apps/ledger-live-desktop/src/renderer/screens/nft/Gallery/Gallery.tsx +++ b/apps/ledger-live-desktop/src/renderer/screens/nft/Gallery/Gallery.tsx @@ -20,6 +20,8 @@ import { State } from "~/renderer/reducers"; import { ProtoNFT } from "@ledgerhq/types-live"; import theme from "@ledgerhq/react-ui/styles/theme"; import { useOnScreen } from "../useOnScreen"; +import { useNftGalleryFilter } from "@ledgerhq/live-nft-react"; +import { useFeature } from "@ledgerhq/live-common/featureFlags/index"; const SpinnerContainer = styled.div` display: flex; @@ -50,6 +52,8 @@ const Footer = styled.footer` `; const Gallery = () => { + const nftsFromSimplehashFeature = useFeature("nftsFromSimplehash"); + const { t } = useTranslation(); const dispatch = useDispatch(); const { id } = useParams<{ id: string }>(); @@ -60,12 +64,19 @@ const Gallery = () => { ); const history = useHistory(); const hiddenNftCollections = useSelector(hiddenNftCollectionsSelector); + + const { nfts, fetchNextPage, hasNextPage } = useNftGalleryFilter({ + nftsOwned: account?.nfts || [], + addresses: account?.freshAddress || "", + chains: [account?.currency.id ?? "ethereum"], + }); + const collections = useMemo( () => - Object.entries(nftsByCollections(account?.nfts)).filter( - ([contract]) => !hiddenNftCollections.includes(`${account?.id}|${contract}`), - ), - [account?.id, account?.nfts, hiddenNftCollections], + Object.entries( + nftsByCollections(nftsFromSimplehashFeature?.enabled ? nfts : account?.nfts), + ).filter(([contract]) => !hiddenNftCollections.includes(`${account?.id}|${contract}`)), + [account?.id, account?.nfts, hiddenNftCollections, nfts, nftsFromSimplehashFeature?.enabled], ); // Should redirect to the account page if there is not NFT anymore in the page. @@ -92,7 +103,12 @@ const Gallery = () => { ); const listFooterRef = useRef(null); const [maxVisibleNFTs, setMaxVisibleNFTs] = useState(1); - const updateMaxVisibleNtfs = () => setMaxVisibleNFTs(maxVisibleNFTs => maxVisibleNFTs + 5); + const updateMaxVisibleNtfs = () => { + setMaxVisibleNFTs(maxVisibleNFTs => maxVisibleNFTs + 5); + if (hasNextPage) { + fetchNextPage(); + } + }; useOnScreen({ enabled: maxVisibleNFTs < (account?.nfts?.length ?? 0), diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 64ded616146c..8582ba88bc70 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -309,6 +309,9 @@ importers: '@sentry/tracing': specifier: 7.84.0 version: 7.84.0 + '@tanstack/react-query': + specifier: ^5.17.19 + version: 5.17.19(react@18.2.0) '@tippyjs/react': specifier: ^4.2.6 version: 4.2.6(react-dom@18.2.0)(react@18.2.0)