What changed, and why it matters
This commit fixes how dates are formatted in the wallet's transaction history so they match the user's selected language/locale. It also slightly reorganizes the buttons shown at the top of the assets/history tabs by moving their definitions into a shared data class. There is no security-relevant change.
No security action needed; this is a routine UI/locale refactoring change.
Security signals we found
No strong security signals were identified.
Evidence from the diff
The patch removes hardcoded locale usage in HistorySection._formatTransactionDate by passing Localizations.localeOf(context).toString() into DateFormat constructors. It refactors AssetsHistorySection and AssetsTopBar so each tab can carry an optional AssetsHistorySectionActionButton (title, icon, callback), replacing string-based tab comparisons and consolidating the ‘Tokens’ and ‘All’ action buttons. Several unused imports are removed. No cryptographic, networking, input-validation, or access-control changes are present.
Changed components
lib/new-ui/widgets/coins_page/assets_history/assets_history_section.dartlib/new-ui/widgets/coins_page/assets_history/assets_top_bar.dartlib/new-ui/widgets/coins_page/assets_history/history_section.dartInspect captured patch +48 / −69
diff --git a/lib/new-ui/widgets/coins_page/assets_history/assets_history_section.dart b/lib/new-ui/widgets/coins_page/assets_history/assets_history_section.dart
index ecc16309..81fad913 100644
--- a/lib/new-ui/widgets/coins_page/assets_history/assets_history_section.dart
+++ b/lib/new-ui/widgets/coins_page/assets_history/assets_history_section.dart
@@ -4,6 +4,7 @@ import 'package:cake_wallet/new-ui/widgets/coins_page/assets_history/assets_top_
import 'package:cake_wallet/new-ui/widgets/coins_page/assets_history/history_modal.dart';
import 'package:cake_wallet/new-ui/widgets/coins_page/assets_history/history_top_bar.dart';
import 'package:cake_wallet/reactions/wallet_connect.dart';
+import 'package:cake_wallet/routes.dart';
import 'package:cake_wallet/src/screens/dashboard/pages/nft_listing_page.dart';
import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
import 'package:cake_wallet/view_model/dashboard/nft_view_model.dart';
@@ -13,11 +14,20 @@ import 'package:modal_bottom_sheet/modal_bottom_sheet.dart';
import 'assets_section.dart';
import 'history_section.dart';
+class AssetsHistorySectionActionButton {
+ final String title;
+ final String iconPath;
+ final VoidCallback onPressed;
+
+ const AssetsHistorySectionActionButton(this.title, this.iconPath, this.onPressed);
+}
+
class AssetsHistorySectionTab {
final String title;
final Widget content;
+ final AssetsHistorySectionActionButton? actionButton;
- AssetsHistorySectionTab(this.title, this.content);
+ const AssetsHistorySectionTab(this.title, this.content, this.actionButton);
}
class AssetsHistorySection extends StatefulWidget {
@@ -36,24 +46,31 @@ class _AssetsHistorySectionState extends State<AssetsHistorySection> {
void reloadTabs() {
final oldTabLength = tabs.length;
+ final hasAssetsTab = widget.dashboardViewModel.balanceViewModel.isHomeScreenSettingsEnabled || (widget.dashboardViewModel.hasMweb && widget.dashboardViewModel.mwebEnabled);
+ final hasNftTab = isNFTACtivatedChain(widget.dashboardViewModel.wallet.type,
+ chainId: widget.dashboardViewModel.wallet.chainId);
tabs = [
- if (widget.dashboardViewModel.balanceViewModel.isHomeScreenSettingsEnabled || (widget.dashboardViewModel.hasMweb && widget.dashboardViewModel.mwebEnabled))
+ if (hasAssetsTab)
AssetsHistorySectionTab(
S.current.assets,
AssetsSection(
dashboardViewModel: widget.dashboardViewModel,
- )),
+ ), AssetsHistorySectionActionButton(S.current.tokens, "assets/new-ui/options_slider.svg", (){
+ Navigator.of(context).pushNamed(
+ Routes.homeSettings,
+ arguments: widget.dashboardViewModel.balanceViewModel,
+ );
+ })),
AssetsHistorySectionTab(
S.current.history,
HistorySection(
detailsAsPage: false,
- roundedTopSection: tabs.length > 1,
+ roundedTopSection: hasAssetsTab || hasNftTab,
dashboardViewModel: widget.dashboardViewModel,
short: true,
- )),
- if (isNFTACtivatedChain(widget.dashboardViewModel.wallet.type,
- chainId: widget.dashboardViewModel.wallet.chainId))
- AssetsHistorySectionTab(S.current.nfts, NFTListingPage(nftViewModel: widget.nftViewModel))
+ ), AssetsHistorySectionActionButton(S.current.all_pascal_case, "assets/new-ui/arrow_right.svg", (){openHistoryModal(context);})),
+ if (hasNftTab)
+ AssetsHistorySectionTab(S.current.nfts, NFTListingPage(nftViewModel: widget.nftViewModel), null)
];
if (oldTabLength != tabs.length) {
setState(() {
@@ -81,7 +98,7 @@ class _AssetsHistorySectionState extends State<AssetsHistorySection> {
AssetsTopBar(
onTransactionHistoryOpened: () => openHistoryModal(context),
dashboardViewModel: widget.dashboardViewModel,
- tabs: tabs.map((item) => item.title).toList(),
+ tabs: tabs,
onTabChange: (index) {
setState(() {
_selectedTab = index;
diff --git a/lib/new-ui/widgets/coins_page/assets_history/assets_top_bar.dart b/lib/new-ui/widgets/coins_page/assets_history/assets_top_bar.dart
index a99e8f13..67fe4c9a 100644
--- a/lib/new-ui/widgets/coins_page/assets_history/assets_top_bar.dart
+++ b/lib/new-ui/widgets/coins_page/assets_history/assets_top_bar.dart
@@ -1,9 +1,5 @@
-import 'package:cake_wallet/core/csv_export_service.dart';
-import 'package:cake_wallet/generated/i18n.dart';
+import 'package:cake_wallet/new-ui/widgets/coins_page/assets_history/assets_history_section.dart';
import 'package:cake_wallet/new-ui/widgets/line_tab_switcher.dart';
-import 'package:cake_wallet/routes.dart';
-import 'package:cake_wallet/src/screens/dashboard/widgets/filter_widget.dart';
-import 'package:cake_wallet/utils/show_pop_up.dart';
import 'package:cake_wallet/src/widgets/cake_image_widget.dart';
import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
import 'package:flutter/material.dart';
@@ -20,13 +16,11 @@ class AssetsTopBar extends StatelessWidget {
final void Function(int) onTabChange;
final VoidCallback onTransactionHistoryOpened;
final int selectedTab;
- final List<String> tabs;
+ final List<AssetsHistorySectionTab> tabs;
final DashboardViewModel dashboardViewModel;
@override
Widget build(BuildContext context) {
- final settingsButtonText = _getSettingsButtonText();
- final hasTokenSettingsButton = settingsButtonText != null;
return SliverToBoxAdapter(
child: Padding(
@@ -36,7 +30,7 @@ class AssetsTopBar extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
LineTabSwitcher(
- tabs: tabs,
+ tabs: tabs.map((item)=>item.title).toList(),
onTabChange: onTabChange,
selectedTab: selectedTab,
),
@@ -57,19 +51,13 @@ class AssetsTopBar extends StatelessWidget {
children: [
Opacity(
- opacity: hasTokenSettingsButton ? 1 : 0,
+ opacity: tabs[selectedTab].actionButton != null ? 1 : 0,
child: GestureDetector(
onTap: () {
- if (tabs[selectedTab] == S.of(context).assets) {
- Navigator.of(context).pushNamed(
- Routes.homeSettings,
- arguments: dashboardViewModel.balanceViewModel,
- );
- } else if (tabs[selectedTab] == S.of(context).history) {
-
- onTransactionHistoryOpened();
- }
- },
+ if(tabs[selectedTab].actionButton != null) {
+ tabs[selectedTab].actionButton?.onPressed();
+ }
+ },
child: Container(
height: 40,
decoration: BoxDecoration(
@@ -82,13 +70,13 @@ class AssetsTopBar extends StatelessWidget {
spacing: 6,
children: [
- if ((settingsButtonText ?? "").isNotEmpty)
+ if ((tabs[selectedTab].actionButton?.title ?? "").isNotEmpty)
Text(
- settingsButtonText ?? "",
+ tabs[selectedTab].actionButton?.title ?? "",
style: TextStyle(color: Theme.of(context).colorScheme.primary),
),
CakeImageWidget(
- imageUrl: _getSettingsButtonIconPath(),
+ imageUrl: tabs[selectedTab].actionButton?.iconPath,
colorFilter: ColorFilter.mode(
Theme.of(context).colorScheme.primary, BlendMode.srcIn)),
],
@@ -106,28 +94,4 @@ class AssetsTopBar extends StatelessWidget {
);
}
- String? _getSettingsButtonIconPath() {
- if (tabs[selectedTab] == S.current.history) {
- return "assets/new-ui/arrow_right.svg";
- }
-
- if (tabs[selectedTab] == S.current.assets &&
- dashboardViewModel.balanceViewModel.isHomeScreenSettingsEnabled) {
- return "assets/new-ui/options_slider.svg";
- }
-
- return null;
- }
-
- String? _getSettingsButtonText() {
- if (tabs[selectedTab] == S.current.assets &&
- dashboardViewModel.balanceViewModel.isHomeScreenSettingsEnabled) {
- return S.current.tokens;
- }
-
- if (tabs[selectedTab] == S.current.history) {
- return S.current.all_pascal_case;
- }
- return null;
- }
}
diff --git a/lib/new-ui/widgets/coins_page/assets_history/history_section.dart b/lib/new-ui/widgets/coins_page/assets_history/history_section.dart
index bb2016b5..56b07cab 100644
--- a/lib/new-ui/widgets/coins_page/assets_history/history_section.dart
+++ b/lib/new-ui/widgets/coins_page/assets_history/history_section.dart
@@ -1,5 +1,3 @@
-import 'dart:math';
-
import 'package:cake_wallet/di.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/new-ui/widgets/coins_page/assets_history/anonpay_history_tile.dart';
@@ -9,7 +7,6 @@ import 'package:cake_wallet/new-ui/widgets/coins_page/assets_history/history_tra
import 'package:cake_wallet/new-ui/widgets/coins_page/assets_history/payjoin_history_tile.dart';
import 'package:cake_wallet/new-ui/widgets/coins_page/assets_history/transaction_details_modal.dart';
import 'package:cake_wallet/routes.dart';
-import 'package:cake_wallet/utils/date_formatter.dart';
import 'package:cake_wallet/view_model/dashboard/anonpay_transaction_list_item.dart';
import 'package:cake_wallet/view_model/dashboard/dashboard_view_model.dart';
import 'package:cake_wallet/view_model/dashboard/date_section_item.dart';
@@ -39,6 +36,7 @@ class HistorySection extends StatelessWidget {
padding: EdgeInsets.only(left: 16.0, right: 16, top: short && roundedTopSection ? 18 : 0),
sliver: Observer(
builder: (_) {
+ final localeName = Localizations.localeOf(context).toString();
final items = short ? dashboardViewModel.itemsShort : dashboardViewModel.items;
return (items.isEmpty)
@@ -100,7 +98,7 @@ class HistorySection extends StatelessWidget {
},
child: HistoryTile(
title: item.formattedTitle + transactionType,
- date: _formatTransactionDate(item.date),
+ date: _formatTransactionDate(item.date, localeName),
amount: item.formattedCryptoAmount,
amountFiat: item.formattedFiatAmount,
hasTokens: item.hasTokens,
@@ -128,7 +126,7 @@ class HistorySection extends StatelessWidget {
from: tradeFrom,
to: tradeTo,
provider: trade.provider,
- date: _formatTransactionDate(item.trade.createdAt ?? DateTime.now()),
+ date: _formatTransactionDate(item.trade.createdAt ?? DateTime.now(), localeName),
amount: trade.amountFormatted(),
receiveAmount: trade.receiveAmountFormatted(),
roundedBottom: roundedBottom,
@@ -154,7 +152,7 @@ class HistorySection extends StatelessWidget {
onTap: () => Navigator.of(context)
.pushNamed(Routes.orderDetails, arguments: item.order),
child: HistoryOrderTile(
- date: _formatTransactionDate(item.order.createdAt),
+ date: _formatTransactionDate(item.order.createdAt, localeName),
amount: item.orderFormattedAmount,
amountFiat: "USD 0.00",
roundedBottom: roundedBottom,
@@ -171,7 +169,7 @@ class HistorySection extends StatelessWidget {
arguments: [item.sessionId, item.transaction],
),
child: PayjoinHistoryTile(
- createdAt: _formatTransactionDate(session.inProgressSince!),
+ createdAt: _formatTransactionDate(session.inProgressSince!, localeName),
amount: dashboardViewModel.appStore.amountParsingProxy
.getDisplayCryptoString(
session.amount.toInt(), CryptoCurrency.btc),
@@ -190,7 +188,7 @@ class HistorySection extends StatelessWidget {
.pushNamed(Routes.anonPayDetailsPage, arguments: transactionInfo),
child: AnonpayHistoryTile(
provider: transactionInfo.provider,
- createdAt: _formatTransactionDate(transactionInfo.createdAt),
+ createdAt: _formatTransactionDate(transactionInfo.createdAt, localeName),
amount: transactionInfo.fiatAmount?.toString() ??
(transactionInfo.amountTo?.toString() ?? ''),
currency: transactionInfo.fiatAmount != null
@@ -220,8 +218,8 @@ class HistorySection extends StatelessWidget {
}
}
- String _formatTransactionDate(DateTime date) {
- final time = DateFormat.Hm();
+ String _formatTransactionDate(DateTime date, String localeName) {
+ final time = DateFormat.Hm(localeName);
final now = DateTime.now();
final today = DateTime(now.year, now.month, now.day);
@@ -239,16 +237,16 @@ class HistorySection extends StatelessWidget {
}
if (daysAgo < 7) {
- final weekday = DateFormat.EEEE().format(date);
+ final weekday = DateFormat.EEEE(localeName).format(date);
return "$weekday, $timeStr";
}
if (date.year == now.year) {
- final dayMonth = DateFormat("d MMMM").format(date);
+ final dayMonth = DateFormat("d MMMM", localeName).format(date);
return "$dayMonth, $timeStr";
}
- final full = DateFormat("d MMM yyyy").format(date);
+ final full = DateFormat("d MMM yyyy", localeName).format(date);
return "$full, $timeStr";
}
}
Why this scored 15/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.