From e435aa58aebb00cb478ae1c82d2ecedf538d3f25 Mon Sep 17 00:00:00 2001 From: Bran <52735957+brancoder@users.noreply.github.com> Date: Tue, 26 Nov 2024 18:19:26 +0100 Subject: [PATCH] feat(wallet): improve displaying assets (#4038) * fix: featch all assets in wallet * fix: bring back asset pagination in wallet * fix: add assets loading on scroll * fix: remove useMemo * fix: add scroll to Other * fix: simplify assets mapping --- .../app/(protected)/assets/page.tsx | 73 +++++++------------ .../components/AssetsList.tsx | 34 ++++++++- .../src/ui/app/pages/home/nfts/index.tsx | 23 ++++-- 3 files changed, 74 insertions(+), 56 deletions(-) diff --git a/apps/wallet-dashboard/app/(protected)/assets/page.tsx b/apps/wallet-dashboard/app/(protected)/assets/page.tsx index 00fe1d57e24..4ff62fed3f8 100644 --- a/apps/wallet-dashboard/app/(protected)/assets/page.tsx +++ b/apps/wallet-dashboard/app/(protected)/assets/page.tsx @@ -3,16 +3,15 @@ 'use client'; -import { PageSizeSelector, PaginationOptions } from '@/components'; -import { Panel, Title, Chip, TitleSize, DropdownPosition } from '@iota/apps-ui-kit'; -import { hasDisplayData, useCursorPagination, useGetOwnedObjects } from '@iota/core'; +import { Panel, Title, Chip, TitleSize } from '@iota/apps-ui-kit'; +import { hasDisplayData, useGetOwnedObjects } from '@iota/core'; import { useCurrentAccount } from '@iota/dapp-kit'; import { IotaObjectData } from '@iota/iota-sdk/client'; import { useState } from 'react'; import { AssetCategory } from '@/lib/enums'; import { AssetList } from '@/components/AssetsList'; -const PAGINATION_RANGE = [20, 40, 60]; +const OBJECTS_PER_REQ = 50; const ASSET_CATEGORIES: { label: string; value: AssetCategory }[] = [ { @@ -27,40 +26,28 @@ const ASSET_CATEGORIES: { label: string; value: AssetCategory }[] = [ export default function AssetsDashboardPage(): React.JSX.Element { const [selectedCategory, setSelectedCategory] = useState(AssetCategory.Visual); - const [limit, setLimit] = useState(PAGINATION_RANGE[1]); - const account = useCurrentAccount(); - const ownedObjectsQuery = useGetOwnedObjects(account?.address, undefined, limit); - - const { data, pagination } = useCursorPagination(ownedObjectsQuery); - - const { data: ownedObjects } = data || {}; + const { data, isFetching, fetchNextPage, hasNextPage } = useGetOwnedObjects( + account?.address, + undefined, + OBJECTS_PER_REQ, + ); - const [visual, nonVisual] = (() => { - const visual: IotaObjectData[] = []; - const nonVisual: IotaObjectData[] = []; + const assets: IotaObjectData[] = []; - ownedObjects - ?.filter((asset) => asset.data && asset.data.objectId) - .forEach((asset) => { - if (asset.data) { + for (const page of data?.pages || []) { + for (const asset of page.data) { + if (asset.data && asset.data.objectId) { + if (selectedCategory == AssetCategory.Visual) { if (hasDisplayData(asset)) { - visual.push(asset.data); - } else { - nonVisual.push(asset.data); + assets.push(asset.data); } + } else if (selectedCategory == AssetCategory.Other) { + assets.push(asset.data); } - }); - - return [visual, nonVisual]; - })(); - - const categoryToAsset: Record = { - [AssetCategory.Visual]: visual, - [AssetCategory.Other]: nonVisual, - }; - - const assetList = categoryToAsset[selectedCategory]; + } + } + } return ( @@ -77,21 +64,13 @@ export default function AssetsDashboardPage(): React.JSX.Element { ))} - -
- setLimit(e)} - limit={limit.toString()} - /> - } - /> -
+
); diff --git a/apps/wallet-dashboard/components/AssetsList.tsx b/apps/wallet-dashboard/components/AssetsList.tsx index ca14660daff..0835f0a98e5 100644 --- a/apps/wallet-dashboard/components/AssetsList.tsx +++ b/apps/wallet-dashboard/components/AssetsList.tsx @@ -4,10 +4,17 @@ import { AssetCategory } from '@/lib/enums'; import { IotaObjectData } from '@iota/iota-sdk/client'; import { AssetTileLink } from '@/components'; +import { LoadingIndicator } from '@iota/apps-ui-kit'; +import { useEffect, useRef } from 'react'; +import { useOnScreen } from '@iota/core'; +import cl from 'clsx'; interface AssetListProps { assets: IotaObjectData[]; selectedCategory: AssetCategory; + hasNextPage: boolean; + isFetchingNextPage: boolean; + fetchNextPage: () => void; } const ASSET_LAYOUT: Record = { @@ -16,12 +23,35 @@ const ASSET_LAYOUT: Record = { [AssetCategory.Other]: 'flex flex-col overflow-auto py-sm', }; -export function AssetList({ assets, selectedCategory }: AssetListProps): React.JSX.Element { +export function AssetList({ + assets, + selectedCategory, + hasNextPage, + isFetchingNextPage, + fetchNextPage, +}: AssetListProps): React.JSX.Element { + const observerElem = useRef(null); + const { isIntersecting } = useOnScreen(observerElem); + const isSpinnerVisible = isFetchingNextPage && hasNextPage; + + useEffect(() => { + if (isIntersecting && hasNextPage && !isFetchingNextPage && fetchNextPage) { + fetchNextPage(); + } + }, [isIntersecting, fetchNextPage, hasNextPage, isFetchingNextPage]); + return ( -
+
{assets.map((asset) => ( ))} +
+ {isSpinnerVisible ? ( +
+ +
+ ) : null} +
); } diff --git a/apps/wallet/src/ui/app/pages/home/nfts/index.tsx b/apps/wallet/src/ui/app/pages/home/nfts/index.tsx index 5c4cba0e491..52c62bf96ae 100644 --- a/apps/wallet/src/ui/app/pages/home/nfts/index.tsx +++ b/apps/wallet/src/ui/app/pages/home/nfts/index.tsx @@ -19,6 +19,7 @@ import HiddenAssets from './HiddenAssets'; import NonVisualAssets from './NonVisualAssets'; import VisualAssets from './VisualAssets'; import { Warning } from '@iota/ui-icons'; +import { useOnScreen } from '@iota/core'; enum AssetCategory { Visual = 'Visual', @@ -44,6 +45,7 @@ const ASSET_CATEGORIES = [ function NftsPage() { const [selectedAssetCategory, setSelectedAssetCategory] = useState(null); const observerElem = useRef(null); + const { isIntersecting } = useOnScreen(observerElem); const accountAddress = useActiveAddress(); const { @@ -51,6 +53,7 @@ function NftsPage() { hasNextPage, isLoading, isFetchingNextPage, + fetchNextPage, error, isPending, isError, @@ -95,6 +98,12 @@ function NftsPage() { ); }, [ownedAssets]); + useEffect(() => { + if (isIntersecting && hasNextPage && !isFetchingNextPage) { + fetchNextPage(); + } + }, [isIntersecting, fetchNextPage, hasNextPage, isFetchingNextPage]); + useEffect(() => { let computeSelectedCategory = false; if ( @@ -172,17 +181,17 @@ function NftsPage() { ) : ( )} +
+ {isSpinnerVisible ? ( +
+ +
+ ) : null} +
)} -
- {isSpinnerVisible ? ( -
- -
- ) : null} -
);