Files
worker/lib/core/utils/l10n_extensions.dart
Phuoc Nguyen 628c81ce13 runable
2025-10-17 17:22:28 +07:00

275 lines
8.5 KiB
Dart

import 'package:flutter/widgets.dart';
import 'package:worker/generated/l10n/app_localizations.dart';
/// Extension for easy access to AppLocalizations
///
/// This extension provides convenient access to localization strings
/// throughout the app without having to write `AppLocalizations.of(context)!`
/// every time.
///
/// Usage:
/// ```dart
/// // Instead of:
/// Text(AppLocalizations.of(context)!.login)
///
/// // You can use:
/// Text(context.l10n.login)
/// ```
extension L10nExtension on BuildContext {
/// Get the current AppLocalizations instance
///
/// This getter provides quick access to all localized strings.
/// It will throw an error if called before the app is initialized,
/// which helps catch localization issues during development.
AppLocalizations get l10n => AppLocalizations.of(this)!;
/// Get the current locale language code (e.g., 'vi', 'en')
String get languageCode => Localizations.localeOf(this).languageCode;
/// Check if the current locale is Vietnamese
bool get isVietnamese => languageCode == 'vi';
/// Check if the current locale is English
bool get isEnglish => languageCode == 'en';
}
/// Helper class for common localization patterns
///
/// This class provides utility methods for formatting dates, times,
/// currencies, and other locale-specific data.
class L10nHelper {
const L10nHelper._();
/// Format a DateTime to localized date string (DD/MM/YYYY for Vietnamese, MM/DD/YYYY for English)
///
/// Example:
/// ```dart
/// final dateStr = L10nHelper.formatDate(context, DateTime.now());
/// // Vietnamese: "17/10/2025"
/// // English: "10/17/2025"
/// ```
static String formatDate(BuildContext context, DateTime date) {
final day = date.day.toString().padLeft(2, '0');
final month = date.month.toString().padLeft(2, '0');
final year = date.year.toString();
return context.l10n.formatDate(day, month, year);
}
/// Format a DateTime to localized date-time string
///
/// Example:
/// ```dart
/// final dateTimeStr = L10nHelper.formatDateTime(context, DateTime.now());
/// // Vietnamese: "17/10/2025 lúc 14:30"
/// // English: "10/17/2025 at 14:30"
/// ```
static String formatDateTime(BuildContext context, DateTime dateTime) {
final day = dateTime.day.toString().padLeft(2, '0');
final month = dateTime.month.toString().padLeft(2, '0');
final year = dateTime.year.toString();
final hour = dateTime.hour.toString().padLeft(2, '0');
final minute = dateTime.minute.toString().padLeft(2, '0');
return context.l10n.formatDateTime(day, month, year, hour, minute);
}
/// Format a number as Vietnamese Dong currency
///
/// Example:
/// ```dart
/// final price = L10nHelper.formatCurrency(context, 1500000);
/// // Returns: "1.500.000 ₫"
/// ```
static String formatCurrency(BuildContext context, double amount) {
final formatted = context.isVietnamese
? _formatNumberVietnamese(amount)
: _formatNumberEnglish(amount);
return context.l10n.formatCurrency(formatted);
}
/// Format number with Vietnamese grouping (dots)
static String _formatNumberVietnamese(double number) {
final parts = number.toStringAsFixed(0).split('.');
final intPart = parts[0];
// Add dots every 3 digits from right
final buffer = StringBuffer();
for (var i = 0; i < intPart.length; i++) {
if (i > 0 && (intPart.length - i) % 3 == 0) {
buffer.write('.');
}
buffer.write(intPart[i]);
}
return buffer.toString();
}
/// Format number with English grouping (commas)
static String _formatNumberEnglish(double number) {
final parts = number.toStringAsFixed(0).split('.');
final intPart = parts[0];
// Add commas every 3 digits from right
final buffer = StringBuffer();
for (var i = 0; i < intPart.length; i++) {
if (i > 0 && (intPart.length - i) % 3 == 0) {
buffer.write(',');
}
buffer.write(intPart[i]);
}
return buffer.toString();
}
/// Format a relative time (e.g., "5 minutes ago", "2 days ago")
///
/// Example:
/// ```dart
/// final relativeTime = L10nHelper.formatRelativeTime(
/// context,
/// DateTime.now().subtract(Duration(minutes: 5)),
/// );
/// // Returns: "5 phút trước" (Vietnamese) or "5 minutes ago" (English)
/// ```
static String formatRelativeTime(BuildContext context, DateTime dateTime) {
final now = DateTime.now();
final difference = now.difference(dateTime);
if (difference.inSeconds < 60) {
return context.l10n.justNow;
} else if (difference.inMinutes < 60) {
return context.l10n.minutesAgo(difference.inMinutes);
} else if (difference.inHours < 24) {
return context.l10n.hoursAgo(difference.inHours);
} else if (difference.inDays < 7) {
return context.l10n.daysAgo(difference.inDays);
} else if (difference.inDays < 30) {
return context.l10n.weeksAgo((difference.inDays / 7).floor());
} else if (difference.inDays < 365) {
return context.l10n.monthsAgo((difference.inDays / 30).floor());
} else {
return context.l10n.yearsAgo((difference.inDays / 365).floor());
}
}
/// Get localized order status string
static String getOrderStatus(BuildContext context, String status) {
switch (status.toLowerCase()) {
case 'pending':
return context.l10n.pending;
case 'processing':
return context.l10n.processing;
case 'shipping':
return context.l10n.shipping;
case 'completed':
return context.l10n.completed;
case 'cancelled':
return context.l10n.cancelled;
default:
return status;
}
}
/// Get localized project status string
static String getProjectStatus(BuildContext context, String status) {
switch (status.toLowerCase()) {
case 'planning':
return context.l10n.planningProjects;
case 'in_progress':
case 'inprogress':
return context.l10n.inProgressProjects;
case 'completed':
return context.l10n.completedProjects;
default:
return status;
}
}
/// Get localized member tier string
static String getMemberTier(BuildContext context, String tier) {
switch (tier.toLowerCase()) {
case 'diamond':
return context.l10n.diamond;
case 'platinum':
return context.l10n.platinum;
case 'gold':
return context.l10n.gold;
default:
return tier;
}
}
/// Get localized user type string
static String getUserType(BuildContext context, String userType) {
switch (userType.toLowerCase()) {
case 'contractor':
return context.l10n.contractor;
case 'architect':
return context.l10n.architect;
case 'distributor':
return context.l10n.distributor;
case 'broker':
return context.l10n.broker;
default:
return userType;
}
}
/// Get localized password strength string
static String getPasswordStrength(BuildContext context, String strength) {
switch (strength.toLowerCase()) {
case 'weak':
return context.l10n.weak;
case 'medium':
return context.l10n.medium;
case 'strong':
return context.l10n.strong;
case 'very_strong':
case 'verystrong':
return context.l10n.veryStrong;
default:
return strength;
}
}
/// Format points with proper pluralization
///
/// Example:
/// ```dart
/// final pointsText = L10nHelper.formatPoints(context, 100);
/// // Returns: "+100 điểm" (Vietnamese) or "+100 points" (English)
/// ```
static String formatPoints(BuildContext context, int points,
{bool showSign = true}) {
if (showSign && points > 0) {
return context.l10n.earnedPoints(points);
} else if (showSign && points < 0) {
return context.l10n.spentPoints(points.abs());
} else {
return context.l10n.pointsBalance(points);
}
}
/// Format item count with pluralization
static String formatItemCount(BuildContext context, int count) {
return context.l10n.itemsInCart(count);
}
/// Format order count with pluralization
static String formatOrderCount(BuildContext context, int count) {
return context.l10n.ordersCount(count);
}
/// Format project count with pluralization
static String formatProjectCount(BuildContext context, int count) {
return context.l10n.projectsCount(count);
}
/// Format days remaining with pluralization
static String formatDaysRemaining(BuildContext context, int days) {
return context.l10n.daysRemaining(days);
}
}