From 9a6ae623afe2fbca8f5bdab5f28fdbe435efed46 Mon Sep 17 00:00:00 2001 From: Juligs Date: Thu, 28 May 2026 17:34:10 +0200 Subject: [PATCH 1/9] chore(wallet): standardize toast position --- .../transaction/TransactionReceipt.tsx | 127 +++++++++++------- .../ui/app/components/receipt-card/index.tsx | 1 + .../src/ui/app/shared/toaster/index.tsx | 56 ++------ 3 files changed, 94 insertions(+), 90 deletions(-) diff --git a/apps/core/src/components/transaction/TransactionReceipt.tsx b/apps/core/src/components/transaction/TransactionReceipt.tsx index bfd2bfe04c..0b74f842d2 100644 --- a/apps/core/src/components/transaction/TransactionReceipt.tsx +++ b/apps/core/src/components/transaction/TransactionReceipt.tsx @@ -1,9 +1,10 @@ // Copyright (c) 2024 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 +import { useState } from 'react'; import { InfoBox, InfoBoxStyle, InfoBoxType } from '@iota/apps-ui-kit'; +import { CheckmarkFilled, Close } from '@iota/apps-ui-icons'; import type { useTransactionSummary } from '../../hooks'; -import { CheckmarkFilled } from '@iota/apps-ui-icons'; import { IotaTransactionBlockResponse } from '@iota/iota-sdk/client'; import { STAKING_REQUEST_EVENT, UNSTAKING_REQUEST_EVENT } from '../../constants'; import { StakeTransactionDetails } from './details'; @@ -18,6 +19,7 @@ interface TransactionReceiptProps { activeAddress: string | null; summary: Exclude, null>; renderExplorerLink: RenderExplorerLink; + stickyStatus?: boolean; } export function TransactionReceipt({ @@ -25,53 +27,72 @@ export function TransactionReceipt({ activeAddress, summary, renderExplorerLink, + stickyStatus, }: TransactionReceiptProps) { const { events } = txn; const isSender = txn.transaction?.data.sender === activeAddress; + const isSuccess = summary.status === 'success'; const stakeTypeTransaction = events?.find(({ type }) => type === STAKING_REQUEST_EVENT); const unstakeTypeTransaction = events?.find(({ type }) => type === UNSTAKING_REQUEST_EVENT); - return ( -
- - {stakeTypeTransaction || unstakeTypeTransaction ? ( - <> - {stakeTypeTransaction ? ( - - ) : null} + const content = + stakeTypeTransaction || unstakeTypeTransaction ? ( + <> + {stakeTypeTransaction ? ( + + ) : null} + {unstakeTypeTransaction ? ( + + ) : null} + + ) : ( + <> + + {isSender && ( + + )} + + ); - {unstakeTypeTransaction ? ( - - ) : null} - - ) : ( - <> - - {isSender && ( - - )} - - )} + const status = ( + + ); + + if (stickyStatus) { + return ( +
+
+ {content} +
+ {status} +
+ ); + } + + return ( +
+ {status} + {content}
); } @@ -83,17 +104,31 @@ interface TransactionStatusProps { } function TransactionStatus({ success, timestamp, isIncoming }: TransactionStatusProps) { + const [dismissed, setDismissed] = useState(false); + + if (dismissed) return null; + const txnDate = timestamp ? formatDate(Number(timestamp), ['day', 'month', 'year', 'hour', 'minute']) : ''; const successMessage = isIncoming ? 'Successfully received' : 'Successfully sent'; + return ( - } - /> +
+ } + /> + +
); } diff --git a/apps/wallet/src/ui/app/components/receipt-card/index.tsx b/apps/wallet/src/ui/app/components/receipt-card/index.tsx index 307eeb0df4..d679f78e6a 100644 --- a/apps/wallet/src/ui/app/components/receipt-card/index.tsx +++ b/apps/wallet/src/ui/app/components/receipt-card/index.tsx @@ -40,6 +40,7 @@ export function ReceiptCard({ txn, activeAddress }: ReceiptCardProps) { summary={summary} activeAddress={activeAddress} renderExplorerLink={ExplorerLinkHelper} + stickyStatus />
diff --git a/apps/wallet/src/ui/app/shared/toaster/index.tsx b/apps/wallet/src/ui/app/shared/toaster/index.tsx index f0c3d255e5..bf369561b2 100644 --- a/apps/wallet/src/ui/app/shared/toaster/index.tsx +++ b/apps/wallet/src/ui/app/shared/toaster/index.tsx @@ -2,57 +2,24 @@ // Modifications Copyright (c) 2024 IOTA Stiftung // SPDX-License-Identifier: Apache-2.0 -import { useMenuIsOpen } from '_components'; -import { useAppSelector } from '_hooks'; -import { getNavIsVisible } from '_redux/slices/app'; -import cl from 'clsx'; +import { useEffect } from 'react'; import { useLocation } from 'react-router-dom'; import { Portal } from '../Portal'; -import { useEffect } from 'react'; import { Toaster as ToasterCore, toast, useToasterStore } from '@iota/core'; -export type ToasterProps = { - bottomNavEnabled?: boolean; -}; +const ROUTES_WITH_BOTTOM_CONTENT = [ + '/send', + '/dapp/connect', + '/dapp/approve', + '/accounts/import-ledger-accounts', + '/accounts/manage/accounts-finder', + '/accounts/manage', +]; const LIMIT_MAX_TOASTS = 5; -function getBottomSpace(pathname: string, isMenuVisible: boolean, isBottomNavSpace: boolean) { - if (isMenuVisible) { - return '!bottom-28'; - } - - const overlayWithActionButton = [ - '/auto-lock', - '/manage/accounts-finder', - '/accounts/import-ledger-accounts', - '/send', - '/accounts/forgot-password/recover-many', - '/accounts/manage', - ].includes(pathname); - - const matchDynamicPaths = ['/dapp/connect', '/dapp/approve'].some((path) => - pathname.startsWith(path), - ); - - if (overlayWithActionButton || isBottomNavSpace || matchDynamicPaths) { - return '!bottom-20'; - } - - return ''; -} - -export function Toaster({ bottomNavEnabled = false }: ToasterProps) { +export function Toaster({ bottomNavEnabled = false }: { bottomNavEnabled?: boolean }) { const { pathname } = useLocation(); - - const menuVisible = useMenuIsOpen(); - const isBottomNavVisible = useAppSelector(getNavIsVisible); - const bottomSpace = getBottomSpace( - pathname, - menuVisible, - isBottomNavVisible && bottomNavEnabled, - ); - const { toasts } = useToasterStore(); useEffect(() => { @@ -62,10 +29,11 @@ export function Toaster({ bottomNavEnabled = false }: ToasterProps) { .forEach((t) => toast.dismiss(t.id)); }, [toasts]); + const hasBottomContent = ROUTES_WITH_BOTTOM_CONTENT.some((path) => pathname.startsWith(path)); return ( From 1bfbfa38f5be7b2283ee26d3a383047e892f5800 Mon Sep 17 00:00:00 2001 From: Juligs Date: Fri, 29 May 2026 11:25:03 +0200 Subject: [PATCH 2/9] chore: update position --- apps/core/src/components/transaction/TransactionReceipt.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/core/src/components/transaction/TransactionReceipt.tsx b/apps/core/src/components/transaction/TransactionReceipt.tsx index 0b74f842d2..3263e1bc6f 100644 --- a/apps/core/src/components/transaction/TransactionReceipt.tsx +++ b/apps/core/src/components/transaction/TransactionReceipt.tsx @@ -124,7 +124,7 @@ function TransactionStatus({ success, timestamp, isIncoming }: TransactionStatus />