CW-1021-Address-formatting-enhancements (#2141)

* Implement visual formatting for addresses

* fix minor issues

* Update transaction_details_page.dart

* Update transaction_details_page.dart

* fix multi recipient address formatting

* Update address_cell.dart
This commit is contained in:
Serhii
2025-04-10 16:16:43 +02:00
committed by GitHub
parent c1e9668b1e
commit 3f25d69244
13 changed files with 292 additions and 123 deletions
@@ -5,11 +5,12 @@ import 'package:cake_wallet/themes/extensions/cake_text_theme.dart';
import 'package:cake_wallet/themes/extensions/filter_theme.dart';
import 'package:cake_wallet/themes/extensions/sync_indicator_theme.dart';
import 'package:cake_wallet/themes/theme_base.dart';
import 'package:cake_wallet/utils/address_formatter.dart';
import 'package:cake_wallet/view_model/send/output.dart';
import 'package:cw_core/crypto_currency.dart';
import 'package:cw_core/pending_transaction.dart';
import 'package:cw_core/wallet_type.dart';
import 'package:flutter/material.dart';
import 'dart:math' as math;
import 'base_bottom_sheet_widget.dart';
@@ -27,6 +28,7 @@ class ConfirmSendingBottomSheet extends BaseBottomSheet {
final String feeFiatAmount;
final List<Output> outputs;
final VoidCallback onSlideComplete;
final WalletType walletType;
final PendingChange? change;
final bool isOpenCryptoPay;
@@ -46,6 +48,7 @@ class ConfirmSendingBottomSheet extends BaseBottomSheet {
required this.feeFiatAmount,
required this.outputs,
required this.onSlideComplete,
required this.walletType,
this.change,
this.isOpenCryptoPay = false,
Key? key,
@@ -91,6 +94,7 @@ class ConfirmSendingBottomSheet extends BaseBottomSheet {
itemTitle: paymentId!,
currentTheme: currentTheme,
itemTitleTextStyle: itemTitleTextStyle,
walletType: walletType,
isBatchSending: false,
amount: '',
address: paymentIdValue!,
@@ -139,6 +143,7 @@ class ConfirmSendingBottomSheet extends BaseBottomSheet {
name: isBatchSending ? batchContactTitle : contactName,
address: _address,
amount: _amount,
walletType: walletType,
isBatchSending: isBatchSending,
itemTitleTextStyle: itemTitleTextStyle,
itemSubTitleTextStyle: itemSubTitleTextStyle,
@@ -149,6 +154,7 @@ class ConfirmSendingBottomSheet extends BaseBottomSheet {
currentTheme: currentTheme,
itemTitleTextStyle: itemTitleTextStyle,
isBatchSending: isBatchSending,
walletType: walletType,
amount: _amount,
address: _address,
itemSubTitleTextStyle: itemSubTitleTextStyle,
@@ -166,6 +172,7 @@ class ConfirmSendingBottomSheet extends BaseBottomSheet {
address: change!.address,
amount: change!.amount + ' ${currency.title}',
isBatchSending: true,
walletType: walletType,
itemTitleTextStyle: itemTitleTextStyle,
itemSubTitleTextStyle: itemSubTitleTextStyle,
tileBackgroundColor: tileBackgroundColor,
@@ -275,6 +282,7 @@ class AddressTile extends StatelessWidget {
required this.address,
required this.itemSubTitleTextStyle,
required this.tileBackgroundColor,
required this.walletType,
});
final String itemTitle;
@@ -285,18 +293,10 @@ class AddressTile extends StatelessWidget {
final String address;
final TextStyle itemSubTitleTextStyle;
final Color tileBackgroundColor;
final WalletType walletType;
@override
Widget build(BuildContext context) {
final addressTextStyle = TextStyle(
fontSize: 12,
fontFamily: 'Lato',
fontWeight: FontWeight.w600,
color: currentTheme.type == ThemeType.bright
? Theme.of(context).extension<CakeTextTheme>()!.titleColor.withOpacity(0.5)
: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
decoration: TextDecoration.none,
);
return Container(
padding: const EdgeInsets.symmetric(horizontal: 14, vertical: 8),
decoration: BoxDecoration(
@@ -313,41 +313,20 @@ class AddressTile extends StatelessWidget {
if (isBatchSending) Text(amount, style: itemTitleTextStyle),
],
),
buildSegmentedAddress(
AddressFormatter.buildSegmentedAddress(
address: address,
evenTextStyle: addressTextStyle,
oddTextStyle: itemSubTitleTextStyle,
walletType: walletType,
evenTextStyle: TextStyle(
fontSize: 12,
fontFamily: 'Lato',
fontWeight: FontWeight.w600,
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
decoration: TextDecoration.none)
),
],
),
);
}
Widget buildSegmentedAddress({
required String address,
int chunkSize = 6,
required TextStyle evenTextStyle,
required TextStyle oddTextStyle,
}) {
final spans = <TextSpan>[];
int index = 0;
for (int i = 0; i < address.length; i += chunkSize) {
final chunk = address.substring(i, math.min(i + chunkSize, address.length));
final style = (index % 2 == 0) ? evenTextStyle : oddTextStyle;
spans.add(
TextSpan(text: '$chunk ', style: style),
);
index++;
}
return RichText(
text: TextSpan(children: spans, style: evenTextStyle),
overflow: TextOverflow.visible,
);
}
}
class AddressExpansionTile extends StatelessWidget {
@@ -362,6 +341,7 @@ class AddressExpansionTile extends StatelessWidget {
required this.itemTitleTextStyle,
required this.itemSubTitleTextStyle,
required this.tileBackgroundColor,
required this.walletType,
});
final String contactType;
@@ -373,19 +353,10 @@ class AddressExpansionTile extends StatelessWidget {
final TextStyle itemTitleTextStyle;
final TextStyle itemSubTitleTextStyle;
final Color tileBackgroundColor;
final WalletType walletType;
@override
Widget build(BuildContext context) {
final addressTextStyle = TextStyle(
fontSize: 12,
fontFamily: 'Lato',
fontWeight: FontWeight.w600,
color: currentTheme.type == ThemeType.bright
? Theme.of(context).extension<CakeTextTheme>()!.titleColor.withOpacity(0.5)
: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
decoration: TextDecoration.none,
);
return Container(
decoration: BoxDecoration(
borderRadius: BorderRadius.all(Radius.circular(10)),
@@ -420,10 +391,15 @@ class AddressExpansionTile extends StatelessWidget {
Row(
children: [
Expanded(
child: buildSegmentedAddress(
address: address,
evenTextStyle: addressTextStyle,
oddTextStyle: itemSubTitleTextStyle,
child: AddressFormatter.buildSegmentedAddress(
address: address,
walletType: walletType,
evenTextStyle: TextStyle(
fontSize: 12,
fontFamily: 'Lato',
fontWeight: FontWeight.w600,
color: Theme.of(context).extension<CakeTextTheme>()!.titleColor,
decoration: TextDecoration.none)
),
),
],
@@ -434,30 +410,4 @@ class AddressExpansionTile extends StatelessWidget {
),
);
}
Widget buildSegmentedAddress({
required String address,
int chunkSize = 6,
required TextStyle evenTextStyle,
required TextStyle oddTextStyle,
}) {
final spans = <TextSpan>[];
int index = 0;
for (int i = 0; i < address.length; i += chunkSize) {
final chunk = address.substring(i, math.min(i + chunkSize, address.length));
final style = (index % 2 == 0) ? evenTextStyle : oddTextStyle;
spans.add(
TextSpan(text: '$chunk ', style: style),
);
index++;
}
return RichText(
text: TextSpan(children: spans, style: evenTextStyle),
overflow: TextOverflow.visible,
);
}
}
+13 -7
View File
@@ -12,7 +12,8 @@ class ListRow extends StatelessWidget {
this.padding,
this.color,
this.hintTextColor,
this.mainTextColor
this.mainTextColor,
this.textWidget
});
final String title;
@@ -24,6 +25,16 @@ class ListRow extends StatelessWidget {
final Color? color;
final Color? hintTextColor;
final Color? mainTextColor;
final Widget? textWidget;
Widget _getTextWidget (BuildContext context) => textWidget ?? Text(
value,
style: TextStyle(
fontSize: valueFontSize,
fontWeight: FontWeight.w500,
color: mainTextColor ?? Theme.of(context).extension<CakeTextTheme>()!.titleColor
),
);
@override
Widget build(BuildContext context) {
@@ -49,12 +60,7 @@ class ListRow extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Expanded(
child: Text(value,
style: TextStyle(
fontSize: valueFontSize,
fontWeight: FontWeight.w500,
color: mainTextColor ?? Theme.of(context).extension<CakeTextTheme>()!.titleColor)),
),
child: _getTextWidget(context)),
image != null
? Padding(
padding: EdgeInsets.only(left: 24),