Skip to content

Commit

Permalink
feat(wallet): improve displaying assets (#4038)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
brancoder authored Nov 26, 2024
1 parent 062a08e commit e435aa5
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 56 deletions.
73 changes: 26 additions & 47 deletions apps/wallet-dashboard/app/(protected)/assets/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 }[] = [
{
Expand All @@ -27,40 +26,28 @@ const ASSET_CATEGORIES: { label: string; value: AssetCategory }[] = [

export default function AssetsDashboardPage(): React.JSX.Element {
const [selectedCategory, setSelectedCategory] = useState<AssetCategory>(AssetCategory.Visual);
const [limit, setLimit] = useState<number>(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, IotaObjectData[]> = {
[AssetCategory.Visual]: visual,
[AssetCategory.Other]: nonVisual,
};

const assetList = categoryToAsset[selectedCategory];
}
}
}

return (
<Panel>
Expand All @@ -77,21 +64,13 @@ export default function AssetsDashboardPage(): React.JSX.Element {
))}
</div>

<AssetList assets={assetList} selectedCategory={selectedCategory} />
<div className="flex flex-row items-center justify-end py-xs">
<PaginationOptions
pagination={pagination}
action={
<PageSizeSelector
pagination={pagination}
range={PAGINATION_RANGE}
dropdownPosition={DropdownPosition.Top}
setLimit={(e) => setLimit(e)}
limit={limit.toString()}
/>
}
/>
</div>
<AssetList
assets={assets}
selectedCategory={selectedCategory}
hasNextPage={hasNextPage}
isFetchingNextPage={isFetching}
fetchNextPage={fetchNextPage}
/>
</div>
</Panel>
);
Expand Down
34 changes: 32 additions & 2 deletions apps/wallet-dashboard/components/AssetsList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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<AssetCategory, string> = {
Expand All @@ -16,12 +23,35 @@ const ASSET_LAYOUT: Record<AssetCategory, string> = {
[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<HTMLDivElement | null>(null);
const { isIntersecting } = useOnScreen(observerElem);
const isSpinnerVisible = isFetchingNextPage && hasNextPage;

useEffect(() => {
if (isIntersecting && hasNextPage && !isFetchingNextPage && fetchNextPage) {
fetchNextPage();
}
}, [isIntersecting, fetchNextPage, hasNextPage, isFetchingNextPage]);

return (
<div className={ASSET_LAYOUT[selectedCategory]}>
<div className={cl('max-h-[600px]', ASSET_LAYOUT[selectedCategory])}>
{assets.map((asset) => (
<AssetTileLink key={asset.digest} asset={asset} type={selectedCategory} />
))}
<div ref={observerElem}>
{isSpinnerVisible ? (
<div className="mt-1 flex h-full w-full justify-center">
<LoadingIndicator />
</div>
) : null}
</div>
</div>
);
}
23 changes: 16 additions & 7 deletions apps/wallet/src/ui/app/pages/home/nfts/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand All @@ -44,13 +45,15 @@ const ASSET_CATEGORIES = [
function NftsPage() {
const [selectedAssetCategory, setSelectedAssetCategory] = useState<AssetCategory | null>(null);
const observerElem = useRef<HTMLDivElement | null>(null);
const { isIntersecting } = useOnScreen(observerElem);

const accountAddress = useActiveAddress();
const {
data: ownedAssets,
hasNextPage,
isLoading,
isFetchingNextPage,
fetchNextPage,
error,
isPending,
isError,
Expand Down Expand Up @@ -95,6 +98,12 @@ function NftsPage() {
);
}, [ownedAssets]);

useEffect(() => {
if (isIntersecting && hasNextPage && !isFetchingNextPage) {
fetchNextPage();
}
}, [isIntersecting, fetchNextPage, hasNextPage, isFetchingNextPage]);

useEffect(() => {
let computeSelectedCategory = false;
if (
Expand Down Expand Up @@ -172,17 +181,17 @@ function NftsPage() {
) : (
<NoData message="No assets found yet." />
)}
<div ref={observerElem}>
{isSpinnerVisible ? (
<div className="mt-1 flex w-full justify-center">
<LoadingIndicator />
</div>
) : null}
</div>
</div>
</Loading>
</>
)}
<div ref={observerElem}>
{isSpinnerVisible ? (
<div className="mt-1 flex w-full justify-center">
<LoadingIndicator />
</div>
) : null}
</div>
</div>
</PageTemplate>
);
Expand Down

0 comments on commit e435aa5

Please sign in to comment.