Skip to content

Commit

Permalink
fix: assets ux (#2756)
Browse files Browse the repository at this point in the history
  • Loading branch information
johnthecat authored Nov 28, 2024
1 parent bdd6974 commit 6dda95a
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import { chainsService } from '@/shared/api/network';
import { type Account, type Chain } from '@/shared/core';
import { useDeferredList } from '@/shared/lib/hooks';
import { isStringsMatchQuery, nullable } from '@/shared/lib/utils';
import { Loader } from '@/shared/ui';
import { Box } from '@/shared/ui-kit';
import { AssetsListView, EmptyAssetsState } from '@/entities/asset';
import { balanceModel } from '@/entities/balance';
import { networkModel, networkUtils } from '@/entities/network';
Expand All @@ -31,7 +33,7 @@ export const AssetsChainView = ({ query, activeShards, hideZeroBalances, assetsV

const [sortedChains, setSortedChains] = useState<Chain[]>([]);

const { list } = useDeferredList({ list: sortedChains });
const { list, isLoading } = useDeferredList({ list: sortedChains, forceFirstRender: true });

useEffect(() => {
if (!activeWallet || assetsView !== AssetsListView.CHAIN_CENTRIC || !activeShards.length) return;
Expand Down Expand Up @@ -72,13 +74,19 @@ export const AssetsChainView = ({ query, activeShards, hideZeroBalances, assetsV
return null;
}

const searchSymbolOnly = sortedChains.some((chain) => {
const searchSymbolOnly = list.some((chain) => {
return chain.assets.some((asset) => isStringsMatchQuery(query, [asset.symbol, asset.name]));
});

return (
<div className="flex h-full w-full flex-col gap-y-4 overflow-y-scroll">
<ul className="flex min-h-full w-full flex-col items-center gap-y-4 py-4">
{isLoading && (
<Box fillContainer verticalAlign="center" horizontalAlign="center">
<Loader color="primary" size={32} />
</Box>
)}

{list.map((chain) => (
<NetworkAssets
key={chain.chainId}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ const $activeTokensWithBalance = createStore<AssetByChains[]>([]);
const $filteredTokens = createStore<AssetByChains[]>([]);
const $sortedTokens = createStore<AssetByChains[]>([]);

const $tokensPopulated = createStore(false).on(once($sortedTokens.updates), () => true);

type UpdateTokenParams = {
activeWallet?: Wallet;
chains: Record<ChainId, Chain>;
Expand Down Expand Up @@ -204,6 +206,7 @@ export const portfolioModel = {
$activeView,
$accounts,
$sortedTokens,
$tokensPopulated,
events: {
activeViewChanged,
accountsChanged,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import { useUnit } from 'effector-react';
import { type Wallet, WalletType } from '@/shared/core';
import { useI18n } from '@/shared/i18n';
import { useDeferredList } from '@/shared/lib/hooks';
import { FootnoteText } from '@/shared/ui';
import { FootnoteText, Loader } from '@/shared/ui';
import { Box } from '@/shared/ui-kit';
import { AssetsListView, EmptyAssetsState } from '@/entities/asset';
import { priceProviderModel } from '@/entities/price';
import { walletModel } from '@/entities/wallet';
Expand All @@ -29,11 +30,16 @@ export const AssetsPortfolioView = () => {

const activeView = useUnit(portfolioModel.$activeView);
const sortedTokens = useUnit(portfolioModel.$sortedTokens);
const tokensPopulated = useUnit(portfolioModel.$tokensPopulated);
const accounts = useUnit(portfolioModel.$accounts);
const fiatFlag = useUnit(priceProviderModel.$fiatFlag);
const wallet = useUnit(walletModel.$activeWallet);

const { list } = useDeferredList({ list: sortedTokens });
const { list, isLoading } = useDeferredList({
list: sortedTokens,
isLoading: !tokensPopulated,
forceFirstRender: true,
});

if (activeView !== AssetsListView.TOKEN_CENTRIC || accounts.length === 0) {
return null;
Expand All @@ -43,15 +49,17 @@ export const AssetsPortfolioView = () => {

return (
<div className="flex min-h-full w-full flex-col items-center gap-y-2 py-4">
<div className={`grid w-[548px] items-center pl-[35px] pr-4 ${colStyle}`}>
<FootnoteText className="text-text-tertiary">{t('balances.token')}</FootnoteText>
<FootnoteText className="text-text-tertiary" align="right">
{fiatFlag && t('balances.price')}
</FootnoteText>
<FootnoteText className="col-end-4 text-text-tertiary" align="right">
{t('balances.balance')}
</FootnoteText>
</div>
{list.length > 0 && (
<div className={`grid w-[548px] items-center pl-[35px] pr-4 ${colStyle}`}>
<FootnoteText className="text-text-tertiary">{t('balances.token')}</FootnoteText>
<FootnoteText className="text-text-tertiary" align="right">
{fiatFlag && t('balances.price')}
</FootnoteText>
<FootnoteText className="col-end-4 text-text-tertiary" align="right">
{t('balances.balance')}
</FootnoteText>
</div>
)}

<ul className="flex min-h-full w-full flex-col items-center gap-y-4">
{list.map((asset) => (
Expand All @@ -60,6 +68,12 @@ export const AssetsPortfolioView = () => {
</li>
))}

{isLoading && (
<Box fillContainer verticalAlign="center" horizontalAlign="center">
<Loader color="primary" size={32} />
</Box>
)}

<EmptyAssetsState />
</ul>
</div>
Expand Down
18 changes: 15 additions & 3 deletions src/renderer/shared/lib/hooks/useDeferredList.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import { useDeferredValue } from 'react';
import { useDeferredValue, useEffect, useState } from 'react';

type Params<T> = {
list: T[];
isLoading?: boolean;
/**
* Render list directly until first deferred value is resolved.
*/
forceFirstRender?: boolean;
};

/**
Expand All @@ -13,9 +17,17 @@ type Params<T> = {
* @returns {boolean} Field isLoading - isLoading parameter + delay, introduced
* by deferred rendering.
*/
export const useDeferredList = <T>({ list, isLoading }: Params<T>) => {
export const useDeferredList = <T>({ list, isLoading, forceFirstRender }: Params<T>) => {
const [firstRender, setFirstRender] = useState(true);
const deferred = useDeferredValue(list);
const shouldForceRender = firstRender && !!forceFirstRender;
const isDeferred = deferred.length === 0 && list.length !== 0;

return { isLoading: isLoading || isDeferred, list: deferred };
useEffect(() => {
if (deferred.length > 0) {
setFirstRender(false);
}
}, [deferred]);

return { isLoading: isLoading || (!shouldForceRender && isDeferred), list: shouldForceRender ? list : deferred };
};
2 changes: 1 addition & 1 deletion src/renderer/shared/lib/hooks/usePrevious.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { useEffect, useRef } from 'react';
* @param value Arbitrary value
*/
export function usePrevious<T>(value: T): T {
const ref = useRef<T>();
const ref = useRef<T>(value);

useEffect(() => {
ref.current = value;
Expand Down

0 comments on commit 6dda95a

Please sign in to comment.