diff --git a/lib/g1/currency.dart b/lib/g1/currency.dart index a7669677d7429ec1e47da797e7c46643f18a152a..6d57a9e03fcfba2a68a1521c618adf2423ad4efa 100644 --- a/lib/g1/currency.dart +++ b/lib/g1/currency.dart @@ -6,7 +6,7 @@ extension CurrencyExtension on Currency { case Currency.G1: return 'Äž1'; case Currency.DU: - return 'DUÄŸ1'; + return 'DU'; } } } diff --git a/lib/ui/notification_controller_mobile.dart b/lib/ui/notification_controller_mobile.dart index 48571df66b529f1c6e3f17ec307d306da0c0ad32..a0dae59d1b9f625dca4bc85f13f6591d814f5a56 100644 --- a/lib/ui/notification_controller_mobile.dart +++ b/lib/ui/notification_controller_mobile.dart @@ -150,11 +150,19 @@ class NotificationController { : tr('notification_new_sent_title'); final String desc = from != null ? tr('notification_new_payment_desc', namedArgs: <String, String>{ - 'amount': formatAmountWithLocale(locale.languageCode, amount, isG1), + 'amount': formatAmountWithLocale( + locale: locale.languageCode, + amount: amount, + isG1: isG1, + useSymbol: true), 'from': from, }) : tr('notification_new_sent_desc', namedArgs: <String, String>{ - 'amount': formatAmountWithLocale(locale.languageCode, amount, isG1), + 'amount': formatAmountWithLocale( + locale: locale.languageCode, + amount: amount, + isG1: isG1, + useSymbol: true), 'to': to!, }); if (kIsWeb) { diff --git a/lib/ui/notification_controller_web.dart b/lib/ui/notification_controller_web.dart index 622549803a3e424f409cf72cd545173b2755d879..f1405f2ac84e07005ee6a78a8e9b6c5e72a42020 100644 --- a/lib/ui/notification_controller_web.dart +++ b/lib/ui/notification_controller_web.dart @@ -101,11 +101,19 @@ class NotificationController { : tr('notification_new_sent_title'); final String desc = from != null ? tr('notification_new_payment_desc', namedArgs: <String, String>{ - 'amount': formatAmountWithLocale(locale.languageCode, amount, isG1), + 'amount': formatAmountWithLocale( + locale: locale.languageCode, + amount: amount, + isG1: isG1, + useSymbol: true), 'from': from, }) : tr('notification_new_sent_desc', namedArgs: <String, String>{ - 'amount': formatAmountWithLocale(locale.languageCode, amount, isG1), + 'amount': formatAmountWithLocale( + locale: locale.languageCode, + amount: amount, + isG1: isG1, + useSymbol: true), 'to': to!, }); try { diff --git a/lib/ui/ui_helpers.dart b/lib/ui/ui_helpers.dart index ee8503cdd082202fadfa82b80e9244f66606e193..340d86a42f0a3a7866e51f11628f717fe120ed63 100644 --- a/lib/ui/ui_helpers.dart +++ b/lib/ui/ui_helpers.dart @@ -124,25 +124,61 @@ bool bigScreen(BuildContext context) => bool smallScreen(BuildContext context) => MediaQuery.of(context).size.width <= smallScreenWidth; -String formatAmount(BuildContext context, double amount, bool isG1) { +String formatAmount( + {required BuildContext context, + required double amount, + required bool isG1, + required bool useSymbol}) { return formatAmountWithLocale( - Localizations.localeOf(context).toString(), amount, isG1); + locale: currentLocale(context), + amount: amount, + isG1: isG1, + useSymbol: useSymbol); } -String formatAmountWithLocale(String locale, double amount, bool isG1) { +String currentLocale(BuildContext context) => + Localizations.localeOf(context).toString(); + +String formatAmountWithLocale( + {required String locale, + required double amount, + required bool isG1, + required bool useSymbol}) { + final NumberFormat currencyFormatter = + currentNumberFormat(isG1: isG1, locale: locale, useSymbol: useSymbol); + return currencyFormatter.format(amount); +} + +NumberFormat currentNumberFormat( + {required bool useSymbol, required bool isG1, required String locale}) { final NumberFormat currencyFormatter = NumberFormat.currency( // in English $10 is G110 ... confusing - symbol: isG1 ? '${Currency.G1.name()} ' : '${Currency.DU.name()} ', + symbol: useSymbol ? currentCurrency(isG1) : '', locale: locale, decimalDigits: isG1 ? 2 : 4, ); - return currencyFormatter.format(amount); + return currencyFormatter; +} + +String currentCurrency(bool isG1) { + return isG1 ? '${Currency.G1.name()} ' : '${Currency.DU.name()} '; +} + +String currentCurrencyTrimmed(bool isG1) { + return currentCurrency(isG1).trim(); } String formatKAmount( - BuildContext context, double amount, bool isG1, double currentUd) => + {required BuildContext context, + required double amount, + required bool isG1, + required double currentUd, + required bool useSymbol}) => formatAmount( - context, isG1 ? amount / 100 : ((amount / 100) / currentUd), isG1); + context: context, + amount: isG1 ? amount / 100 : ((amount / 100) / currentUd), + isG1: isG1, + useSymbol: useSymbol); double parseToDoubleLocalized( {required String locale, required String number}) => @@ -361,3 +397,14 @@ final GlobalKey<ScaffoldMessengerState> globalMessengerKey = GlobalKey<ScaffoldMessengerState>(); const Color deleteColor = Color(0xFFFE4A49); + +bool isSymbolPlacementBefore(String pattern) { + final int symbolIndex = pattern.indexOf('\u00A4'); + final int numberIndex = pattern.indexOf('#'); + + if (symbolIndex < numberIndex) { + return true; + } else { + return false; + } +} diff --git a/lib/ui/widgets/fourth_screen/transaction_item.dart b/lib/ui/widgets/fourth_screen/transaction_item.dart index 51f4b2611e7fda2c4f21c13b0e4300e8a78f0c16..c606d9f8653251e65b5619f36a17ee39acd0e949 100644 --- a/lib/ui/widgets/fourth_screen/transaction_item.dart +++ b/lib/ui/widgets/fourth_screen/transaction_item.dart @@ -23,6 +23,8 @@ class TransactionListItem extends StatelessWidget { required this.index, required this.isG1, required this.currentUd, + required this.currentSymbol, + required this.isCurrencyBefore, this.afterCancel, this.afterRetry}); @@ -31,6 +33,8 @@ class TransactionListItem extends StatelessWidget { final int index; final bool isG1; final double currentUd; + final String currentSymbol; + final bool isCurrencyBefore; final VoidCallback? afterCancel; final VoidCallback? afterRetry; @@ -49,10 +53,15 @@ class TransactionListItem extends StatelessWidget { Color? iconColor; String statusText; - final amountWithSymbol = - formatKAmount(context, transaction.amount, isG1, currentUd); + final String amountWithSymbol = formatKAmount( + context: context, + amount: transaction.amount, + isG1: isG1, + currentUd: currentUd, + useSymbol: false); + final String amountS = - '${transaction.amount < 0 ? "" : "+"}${amountWithSymbol}'; + '${transaction.amount < 0 ? "" : "+"}$amountWithSymbol'; statusText = tr('transaction_${transaction.type.name}'); switch (transaction.type) { case TransactionType.pending: @@ -219,16 +228,26 @@ class TransactionListItem extends StatelessWidget { mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.end, children: <Widget>[ - Text( - amountS, - style: TextStyle( - // fontWeight: FontWeight.bold, - color: transaction.type == TransactionType.received || - transaction.type == TransactionType.receiving - ? Colors.blue - : Colors.red, - ), - ), + Text.rich(TextSpan( + children: <InlineSpan>[ + if (isCurrencyBefore) + currencyBalanceWidget(isG1, currentSymbol), + if (isCurrencyBefore) separatorSpan(), + TextSpan( + text: amountS, + style: TextStyle( + // fontWeight: FontWeight.bold, + color: transaction.type == TransactionType.received || + transaction.type == TransactionType.receiving + ? Colors.blue + : Colors.red, + ), + ), + if (!isCurrencyBefore) separatorSpan(), + if (!isCurrencyBefore) + currencyBalanceWidget(isG1, currentSymbol), + ], + )), const SizedBox(height: 4.0), Tooltip( message: DateFormat.yMd(context.locale.languageCode) @@ -258,3 +277,33 @@ class TransactionListItem extends StatelessWidget { afterRetry!(); } } + +WidgetSpan separatorSpan() { + return const WidgetSpan( + child: SizedBox(width: 3), + ); +} + +InlineSpan currencyBalanceWidget(bool isG1, String currentSymbol) { + return TextSpan(children: <InlineSpan>[ + TextSpan( + text: currentSymbol, + style: const TextStyle( + color: Colors.black54, + ), + ), + if (!isG1) + WidgetSpan( + child: Transform.translate( + offset: const Offset(1, 4), + child: const Text( + 'Äž1', + style: TextStyle( + fontSize: 12, + // fontWeight: FontWeight.w500, + // fontFeatures: <FontFeature>[FontFeature.subscripts()], + color: Colors.black54, + ), + ))) + ]); +} diff --git a/lib/ui/widgets/fourth_screen/transaction_page.dart b/lib/ui/widgets/fourth_screen/transaction_page.dart index b174495a9b9459d867e60122b660553829f0afcc..dad5a51400a11dfdf47baec7d90c1ac1bc293b08 100644 --- a/lib/ui/widgets/fourth_screen/transaction_page.dart +++ b/lib/ui/widgets/fourth_screen/transaction_page.dart @@ -48,6 +48,7 @@ class _TransactionsAndBalanceWidgetState final int _pendingPageSize = 30; final Cron cron = Cron(); + static const double balanceFontSize = 36.0; @override void initState() { @@ -141,10 +142,17 @@ class _TransactionsAndBalanceWidgetState final String myPubKey = SharedPreferencesHelper().getPubKey(); final bool isG1 = appCubit.currency == Currency.G1; final double currentUd = appCubit.currentUd; + final String currentSymbol = currentCurrencyTrimmed(isG1); + final NumberFormat currentNumber = currentNumberFormat( + useSymbol: true, isG1: isG1, locale: currentLocale(context)); + final bool isCurrencyBefore = + isSymbolPlacementBefore(currentNumber.symbols.CURRENCY_PATTERN); + return BlocBuilder<TransactionCubit, TransactionState>( builder: (BuildContext context, TransactionState transBalanceState) { // final List<Transaction> transactions = transBalanceState.transactions; final double balance = transBalanceState.balance; + return BackdropScaffold( appBar: BackdropAppBar( backgroundColor: Theme.of(context).colorScheme.inversePrimary, @@ -190,14 +198,30 @@ class _TransactionsAndBalanceWidgetState Padding( padding: const EdgeInsets.symmetric(vertical: 10.0), child: Center( - child: Text( - formatKAmount(context, balance, isG1, currentUd), - style: TextStyle( - fontSize: 36.0, - color: - balance == 0 ? Colors.lightBlue : Colors.lightBlue, - fontWeight: FontWeight.bold), - )), + child: Text.rich(TextSpan( + children: <InlineSpan>[ + if (isCurrencyBefore) + currencyBalanceWidget(isG1, currentSymbol), + if (isCurrencyBefore) separatorSpan(), + TextSpan( + text: formatKAmount( + context: context, + amount: balance, + isG1: isG1, + currentUd: currentUd, + useSymbol: false), + style: TextStyle( + fontSize: balanceFontSize, + color: balance == 0 + ? Colors.lightBlue + : Colors.lightBlue, + fontWeight: FontWeight.bold), + ), + if (!isCurrencyBefore) separatorSpan(), + if (!isCurrencyBefore) + currencyBalanceWidget(isG1, currentSymbol), + ], + ))), ), // if (!kReleaseMode) TransactionChart(transactions: transactions) ], @@ -234,7 +258,9 @@ class _TransactionsAndBalanceWidgetState index: index, transaction: tx, isG1: isG1, + currentSymbol: currentSymbol, currentUd: currentUd, + isCurrencyBefore: isCurrencyBefore, afterRetry: () => _refresh(), afterCancel: () => _refresh()); }, @@ -253,6 +279,8 @@ class _TransactionsAndBalanceWidgetState pubKey: myPubKey, currentUd: currentUd, isG1: isG1, + isCurrencyBefore: isCurrencyBefore, + currentSymbol: currentSymbol, index: index + (_pendingController.itemList != null ? _pendingController.itemList!.length @@ -269,6 +297,38 @@ class _TransactionsAndBalanceWidgetState }); } + InlineSpan separatorSpan() { + return const WidgetSpan( + child: SizedBox(width: 7), + ); + } + + InlineSpan currencyBalanceWidget(bool isG1, String currentSymbol) { + return TextSpan(children: <InlineSpan>[ + TextSpan( + text: currentSymbol, + style: const TextStyle( + fontSize: balanceFontSize, + fontWeight: FontWeight.w500, + color: Colors.deepPurple, + ), + ), + if (!isG1) + WidgetSpan( + child: Transform.translate( + offset: const Offset(2, 16), + child: const Text( + 'Äž1', + style: TextStyle( + fontSize: balanceFontSize - 10, + fontWeight: FontWeight.w500, + // fontFeatures: <FontFeature>[FontFeature.subscripts()], + color: Colors.deepPurple, + ), + ))) + ]); + } + Future<void> _refresh() { return Future<void>.sync(() { _pagingController.refresh();