From 5d559af789928cc7b1b873c036bbf95d6fddb713 Mon Sep 17 00:00:00 2001 From: IvanMahda Date: Fri, 20 Dec 2024 10:40:44 +0200 Subject: [PATCH] Manage Token Filter Token Token Info Add Token --- .../src/assets/svgX/info-black.svg | 5 + .../Account/Tokens/ManageTokens/utils.ts | 2 +- .../src/popup/popupX/constants/routes.ts | 6 + .../popupX/pages/ManageTokens/AddToken.tsx | 104 +++++++++++++++--- .../pages/ManageTokens/ManageTokenList.tsx | 17 ++- .../pages/ManageTokens/ManageTokens.scss | 16 ++- .../pages/ManageTokens/SearchTokenDetails.tsx | 79 +++++++++++++ .../popupX/pages/ManageTokens/i18n/en.ts | 3 + .../popup/popupX/pages/ManageTokens/index.ts | 1 + .../pages/TokenDetails/TokenDetails.scss | 2 +- .../popupX/pages/TokenDetails/i18n/en.ts | 1 + .../popupX/shared/Form/Search/Search.tsx | 2 +- .../FullscreenNotice/FullscreenNotice.scss | 2 +- .../popup/popupX/shared/Toast/Messages.tsx | 15 ++- .../src/popup/popupX/shared/Toast/Toast.scss | 21 +++- .../popupX/shared/TokenList/TokenList.scss | 17 +++ .../popupX/shared/TokenList/TokenList.tsx | 33 +++++- .../src/popup/popupX/shared/i18n/en.ts | 3 + .../src/popup/popupX/shared/utils/hooks.tsx | 11 +- .../src/popup/popupX/shell/Routes.tsx | 13 ++- .../src/popup/shared/Modal/Modal.scss | 2 +- 21 files changed, 319 insertions(+), 36 deletions(-) create mode 100644 packages/browser-wallet/src/assets/svgX/info-black.svg create mode 100644 packages/browser-wallet/src/popup/popupX/pages/ManageTokens/SearchTokenDetails.tsx diff --git a/packages/browser-wallet/src/assets/svgX/info-black.svg b/packages/browser-wallet/src/assets/svgX/info-black.svg new file mode 100644 index 000000000..e500f33ef --- /dev/null +++ b/packages/browser-wallet/src/assets/svgX/info-black.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/packages/browser-wallet/src/popup/pages/Account/Tokens/ManageTokens/utils.ts b/packages/browser-wallet/src/popup/pages/Account/Tokens/ManageTokens/utils.ts index 8b7eb0d28..871fef594 100644 --- a/packages/browser-wallet/src/popup/pages/Account/Tokens/ManageTokens/utils.ts +++ b/packages/browser-wallet/src/popup/pages/Account/Tokens/ManageTokens/utils.ts @@ -6,7 +6,7 @@ import { MakeOptional } from 'wallet-common-helpers'; export const TOKENS_PAGE_SIZE = 20; -type TokenWithPageID = MakeOptional & { +export type TokenWithPageID = MakeOptional & { pageId: number; }; diff --git a/packages/browser-wallet/src/popup/popupX/constants/routes.ts b/packages/browser-wallet/src/popup/popupX/constants/routes.ts index 36a56595c..171eb602e 100644 --- a/packages/browser-wallet/src/popup/popupX/constants/routes.ts +++ b/packages/browser-wallet/src/popup/popupX/constants/routes.ts @@ -145,6 +145,12 @@ export const relativeRoutes = { path: 'manageTokenList', addToken: { path: 'addToken', + contractIndex: { + path: ':contractIndex', + details: { + path: 'details', + }, + }, }, }, }, diff --git a/packages/browser-wallet/src/popup/popupX/pages/ManageTokens/AddToken.tsx b/packages/browser-wallet/src/popup/popupX/pages/ManageTokens/AddToken.tsx index cce5925f5..637a6b4b5 100644 --- a/packages/browser-wallet/src/popup/popupX/pages/ManageTokens/AddToken.tsx +++ b/packages/browser-wallet/src/popup/popupX/pages/ManageTokens/AddToken.tsx @@ -1,13 +1,18 @@ -import React, { useCallback, useEffect, useRef } from 'react'; -import Page from '@popup/popupX/shared/Page'; +import React, { useCallback, useEffect, useRef, useState } from 'react'; +import { useNavigate, useParams } from 'react-router-dom'; import { useTranslation } from 'react-i18next'; +import Page from '@popup/popupX/shared/Page'; import Text from '@popup/popupX/shared/Text'; import FormSearch from '@popup/popupX/shared/Form/Search'; import { useForm } from '@popup/popupX/shared/Form'; import { useAtom, useAtomValue, useSetAtom } from 'jotai'; import { grpcClientAtom } from '@popup/store/settings'; import { confirmCIS2Contract, ContractDetails } from '@shared/utils/token-helpers'; -import { fetchTokensConfigure, FetchTokensResponse } from '@popup/pages/Account/Tokens/ManageTokens/utils'; +import { + fetchTokensConfigure, + FetchTokensResponse, + TokenWithPageID, +} from '@popup/pages/Account/Tokens/ManageTokens/utils'; import { selectedAccountAtom } from '@popup/store/account'; import { contractDetailsAtom, contractTokensAtom } from '@popup/pages/Account/Tokens/ManageTokens/state'; import { SubmitHandler } from 'react-hook-form'; @@ -16,25 +21,40 @@ import { ContractAddress } from '@concordium/web-sdk'; import { logWarningMessage } from '@shared/utils/log-helpers'; import Form from '@popup/popupX/shared/Form/Form'; import TokenList from '@popup/popupX/shared/TokenList'; +import { LoaderInline } from '@popup/popupX/shared/Loader'; +import Button from '@popup/popupX/shared/Button'; +import { absoluteRoutes } from '@popup/popupX/constants/routes'; +import { currentAccountTokensAtom } from '@popup/store/token'; +import { TokenIdAndMetadata } from '@shared/storage/types'; +import { useGenericToast } from '@popup/popupX/shared/utils/hooks'; const VALIDATE_INDEX_DELAY_MS = 500; type FormValues = { contractIndex: string; + tokenId: string; }; -// ToDo page UI need full rework +// ToDo update token infinity-load, check, add function AddToken({ account }: { account: string }) { const { t } = useTranslation('x', { keyPrefix: 'mangeTokens' }); + const params = useParams(); + const nav = useNavigate(); + const [isLoading, setIsLoading] = useState(false); + const [checkedTokens, setCheckedTokens] = useState([]); + const [filteredTokens, setFilteredTokens] = useState([]); + const toast = useGenericToast(); const form = useForm({ - defaultValues: { contractIndex: '' }, + defaultValues: { contractIndex: params.contractIndex || '' }, }); const contractIndexValue = form.watch('contractIndex'); + const tokenIdValue = form.watch('tokenId'); const client = useAtomValue(grpcClientAtom); const validContract = useRef<{ details: ContractDetails; tokens: FetchTokensResponse } | undefined>(); const setContractDetails = useSetAtom(contractDetailsAtom); const [, updateTokens] = useAtom(contractTokensAtom); + const [, setAccountTokens] = useAtom(currentAccountTokensAtom); const onSubmit: SubmitHandler = async () => { if (validContract.current === undefined) { throw new Error('Expected contract details'); @@ -62,10 +82,12 @@ function AddToken({ account }: { account: string }) { return t('indexMax'); } + setIsLoading(true); let instanceInfo; try { instanceInfo = await client.getInstanceInfo(ContractAddress.create(index)); } catch { + setIsLoading(false); return t('noContractFound'); } @@ -74,6 +96,7 @@ function AddToken({ account }: { account: string }) { const error = await confirmCIS2Contract(client, cd); if (error !== undefined) { + setIsLoading(false); return error; } @@ -92,10 +115,13 @@ function AddToken({ account }: { account: string }) { } if (response.tokens.length === 0) { + setIsLoading(false); return t('noTokensError'); } validContract.current = { details: cd, tokens: response }; + setFilteredTokens(response.tokens); + setIsLoading(false); return true; }, VALIDATE_INDEX_DELAY_MS, @@ -108,6 +134,39 @@ function AddToken({ account }: { account: string }) { validContract.current = undefined; }, [contractIndexValue]); + useEffect(() => { + setFilteredTokens([ + ...(validContract.current?.tokens.tokens || []).filter( + ({ id, metadata }) => id.includes(tokenIdValue) || (metadata?.name || '').includes(tokenIdValue) + ), + ]); + }, [tokenIdValue]); + + const navToTokenDetails = (token: TokenWithPageID, contractIndex: string) => + nav( + absoluteRoutes.home.manageTokenList.addToken.contractIndex.details.path.replace( + ':contractIndex', + contractIndex + ), + { state: { token } } + ); + + const checkToken = (checked: boolean, token: TokenWithPageID) => { + if (checked) { + setCheckedTokens([...checkedTokens, token]); + } else { + setCheckedTokens(checkedTokens.filter((c) => c.id !== token.id)); + } + }; + + const setTokens = () => { + setAccountTokens({ contractIndex: contractIndexValue, newTokens: checkedTokens as TokenIdAndMetadata[] }); + toast('Token list updated', `Update count ${checkedTokens.length}`); + nav(absoluteRoutes.home.manageTokenList.path); + }; + + const haveTokens = validContract.current?.tokens.tokens.length || 0; + return ( @@ -115,28 +174,37 @@ function AddToken({ account }: { account: string }) { {t('enterContract')}
{(f) => ( - + <> + + {haveTokens > 4 && } + )} + {isLoading && !haveTokens && } - {validContract.current?.tokens.tokens.map((token) => ( + {filteredTokens.map((token) => ( navToTokenDetails(token, contractIndexValue)} + onSelect={(checked: boolean) => { + checkToken(checked, token); + }} /> ))} + {!!haveTokens && }
); } diff --git a/packages/browser-wallet/src/popup/popupX/pages/ManageTokens/ManageTokenList.tsx b/packages/browser-wallet/src/popup/popupX/pages/ManageTokens/ManageTokenList.tsx index 2995355e4..5ecf247b0 100644 --- a/packages/browser-wallet/src/popup/popupX/pages/ManageTokens/ManageTokenList.tsx +++ b/packages/browser-wallet/src/popup/popupX/pages/ManageTokens/ManageTokenList.tsx @@ -10,6 +10,9 @@ import { useFlattenedAccountTokens } from '@popup/pages/Account/Tokens/utils'; import { getMetadataUnique } from '@shared/utils/token-helpers'; import { withSelectedCredential } from '@popup/popupX/shared/utils/hoc'; import TokenList from '@popup/popupX/shared/TokenList'; +import { useUpdateAtom } from 'jotai/utils'; +import { removeTokenFromCurrentAccountAtom } from '@popup/store/token'; +import { useGenericToast } from '@popup/popupX/shared/utils/hooks'; /** Hook loading every fungible token added to the account. */ function useAccountFungibleTokens(account: WalletCredential) { @@ -19,10 +22,17 @@ function useAccountFungibleTokens(account: WalletCredential) { function ManageTokenList({ credential }: { credential: WalletCredential }) { const { t } = useTranslation('x', { keyPrefix: 'mangeTokens' }); + const remove = useUpdateAtom(removeTokenFromCurrentAccountAtom); const nav = useNavigate(); + const toast = useGenericToast(); const navToAddToken = () => nav(relativeRoutes.home.manageTokenList.addToken.path); const tokens = useAccountFungibleTokens(credential); + const removeToken = (contractIndex: string, id: string, name?: string) => { + remove({ contractIndex, tokenId: id }); + toast(t('removed'), name); + }; + return ( @@ -31,7 +41,12 @@ function ManageTokenList({ credential }: { credential: WalletCredential }) { {tokens.map((token) => ( - + removeToken(token.contractIndex, token.id, token?.metadata?.name)} + /> ))} diff --git a/packages/browser-wallet/src/popup/popupX/pages/ManageTokens/ManageTokens.scss b/packages/browser-wallet/src/popup/popupX/pages/ManageTokens/ManageTokens.scss index b8246b92d..e1a51a2a3 100644 --- a/packages/browser-wallet/src/popup/popupX/pages/ManageTokens/ManageTokens.scss +++ b/packages/browser-wallet/src/popup/popupX/pages/ManageTokens/ManageTokens.scss @@ -5,11 +5,25 @@ } .add-token-x { + .text__main_regular { + margin-bottom: rem(20px); + } + .form-search { - margin-top: rem(24px); + margin-top: rem(4px); } .token-list-x { margin-top: rem(8px); + overflow: auto; + max-height: rem(200px); + + &::-webkit-scrollbar { + display: none; + } + } + + .loader-x { + margin: rem(120px) auto 0 auto; } } diff --git a/packages/browser-wallet/src/popup/popupX/pages/ManageTokens/SearchTokenDetails.tsx b/packages/browser-wallet/src/popup/popupX/pages/ManageTokens/SearchTokenDetails.tsx new file mode 100644 index 000000000..3ba96cd01 --- /dev/null +++ b/packages/browser-wallet/src/popup/popupX/pages/ManageTokens/SearchTokenDetails.tsx @@ -0,0 +1,79 @@ +import React from 'react'; +import { useLocation, useParams } from 'react-router-dom'; +import { useTranslation } from 'react-i18next'; +import Page from '@popup/popupX/shared/Page'; +import Card from '@popup/popupX/shared/Card'; +import Img from '@popup/shared/Img'; +import Text from '@popup/popupX/shared/Text'; +import Button from '@popup/popupX/shared/Button'; +import { TokenWithPageID } from '@popup/pages/Account/Tokens/ManageTokens/utils'; +import FullscreenNotice from '@popup/popupX/shared/FullscreenNotice'; +import { useCopyToClipboard } from '@popup/popupX/shared/utils/hooks'; +import Copy from '@assets/svgX/copy.svg'; +import Notebook from '@assets/svgX/notebook.svg'; + +const SUB_INDEX = 0; + +interface Location { + state: { + token: TokenWithPageID; + }; +} + +export default function SearchTokenDetails() { + const { t } = useTranslation('x', { keyPrefix: 'tokenDetails' }); + const [isOpen, setIsOpen] = React.useState(false); + const copyToClipboard = useCopyToClipboard(); + const params = useParams(); + const location = useLocation() as Location; + const { metadata = {}, id } = location.state.token || { metadata: {} }; + const { thumbnail, display, symbol, name, description, decimals } = metadata; + + return ( + <> + setIsOpen(false)}> + + + } + onClick={() => copyToClipboard(JSON.stringify(metadata, null, 2))} + /> + + + + {Object.entries(metadata).map(([k, v]) => ( + + ))} + + + + + + + +
+ {symbol} + {name} +
+ + {decimals && } + {id && } + +
+ } + label={t('showRawMetadata')} + onClick={() => { + setIsOpen(true); + }} + /> +
+
+ + ); +} diff --git a/packages/browser-wallet/src/popup/popupX/pages/ManageTokens/i18n/en.ts b/packages/browser-wallet/src/popup/popupX/pages/ManageTokens/i18n/en.ts index 3146da52b..1f5eca321 100644 --- a/packages/browser-wallet/src/popup/popupX/pages/ManageTokens/i18n/en.ts +++ b/packages/browser-wallet/src/popup/popupX/pages/ManageTokens/i18n/en.ts @@ -1,8 +1,11 @@ const t = { manageTokenList: 'Manage token list', addToken: 'Add token', + addSelected: 'Add selected tokens', + removed: 'Token removed', enterContract: 'Enter a contract index to select tokens from.', contractIndex: 'Contract index', + tokenName: 'Token name', invalidIndex: 'Contract index must be an integer', indexMax: 'Contract index can not exceed 18446744073709551615', noContractFound: 'No contract found on index', diff --git a/packages/browser-wallet/src/popup/popupX/pages/ManageTokens/index.ts b/packages/browser-wallet/src/popup/popupX/pages/ManageTokens/index.ts index cd3f47fed..d6e629dc2 100644 --- a/packages/browser-wallet/src/popup/popupX/pages/ManageTokens/index.ts +++ b/packages/browser-wallet/src/popup/popupX/pages/ManageTokens/index.ts @@ -1,2 +1,3 @@ export { default as ManageTokenList } from './ManageTokenList'; export { default as AddToken } from './AddToken'; +export { default as SearchTokenDetails } from './SearchTokenDetails'; diff --git a/packages/browser-wallet/src/popup/popupX/pages/TokenDetails/TokenDetails.scss b/packages/browser-wallet/src/popup/popupX/pages/TokenDetails/TokenDetails.scss index 4f1968603..35ca61cad 100644 --- a/packages/browser-wallet/src/popup/popupX/pages/TokenDetails/TokenDetails.scss +++ b/packages/browser-wallet/src/popup/popupX/pages/TokenDetails/TokenDetails.scss @@ -58,7 +58,7 @@ margin-top: rem(24px); align-self: flex-start; - &:last-child { + &:last-child:not(:only-of-type) { margin-top: rem(12px); .label__main { diff --git a/packages/browser-wallet/src/popup/popupX/pages/TokenDetails/i18n/en.ts b/packages/browser-wallet/src/popup/popupX/pages/TokenDetails/i18n/en.ts index 4875f6848..4d891366c 100644 --- a/packages/browser-wallet/src/popup/popupX/pages/TokenDetails/i18n/en.ts +++ b/packages/browser-wallet/src/popup/popupX/pages/TokenDetails/i18n/en.ts @@ -7,6 +7,7 @@ const t = { description: 'Description', decimals: 'Decimals', indexSubindex: 'Contract index, subindex', + tokenId: 'Token ID', showRawMetadata: 'Show raw metadata', hideToken: 'Hide token from account', atDisposal: 'At disposal', diff --git a/packages/browser-wallet/src/popup/popupX/shared/Form/Search/Search.tsx b/packages/browser-wallet/src/popup/popupX/shared/Form/Search/Search.tsx index db9d4a0ef..a7eb7c9be 100644 --- a/packages/browser-wallet/src/popup/popupX/shared/Form/Search/Search.tsx +++ b/packages/browser-wallet/src/popup/popupX/shared/Form/Search/Search.tsx @@ -9,7 +9,7 @@ type Props = Pick, 'className' | 'autoFocu RequiredControlledFieldProps & Omit; -export function Search({ value, className, autoFocus, ...props }: Props) { +export function Search({ className, autoFocus, ...props }: Props) { return (
diff --git a/packages/browser-wallet/src/popup/popupX/shared/FullscreenNotice/FullscreenNotice.scss b/packages/browser-wallet/src/popup/popupX/shared/FullscreenNotice/FullscreenNotice.scss index d9096e8a9..9133a166e 100644 --- a/packages/browser-wallet/src/popup/popupX/shared/FullscreenNotice/FullscreenNotice.scss +++ b/packages/browser-wallet/src/popup/popupX/shared/FullscreenNotice/FullscreenNotice.scss @@ -4,7 +4,7 @@ bottom: 0; left: 0; right: 0; - z-index: 1000; + z-index: 3; &__back { border: none; diff --git a/packages/browser-wallet/src/popup/popupX/shared/Toast/Messages.tsx b/packages/browser-wallet/src/popup/popupX/shared/Toast/Messages.tsx index b6fe8f4ee..9e590384a 100644 --- a/packages/browser-wallet/src/popup/popupX/shared/Toast/Messages.tsx +++ b/packages/browser-wallet/src/popup/popupX/shared/Toast/Messages.tsx @@ -1,7 +1,8 @@ import React from 'react'; -import Check from '@assets/svgX/check.svg'; import { displaySplitAddressShort } from '@popup/shared/utils/account-helpers'; import Text from '@popup/popupX/shared/Text'; +import Check from '@assets/svgX/check.svg'; +import Info from '@assets/svgX/info-black.svg'; export function CopyAddress({ address, message }: { address: string; message: string }) { return ( @@ -14,3 +15,15 @@ export function CopyAddress({ address, message }: { address: string; message: st
); } + +export function GenericMessage({ title, message }: { title: string; message?: string }) { + return ( +
+ +
+ {title} + {message} +
+
+ ); +} diff --git a/packages/browser-wallet/src/popup/popupX/shared/Toast/Toast.scss b/packages/browser-wallet/src/popup/popupX/shared/Toast/Toast.scss index 85dd6a664..a935d9698 100644 --- a/packages/browser-wallet/src/popup/popupX/shared/Toast/Toast.scss +++ b/packages/browser-wallet/src/popup/popupX/shared/Toast/Toast.scss @@ -10,7 +10,7 @@ border-radius: rem(16px); padding: rem(10px) rem(15px); position: absolute; - z-index: 2; + z-index: 4; bottom: rem(16px); backdrop-filter: blur(5px); box-shadow: 0 -6px 15.3px 0 rgba($color-black, 0.25); @@ -50,12 +50,23 @@ } } -.copy-address-x { +.copy-address-x, +.generic-toast-x { display: flex; flex-direction: row; align-items: center; - .copy-message { + svg { + width: rem(24px); + height: rem(24px); + + path { + fill: $color-black; + } + } + + .copy-message, + .generic-toast-message { display: flex; flex-direction: column; align-items: flex-start; @@ -69,6 +80,10 @@ .capture__main_small { color: $color-black; + + &:empty { + display: none; + } } } } diff --git a/packages/browser-wallet/src/popup/popupX/shared/TokenList/TokenList.scss b/packages/browser-wallet/src/popup/popupX/shared/TokenList/TokenList.scss index 53609fd37..496c5ede6 100644 --- a/packages/browser-wallet/src/popup/popupX/shared/TokenList/TokenList.scss +++ b/packages/browser-wallet/src/popup/popupX/shared/TokenList/TokenList.scss @@ -32,5 +32,22 @@ .form-input__checkbox { margin-left: auto; } + + .button__icon.text { + margin-left: auto; + + &:hover:not(:disabled) { + opacity: 1; + } + + .label__main { + color: $color-mineral-2; + text-decoration: underline; + + &:hover { + color: $color-white; + } + } + } } } diff --git a/packages/browser-wallet/src/popup/popupX/shared/TokenList/TokenList.tsx b/packages/browser-wallet/src/popup/popupX/shared/TokenList/TokenList.tsx index 02bbd108b..0ec9f066a 100644 --- a/packages/browser-wallet/src/popup/popupX/shared/TokenList/TokenList.tsx +++ b/packages/browser-wallet/src/popup/popupX/shared/TokenList/TokenList.tsx @@ -1,8 +1,10 @@ import React, { ReactNode } from 'react'; import clsx from 'clsx'; +import { useTranslation } from 'react-i18next'; import Img from '@popup/shared/Img'; import Text from '@popup/popupX/shared/Text'; import { Checkbox } from '@popup/popupX/shared/Form/Checkbox'; +import Button from '@popup/popupX/shared/Button/Button'; type TokenListProps = { className?: string; children: ReactNode }; @@ -10,23 +12,48 @@ function TokenListRoot({ className, children }: TokenListProps) { return
{children}
; } -type TokenListItemProps = { thumbnail?: string; symbol?: string; className?: string }; +type TokenListItemProps = { thumbnail?: string; symbol?: string; className?: string; onClick?: () => void }; -function TokenListItem({ thumbnail, symbol, className }: TokenListItemProps) { +function TokenListItem({ + thumbnail, + symbol, + className, + onClick, + onSelect, +}: TokenListItemProps & { onSelect: (checked: boolean) => void }) { + const onCheck = (e: React.MouseEvent) => { + e.stopPropagation(); + onSelect((e.target as HTMLInputElement).checked); + }; + return ( + +
+ {symbol} +
+ {symbol} + +
+ ); +} + +function TokenListItemHide({ thumbnail, symbol, className, onClick }: TokenListItemProps) { + const { t } = useTranslation('x', { keyPrefix: 'sharedX.tokenList' }); return (
{symbol}
{symbol} - +
); } const TokenList = TokenListRoot as typeof TokenListRoot & { Item: typeof TokenListItem; + ItemHide: typeof TokenListItemHide; }; TokenList.Item = TokenListItem; +TokenList.ItemHide = TokenListItemHide; export default TokenList; diff --git a/packages/browser-wallet/src/popup/popupX/shared/i18n/en.ts b/packages/browser-wallet/src/popup/popupX/shared/i18n/en.ts index 3f0893b2e..50885be7d 100644 --- a/packages/browser-wallet/src/popup/popupX/shared/i18n/en.ts +++ b/packages/browser-wallet/src/popup/popupX/shared/i18n/en.ts @@ -91,6 +91,9 @@ const t = { unlock: 'Unlock', enterPassword: 'Please enter your passcode to enter the wallet.', }, + tokenList: { + hideToken: 'Hide token', + }, }; export default t; diff --git a/packages/browser-wallet/src/popup/popupX/shared/utils/hooks.tsx b/packages/browser-wallet/src/popup/popupX/shared/utils/hooks.tsx index 9ebbbdf9b..84835d729 100644 --- a/packages/browser-wallet/src/popup/popupX/shared/utils/hooks.tsx +++ b/packages/browser-wallet/src/popup/popupX/shared/utils/hooks.tsx @@ -3,7 +3,7 @@ import { useTranslation } from 'react-i18next'; import { useSetAtom } from 'jotai'; import { addToastAtom } from '@popup/state'; import { copyToClipboard } from '@popup/popupX/shared/utils/helpers'; -import { CopyAddress } from '@popup/popupX/shared/Toast/Messages'; +import { CopyAddress, GenericMessage } from '@popup/popupX/shared/Toast/Messages'; export function useCopyAddress() { const { t } = useTranslation('x', { keyPrefix: 'sharedX.messages' }); @@ -19,6 +19,13 @@ export function useCopyToClipboard() { const addToast = useSetAtom(addToastAtom); return (text: string) => { - copyToClipboard(text).then(() => addToast(t('copied'))); + copyToClipboard(text).then(() => addToast()); + }; +} + +export function useGenericToast() { + const addToast = useSetAtom(addToastAtom); + return (title: string, message?: string) => { + addToast(); }; } diff --git a/packages/browser-wallet/src/popup/popupX/shell/Routes.tsx b/packages/browser-wallet/src/popup/popupX/shell/Routes.tsx index fa8549d35..aca71192b 100644 --- a/packages/browser-wallet/src/popup/popupX/shell/Routes.tsx +++ b/packages/browser-wallet/src/popup/popupX/shell/Routes.tsx @@ -37,7 +37,7 @@ import SignCis3Message from '@popup/popupX/pages/prompts/SignCis3Message'; import SignMessage from '@popup/popupX/pages/prompts/SignMessage'; import SendTransaction from '@popup/popupX/pages/prompts/SendTransaction'; import ExternalRequestLayout from '@popup/popupX/page-layouts/ExternalRequestLayout'; -import { ManageTokenList, AddToken } from '@popup/popupX/pages/ManageTokens'; +import { ManageTokenList, AddToken, SearchTokenDetails } from '@popup/popupX/pages/ManageTokens'; import { Nft, NftDetails, NftRaw } from 'src/popup/popupX/pages/Nft'; import { DelegationResult } from '../pages/EarningRewards/Delegator/Result'; import SubmittedTransaction from '../pages/SubmittedTransaction'; @@ -113,7 +113,16 @@ export default function Routes({ messagePromptHandlers }: { messagePromptHandler /> } /> - } path={relativeRoutes.home.manageTokenList.addToken.path} /> + + } /> + + } /> + } + /> + + } path={relativeRoutes.settings.path}> diff --git a/packages/browser-wallet/src/popup/shared/Modal/Modal.scss b/packages/browser-wallet/src/popup/shared/Modal/Modal.scss index b9b01f405..239e1f831 100644 --- a/packages/browser-wallet/src/popup/shared/Modal/Modal.scss +++ b/packages/browser-wallet/src/popup/shared/Modal/Modal.scss @@ -4,7 +4,7 @@ bottom: 0; left: 0; right: 0; - z-index: 1000; + z-index: 3; overflow: auto; &--align-bottom {