From 2057123543ce56298fb27bd6e3b4a288a47c0e98 Mon Sep 17 00:00:00 2001 From: Tiago Silva Date: Thu, 5 Sep 2024 19:39:32 +0100 Subject: [PATCH 01/12] Add duplicate symbol warning to token list selection - Add duplicate symbol warning with address and tooltip - Add logic to check duplicate symbol in token list --- .../ModalTokenList/ModalTokenListContent.tsx | 26 ++++++++++-- .../ModalTokenListDuplicateWarning.tsx | 42 +++++++++++++++++++ 2 files changed, 65 insertions(+), 3 deletions(-) create mode 100644 src/libs/modals/modals/ModalTokenList/ModalTokenListDuplicateWarning.tsx diff --git a/src/libs/modals/modals/ModalTokenList/ModalTokenListContent.tsx b/src/libs/modals/modals/ModalTokenList/ModalTokenListContent.tsx index 3367af758..e12744d26 100644 --- a/src/libs/modals/modals/ModalTokenList/ModalTokenListContent.tsx +++ b/src/libs/modals/modals/ModalTokenList/ModalTokenListContent.tsx @@ -14,10 +14,22 @@ import { lsService } from 'services/localeStorage'; import { ReactComponent as IconStar } from 'assets/icons/star.svg'; import { WarningWithTooltip } from 'components/common/WarningWithTooltip/WarningWithTooltip'; import { CategoryWithCounter } from 'libs/modals/modals/common/CategoryWithCounter'; +import { ModalTokenListDuplicateWarning } from 'libs/modals/modals/ModalTokenList/ModalTokenListDuplicateWarning'; const categories = ['popular', 'favorites', 'all'] as const; export type ChooseTokenCategory = (typeof categories)[number]; +const getDuplicateTokenSymbols = (tokens: Token[]): string[] => { + return Object.values( + tokens.reduce((r: { [symbol: string]: string[] }, v) => { + (r[v.symbol] ??= []).push(v.symbol); + return r; + }, {}) + ) + .filter((g) => g.length > 1) + .flat(); +}; + type Props = { tokens: { [k in ChooseTokenCategory]: Token[] }; onSelect: (token: Token) => void; @@ -39,6 +51,11 @@ export const ModalTokenListContent: FC = ({ ); const _tokens = !!search ? tokens.all : tokens[selectedList]; + const duplicates = useMemo( + () => getDuplicateTokenSymbols(tokens.all), + [tokens.all] + ); + const setSelectedList = (category: ChooseTokenCategory) => { _setSelectedList(category); lsService.setItem('chooseTokenCategory', category); @@ -47,7 +64,7 @@ export const ModalTokenListContent: FC = ({ const rowVirtualizer = useVirtualizer({ count: _tokens.length, getScrollElement: () => parentRef.current, - estimateSize: () => 55, + estimateSize: () => 60, overscan: 10, }); @@ -68,7 +85,7 @@ export const ModalTokenListContent: FC = ({ const suspiciousTokenTooltipMsg = 'This token is not part of any known token list. Always conduct your own research before trading.'; - const selectCatergory = (e: FormEvent) => { + const selectCategory = (e: FormEvent) => { if (e.target instanceof HTMLInputElement) { setSelectedList(e.target.value as ChooseTokenCategory); } @@ -79,7 +96,7 @@ export const ModalTokenListContent: FC = ({
{categories.map((category) => ( = ({
{token.name ?? token.symbol}
+ {duplicates.includes(token.symbol) && ( + + )}