This commit is contained in:
2026-03-26 00:57:25 +03:00
parent 71de991587
commit 8ba9ae0b9f
9 changed files with 64 additions and 54 deletions
+9 -1
View File
@@ -127,7 +127,7 @@ class AppCurrencies {
CurrencyOption(symbol: '\$', name: 'US Dollar', code: 'USD'),
CurrencyOption(symbol: '', name: 'Euro', code: 'EUR'),
CurrencyOption(symbol: '£', name: 'British Pound', code: 'GBP'),
CurrencyOption(symbol: 'Br', name: 'Belarusian Ruble', code: 'BYN'),
CurrencyOption(symbol: '', name: 'Belarusian Ruble', code: 'BYN'),
CurrencyOption(symbol: '', name: 'Russian Ruble', code: 'RUB'),
CurrencyOption(symbol: '', name: 'Ukrainian Hryvnia', code: 'UAH'),
];
@@ -139,3 +139,11 @@ class AppCurrencies {
);
}
}
/// `(code, textSymbol)` for pickers and conversion rows. BYN uses `''` — use BynSign in UI.
const List<(String, String)> kDisplayCurrencies = [
('USD', r'$'),
('EUR', ''),
('BYN', ''),
('RUB', ''),
];
@@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import '../../../core/constants.dart';
import '../../../shared/widgets/byn_sign.dart';
class CurrencyPicker extends StatelessWidget {
@@ -13,12 +14,7 @@ class CurrencyPicker extends StatelessWidget {
@override
Widget build(BuildContext context) {
final currencies = [
('USD', '\$'),
('EUR', ''),
('BYN', 'Br'),
('RUB', ''),
];
final currencies = kDisplayCurrencies;
final colorScheme = Theme.of(context).colorScheme;
return Row(
@@ -1,6 +1,7 @@
import 'dart:ui';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../../../core/constants.dart';
import '../../../../shared/models/account.dart';
import '../../../../shared/models/transaction.dart';
import '../../../../shared/widgets/byn_sign.dart';
@@ -281,13 +282,7 @@ class _AccountEditorOverlayState extends State<AccountEditorOverlay> {
),
child: Column(
mainAxisSize: MainAxisSize.min,
children:
[
('USD', '\$'),
('EUR', ''),
('BYN', 'Br'),
('RUB', ''),
].map((entry) {
children: kDisplayCurrencies.map((entry) {
final isSelected = entry.$1 == _selectedCurrency;
return InkWell(
onTap: () {
@@ -1,5 +1,6 @@
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../../../core/constants.dart';
import '../../../../shared/widgets/byn_sign.dart';
class AccountEditorPanel extends ConsumerWidget {
@@ -169,12 +170,7 @@ class AccountEditorPanel extends ConsumerWidget {
).colorScheme.onSurface,
)
: Text(
[
('USD', '\$'),
('EUR', ''),
('BYN', 'Br'),
('RUB', ''),
]
kDisplayCurrencies
.firstWhere(
(c) => c.$1 == selectedCurrency,
)
@@ -12,8 +12,6 @@ import '../../settings/provider.dart';
import '../provider.dart';
String _smartBalance(double amount, AmountFormat fmt, String symbol) {
const spaceAfter = {'Br'};
final sep = spaceAfter.contains(symbol) || symbol.isEmpty ? ' ' : '';
final isWhole = amount == amount.floorToDouble();
String formatted;
@@ -25,7 +23,7 @@ String _smartBalance(double amount, AmountFormat fmt, String symbol) {
} else {
formatted = fmt.format(amount);
}
return symbol.isEmpty ? formatted : '$symbol$sep$formatted';
return symbol.isEmpty ? formatted : '$symbol$formatted';
}
class BalanceCard extends ConsumerStatefulWidget {
@@ -139,13 +137,7 @@ class BalanceCardState extends ConsumerState<BalanceCard>
final secondary = widget.previewSecondary ?? savedColors.secondary;
final gradientType = widget.previewGradientType ?? savedColors.gradientType;
final allCurrencies = [
('USD', r'$'),
('EUR', ''),
('BYN', 'Br'),
('RUB', ''),
];
final others = allCurrencies
final others = kDisplayCurrencies
.where((c) => c.$1 != widget.currencyInfo.code)
.toList();
@@ -253,7 +245,7 @@ class BalanceCardState extends ConsumerState<BalanceCard>
fontSize: 48,
color: onCard,
),
const SizedBox(width: 4),
const SizedBox(width: 2),
Text(
_smartBalance(
widget.balance,
+2 -2
View File
@@ -199,7 +199,6 @@ class ExportService {
Future<String> exportToCSV() async {
final transactionsAsync = _ref.read(transactionsProvider);
final transactions = transactionsAsync.valueOrNull ?? [];
final currency = _ref.read(currencyProvider);
final fmt = _ref.read(amountFormatProvider);
final buffer = StringBuffer();
@@ -209,7 +208,8 @@ class ExportService {
final date = DateFormat('yyyy-MM-dd').format(tx.date);
final type = tx.type.name;
final category = tx.category;
final amount = formatAmount(tx.currency, tx.amount, fmt);
final sym = currencyMap[tx.currencyCode]?.symbol ?? '';
final amount = formatAmount(sym, tx.amount, fmt);
final note = tx.note?.replaceAll(',', ';') ?? '';
buffer.writeln('$date,$type,$category,$amount,${tx.currencyCode},$note');
}
@@ -3,6 +3,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
import '../../../core/constants.dart';
import '../../../core/l10n/locale_provider.dart';
import '../../../shared/providers/amount_format_provider.dart';
import '../../../shared/widgets/byn_sign.dart';
import '../provider.dart';
class AmountFormatSection extends ConsumerWidget {
@@ -94,20 +95,45 @@ class AmountFormatSection extends ConsumerWidget {
: FontWeight.w500,
),
),
Text(
format.example.replaceFirst(
'SYM',
currencyInfo.symbol.isEmpty
? 'Br'
: currencyInfo.symbol,
),
style: TextStyle(
color: Theme.of(
context,
).colorScheme.onSurface.withOpacity(0.6),
fontSize: 12,
),
),
currencyInfo.code == 'BYN'
? Row(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
BynSign(
fontSize: 12,
color: Theme.of(context)
.colorScheme
.onSurface
.withOpacity(0.6),
),
Text(
format.example.replaceFirst(
RegExp(r'SYM\s*'),
'',
),
style: TextStyle(
color: Theme.of(context)
.colorScheme
.onSurface
.withOpacity(0.6),
fontSize: 12,
),
),
],
)
: Text(
format.example.replaceFirst(
'SYM',
currencyInfo.symbol,
),
style: TextStyle(
color: Theme.of(
context,
).colorScheme.onSurface.withOpacity(0.6),
fontSize: 12,
),
),
],
),
),
+2 -5
View File
@@ -1,10 +1,7 @@
import '../../core/constants.dart';
String formatAmount(String symbol, double amount, AmountFormat fmt) {
const spaceAfter = {'Br'};
final formatted = fmt.format(amount);
// For BYN, symbol is empty string, so we use 'Br' for text-only contexts like CSV
final displaySymbol = symbol.isEmpty ? 'Br' : symbol;
final sep = spaceAfter.contains(displaySymbol) ? ' ' : '';
return '$displaySymbol$sep$formatted';
if (symbol.isEmpty) return formatted;
return '$symbol$formatted';
}
+2 -2
View File
@@ -14,9 +14,9 @@ class BynSign extends StatelessWidget {
'\uE901',
style: TextStyle(
fontFamily: 'BynSymbol',
fontSize: fontSize,
fontSize: fontSize * 1.1,
color: color,
fontWeight: FontWeight.w700,
fontWeight: FontWeight.w900,
height: 1.0,
),
),