import 'package:flutter/widgets.dart'; import 'package:worker/generated/l10n/app_localizations.dart'; /// Extension on [BuildContext] for easy access to localizations /// /// Usage: /// ```dart /// Text(context.l10n.login) /// ``` /// /// This provides a shorter and more convenient way to access localized strings /// compared to the verbose `AppLocalizations.of(context)!` syntax. extension LocalizationExtension on BuildContext { /// Get the current app localizations /// /// Returns the [AppLocalizations] instance for the current context. /// This will never be null because the app always has a default locale. AppLocalizations get l10n => AppLocalizations.of(this); } /// Extension on [AppLocalizations] for additional formatting utilities extension LocalizationUtilities on AppLocalizations { /// Format currency in Vietnamese Dong /// /// Example: 100000 -> "100.000 ₫" String formatCurrency(double amount) { final formatter = _getCurrencyFormatter(); return formatter.format(amount); } /// Format points display with formatted number /// /// Example: 1500 -> "1.500 điểm" or "1,500 points" String formatPointsDisplay(int points) { // Use the generated method which already handles the formatting return pointsBalance(points); } /// Format large numbers with thousand separators /// /// Example: 1000000 -> "1.000.000" String formatNumber(num number) { return _formatNumber(number); } /// Get currency formatter based on locale _CurrencyFormatter _getCurrencyFormatter() { if (localeName.startsWith('vi')) { return const _VietnameseCurrencyFormatter(); } else { return const _EnglishCurrencyFormatter(); } } /// Format number with thousand separators String _formatNumber(num number) { final parts = number.toString().split('.'); final integerPart = parts[0]; final decimalPart = parts.length > 1 ? parts[1] : ''; // Add thousand separators final buffer = StringBuffer(); final reversedInteger = integerPart.split('').reversed.join(); for (var i = 0; i < reversedInteger.length; i++) { if (i > 0 && i % 3 == 0) { buffer.write(localeName.startsWith('vi') ? '.' : ','); } buffer.write(reversedInteger[i]); } final formattedInteger = buffer.toString().split('').reversed.join(); if (decimalPart.isNotEmpty) { return '$formattedInteger.$decimalPart'; } return formattedInteger; } } /// Abstract currency formatter abstract class _CurrencyFormatter { const _CurrencyFormatter(); String format(double amount); } /// Vietnamese currency formatter /// /// Format: 100.000 ₫ class _VietnameseCurrencyFormatter extends _CurrencyFormatter { const _VietnameseCurrencyFormatter(); @override String format(double amount) { final rounded = amount.round(); final parts = rounded.toString().split('').reversed.join(); final buffer = StringBuffer(); for (var i = 0; i < parts.length; i++) { if (i > 0 && i % 3 == 0) { buffer.write('.'); } buffer.write(parts[i]); } final formatted = buffer.toString().split('').reversed.join(); return '$formatted ₫'; } } /// English currency formatter /// /// Format: ₫100,000 class _EnglishCurrencyFormatter extends _CurrencyFormatter { const _EnglishCurrencyFormatter(); @override String format(double amount) { final rounded = amount.round(); final parts = rounded.toString().split('').reversed.join(); final buffer = StringBuffer(); for (var i = 0; i < parts.length; i++) { if (i > 0 && i % 3 == 0) { buffer.write(','); } buffer.write(parts[i]); } final formatted = buffer.toString().split('').reversed.join(); return '₫$formatted'; } }