[Wallet]: Prices Updated Tooltip (#34578)

Introduces a Last updated time ago tooltip in the Wallet that we can display when hovering over prices.
This commit is contained in:
Douglas Daniel
2026-03-10 09:00:27 -05:00
committed by GitHub
parent a54d56b28d
commit 8378c4d212
8 changed files with 82 additions and 13 deletions
@@ -684,6 +684,7 @@ inline constexpr webui::LocalizedString kLocalizedStrings[] = {
{"braveWalletAccountsDeposit", IDS_BRAVE_WALLET_ACCOUNTS_DEPOSIT},
{"braveWalletAccountsRemove", IDS_BRAVE_WALLET_ACCOUNTS_REMOVE},
{"braveWalletAccountSettings", IDS_BRAVE_WALLET_ACCOUNT_SETTINGS},
{"braveWalletLastUpdatedAgo", IDS_BRAVE_WALLET_LAST_UPDATED_AGO},
{"braveWalletNoAvailableAssets", IDS_BRAVE_WALLET_NO_AVAILABLE_ASSETS},
{"braveWalletNoAvailableAssetsDescription",
IDS_BRAVE_WALLET_NO_AVAILABLE_ASSETS_DESCRIPTION},
@@ -36,6 +36,7 @@ export const LOCAL_STORAGE_KEYS = {
FILTERED_OUT_DAPP_CATEGORIES: 'BRAVE_WALLET_FILTERED_OUT_DAPP_CATEGORIES',
HAS_ACCEPTED_PARTNER_TERMS: 'BRAVE_WALLET_HAS_ACCEPTED_PARTNER_TERMS',
TOKEN_SPOT_PRICES: 'BRAVE_WALLET_TOKEN_SPOT_PRICES',
TOKEN_SPOT_PRICES_LAST_UPDATED: 'BRAVE_WALLET_TOKEN_SPOT_PRICES_LAST_UPDATED',
} as const
const LOCAL_STORAGE_KEYS_DEPRECATED = {
@@ -98,6 +98,9 @@ import {
PortfolioOverviewHeader, //
} from '../../card-headers/portfolio-overview-header'
import { Banners } from '../banners/banners'
import {
LastPricesUpdatedTooltip, //
} from '../../../shared/last_prices_updated_tooltip/last_prices_updated_tooltip'
// Styled Components
import {
@@ -574,11 +577,13 @@ export const PortfolioOverview = () => {
>
<BalanceAndChangeWrapper>
{formattedFullPortfolioFiatBalance !== '' ? (
<BalanceText>
{hidePortfolioBalances
? '******'
: formattedFullPortfolioFiatBalance}
</BalanceText>
<LastPricesUpdatedTooltip>
<BalanceText>
{hidePortfolioBalances
? '******'
: formattedFullPortfolioFiatBalance}
</BalanceText>
</LastPricesUpdatedTooltip>
) : (
<Column padding='9px 0px'>
<LoadingSkeleton
@@ -0,0 +1,49 @@
// Copyright (c) 2026 The Brave Authors. All rights reserved.
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
// You can obtain one at https://mozilla.org/MPL/2.0/.
import * as React from 'react'
import Tooltip from '@brave/leo/react/tooltip'
// Constants
import {
LOCAL_STORAGE_KEYS, //
} from '../../../common/constants/local-storage-keys'
// Utils
import { formatDateAsRelative } from '../../../utils/datetime-utils'
import { getLocale } from '../../../../common/locale'
interface Props {
children: React.ReactNode
}
export const LastPricesUpdatedTooltip = ({ children }: Props) => {
// State
const [label, setLabel] = React.useState('')
// Methods
const onMouseEnter = React.useCallback(() => {
const lastUpdated = window.localStorage.getItem(
LOCAL_STORAGE_KEYS.TOKEN_SPOT_PRICES_LAST_UPDATED,
)
if (lastUpdated) {
setLabel(
getLocale('braveWalletLastUpdatedAgo').replace(
'$1',
formatDateAsRelative(new Date(lastUpdated)),
),
)
}
}, [])
return (
<Tooltip
text={label}
hidden={!label}
>
<span onMouseEnter={onMouseEnter}>{children}</span>
</Tooltip>
)
}
@@ -33,6 +33,9 @@ import {
import {
ShieldedLabel, //
} from '../../../../components/shared/shielded_label/shielded_label'
import {
LastPricesUpdatedTooltip, //
} from '../../../../components/shared/last_prices_updated_tooltip/last_prices_updated_tooltip'
// Styled Components
import {
@@ -253,14 +256,16 @@ export const TokenListItem = React.forwardRef<HTMLDivElement, Props>(
{tokenHasMultipleAccounts && formattedFiatBalance && (
<AccountsIcon />
)}
<FiatBalanceText
textSize='14px'
isBold={true}
textAlign='right'
textColor='primary'
>
{formattedFiatBalance}
</FiatBalanceText>
<LastPricesUpdatedTooltip>
<FiatBalanceText
textSize='14px'
isBold={true}
textAlign='right'
textColor='primary'
>
{formattedFiatBalance}
</FiatBalanceText>
</LastPricesUpdatedTooltip>
</Row>
<Row width='unset'>
{spotPrice?.percentageChange24h ? (
@@ -539,6 +539,9 @@ provideStrings({
'Password is required to take this action.',
braveWalletAddToken: 'Add token',
// Spot Prices
braveWalletLastUpdatedAgo: 'Last updated $1 ago',
// Empty Token List State
braveWalletNoAvailableAssets: 'No available assets',
braveWalletNoAvailableAssetsDescription:
@@ -250,6 +250,10 @@ export const mergeAndPersistSpotPrices = (
LOCAL_STORAGE_KEYS.TOKEN_SPOT_PRICES,
JSON.stringify(existing),
)
window.localStorage.setItem(
LOCAL_STORAGE_KEYS.TOKEN_SPOT_PRICES_LAST_UPDATED,
new Date().toISOString(),
)
} catch (error) {
console.error(error)
}
+1
View File
@@ -344,6 +344,7 @@
<message name="IDS_BRAVE_WALLET_ACCOUNTS_DEPOSIT" desc="Account list item Deposit button">Deposit</message>
<message name="IDS_BRAVE_WALLET_ACCOUNTS_REMOVE" desc="Account list item Remove button">Remove</message>
<message name="IDS_BRAVE_WALLET_ACCOUNT_SETTINGS" desc="Account settings label">Account settings</message>
<message name="IDS_BRAVE_WALLET_LAST_UPDATED_AGO" desc="Tooltip showing how long ago prices were last updated, e.g. Last updated 5m ago">Last updated <ph name="TIME_AGO"><ex>5m</ex>$1</ph> ago</message>
<message name="IDS_BRAVE_WALLET_NO_AVAILABLE_ASSETS" desc="No availible assets title on the portfolio page">No available assets</message>
<message name="IDS_BRAVE_WALLET_NO_AVAILABLE_ASSETS_DESCRIPTION" desc="No availible assets description on the portfolio page">Deposit or purchase tokens to get started. If you don't see tokens from an imported account, check the filters and display settings. Unknown tokens may need to be added as custom assets.</message>
<message name="IDS_BRAVE_WALLET_ACCOUNT_SETTINGS_SHOW_KEY" desc="Account settings modal show key button">Show key</message>